0

我刚开始学习 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 代码 = 1。我完全找不到这个问题的答案,我四处寻找,但不幸的是找不到任何东西。我也知道它也在加载文件,因为这是我遇到但解决的第一个问题。下面是我的所有代码(在一个文件中。我很快就会从头开始制作一个全新的项目)。

主文件

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

1 回答 1

1

EXC_BAD_ACCESS通常意味着您正在尝试访问已释放或解除分配的一块内存。这是对该术语的 Google 搜索的第一个响应,该术语EXC_BAD_ACCESS解释了追踪原因的两种策略。

于 2013-04-16T08:21:25.153 回答