OpenGL OBJ Loader Error: EXC_BAD_ACCESS code = 1



我刚刚开始学习OpenGL,这个程序是我把自己和一些直接从教程中复制的东西放在一起的混合物,以加快过程(就像你很快就会看到的整个OBJ加载器)。

出现错误
            glNormal3f(normals[faces[i]->facenum-1]->x,normals[faces[i]->facenum-1]->y,normals[faces[i]->facenum-1]->z);
            //draw the faces
            glVertex3f(vertex[faces[i]->faces[0]-1]->x,vertex[faces[i]->faces[0]-1]->y,vertex[faces[i]->faces[0]-1]->z);
            glVertex3f(vertex[faces[i]->faces[1]-1]->x,vertex[faces[i]->faces[1]-1]->y,vertex[faces[i]->faces[1]-1]->z);
            glVertex3f(vertex[faces[i]->faces[2]-1]->x,vertex[faces[i]->faces[2]-1]->y,vertex[faces[i]->faces[2]-1]->z);
            glVertex3f(vertex[faces[i]->faces[3]-1]->x,vertex[faces[i]->faces[3]-1]->y,vertex[faces[i]->faces[3]-1]->z);

,错误是EXC_BAD_ACCESS code = 1。我完全迷失了这个问题的答案,我四处搜索,但不幸的是找不到任何东西。我还知道它正在加载文件,因为这是我遇到的第一个问题,但已经解决了。下面是我所有的代码(在一个文件中)。我很快就会从头开始做一个全新的项目)。

Main.cpp

#include <GLUT/GLUT.h>
#include <math.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <fstream>
#include <cmath>
void init();
void keyboard(unsigned char key, int x, int y);
void reshape(int w, int h);
void display();
void camera();
void cubePositions();
void drawCube();
void enable();
void plane();
// Roation angles.
float xPos = 0;
float yPos = 0;
float zPos = 0;
float xRot = 0;
float yRot = 0;
float angle = 0.0;
float lastx, lasty;
// Cubes position arrays.
float cubePosZ[10];
float cubePozX[10];
// Fog variables.
GLfloat fogAngle = 0.0;
GLfloat density = 0.1;
GLfloat fogColor[4] = {0.5, 0.5, 0.5, 1.0};
#define checkImageWidth 64
#define checkImageHeight 64
static GLubyte checkImage[checkImageHeight][checkImageWidth][4];
static GLuint texName;
void makeCheckImage(void)
{
    int i, j, c;
    for (i = 0; i < checkImageHeight; i++) {
        for (j = 0; j < checkImageWidth; j++) {
            c = ((((i&0x8)==0)^((j&0x8))==0))*255;
            checkImage[i][j][0] = (GLubyte) c;
            checkImage[i][j][1] = (GLubyte) c;
            checkImage[i][j][2] = (GLubyte) c;
            checkImage[i][j][3] = (GLubyte) 255;
        }
    }
}
struct coordinate{
    float x,y,z;
    coordinate(float a,float b,float c) : x(a),y(b),z(c) {};
};
//for faces, it can contain triangles and quads as well, the four variable contain which is that
struct face{
    int facenum;
    bool four;
    int faces[4];
    face(int facen,int f1,int f2,int f3) : facenum(facen){  //constructor for triangle
        faces[0]=f1;
        faces[1]=f2;
        faces[2]=f3;
        four=false;
    }
    face(int facen,int f1,int f2,int f3,int f4) : facenum(facen){ //overloaded constructor for quad
        faces[0]=f1;
        faces[1]=f2;
        faces[2]=f3;
        faces[3]=f4;
        four=true;
    }
};
       //we rotate or object with angle degrees
