Jump to content
  • Advertisement
Sign in to follow this  
Matt328

OpenGL Interleaved Arrays

This topic is 2260 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.

Share this post


Link to post
Share on other sites
Advertisement
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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!