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:
[source lang="cpp"]struct VertexPositionNormalTexture { float x, y, z; //Vertex float nx, ny, nz; //Normal float s0, t0; //Texcoord0};[/source]
Here is creation of my buffer objects:
[source lang="cpp"]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;}[/source]
And here is the function that renders the object:
[source lang="cpp"]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);}[/source]
And in my main area for now, i'm doing this in my loop:
[source lang="cpp"] 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();[/source]
One last piece that may be relevant, here is how I am creating my model-view-projection matrix:
[source lang="cpp"]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;[/source]
I lied, you may need to check out my vertex shader as well:
[source lang="cpp"]#version 330layout(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;}[/source]
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.
Interleaved Arrays
Started by Matt328, Jul 16 2012 08:20 PM
4 replies to this topic
Sponsor:
#2 Members - Reputation: 1604
Posted 16 July 2012 - 11:59 PM
Had a look over your code snippets, but couldn't find anything obviously wrong. Do you have glGetError() checks in place to detect if a call is failing?
Me+PC=clb.demon.fi | C++ Math and Geometry library: MathGeoLib, test it live! | C++ Game Networking: kNet | 2D Bin Packing: RectangleBinPack | Use gcc/clang/emcc from VS: vs-tool | Resume+Portfolio | gfxapi, test it live!
#3 Members - Reputation: 288
Posted 17 July 2012 - 03:16 AM
I use 3.2 Core for compatibility with OSX 10.7 but on that version at least, Vertex Array Objects are required. Perhaps this is true of 4.x?
They are similar to Input Layouts in D3D10+ or FVFs in D3D9 in that they describe the data you're passing to the pipeline. In the case of VAOs, you just create and bind a VAO, get the indices of your attributes and bind them with the correct offsets.
They are similar to Input Layouts in D3D10+ or FVFs in D3D9 in that they describe the data you're passing to the pipeline. In the case of VAOs, you just create and bind a VAO, get the indices of your attributes and bind them with the correct offsets.
#4 Moderators - Reputation: 4933
Posted 17 July 2012 - 03:33 AM
As Neilo said, you need a VAO object to store VBO bindings.
But I just wanted to mention a small error, although likely not related to the error you're asking about. Your first call to glBufferData is passed an incorrect size; four vertices when the array contains three.
But I just wanted to mention a small error, although likely not related to the error you're asking about. Your first call to glBufferData is passed an incorrect size; four vertices when the array contains three.
#5 Members - Reputation: 182
Posted 17 July 2012 - 08:02 PM
Figured this out. In line 43 of my second code snip, notice anything wrong there? I bind the vertex buffer again, and give it the index data. No wonder nothing was getting rendered, and my vertex buffer was corrupted.
What tipped me off, as I was just about to call it a night, i was staring at the Vertex Buffer Objects node in gDEBugger, and noticed VBO2 said something to the effect of 'not attached'. Not attached? And why is my index data showing up in VBO1 if I'm setting data in the vertex buffer first, I would think the index data would be in VBO2.
Thanks to Neilo and Brother Bob though for pointing out VAOs. They are pretty slick.
What tipped me off, as I was just about to call it a night, i was staring at the Vertex Buffer Objects node in gDEBugger, and noticed VBO2 said something to the effect of 'not attached'. Not attached? And why is my index data showing up in VBO1 if I'm setting data in the vertex buffer first, I would think the index data would be in VBO2.
Thanks to Neilo and Brother Bob though for pointing out VAOs. They are pretty slick.






