OpenGL ES(在iOS上):glDrawArrays上的EXC_BAD_ACCESS要求进行球体绘制 [英] OpenGL ES (on iOS): EXC_BAD_ACCESS on glDrawArrays call for sphere drawing

查看:109
本文介绍了OpenGL ES(在iOS上):glDrawArrays上的EXC_BAD_ACCESS要求进行球体绘制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要一个过程生成的OpenGL ES球形-我在Google周围搜索并发现了

I'm in need of a procedurally-generated OpenGL ES sphere - I googled around and discovered this OGL code, and decided it looked neat so I'd modify it to be OGLES instead. I eliminated the OGL-only glBegin(), glEnd() and modified the original drawtri and drawsphere to be generatetri and generateSpherePoints. These new functions assign GLfloat values into static arrays for the sphere normals and vertices, meaning I can then call a new function drawSphere() at whim and the points needn't be recalculated. I've also added x,y,z parameters to generateSpherePoints, allowing specification of a non-zero sphere centre.

问题是我的OGLES版本在glDrawArrays行的XCode中给出了EXC_BAD_ACCESS.通过调试器,我检查了'sphereNormals'和'sphereVertices'数组,并根据需要很好地填充了它们.如果有人可以提出这个问题,我将不胜感激,因为我现在一无所知!

The problem is that my OGLES version gives an EXC_BAD_ACCESS in XCode at the glDrawArrays line. Through the debugger I've inspected the 'sphereNormals' and 'sphereVertices' arrays and they look well populated as desired. I'd be very grateful if someone can suggest what the issue might be, as I'm clueless right about now!

#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);
}

推荐答案

EXC_BAD_ACCESS意味着您的代码正在尝试访问它不拥有的内存地址.最常见的原因是内存管理代码中的错误,该错误导致对象在仍在使用时被释放.例如,您的代码可能无法保留所需的对象,或者可能过早释放了对象.

EXC_BAD_ACCESS means that your code is attempting to access a memory address that it doesn't own. The most common cause of this is an error in memory management code that causes an object to be deallocated while it's still in use. For example, your code may have failed to retain an object it needs, or it may have released an object prematurely.

在这种情况下,我想您要绘制的视图可能已经过早地释放.但是,您不必猜测,而是应该使用NSZombieEnabled工具来找出代码尝试访问的已释放对象.请参阅 iOS开发指南 调试应用程序部分.

In this case, I would guess that the view you're drawing to may have been deallocated prematurely. But rather than guessing, you should use the NSZombieEnabled facility to figure out which deallocated object the code is attempting to access. See the iOS Development Guide section on Debugging Applications.

这篇关于OpenGL ES(在iOS上):glDrawArrays上的EXC_BAD_ACCESS要求进行球体绘制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