3

I am having trouble spotting my mistake with this OpenGL implementation. When I run the program the only thing I get is a black screen. I should be seeing a cube. I am not getting any sort of errors. I have suspicion the culprit may lye with the VAO:

// draws the view
-(void)drawRect:(NSRect)dirtyRect
{
// clear the viewport
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

shaderProgramID = [self loadShaders];

// get uniform locations
uniformLocations[0] = glGetUniformLocation(shaderProgramID, "rotationX");
uniformLocations[1] = glGetUniformLocation(shaderProgramID, "rotationY");
uniformLocations[2] = glGetUniformLocation(shaderProgramID, "rotationZ");
uniformLocations[3] = glGetUniformLocation(shaderProgramID, "translation");
uniformLocations[4] = glGetUniformLocation(shaderProgramID, "projection");

// use this program
glUseProgram(shaderProgramID);

// create VAO
glGenVertexArraysAPPLE(1, &vao);
glBindVertexArrayAPPLE(vao);
glGenBuffers(3, vbo);

// bind and copy data for vertex position data
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(cubePositionData), cubePositionData, GL_STATIC_DRAW);
glVertexAttribPointer(TCV_VERTEX_POS_INDEX, TCV_NUM_POS_COMPONENTS, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(TCV_VERTEX_POS_INDEX);

// bind and copy data for vertex color data
glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(cubeColorData), cubeColorData, GL_STATIC_DRAW);
glVertexAttribPointer(TCV_VERTEX_COLOR_INDEX, TCV_NUM_COLOR_COMPONENTS, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(TCV_VERTEX_COLOR_INDEX);

// bind and copy data for vertex indices data
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[2]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(cubeIndices), cubeIndices, GL_STATIC_DRAW);
glVertexAttribPointer(TCV_VERTEX_INDICES_INDEX, TCV_NUM_INDEX_ARRAY_COMPONENTS, GL_UNSIGNED_BYTE, GL_FALSE, 0, 0);
glEnableVertexAttribArray(TCV_VERTEX_INDICES_INDEX);

// load uniform data into shader program
glUniformMatrix4fv(uniformLocations[0], 1, GL_FALSE, rotationMatX);
glUniformMatrix4fv(uniformLocations[1], 1, GL_FALSE, rotationMatY);
glUniformMatrix4fv(uniformLocations[2], 1, GL_FALSE, rotationMatZ);
glUniformMatrix4fv(uniformLocations[3], 1, GL_FALSE, translationMat);
glUniformMatrix4fv(uniformLocations[4], 1, GL_FALSE, projectionMat);

// tell OGL to draw the cube, in this order
glDrawElements(GL_TRIANGLES, 12, GL_UNSIGNED_BYTE, cubeIndices);

// unbind VAO
glBindVertexArrayAPPLE(0);

// no longer using program
glUseProgram(0);

// flush buffer
glFlush();
[[self openGLContext] flushBuffer];
}
Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
xBACP
  • 531
  • 1
  • 3
  • 17
  • 1
    This may sound like a broken record, but have you checked for glError after every single gl call? – Jari Komppa Dec 20 '12 at 16:32
  • I would run this through OpenGL Profiler to check if all the states are correct on rendering, and that no errors occur: "/Developer/Applications/Graphics Tools/OpenGL Profiler" – kvark Dec 05 '13 at 20:43

1 Answers1

0

I have had a similar problem with my OpenGL experiments. I was also using separate buffer objects for the vertex positions and vertex colors data. I believe only one GL_ARRAY_BUFFER can be bound to the Vertex Array Object. So put all of your data into one combined buffer and then set up your attribute pointers with offsets into that buffer.

Your VBO / VAO setup should be something like:

glGenVertexArrays(1, &vertexArray);
glBindVertexArray(vertexArray);

glGenBuffers(1,&vertexBuffer);
glBindBuffer(vertexBuffer);
glBindBufferData(GL_ARRAY_BUFFER, sizeof(cubePositionAndColorData), cubePositionAndColorData, GL_STATIC_DRAW);

glVertexAttribPointer(kPositionAttribute, NUM_VERTEX_COMPONENTS, GL_FLOAT, GL_FALSE, 0, 0);
// colorStartingIndex is probably just NUM_VERTEX_COMPONENTS*sizeof(GLfloat)
glVertexAttribPointer(kColorAttribute, NUM_COLOR_COMPONENTS, GL_FLOAT, GL_FALSE, 0, (void *)colorStartingIndex);

glEnableVertexAttribArray(kPositionAttribute);
glEnableVertexAttribArray(kColorAttribute);

glGenBuffers(1,&indexBuffer);
glBindBuffer(indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(cubeIndices), cubeIndices, GL_STATIC_DRAW);

glBindVertexArray(0);

Then, within your -drawRect: function, you can use the program, set up your uniforms and call glDrawElements():

glUseProgram(shaderProgramID);

// do the necessary uniform configuration
glUniformMatrix4fv(...)

glBindVertexArray(vertexArray);
glDrawElements(GL_TRIANGLES, 12, GL_UNSIGNED_BYTE, 0);

glBindVertexArray(0);

glUseProgram(0);

Two other items worth noting:

  1. I suggest moving all of the buffer initialization out of your -drawRect: method, since it will be called every time the view is repainted. That means you're recopying all of the data to the OpenGL server on every -drawRect:.
  2. If you are using a more recent version of osx, you should consider using the latest version of OpenGL (OpenGL/gl3.h).
dbrwn
  • 131
  • 5