Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 1 of 2 12 LastLast
Results 1 to 10 of 12

Thread: Drawing a Wavefront OBJ cube

  1. #1
    Junior Member Newbie
    Join Date
    May 2012
    Posts
    8

    Question Drawing a Wavefront OBJ cube

    Hello everyone,

    I have finally finished my Wavefront OBJ parser (sort of), and trying to test a cube shape, which is unfortunately failing for me.

    To begin with i only want to draw the cube actual cube, i dont care about textures or normals!

    So this is my Wavefront OBJ file:

    Code :
    v -0.307796 0.00433517 0
    v 0.299126 0.00433517 0
    v 0.299126 0.00433517 0.48337
    v -0.307796 0.00433517 0.48337
    v -0.307796 0.364153 0.48337
    v 0.299126 0.364153 0.48337
    v 0.299126 0.364153 0
    v -0.307796 0.364153 0
     
    f 7/1/1 3/2/2 2/3/3
    f 3/4/4 7/5/5 6/6/6
    f 5/7/7 1/8/8 4/9/9
    f 1/10/10 5/11/11 8/12/12
    f 7/13/13 1/14/14 8/15/15
    f 1/16/16 7/17/17 2/18/18
    f 3/19/19 5/20/20 4/21/21
    f 5/22/22 3/23/23 6/24/24
    f 5/25/25 7/26/26 8/27/27
    f 7/28/28 5/29/29 6/30/30
    f 3/31/31 1/32/32 2/33/33
    f 1/34/34 3/35/35 4/36/36

    So basically the faces is written in following form: f v1/vt1/vn1 v2/vt2/vn2 v3/vt3/vn3 ...

    Since i only want the index of the vertices (dont care for normals and textures) i save vertices and my indices as:

    Code :
    const Vertex Vertices[] = {
        {-0.307796,0.00433517,0},
        {0.299126,0.00433517,0},
        {0.299126,0.00433517,0.48337},
        {-0.307796,0.00433517,0.48337},
        {-0.307796,0.364153,0.48337},
        {0.299126,0.364153,0.48337},
        {0.299126,0.364153,0},
        {-0.307796,0.364153,0}
    };
     
    const GLubyte Indices[] = {
        7, 3, 2, 
        3, 7, 6, 
        5, 1, 4, 
        1, 5, 8, 
        7, 1, 8, 
        1, 7, 2, 
        3, 5, 4, 
        5, 3, 6, 
        5, 7, 8, 
        7, 5, 6, 
        3, 1, 2, 
        1, 3, 4 
    };

    And all the OpenGL stuff (objective-C):

    Code :
    - (void)setupRenderBuffer {
        glGenRenderbuffers(1, &_colorRenderBuffer);
        glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderBuffer);        
        [_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:_eaglLayer];    
    }
     
    - (void)setupDepthBuffer {
        glGenRenderbuffers(1, &_depthRenderBuffer);
        glBindRenderbuffer(GL_RENDERBUFFER, _depthRenderBuffer);
        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, self.frame.size.width, self.frame.size.height);    
    }
     
    - (void)setupFrameBuffer {    
        GLuint framebuffer;
        glGenFramebuffers(1, &framebuffer);
        glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);   
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _colorRenderBuffer);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthRenderBuffer);
    }
     
    - (GLuint)compileShader:(NSString*)shaderName withType:(GLenum)shaderType {
     
        // 1
        NSString* shaderPath = [[NSBundle mainBundle] pathForResource:shaderName ofType:@"glsl"];
        NSError* error;
        NSString* shaderString = [NSString stringWithContentsOfFile:shaderPath encoding:NSUTF8StringEncoding error:&error];
        if (!shaderString) {
            NSLog(@"Error loading shader: %@", error.localizedDescription);
            exit(1);
        }
     
        // 2
        GLuint shaderHandle = glCreateShader(shaderType);    
     
        // 3
        const char * shaderStringUTF8 = [shaderString UTF8String];    
        int shaderStringLength = [shaderString length];
        glShaderSource(shaderHandle, 1, &shaderStringUTF8, &shaderStringLength);
     
        // 4
        glCompileShader(shaderHandle);
     
        // 5
        GLint compileSuccess;
        glGetShaderiv(shaderHandle, GL_COMPILE_STATUS, &compileSuccess);
        if (compileSuccess == GL_FALSE) {
            GLchar messages[256];
            glGetShaderInfoLog(shaderHandle, sizeof(messages), 0, &messages[0]);
            NSString *messageString = [NSString stringWithUTF8String:messages];
            NSLog(@"%@", messageString);
            exit(1);
        }
     
        return shaderHandle;
     
    }
     
    - (void)compileShaders {
     
        // 1
        GLuint vertexShader = [self compileShader:@"SimpleVertex" withType:GL_VERTEX_SHADER];
        GLuint fragmentShader = [self compileShader:@"SimpleFragment" withType:GL_FRAGMENT_SHADER];
     
        // 2
        GLuint programHandle = glCreateProgram();
        glAttachShader(programHandle, vertexShader);
        glAttachShader(programHandle, fragmentShader);
        glLinkProgram(programHandle);
     
        // 3
        GLint linkSuccess;
        glGetProgramiv(programHandle, GL_LINK_STATUS, &linkSuccess);
        if (linkSuccess == GL_FALSE) {
            GLchar messages[256];
            glGetProgramInfoLog(programHandle, sizeof(messages), 0, &messages[0]);
            NSString *messageString = [NSString stringWithUTF8String:messages];
            NSLog(@"%@", messageString);
            exit(1);
        }
     
        // 4
        glUseProgram(programHandle);
     
        // 5
        _positionSlot = glGetAttribLocation(programHandle, "Position");
        _colorSlot = glGetAttribLocation(programHandle, "SourceColor");
        glEnableVertexAttribArray(_positionSlot);
        glEnableVertexAttribArray(_colorSlot);
     
        _projectionUniform = glGetUniformLocation(programHandle, "Projection");
        _modelViewUniform = glGetUniformLocation(programHandle, "Modelview");
    }
     
    - (void)setupVBOs {
     
        GLuint vertexBuffer;
        glGenBuffers(1, &vertexBuffer);
        glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
        glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
     
        GLuint indexBuffer;
        glGenBuffers(1, &indexBuffer);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW);
     
    }
     
    - (void)render:(CADisplayLink*)displayLink {
        glClearColor(0, 104.0/255.0, 55.0/255.0, 1.0);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glEnable(GL_DEPTH_TEST);
     
        CC3GLMatrix *projection = [CC3GLMatrix matrix];
        float h = 4.0f * self.frame.size.height / self.frame.size.width;
        [projection populateFromFrustumLeft:-2 andRight:2 andBottom:-h/2 andTop:h/2 andNear:4 andFar:10];
        glUniformMatrix4fv(_projectionUniform, 1, 0, projection.glMatrix);
     
        CC3GLMatrix *modelView = [CC3GLMatrix matrix];
        [modelView populateFromTranslation:CC3VectorMake(sin(CACurrentMediaTime()), 0, -7)];
        _currentRotation += displayLink.duration * 90;
        [modelView rotateBy:CC3VectorMake(_currentRotation, _currentRotation, 0)];
        glUniformMatrix4fv(_modelViewUniform, 1, 0, modelView.glMatrix);
     
        // 1
        glViewport(0, 0, self.frame.size.width, self.frame.size.height);
     
        // 2
        glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
        glVertexAttribPointer(_colorSlot, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) (sizeof(float) * 3));
     
        // 3
    //    glDrawElements(GL_TRIANGLES, sizeof(Indices)/sizeof(Indices[0]), GL_UNSIGNED_BYTE, 0);
        glDrawElements(GL_TRIANGLES, sizeof(Indices), GL_UNSIGNED_BYTE, 0);
     
        [_context presentRenderbuffer:GL_RENDERBUFFER];
    }

    So to get back to the actual issue, i do not exactly get what should have looked like a actual cube. It looks like some bits and pieces are missing in terms of connections to vertices.

    I have taken a screenshot to show what i am viewing:

    Click image for larger version. 

