I believe that's what I'm trying to do. Coming from DirectX, you would define a structure for your vertices, pack up a position, normal, texturecoords, whatever else your shader needed, and bind an array of them to the api to be drawn using an index buffer. I'm trying to get that same thing going with OpenGL 4.2, and having a hard time getting anything rendered on the screen.
Here is my vertex structure:
struct VertexPositionNormalTexture {
float x, y, z; //Vertex
float nx, ny, nz; //Normal
float s0, t0; //Texcoord0
};
Here is creation of my buffer objects:
BWResult create_cube_geometry(Geometry* geometry, VertexType type) {
VertexPositionNormalTexture pvertex[3];
//VERTEX 0
pvertex[0].x = 0.0;
pvertex[0].y = 0.0;
pvertex[0].z = 0.0;
pvertex[0].nx = 0.0;
pvertex[0].ny = 0.0;
pvertex[0].nz = 1.0;
pvertex[0].s0 = 0.0;
pvertex[0].t0 = 0.0;
//VERTEX 1
pvertex[1].x = 1.0;
pvertex[1].y = 0.0;
pvertex[1].z = 0.0;
pvertex[1].nx = 0.0;
pvertex[1].ny = 0.0;
pvertex[1].nz = 1.0;
pvertex[1].s0 = 1.0;
pvertex[1].t0 = 0.0;
//VERTEX 2
pvertex[2].x = 0.0;
pvertex[2].y = 1.0;
pvertex[2].z = 0.0;
pvertex[2].nx = 0.0;
pvertex[2].ny = 0.0;
pvertex[2].nz = 1.0;
pvertex[2].s0 = 0.0;
pvertex[2].t0 = 1.0;
GLushort indices[3];
indices[0] = 0;
indices[1] = 1;
indices[2] = 2;
GLuint vertexBuffer;
glGenBuffers(1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(VertexPositionNormalTexture) * 4, pvertex, GL_STATIC_DRAW);
GLuint indexBuffer;
glGenBuffers(1, &indexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 3 * sizeof(GLushort), indices, GL_STATIC_DRAW);
geometry->indexBufferId = indexBuffer;
geometry->vertexBufferId = vertexBuffer;
geometry->vertexType = VERTEX_PNT;
geometry->indexBufferSize = 6;
geometry->vertexSize = sizeof(GLfloat) * 8;
geometry->offset1 = sizeof(GLfloat) * 3;
geometry->offset2 = geometry->offset1 + (sizeof(GLfloat) * 3);
return BW_SUCCESS;
}
And here is the function that renders the object:
void render_geometry(Geometry geometry, ShaderInfo shaderInfo) {
glBindBuffer(GL_ARRAY_BUFFER, geometry.vertexBufferId);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, geometry.indexBufferId);
// Set Position Pointer
GLuint positionAttribute = glGetAttribLocation(shaderInfo.programId, "position");
glEnableVertexAttribArray(positionAttribute);
glVertexAttribPointer(positionAttribute, 3, GL_FLOAT, GL_FALSE, geometry.vertexSize, BUFFER_OFFSET(0));
// Set Normal Pointer
GLuint normalAttribute = glGetAttribLocation(shaderInfo.programId, "normal");
glEnableVertexAttribArray(normalAttribute);
glVertexAttribPointer(normalAttribute, 3, GL_FLOAT, GL_FALSE, geometry.vertexSize, BUFFER_OFFSET(12));
// Set TexCoord Pointer
GLuint texCoordAttribute = glGetAttribLocation(shaderInfo.programId, "texCoord");
glEnableVertexAttribArray(texCoordAttribute);
glVertexAttribPointer(texCoordAttribute, 2, GL_FLOAT, GL_FALSE, geometry.vertexSize, BUFFER_OFFSET(24));
glDrawElements(GL_TRIANGLE_STRIP, 3, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0));
glDisableVertexAttribArray(positionAttribute);
glDisableVertexAttribArray(normalAttribute);
glDisableVertexAttribArray(texCoordAttribute);
}
And in my main area for now, i'm doing this in my loop:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
running = !glfwGetKey(GLFW_KEY_ESC) && glfwGetWindowParam(GLFW_OPENED);
glUseProgram(shader_info.programId);
GLuint matrixId = glGetUniformLocation(shader_info.programId, "MVP");
glUniformMatrix4fv(matrixId, 1, GL_FALSE, &mvp[0][0]);
render_geometry(geo, shader_info);
glUseProgram(0);
glfwSwapBuffers();
One last piece that may be relevant, here is how I am creating my model-view-projection matrix:
glm::mat4 projection = glm::perspective(45.0f, 16.0f / 9.0f, 0.1f, 100.0f);
glm::mat4 view = glm::lookAt(glm::vec3(0, 0, 10), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));
glm::mat4 model = glm::mat4(1.0f);
glm::mat4 mvp = projection * view * model;
I lied, you may need to check out my vertex shader as well:
#version 330
layout(location = 0) in vec3 position;
layout(location = 1) in vec2 texCoord;
out vec2 UV;
uniform mat4 MVP;
void main() {
vec4 v = vec4(position, 1);
gl_Position = MVP * v;
UV = texCoord;
}
I have a fragment shader that just sets the color to white for now.
Sorry for the code dumps, but I think that is all the main parts where I might have something messed up. With DX, I would fire up PIX and be able to look at the contents of a) the bound buffer, and b) debug the individual vertices through the shader stages to find out where something went wrong. With gDEBugger, in the 'Textures, Buffers, and Images viewer' when I click on my VBO that should contain my vertices, I get 'Unable to load Buffer'. I'm guessing that is indicating something is messed up with the way I'm binding my buffer, or specifying its data, but I can't for the life of me find a complete example using interleaved arrays with modern OpenGL.