0

I am currently following a basic OpenGL tutorial where the goal is to read data from an .OBJ file and then render the model. The tutorial is located here - http://www.opengl-tutorial.org/beginners-tutorials/tutorial-7-model-loading/.

Currently, my program opens the OBJ file specified and parses it using the parsing engine discussed in the tutorial here - http://www.opengl-tutorial.org/beginners-tutorials/tutorial-7-model-loading/#Reading_the_file.

The object I am trying to render is the Cube located on the same tutorial page URL.

I believe my problem lies in my display(void) function. After I execute glutDisplayFunc(display); in my main(), I am presented with a black window, rather than my rendered model.

This is my current display(void) function:

void display(void)
{
    GLuint vbo;

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    glBegin(GL_TRIANGLES);
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3) * 3, &vertices[0], GL_STATIC_DRAW);
    glDrawElements(GL_TRIANGLES, vertices.size() * sizeof(glm::vec3) * 3, GL_UNSIGNED_INT, &vertices[0]);

    // check OpenGL error
    GLenum err;
    while ((err = glGetError()) != GL_NO_ERROR)
    {
        printf("OpenGL error: %u", err);
    }

    glEnd();

    glutSwapBuffers();
}

And here is the data my parser reads in, perhaps it is a parsing issue:

Success: GLEW_OK Success: Opened OBJ File cube.obj Read in Vertices: 1.000000, -1.000000, -1.000000 Read in Vertices: 1.000000, -1.000000, 1.000000 Read in Vertices: -1.000000, -1.000000, 1.000000 Read in Vertices: -1.000000, -1.000000, -1.000000 Read in Vertices: 1.000000, 1.000000, -1.000000 Read in Vertices: 0.999999, 1.000000, 1.000001 Read in Vertices: -1.000000, 1.000000, 1.000000 Read in Vertices: -1.000000, 1.000000, -1.000000 Read in texture coordinate: 0.748573, 0.750412 Read in texture coordinate: 0.749279, 0.501284 Read in texture coordinate: 0.999110, 0.501077 Read in texture coordinate: 0.999455, 0.750380 Read in texture coordinate: 0.250471, 0.500702 Read in texture coordinate: 0.249682, 0.749677 Read in texture coordinate: 0.001085, 0.750380 Read in texture coordinate: 0.001517, 0.499994 Read in texture coordinate: 0.499422, 0.500239 Read in texture coordinate: 0.500149, 0.750166 Read in texture coordinate: 0.748355, 0.998230 Read in texture coordinate: 0.500193, 0.998728 Read in texture coordinate: 0.498993, 0.250415 Read in texture coordinate: 0.748953, 0.250920 Read in Normals: 0.000000, 0.000000, -1.000000 Read in Normals: -1.000000, -0.000000, -0.000000 Read in Normals: -0.000000, -0.000000, 1.000000 Read in Normals: -0.000001, 0.000000, 1.000000 Read in Normals: 1.000000, -0.000000, 0.000000 Read in Normals: 1.000000, 0.000000, 0.000001 Read in Normals: 0.000000, 1.000000, -0.000000 Read in Normals: -0.000000, -1.000000, 0.000000 Reached end of file Out Vertices Size: 234

glGetError() has not produced an error for me once, so I was not able to debug the issue that way.

Any suggestions / input?

3
  • 1
    The cube is build around the origin, so if the camera is not moved backward you might not see it because you only "see" the back faces of the cube and they are not rendered because you might have culling enabled (default). Did you try to move the camera around? As a second hint you might want to double check the winding order of the triangles. - Also usually you call glGenBuffers and glBufferData only once per object and not every frame to this during initialization... Commented Mar 17, 2015 at 21:23
  • Yes I have moved the camera around but only black screen results. As for your second hint, I did call glGenBuffers and glBufferData only once for this object, in display(void). Thanks for your reply Commented Mar 17, 2015 at 21:35
  • In addition to what @AndonM.Coleman said, your call to glDrawElements is most likely incorrect. You do not appear to have an index buffer (since vertices appears to be your position/normals etc). Instead you should do glDrawArrays(GL_TRIANGLES, 0, vertices.size()). Commented Mar 17, 2015 at 21:52