Name:	Skærmbillede 2012-05-22 kl. 22.39.41.jpg 
Views:	158 
Size:	3.0 KB 
ID:	738

  2. #2
    Member Regular Contributor
    Join Date
    Jan 2012
    Location
    Germany
    Posts
    325
    Your indices start at 1, you should count starting from 0.

  3. #3
    Junior Member Newbie
    Join Date
    May 2012
    Posts
    8
    I assume that the first in my Wavefront OBJ file is vt0, if thats what you mean? If thats the case i do start with the first indice which is '0'.
    Last edited by Graphicz; 05-23-2012 at 06:54 AM.

  4. #4
    Member Regular Contributor
    Join Date
    Jan 2012
    Location
    Germany
    Posts
    325
    Code :
    const Vertex Vertices[] = {     {-0.307796,0.00433517,0},     {0.299126,0.00433517,0},     {0.299126,0.00433517,0.48337},     {-0.307796,0.00433517,0.48337},     {-0.307796,0.364153,0.48337},     {0.299126,0.364153,0.48337},     {0.299126,0.364153,0},     {-0.307796,0.364153,0} };  
    const GLubyte Indices[] = {     7, 3, 2,      3, 7, 6,      5, 1, 4,      1, 5, 8,      7, 1, 8,      1, 7, 2,      3, 5, 4,      5, 3, 6,      5, 7, 8,      7, 5, 6,      3, 1, 2,      1, 3, 4  };

    Your indices start at 1 and go to 8, you should index from 0 to 7 as your VBO only has 8 vertices in it.

    Also, your glVertexAttribPointer calls seem wrong: stride is the size in bytes of one vertex, 3*sizeof(float) for the position, not sizeof(Vertex). I also don't see color in your buffer.
    Last edited by menzel; 05-23-2012 at 07:34 AM.

  5. #5
    Junior Member Newbie
    Join Date
    May 2012
    Posts
    8
    Is there a way to create a offset? Because the exporting from AC3D creates the values as they are. I see its a problem now..

  6. #6
    Junior Member Newbie
    Join Date
    May 2012
    Posts
    8
    http://en.wikipedia.org/wiki/Wavefront_OBJ

    Vertex
    A valid vertex index starts from 1 and matches the corresponding vertex elements of a previously defined vertex list. Each face can contain three or more vertices.
    f v1 v2 v3 v4 ...

  7. #7
    Junior Member Newbie
    Join Date
    May 2012
    Posts
    8
    I tested following which was found randomly:


    Quote Originally Posted by menzel View Post
    Code :
    const Vertex Vertices[] = {     {-0.307796,0.00433517,0},     {0.299126,0.00433517,0},     {0.299126,0.00433517,0.48337},     {-0.307796,0.00433517,0.48337},     {-0.307796,0.364153,0.48337},     {0.299126,0.364153,0.48337},     {0.299126,0.364153,0},     {-0.307796,0.364153,0} };  
    const GLubyte Indices[] = {     7, 3, 2,      3, 7, 6,      5, 1, 4,      1, 5, 8,      7, 1, 8,      1, 7, 2,      3, 5, 4,      5, 3, 6,      5, 7, 8,      7, 5, 6,      3, 1, 2,      1, 3, 4  };

    Your indices start at 1 and go to 8, you should index from 0 to 7 as your VBO only has 8 vertices in it.

    Also, your glVertexAttribPointer calls seem wrong: stride is the size in bytes of one vertex, 3*sizeof(float) for the position, not sizeof(Vertex). I also don't see color in your buffer.
    I found a random cube online, with following values:

    Code :
    //const GLubyte Indices[] = {
    //    6,1,1, 3,2,2, 2,3,3, 7,4,4,
    //    8,5,5, 1,6,6, 4,7,7, 5,8,8,
    //    7,9,9, 2,10,10, 1,11,11, 8,12,12,
    //    5,13,13, 4,14,14, 3,15,15, 6,16,16,
    //    8,17,17, 5,18,18, 6,19,19, 7,20,20,
    //    1,21,21, 2,22,22, 3,23,23, 4,24,24
    //};
     
    //const GLubyte Indices[] = {
    //    // Front
    //    0, 1, 2,
    //    2, 3, 0,
    //    // Back
    //    4, 6, 5,
    //    4, 7, 6,
    //    // Left
    //    2, 7, 3,
    //    7, 6, 2,
    //    // Right
    //    0, 4, 1,
    //    4, 1, 5,
    //    // Top
    //    6, 2, 1, 
    //    1, 6, 5,
    //    // Bottom
    //    0, 3, 7,
    //    0, 7, 4    
    //};

    This compiles quite fine, i assume theres something wrong with the values i get from my model. But it does not make much sense since i can open it in different 3D programs as is.

  8. #8
    Junior Member Newbie
    Join Date
    May 2012
    Posts
    8
    Quote Originally Posted by menzel View Post
    Code :
    const Vertex Vertices[] = {     {-0.307796,0.00433517,0},     {0.299126,0.00433517,0},     {0.299126,0.00433517,0.48337},     {-0.307796,0.00433517,0.48337},     {-0.307796,0.364153,0.48337},     {0.299126,0.364153,0.48337},     {0.299126,0.364153,0},     {-0.307796,0.364153,0} };  
    const GLubyte Indices[] = {     7, 3, 2,      3, 7, 6,      5, 1, 4,      1, 5, 8,      7, 1, 8,      1, 7, 2,      3, 5, 4,      5, 3, 6,      5, 7, 8,      7, 5, 6,      3, 1, 2,      1, 3, 4  };

    Your indices start at 1 and go to 8, you should index from 0 to 7 as your VBO only has 8 vertices in it.

    Also, your glVertexAttribPointer calls seem wrong: stride is the size in bytes of one vertex, 3*sizeof(float) for the position, not sizeof(Vertex). I also don't see color in your buffer.
    Thanks for pointing that issue out. I just did "-1" in my parser and everything was fixed.

  9. #9
    Junior Member Newbie
    Join Date
    May 2012
    Posts
    8
    Okay, so i got the parsing stuff in place. Im trying to start from scratch with the code. Im trying to use VAO which is somewhat failing for me, since only 10% of the object is rendered. Im not sure why and how the rest is not rendered?

    The parser stuff:
    Code :
        struct ObjMeshVertex{
            Vector3f pos;
            Vector2f texcoord;
            Vector3f normal;
        };
     
        struct ObjMeshFace{
            ObjMeshVertex vertices[3];
        };
     
        struct ObjMesh{
            std::vector<ObjMeshFace> faces;
        };
     
        ObjMesh myMesh;
     
        for(size_t i = 0; i < faces.size(); ++i){
            ObjMeshFace face;
            for(size_t j = 0; j < 3; ++j){
                face.vertices[j].pos        = positions[faces[i].pos_index[j] - 1];
                face.vertices[j].texcoord   = texcoords[faces[i].tex_index[j] - 1];
                face.vertices[j].normal     = normals[faces[i].nor_index[j] - 1];
            }
            myMesh.faces.push_back(face);
        }

    Setup:
    Code :
            glGenVertexArraysOES(1, &_boxVAO);
            glBindVertexArrayOES(_boxVAO);
     
            int sizeOfFaces = myMesh.faces.size() * sizeof(ObjMeshFace);
            glGenBuffers(1, &_boxBuffer);
            glBindBuffer(GL_ARRAY_BUFFER, _boxBuffer);
            glBufferData(GL_ARRAY_BUFFER, sizeOfFaces, &(myMesh.faces[0]), GL_STATIC_DRAW);
     
     
            glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(ObjMeshVertex), 0);
            glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(ObjMeshVertex), (void*)offsetof(ObjMeshVertex, texcoord));        
            glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE ,sizeof(ObjMeshVertex), (void*)offsetof(ObjMeshVertex, normal));
     
            glEnableVertexAttribArray(0);
            glEnableVertexAttribArray(1);
            glEnableVertexAttribArray(2);
     
            glBindVertexArrayOES(0);

    Draw:
    Code :
        glBindVertexArrayOES(_boxVAO);
        glDrawArrays(GL_TRIANGLES, 0, indicesize);
    Where indicesize = myMesh.faces.size()

  10. #10
    Senior Member OpenGL Pro BionicBytes's Avatar
    Join Date
    Mar 2009
    Location
    UK, London
    Posts
    1,170
    Code :
    glDrawArrays(GL_TRIANGLES, 0, indicesize);
    Are you sure you have the right value for indicesize as this needs to represent all faces (where each face = 3 triangles, and each triangle=3 verticies).
    So you could be a factor of 9 out.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •