diff options
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/intern/CCGSubSurf.c | 185 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/CCGSubSurf.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/subsurf_ccg.c | 122 |
3 files changed, 259 insertions, 49 deletions
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c index d28136d4713..0d0283b8cb6 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf.c +++ b/source/blender/blenkernel/intern/CCGSubSurf.c @@ -3,6 +3,7 @@ #include <stdlib.h> #include <string.h> #include <math.h> +#include <float.h> #include "CCGSubSurf.h" @@ -278,6 +279,10 @@ struct _CCGSubSurf { int allowEdgeCreation; void *q, *r; + + // data for calc vert normals + int calcVertNormals; + int normalDataOffset; // data for age'ing (to debug sync) int currentAge; @@ -422,6 +427,11 @@ static void *_edge_getCo(CCGEdge *e, int lvl, int x, int dataSize) { int levelBase = lvl + (1<<lvl) - 1; return &EDGE_getLevelData(e)[dataSize*(levelBase + x)]; } +static float *_edge_getNo(CCGEdge *e, int lvl, int x, int dataSize, int normalDataOffset) { + int levelBase = lvl + (1<<lvl) - 1; + return (float*) &EDGE_getLevelData(e)[dataSize*(levelBase + x) + normalDataOffset]; +} + static void *_edge_getCoVert(CCGEdge *e, CCGVert *v, int lvl, int x, int dataSize) { int levelBase = lvl + (1<<lvl) - 1; if (v==e->v0) { @@ -493,6 +503,12 @@ static void *_face_getIFCo(CCGFace *f, int lvl, int S, int x, int y, int levels, byte *gridBase = FACE_getCenterData(f) + dataSize*(1 + S*(maxGridSize + maxGridSize*maxGridSize)); return &gridBase[dataSize*(maxGridSize + (y*maxGridSize + x)*spacing)]; } +static float *_face_getIFNo(CCGFace *f, int lvl, int S, int x, int y, int levels, int dataSize, int normalDataOffset) { + int maxGridSize = 1 + (1<<(levels-1)); + int spacing = 1<<(levels-lvl); + byte *gridBase = FACE_getCenterData(f) + dataSize*(1 + S*(maxGridSize + maxGridSize*maxGridSize)); + return (float*) &gridBase[dataSize*(maxGridSize + (y*maxGridSize + x)*spacing) + normalDataOffset]; +} static int _face_getVertIndex(CCGFace *f, CCGVert *v) { int i; for (i=0; i<f->numVerts; i++) @@ -530,6 +546,9 @@ static void *_face_getIFCoEdge(CCGFace *f, CCGEdge *e, int lvl, int eX, int eY, } return _face_getIFCo(f, levels, S, cx, cy, levels, dataSize); } +static float *_face_getIFNoEdge(CCGFace *f, CCGEdge *e, int lvl, int eX, int eY, int levels, int dataSize, int normalDataOffset) { + return (float*) ((byte*) _face_getIFCoEdge(f, e, lvl, eX, eY, levels, dataSize) + normalDataOffset); +} static void _face_free(CCGFace *f, CCGSubSurf *ss) { CCGSUBSURF_free(ss, f); @@ -574,6 +593,9 @@ CCGSubSurf *ccgSubSurf_new(CCGMeshIFC *ifc, CCGMeshHDL meshData, int subdivLevel ss->useAgeCounts = 0; ss->vertUserAgeOffset = ss->edgeUserAgeOffset = ss->faceUserAgeOffset = 0; + ss->calcVertNormals = 0; + ss->normalDataOffset = 0; + ss->q = CCGSUBSURF_alloc(ss, ss->meshIFC.vertDataSize); ss->r = CCGSUBSURF_alloc(ss, ss->meshIFC.vertDataSize); @@ -660,6 +682,22 @@ CCGError ccgSubSurf_setUseAgeCounts(CCGSubSurf *ss, int useAgeCounts, int vertUs return eCCGError_None; } +CCGError ccgSubSurf_setCalcVertexNormals(CCGSubSurf *ss, int useVertNormals, int normalDataOffset) { + if (useVertNormals) { + if (normalDataOffset<0 || normalDataOffset+12>ss->meshIFC.vertDataSize) { + return eCCGError_InvalidValue; + } else { + ss->calcVertNormals = 1; + ss->normalDataOffset = normalDataOffset; + } + } else { + ss->calcVertNormals = 0; + ss->normalDataOffset = 0; + } + + return eCCGError_None; +} + /***/ CCGError ccgSubSurf_initFullSync(CCGSubSurf *ss) { @@ -1660,6 +1698,153 @@ static void ccgSubSurf__sync(CCGSubSurf *ss) { } } } + +#define FACE_getIFNo(f, lvl, S, x, y) _face_getIFNo(f, lvl, S, x, y, subdivLevels, vertDataSize, normalDataOffset) +#define AddNo(a, b) {a[0]+= b[0], a[1]+= b[1], a[2] += b[2];} +#define CopyNo(a, b) {a[0] = b[0], a[1] = b[1], a[2] = b[2];} + if (ss->calcVertNormals) { + int lvl = ss->subdivLevels; + int edgeSize = 1 + (1<<lvl); + int gridSize = 1 + (1<<(lvl-1)); + int normalDataOffset = ss->normalDataOffset; + + for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) { + CCGFace *f = (CCGFace*) effectedF[ptrIdx]; + int S, x, y; + + for (S=0; S<f->numVerts; S++) { + for (y=0; y<gridSize; y++) { + for (x=0; x<gridSize; x++) { + float *no = FACE_getIFNo(f, lvl, S, x, y); + no[0] = no[1] = no[2] = 0.0; + } + } + } + } + + for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) { + CCGFace *f = (CCGFace*) effectedF[ptrIdx]; + int S, x, y; + + for (S=0; S<f->numVerts; S++) { + for (y=0; y<gridSize-1; y++) { + for (x=0; x<gridSize-1; x++) { + float *a = FACE_getIFCo(f, lvl, S, x+0, y+0); + float *b = FACE_getIFCo(f, lvl, S, x+1, y+0); + float *c = FACE_getIFCo(f, lvl, S, x+1, y+1); + float *d = FACE_getIFCo(f, lvl, S, x+0, y+1); + float a_cX = c[0]-a[0], a_cY = c[1]-a[1], a_cZ = c[2]-a[2]; + float b_dX = d[0]-b[0], b_dY = d[1]-b[1], b_dZ = d[2]-b[2]; + float no[3]; + + no[0] = b_dY*a_cZ - b_dZ*a_cY; + no[1] = b_dZ*a_cX - b_dX*a_cZ; + no[2] = b_dX*a_cY - b_dY*a_cX; + + AddNo(FACE_getIFNo(f, lvl, S, x+0, y+0), no); + AddNo(FACE_getIFNo(f, lvl, S, x+1, y+0), no); + AddNo(FACE_getIFNo(f, lvl, S, x+1, y+1), no); + AddNo(FACE_getIFNo(f, lvl, S, x+0, y+1), no); + + if (x==0 && y==0) { + int K; + + AddNo(FACE_getIFNo(f, lvl, (S+1)%f->numVerts, 0, 1), no); + AddNo(FACE_getIFNo(f, lvl, (S-1+f->numVerts)%f->numVerts, 1, 0), no); + + for (K=0; K<f->numVerts; K++) { + if (K!=S) { + AddNo(FACE_getIFNo(f, lvl, K, 0, 0), no); + } + } + } else if (y==0) { + AddNo(FACE_getIFNo(f, lvl, (S+1)%f->numVerts, 0, x), no); + AddNo(FACE_getIFNo(f, lvl, (S+1)%f->numVerts, 0, x+1), no); + } else if (x==0) { + AddNo(FACE_getIFNo(f, lvl, (S-1+f->numVerts)%f->numVerts, y, 0), no); + AddNo(FACE_getIFNo(f, lvl, (S-1+f->numVerts)%f->numVerts, y+1, 0), no); + } + } + } + } + } + for (ptrIdx=0; ptrIdx<numEffectedV; ptrIdx++) { + CCGVert *v = (CCGVert*) effectedV[ptrIdx]; + float no[3] = {0}; + + for (i=0; i<v->numFaces; i++) { + CCGFace *f = v->faces[i]; + AddNo(no, FACE_getIFNo(f, lvl, _face_getVertIndex(f,v), gridSize-1, gridSize-1)); + } + + for (i=0; i<v->numFaces; i++) { + CCGFace *f = v->faces[i]; + CopyNo(FACE_getIFNo(f, lvl, _face_getVertIndex(f,v), gridSize-1, gridSize-1), no); + } + } + for (ptrIdx=0; ptrIdx<numEffectedE; ptrIdx++) { + CCGEdge *e = (CCGEdge*) effectedE[ptrIdx]; + int x; + + for (x=0; x<edgeSize; x++) { + float *no = _edge_getNo(e, lvl, x, vertDataSize, normalDataOffset); + no[0] = no[1] = no[2] = 0.0; + } + + for (i=0; i<e->numFaces; i++) { + CCGFace *f = e->faces[i]; + + for (x=1; x<edgeSize-1; x++) { + AddNo( _edge_getNo(e, lvl, x, vertDataSize, normalDataOffset), + _face_getIFNoEdge(f, e, lvl, x, 0, subdivLevels, vertDataSize, normalDataOffset)); + } + } + + for (i=0; i<e->numFaces; i++) { + CCGFace *f = e->faces[i]; + + for (x=1; x<edgeSize-1; x++) { + CopyNo( _face_getIFNoEdge(f, e, lvl, x, 0, subdivLevels, vertDataSize, normalDataOffset), + _edge_getNo(e, lvl, x, vertDataSize, normalDataOffset)); + } + } + } + for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) { + CCGFace *f = (CCGFace*) effectedF[ptrIdx]; + int S; + + for (S=0; S<f->numVerts; S++) { + CopyNo( FACE_getIFNo(f, lvl, (S+1)%f->numVerts, 0, gridSize-1), + FACE_getIFNo(f, lvl, S, gridSize-1, 0)); + } + } + for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) { + CCGFace *f = (CCGFace*) effectedF[ptrIdx]; + int S, x, y; + + for (S=0; S<f->numVerts; S++) { + for (y=0; y<gridSize; y++) { + for (x=0; x<gridSize; x++) { + float *no = FACE_getIFNo(f, lvl, S, x, y); + float length = sqrt(no[0]*no[0] + no[1]*no[1] + no[2]*no[2]); + + if (length>FLT_EPSILON) { + float invLength = 1.0f/length; + no[0] *= invLength; + no[1] *= invLength; + no[2] *= invLength; + } else { + no[0] = no[1] = no[2] = 0.0; + } + } + } + } + } + } +#undef CopyNo +#undef AddNo +#undef FACE_getIFNo + #undef VERT_getCo #undef EDGE_getCo #undef FACE_getIECo diff --git a/source/blender/blenkernel/intern/CCGSubSurf.h b/source/blender/blenkernel/intern/CCGSubSurf.h index 84e30b431df..7ebce5b569f 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf.h +++ b/source/blender/blenkernel/intern/CCGSubSurf.h @@ -65,6 +65,7 @@ CCGError ccgSubSurf_processSync (CCGSubSurf *ss); CCGError ccgSubSurf_setSubdivisionLevels (CCGSubSurf *ss, int subdivisionLevels); CCGError ccgSubSurf_setAllowEdgeCreation (CCGSubSurf *ss, int allowEdgeCreation); CCGError ccgSubSurf_setUseAgeCounts (CCGSubSurf *ss, int useAgeCounts, int vertUserOffset, int edgeUserOffset, int faceUserOffset); +CCGError ccgSubSurf_setCalcVertexNormals (CCGSubSurf *ss, int useVertNormals, int normalDataOffset); /***/ diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 35a5091c9ca..d1323b6e69f 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -72,6 +72,11 @@ typedef struct _SubSurf { Mesh *me; } SubSurf; +typedef struct _VertData { + float co[3]; + float no[3]; +} VertData; + static void _subsurfNew_meshIFC_vertDataCopy(CCGMeshHDL mv, void *tv, void *av) { float *t= tv, *a= av; t[0]= a[0]; @@ -140,7 +145,7 @@ static CCGSubSurf *_getSubSurf(SubSurf *ss, int subdivLevels, int useArena) { } else { ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 4; } - ifc.vertDataSize= 12; + ifc.vertDataSize= sizeof(VertData); ifc.vertDataZero= _subsurfNew_meshIFC_vertDataZero; ifc.vertDataEqual= _subsurfNew_meshIFC_vertDataEqual; ifc.vertDataCopy= _subsurfNew_meshIFC_vertDataCopy; @@ -166,6 +171,8 @@ static CCGSubSurf *_getSubSurf(SubSurf *ss, int subdivLevels, int useArena) { ccgSubSurf_setUseAgeCounts(ccgSS, 1, 4, 8, 4); } + ccgSubSurf_setCalcVertexNormals(ccgSS, 1, BLI_STRUCT_OFFSET(VertData, no)); + return ccgSS; } @@ -565,10 +572,10 @@ static void subSurf_sync(SubSurf *ss) { int i; for (i=0; i<ss->me->totvert; i++) { - ccgSubSurf_syncVert(ss->subSurf, (CCGVertHDL) i, ss->me->mvert[i].co); + ccgSubSurf_syncVert(ss->subSurf, (CCGVertHDL) i, subSurf->me->mvert[i].co); } - if (ss->me->medge) { + if (subSurf->me->medge) { for (i=0; i<ss->me->totedge; i++) { MEdge *med = &ss->me->medge[i]; float crease = med->crease*creaseFactor/255.0f; @@ -670,7 +677,7 @@ static void ccgDM_drawEdges(DerivedMesh *dm) { for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { CCGEdge *e = ccgEdgeIterator_getCurrent(ei); EditEdge *eed= ccgSubSurf_getEdgeEdgeHandle(ss, e); - float (*edgeData)[3] = ccgSubSurf_getEdgeDataArray(ss, e); + VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); if (eed->h!=0) continue; @@ -682,8 +689,8 @@ static void ccgDM_drawEdges(DerivedMesh *dm) { glBegin(GL_LINE_STRIP); for (i=0; i<edgeSize-1; i++) { - glVertex3fv(edgeData[i]); - glVertex3fv(edgeData[i+1]); + glVertex3fv(edgeData[i].co); + glVertex3fv(edgeData[i+1].co); } glEnd(); } @@ -701,22 +708,22 @@ static void ccgDM_drawEdges(DerivedMesh *dm) { continue; for (S=0; S<numVerts; S++) { - float (*faceGridData)[3] = ccgSubSurf_getFaceGridDataArray(ss, f, S); + VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); glBegin(GL_LINE_STRIP); for (x=0; x<gridSize; x++) - glVertex3fv(faceGridData[x]); + glVertex3fv(faceGridData[x].co); glEnd(); for (y=1; y<gridSize-1; y++) { glBegin(GL_LINE_STRIP); for (x=0; x<gridSize; x++) - glVertex3fv(faceGridData[y*gridSize + x]); + glVertex3fv(faceGridData[y*gridSize + x].co); glEnd(); } for (x=1; x<gridSize-1; x++) { glBegin(GL_LINE_STRIP); for (y=0; y<gridSize; y++) - glVertex3fv(faceGridData[y*gridSize + x]); + glVertex3fv(faceGridData[y*gridSize + x].co); glEnd(); } } @@ -733,12 +740,12 @@ static void ccgDM_drawMappedEdges(DerivedMesh *dm) { for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { CCGEdge *e = ccgEdgeIterator_getCurrent(ei); - float (*edgeData)[3] = ccgSubSurf_getEdgeDataArray(ss, e); + VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); glBegin(GL_LINE_STRIP); for (i=0; i<edgeSize-1; i++) { - glVertex3fv(edgeData[i]); - glVertex3fv(edgeData[i+1]); + glVertex3fv(edgeData[i].co); + glVertex3fv(edgeData[i+1].co); } glEnd(); } @@ -755,12 +762,12 @@ static void ccgDM_drawLooseEdges(DerivedMesh *dm) { CCGEdge *e = ccgEdgeIterator_getCurrent(ei); if (!ccgSubSurf_getEdgeNumFaces(ss, e)) { - float (*edgeData)[3] = ccgSubSurf_getEdgeDataArray(ss, e); + VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); glBegin(GL_LINE_STRIP); for (i=0; i<edgeSize-1; i++) { - glVertex3fv(edgeData[i]); - glVertex3fv(edgeData[i+1]); + glVertex3fv(edgeData[i].co); + glVertex3fv(edgeData[i+1].co); } glEnd(); } @@ -779,38 +786,55 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, void (*setMaterial)(int)) { CCGFace *f= ccgFaceIterator_getCurrent(fi); EditFace *efa= ccgSubSurf_getFaceFaceHandle(ss, f); int S, x, y, numVerts= ccgSubSurf_getFaceNumVerts(ss, f); + int isSmooth = !(me->flag&ME_AUTOSMOOTH) && (efa->flag&ME_SMOOTH); - setMaterial(efa->mat_nr+1); if (efa->h!=0) continue; + setMaterial(efa->mat_nr+1); + glShadeModel(isSmooth?GL_SMOOTH:GL_FLAT); for (S=0; S<numVerts; S++) { - float (*faceGridData)[3] = ccgSubSurf_getFaceGridDataArray(ss, f, S); + VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); - for (y=0; y<gridSize-1; y++) { + if (isSmooth) { + for (y=0; y<gridSize-1; y++) { + glBegin(GL_QUAD_STRIP); + for (x=0; x<gridSize; x++) { + VertData *a = &faceGridData[(y+0)*gridSize + x]; + VertData *b = &faceGridData[(y+1)*gridSize + x]; - glBegin(GL_QUADS); - for (x=0; x<gridSize-1; x++) { - float *a = faceGridData[(y+0)*gridSize + x]; - float *b = faceGridData[(y+0)*gridSize + x + 1]; - float *c = faceGridData[(y+1)*gridSize + x + 1]; - float *d = faceGridData[(y+1)*gridSize + x]; - - if (x<gridSize-1) { - float a_cX = c[0]-a[0], a_cY = c[1]-a[1], a_cZ = c[2]-a[2]; - float b_dX = d[0]-b[0], b_dY = d[1]-b[1], b_dZ = d[2]-b[2]; - float no[3]; - - no[0] = b_dY*a_cZ - b_dZ*a_cY; - no[1] = b_dZ*a_cX - b_dX*a_cZ; - no[2] = b_dX*a_cY - b_dY*a_cX; - glNormal3fv(no); + glNormal3fv(a->no); + glVertex3fv(a->co); + glNormal3fv(b->no); + glVertex3fv(b->co); } + glEnd(); + } + } else { + glBegin(GL_QUADS); + for (y=0; y<gridSize-1; y++) { + for (x=0; x<gridSize-1; x++) { + float *a = faceGridData[(y+0)*gridSize + x].co; + float *b = faceGridData[(y+0)*gridSize + x + 1].co; + float *c = faceGridData[(y+1)*gridSize + x + 1].co; + float *d = faceGridData[(y+1)*gridSize + x].co; + + if (x<gridSize-1) { + float a_cX = c[0]-a[0], a_cY = c[1]-a[1], a_cZ = c[2]-a[2]; + float b_dX = d[0]-b[0], b_dY = d[1]-b[1], b_dZ = d[2]-b[2]; + float no[3]; + + no[0] = b_dY*a_cZ - b_dZ*a_cY; + no[1] = b_dZ*a_cX - b_dX*a_cZ; + no[2] = b_dX*a_cY - b_dY*a_cX; + glNormal3fv(no); + } - glVertex3fv(d); - glVertex3fv(c); - glVertex3fv(b); - glVertex3fv(a); + glVertex3fv(d); + glVertex3fv(c); + glVertex3fv(b); + glVertex3fv(a); + } } glEnd(); } @@ -849,12 +873,12 @@ static void ccgDM_drawMappedEdgeEM(DerivedMesh *dm, void *edge) { CCGSubSurf *ss = ccgdm->ss->subSurf; CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss); CCGEdge *e = ccgSubSurf_getEdge(ss, edge); - float (*edgeData)[3] = ccgSubSurf_getEdgeDataArray(ss, e); + VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); int i, edgeSize = ccgSubSurf_getEdgeSize(ss); glBegin(GL_LINE_STRIP); for (i=0; i<edgeSize; i++) - glVertex3fv(edgeData[i]); + glVertex3fv(edgeData[i].co); glEnd(); ccgEdgeIterator_free(ei); @@ -868,7 +892,7 @@ static void ccgDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { CCGEdge *e = ccgEdgeIterator_getCurrent(ei); EditEdge *edge = ccgSubSurf_getEdgeEdgeHandle(ss, e); - float (*edgeData)[3] = ccgSubSurf_getEdgeDataArray(ss, e); + VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); glBegin(GL_LINE_STRIP); if (!setDrawOptions || setDrawOptions(userData, edge)) { @@ -878,8 +902,8 @@ static void ccgDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void } for (i=0; i<edgeSize-1; i++) { - glVertex3fv(edgeData[i]); - glVertex3fv(edgeData[i+1]); + glVertex3fv(edgeData[i].co); + glVertex3fv(edgeData[i+1].co); } } glEnd(); @@ -896,7 +920,7 @@ static void ccgDM_drawMappedEdgesInterpEM(DerivedMesh *dm, int (*setDrawOptions) for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { CCGEdge *e = ccgEdgeIterator_getCurrent(ei); EditEdge *edge = ccgSubSurf_getEdgeEdgeHandle(ss, e); - float (*edgeData)[3] = ccgSubSurf_getEdgeDataArray(ss, e); + VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); glBegin(GL_LINE_STRIP); if (!setDrawOptions || setDrawOptions(userData, edge)) { @@ -908,7 +932,7 @@ static void ccgDM_drawMappedEdgesInterpEM(DerivedMesh *dm, int (*setDrawOptions) glColor3ub(0, ageCol>0?ageCol:0, 0); } - glVertex3fv(edgeData[i]); + glVertex3fv(edgeData[i].co); } } glEnd(); @@ -927,13 +951,13 @@ static void ccgDM_drawMappedFacesEM(DerivedMesh *dm, int (*setDrawOptions)(void int S, x, y, numVerts= ccgSubSurf_getFaceNumVerts(ss, f); for (S=0; S<numVerts; S++) { - float (*faceGridData)[3] = ccgSubSurf_getFaceGridDataArray(ss, f, S); + VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); for (y=0; y<gridSize-1; y++) { glBegin(GL_QUAD_STRIP); for (x=0; x<gridSize; x++) { - glVertex3fv(faceGridData[(y+0)*gridSize + x]); - glVertex3fv(faceGridData[(y+1)*gridSize + x]); + glVertex3fv(faceGridData[(y+0)*gridSize + x].co); + glVertex3fv(faceGridData[(y+1)*gridSize + x].co); } glEnd(); } |