I’ve played with OpenGL a fair bit in the past, but never anything using the “newer” VAO/VBO and Shader stuff, so bear with me here…
What I’ve already managed to achieve is being able to render a VAO - consisting of for now a Vertex VBO and a Colour VBO, though hopefully with textures and normals added in later - using a vertex and fragment shader. What I’d like to do is extend it so that I can define each vertex only once and use indices to specify which ones are actually used, when rendering a model that shares vertices…
If I’m understanding things right, I need to be using glDrawElements to draw the indexed version, having set up a VBO bound to the GL_ELEMENT_ARRAY_BUFFER target. I can’t make it work though, and I can’t for the life of me work out why not…
The code that I’ve got so far that works fine looks - roughly - like the following: (I say roughly because it’s actually several different C++ classes spread across a few files, but that’s essentially what the OpenGL specific calls look like)
// Setup
// vertex shader
GLuint mVertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(mVertexShader, 1, (const GLchar**)&src, &len);
glCompileShader(mVertexShader);
// fragment shader
GLuint mFragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(mFragmentShader, 1, (const GLchar**)&src, &len);
glCompileShader(mFragmentShader);
// program
GLuint mProgram = glCreateProgram();
glAttachShader(mProgram, mVertexShader);
glAttachShader(mProgram, mFragmentShader);
glBindAttribLocation(mProgram, 0, "in_Position");
glBindAttribLocation(mProgram, 1, "in_Colour");
glLinkProgram(mProgram);
// vao
GLuint mVao
glGenVertexArrays(1, &mVao);
// vertex vbo
GLuint mVertexVbo
glGenBuffers(1, &mVertexVbo);
glBindBuffer(GL_ARRAY_BUFFER, mVertexVbo);
glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(GLfloat), rawVertexData, GL_STATIC_DRAW);
// colour vbo
GLuint mColourVbo
glGenBuffers(1, &mColourVbo);
glBindBuffer(GL_ARRAY_BUFFER, mColourVbo);
glBufferData(GL_ARRAY_BUFFER, colourCount * sizeof(GLfloat), rawColourData, GL_STATIC_DRAW);
// Render
// program
glUseProgram(mProgram);
glUniformMatrix4fv(glGetUniformLocation(mProgram, "mvpmatrix"),
1,
GL_FALSE,
glm::value_ptr(matrix));
// general setup
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// vao
glBindVertexArray(mVao);
// vertex vbo
glBindBuffer(GL_ARRAY_BUFFER, mVertexVbo);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
// colour vbo
glBindBuffer(GL_ARRAY_BUFFER, mColourVbo);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(1);
glDrawArrays(GL_TRIANGLES, 0, rows);
My understanding was that in order to use Indices instead I’d simply replace the last line with
// index vbo
GLuint mIndexVbo
glGenBuffers(1, &mIndexVbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexVbo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexCount * sizeof(GLubyte), rawIndexData, GL_STATIC_DRAW);
glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_BYTE, 0);
But when I do that I get a black screen instead of my - currently - two triangles being drawn…
What am I doing wrong?