1 Answer 1

2

None of those commands (including glGetError (...)) are valid between glBegin (...) and glEnd (...). If you move the calls to glGetError to come after glEnd, you should get GL_INVALID_OPERATION one or more times.

Remove glBegin and glEnd, they serve no purpose in this code, and only render the rest of your commands invalid.

Name

glBegin — delimit the vertices of a primitive or a group of like primitives

C Specification

void glBegin( GLenum mode);

Description

[...]

Only a subset of GL commands can be used between glBegin and glEnd. The commands are glVertex, glColor, glSecondaryColor, glIndex, glNormal, glFogCoord, glTexCoord, glMultiTexCoord, glVertexAttrib, glEvalCoord, glEvalPoint, glArrayElement, glMaterial, and glEdgeFlag. Also, it is acceptable to use glCallList or glCallLists to execute display lists that include only the preceding commands. If any other GL command is executed between glBegin and glEnd, the error flag is set and the command is ignored.


Regarding the rest of your code, you should not be generating a new buffer every frame. Do that once during initialization, add a vertex pointer, and change your draw command to glDrawArrays (...):

glDrawArrays (GL_TRIANGLES, 0, vertices.size());

glDrawElements (...) is only to be used if you have an index buffer. Unless I completely misunderstood the structure of your data, vertices is your vertex data, and does not store a list of indices.


Update 1:

After reading the tutorial your question is based on, the following changes are necessary when you load your .obj model:

GLuint buffers [3];
glGenBuffers(3, buffers);

// Position Buffer = 0
glBindBuffer(GL_ARRAY_BUFFER, buffers [0]);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), &vertices[0], GL_STATIC_DRAW);
glVertexPointer (3, GL_FLOAT, 0, NULL);
// ^^^^^^^^^^^^ Sources data from VBO bound to `GL_ARRAY_BUFFER`, so a NULL pointer is OK
glEnableClientState (GL_VERTEX_ARRAY); // Use this array for drawing

// Tex Coords = 1
glBindBuffer (GL_ARRAY_BUFFER, buffers [1]);
glBufferData (GL_ARRAY_BUFFER, uvs.size () * sizeof (glm::vec2), &uvs [0], GL_STATIC_DRAW);
glTexCoordPointer   (2, GL_FLOAT, 0, NULL);
glEnableClientState (GL_TEXTURE_COORD_ARRAY);

// Normals = 2
glBindBuffer (GL_ARRAY_BUFFER, buffers [2]);
glBufferData (GL_ARRAY_BUFFER, normals.size () * sizeof (glm::vec3), &normals [0], GL_STATIC_DRAW);
glNormalPointer (GL_FLOAT, 0, NULL);
glEnableClientState (GL_NORMAL_ARRAY);

Keep in mind, once you learn to use shaders, you should stop using functions such as glVertexPointer (...) and glEnableClientState (...). You will be expected to use glVertexAttribPointer (...) and glEnableVertexAttribArray (...) instead.

I wrote the code this way so you can get something up and running immediately, but it's not the modern way of writing GL software.

Sign up to request clarification or add additional context in comments.

11 Comments

First of all, thank you very much for your reply and consideration. I understand why glBegin() and glEnd() were causing issues and I've removed them. I have also changed the draw command to glDrawArrays (GL_TRIANGLES, 0, vertices.size());. Also, I have removed glGenBuffers(), glBindBuffer(), and glBufferData() from display(void) and placed them in main, since I assume having them in display(void) was causing a new buffer to be generated every frame. However, I am still seeing a black window displayed, even though everything compiles okay. What exactly do you mean by "add a vertex pointer"?
@Coder: Probably better if I show you. I just took a peak at the tutorial this is based on, and I think I have enough information to add this to my answer in a couple of minutes.
@Coder: Are you familiar with shaders at this point? The original tutorial was written assuming you were going to use them, but I can write this answer using old-style vertex arrays (without shaders) if need be.
At this point I am not familiar with them. My next step will be to implement one, once I am able to get the model to just display normally. Thank you very much sir
@Coder: I'll take a look at it tomorrow morning.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.