int loadObject(const char* filename)
{
    std::vector<std::string*> coord;        //read every single line of the obj file as a string
    std::vector<coordinate*> vertex;
    std::vector<face*> faces;
    std::vector<coordinate*> normals;       //normal vectors for every face
    std::ifstream in(filename);     //open the .obj file
    if(!in.is_open())       //if not opened, exit with -1
    {
        std::cout << "Nor oepened" << std::endl;
        return -1;
    }
    char buf[256];
    //read in every line to coord
    while(!in.eof())
    {
        in.getline(buf,256);
        coord.push_back(new std::string(buf));
    }
    //go through all of the elements of coord, and decide what kind of element is that
    for(int i=0;i<coord.size();i++)
    {
        if(coord[i]->c_str()[0]=='#')   //if it is a comment (the first character is #)
            continue;       //we don't care about that
        else if(coord[i]->c_str()[0]=='v' && coord[i]->c_str()[1]==' ') //if vector
        {
            float tmpx,tmpy,tmpz;
            sscanf(coord[i]->c_str(),"v %f %f %f",&tmpx,&tmpy,&tmpz);       //read in the 3 float coordinate to tmpx,tmpy,tmpz
            vertex.push_back(new coordinate(tmpx,tmpy,tmpz));       //and then add it to the end of our vertex list
        }else if(coord[i]->c_str()[0]=='v' && coord[i]->c_str()[1]=='n')        //if normal vector
        {
            float tmpx,tmpy,tmpz;   //do the same thing
            sscanf(coord[i]->c_str(),"vn %f %f %f",&tmpx,&tmpy,&tmpz);
            normals.push_back(new coordinate(tmpx,tmpy,tmpz));
        }else if(coord[i]->c_str()[0]=='f')     //if face
        {
            int a,b,c,d,e;
            if(count(coord[i]->begin(),coord[i]->end(),' ')==3)     //if it is a triangle (it has 3 space in it)
            {
                sscanf(coord[i]->c_str(),"f %d//%d %d//%d %d//%d",&a,&b,&c,&b,&d,&b);
                faces.push_back(new face(b,a,c,d));     //read in, and add to the end of the face list
            }else{
                sscanf(coord[i]->c_str(),"f %d//%d %d//%d %d//%d %d//%d",&a,&b,&c,&b,&d,&b,&e,&b);
                faces.push_back(new face(b,a,c,d,e));   //do the same, except we call another constructor, and we use different pattern
            }
        }
    }
    //raw
    int num;        //the id for the list
    num=glGenLists(1);      //generate a uniqe
    glNewList(num,GL_COMPILE);      //and create it
    for(int i=0;i<faces.size();i++)
    {
        if(faces[i]->four)      //if it's a quad draw a quad
        {
            glBegin(GL_QUADS);
            //basically all I do here, is use the facenum (so the number of the face) as an index for the normal, so the 1st normal owe to the first face
            //I subtract 1 because the index start from 0 in C++
            glNormal3f(normals[faces[i]->facenum-1]->x,normals[faces[i]->facenum-1]->y,normals[faces[i]->facenum-1]->z);
            //draw the faces
            glVertex3f(vertex[faces[i]->faces[0]-1]->x,vertex[faces[i]->faces[0]-1]->y,vertex[faces[i]->faces[0]-1]->z);
            glVertex3f(vertex[faces[i]->faces[1]-1]->x,vertex[faces[i]->faces[1]-1]->y,vertex[faces[i]->faces[1]-1]->z);
            glVertex3f(vertex[faces[i]->faces[2]-1]->x,vertex[faces[i]->faces[2]-1]->y,vertex[faces[i]->faces[2]-1]->z);
            glVertex3f(vertex[faces[i]->faces[3]-1]->x,vertex[faces[i]->faces[3]-1]->y,vertex[faces[i]->faces[3]-1]->z);
            glEnd();
        }else{
            glBegin(GL_TRIANGLES);
            glNormal3f(normals[faces[i]->facenum-1]->x,normals[faces[i]->facenum-1]->y,normals[faces[i]->facenum-1]->z);
            glVertex3f(vertex[faces[i]->faces[0]-1]->x,vertex[faces[i]->faces[0]-1]->y,vertex[faces[i]->faces[0]-1]->z);
            glVertex3f(vertex[faces[i]->faces[1]-1]->x,vertex[faces[i]->faces[1]-1]->y,vertex[faces[i]->faces[1]-1]->z);
            glVertex3f(vertex[faces[i]->faces[2]-1]->x,vertex[faces[i]->faces[2]-1]->y,vertex[faces[i]->faces[2]-1]->z);
            glEnd();
        }
    }
    glEndList();
    //delete everything to avoid memory leaks
    for(int i=0;i<coord.size();i++)
        delete coord[i];
    for(int i=0;i<faces.size();i++)
        delete faces[i];
    for(int i=0;i<normals.size();i++)
        delete normals[i];
    for(int i=0;i<vertex.size();i++)
        delete vertex[i];
    return num;     //return with the id
}

// Sets the position of the cubes randomly. Can later be used for more purposeful placements.
void cubePositions()
{
    for (int i = 0; i < 10; i++)
    {
        cubePosZ[i] = rand() % 5 + 5;
        cubePozX[i] = rand() % 5 + 5;
    }
}
void drawCube()
{
    for (int i = 0; i < 10; i++)
    {
        glPushMatrix();
        //glTranslated(-cubePozX[i + 1] * 10, -1, -cubePosZ[i + 1] * 10);
        glTranslated((i + 4), 0, (i - 5));
        glTranslatef(i, 0, 5 * i);
        glScalef(2, 2, 2);
        glBegin(GL_QUADS);
        glTexCoord2f(1, 0);
        glVertex3f(-1, -1, 0);
        glNormal3f(1, 1, 1);
        glTexCoord2f(1, 1);
        glVertex3f(-1, 1, 0);
        glTexCoord2f(0, 1);
        glVertex3f(1, 1, 0);
        glTexCoord2f(0, 0);
        glVertex3f(1, -1, 0);
        glVertex3f(-1, -1, -1);
        glVertex3f(-1, 1, -1);
        glEnd();
        glPopMatrix();
    }
}
void plane()
{
    glPushMatrix();
    glColor4f(1.0, 0.0, 1.0, 1.0);
    glTranslatef(0, -2.5, 0.0);
    glScalef(100, 2, 100);
    glBegin(GL_QUADS);
    glTexCoord2f(0.0, 0.0);
    glVertex3f(-1, 0, 1);
    glTexCoord2f(1.0, 0.0);
    glVertex3f(-1, 0, -0.5);
    glTexCoord2f(1.0, 1.0);
    glVertex3f(1, 0, -0.5);
    glTexCoord2f(0.0, 1.0);
    glVertex3f(1, 0, 1);
    glEnd();
    glPopMatrix();
}
int cube;
void init()
{
    cubePositions();
    cube = loadObject("/Users/Admin/test.obj");
}
void enable()
{
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable(GL_TEXTURE_2D);
    float col[] = {1.0, 1.0, 1.0, 1.0};
    glLightfv(GL_LIGHT0, GL_DIFFUSE, col);
}
void camera()
{
    glRotatef(xRot, 1.0, 0.0, 0.0);
    glRotatef(yRot, 0.0, 1.0, 0.0);
    glTranslated(-xPos, -yPos, -zPos);
}
void display()
{
    glClearColor(0.8, 0.8, 0.8, 1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    camera();
    enable();
    drawCube();
    plane();
    glCallList(cube);
    glTranslated(-2, 0, 0);
    glutSwapBuffers();
    angle++;
}
void reshape(int w, int h)
{
    glViewport (0, 0, (GLsizei)w, (GLsizei)h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective (60, (GLfloat)w / (GLfloat)h, 1.0, 1000.0);
    glMatrixMode (GL_MODELVIEW);
}
void keyboard(unsigned char key, int x, int y)
{
    if (key == 27)
    {
        exit(0);
    }
    if (key == 'q')
    {
        xRot += 0.5;
        if (xRot > 360)
        {
            xRot -= 360;
        }
    }
    if (key == 'z')
    {
        xRot -= 0.5;
        if (xRot < - 360)
        {
            xRot += 360;
        }
    }
    if (key == 'w')
    {
        float xRotRad;
        float yRotRad;
        xRotRad = (xRot / 180 * 3.14159f);
        yRotRad = (yRot / 180 * 3.14159f);
        xPos += float(sin(yRotRad));
        zPos -= float(cos(yRotRad));
        yPos -= float(sin(xRotRad));
    }
    if (key == 's')
    {
        float xRotRad;
        float yRotRad;
        xRotRad = (xRot / 180 * 3.14159f);
        yRotRad = (yRot / 180 * 3.14159f);
        xPos -= float(sin(yRotRad));
        zPos += float(cos(yRotRad));
        yPos += float(sin(xRotRad));
    }
    if (key == 'd')
    {
        yRot += 1;
        if (yRot > 360)
        {
            yRot -= 360;
        }
    }
    if (key == 'a')
    {
        yRot -= 1;
        if (yRot < -360)
        {
            yRot += 360;
        }
    }
    if (key == 'x')
    {
        yPos -= 1;
    }
    if (key == 'c')
    {
        yPos += 1;
    }
}
void mouseMovement(int x, int y)
{
    int diffX = x - lastx;
    int diffY = y - lasty;
    lastx = x;
    lasty = y;
    xRot += (float)diffY;
    yRot += (float)diffX;
}
int main(int argc, char * argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
    glutInitWindowSize(1000, 1000);
    glutInitWindowPosition(100, 100);
    glutCreateWindow("OpenGL GLUT Computing - Taylor Moore");
    init();
    glutDisplayFunc(display);
    glutIdleFunc(display);
    glutReshapeFunc(reshape);
    glutKeyboardFunc(keyboard);
    glutPassiveMotionFunc(mouseMovement);
    glutMainLoop();
    return 0;
}

EXC_BAD_ACCESS通常意味着您正在尝试访问已释放或dealloed的内存块。以下是对谷歌搜索EXC_BAD_ACCESS的第一个回应,解释了追踪原因的两种策略。

最新更新