user1982365
user1982365

Reputation: 43

OpenGL OBJ Loader Error: EXC_BAD_ACCESS code = 1

I've just began learning OpenGL and this program is a mixture of stuff I've put together myself and some stuff straight copied from tutorials to speed up the process (like the whole OBJ loader you will see soon).

I'm having an error on

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

and that error is EXC_BAD_ACCESS code = 1. I'm completely lost for answers to this issue and I've searched around but couldn't find anything unfortunately. I also know for a fact that it is loading the file as well because that was the first issue I faced but resolved. Below is all my code (which is in one file. I'll be making a whole new project from scratch soon).

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

Upvotes: 0

Views: 555

Answers (1)

Alex Reynolds
Alex Reynolds

Reputation: 96937

EXC_BAD_ACCESS usually means you are trying to access a chunk of memory that has been released or dealloc'ed. Here's the first response to a Google search on the term EXC_BAD_ACCESS that explains two strategies for tracking down the cause.

Upvotes: 1

Related Questions