我需要程序生成的OpenGL ES球體 - 我搜索並發現了this OGL code,並且認爲它看起來很整潔,所以我將它修改爲改爲OGLES。我刪除了僅OGL的glBegin(),glEnd()並將原始的drawtri和drawsphere修改爲generatetri和generateSpherePoints。這些新函數將GLfloat值分配給球體法線和頂點的靜態數組,這意味着我可以隨時調用一個新的函數drawSphere(),並且這些點不需要重新計算。我還添加了x,y,z參數來生成SpherePoints,從而允許指定非零球體中心。OpenGL ES(在iOS上):glDrawArrays上的EXC_BAD_ACCESS調用球體繪圖
問題是,我的OGLES版本在glDrawArrays行的XCode中提供了EXC_BAD_ACCESS。通過調試器,我檢查了'sphereNormals'和'sphereVertices'數組,並且他們看起來很滿意。如果有人能夠提出這個問題,我會非常感激,因爲我現在無能爲力!
#define SX .525731112119133606
#define SZ .850650808352039932
/* Drawing Sphere */
static GLfloat vdata[12][3] = {
{-SX, 0.0, SZ}, {SX, 0.0, SZ}, {-SX, 0.0, -SZ}, {SX, 0.0, -SZ},
{0.0, SZ, SX}, {0.0, SZ, -SX}, {0.0, -SZ, SX}, {0.0, -SZ, -SX},
{SZ, SX, 0.0}, {-SZ, SX, 0.0}, {SZ, -SX, 0.0}, {-SZ, -SX, 0.0}
};
static GLuint tindices[20][3] = {
{0,4,1}, {0,9,4}, {9,5,4}, {4,5,8}, {4,8,1},
{8,10,1}, {8,3,10}, {5,3,8}, {5,2,3}, {2,7,3},
{7,10,3}, {7,6,10}, {7,11,6}, {11,0,6}, {0,1,6},
{6,1,10}, {9,0,11}, {9,11,2}, {9,2,5}, {7,2,11} };
void normalize(GLfloat *a) {
GLfloat d=sqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]);
a[0]/=d; a[1]/=d; a[2]/=d;
}
static const int ndiv = 5;
static const int vecSize = 3;
static const int isoVertexCount = 3;
static const int spherePointsSectionCount = 20;
static const int pointSectionSize = 9216;// value MUST be updated to be result of calcPointSectionSize(ndiv)
static const int pointCount = 184320;// value MUST be updated to be spherePointsSectionCount*pointSectionSize;
static const int sphereVertsCount = 61440; // value MUST be updated to be pointCount/vecSize;
static GLfloat spherePoints[184320]; // size MUST be updated to be pointCount value
static GLfloat sphereNormals[184320]; // size MUST be updated to be pointCount value
int calcPointSectionSize(int div) {
return vecSize*isoVertexCount*powf(4.0f,(float)(div));
}
// OpenGL ES doesn't support glBegin(), glEnd() so must use glDrawArrays() instead
void generatetri(GLfloat *a, GLfloat *b, GLfloat *c, int div, float r, int pos) {
if (div<=0) {
int X = 0, Y = 1, Z = 2;
sphereNormals[pos+X] = a[X];
sphereNormals[pos+Y] = a[Y];
sphereNormals[pos+Z] = a[Z];
spherePoints[pos+X] = a[X]*r;
spherePoints[pos+Y] = a[Y]*r;
spherePoints[pos+Z] = a[Z]*r;
sphereNormals[pos+vecSize+X] = b[X];
sphereNormals[pos+vecSize+Y] = b[Y];
sphereNormals[pos+vecSize+Z] = b[Z];
spherePoints[pos+vecSize+X] = b[X]*r;
spherePoints[pos+vecSize+Y] = b[Y]*r;
spherePoints[pos+vecSize+Z] = b[Z]*r;
sphereNormals[pos+2*vecSize+X] = c[X];
sphereNormals[pos+2*vecSize+Y] = c[Y];
sphereNormals[pos+2*vecSize+Z] = c[Z];
spherePoints[pos+2*vecSize+X] = c[X]*r;
spherePoints[pos+2*vecSize+Y] = c[Y]*r;
spherePoints[pos+2*vecSize+Z] = c[Z]*r;
/*
glNormal3fv(a); glVertex3f(a[0]*r, a[1]*r, a[2]*r);
glNormal3fv(b); glVertex3f(b[0]*r, b[1]*r, b[2]*r);
glNormal3fv(c); glVertex3f(c[0]*r, c[1]*r, c[2]*r);
*/
} else {
GLfloat ab[3], ac[3], bc[3];
for (int i=0;i<3;i++) {
ab[i]=(a[i]+b[i])/2;
ac[i]=(a[i]+c[i])/2;
bc[i]=(b[i]+c[i])/2;
}
normalize(ab); normalize(ac); normalize(bc);
const int pointSectionSize = calcPointSectionSize(div-1);
generatetri(a, ab, ac, div-1, r, pos+0*pointSectionSize);
generatetri(b, bc, ab, div-1, r, pos+1*pointSectionSize);
generatetri(c, ac, bc, div-1, r, pos+2*pointSectionSize);
generatetri(ab, bc, ac, div-1, r, pos+3*pointSectionSize);
}
}
void generateSpherePoints(float x, float y, float z, float radius) {
for (int i=0;i<20;i++) {
GLfloat *va = vdata[tindices[i][0]];
GLfloat *vb = vdata[tindices[i][1]];
GLfloat *vc = vdata[tindices[i][2]];
GLfloat a[3] = {va[0]+x,va[1]+y,va[2]+z};
GLfloat b[3] = {vb[0]+x,vb[1]+y,vb[2]+z};
GLfloat c[3] = {vc[0]+x,vc[1]+y,vc[2]+z};
generatetri(a, b, c, ndiv, radius, i*pointSectionSize);
}
}
void drawSphere() {
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glNormalPointer(GL_FLOAT, 0, sphereNormals);
glVertexPointer(3, GL_FLOAT, 0, spherePoints);
glDrawArrays(GL_TRIANGLES, 0, sphereVertsCount);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
}
代碼看起來不錯,也許你會更好用已經過測試的等效iOS代碼:http://iphonedevelopment.blogspot.com/2009/05/procedural-spheres-in-opengl-es.html – 2011-04-27 19:43:14
感謝Julio - 正如我在原始的OGL代碼搜索中看到的那個鏈接,但是由於作者聲明性能很差,所以避免了它。我想,只要我按照我的方式緩存點,我使用哪種方法並不重要。我將根據下面的cduhn的建議,使用NSZombie來尋找問題。 – KomodoDave 2011-04-27 22:54:35