Reputation: 1271
I just started learning OpenGL and I am having some trouble with glDrawElements. I am trying to draw two triangles using glDrawElements with GL_TRIANGLE, but only one triangle appears.
What is expected: glDrawElements draw two triangles with vertices
(0,0) (1,1) (-1,1) and (0,0) (-1,-1) (1,-1)
What happens: glDrawElements draw one triangle with vertices (0,0) (1,1) (-1,1)
Short, Self Contained, Correct (Compilable), Example:
#include <GL/glew.h>
#include <GLFW/glfw3.h>
int main(int argc, char *argv[])
{
glfwInit();
GLFWwindow* window = glfwCreateWindow(640, 480, "Sample code does not display two triangles", NULL, NULL);
glfwMakeContextCurrent(window);
glewInit();
GLfloat vertices[] {
+0.0f, +0.0f, //0
+1.0f, +1.0f, //1
-1.0f, +1.0f, //2
-1.0f, -1.0f //3
+1.0f, -1.0f //4
};
GLuint vertexBufferID;
glGenBuffers(1, &vertexBufferID);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
GLuint indexBufferID;
GLushort indices[] {0,1,2, 0,3,4};
glGenBuffers(1, &indexBufferID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
while (!glfwWindowShouldClose(window))
{
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
return 0;
}
This sample opens a 640x480 GLFW window, displays a triangle with vertices in both upper corners and the third vertex in the middle of the window. The other triangle, with vertices in both bottom corners and the third vertex in the middle, is missing. Why is that?
Specs:
OS: Linux Mint 17
GPU: nVidia GTX 275
GPU driver: 331.67
GLEW version: 1.10.0
GLFW version: 3.0.4
Upvotes: 3
Views: 6581
Reputation: 52082
Commas are important. This:
GLfloat vertices[] =
{
+0.0f, +0.0f, //0
+1.0f, +1.0f, //1
-1.0f, +1.0f, //2
-1.0f, -1.0f //3
+1.0f, -1.0f //4
};
size_t elements = sizeof( vertices ) / sizeof( GLfloat ) = 9(!)
is not the same as this:
GLfloat vertices[] =
{
+0.0f, +0.0f, //0
+1.0f, +1.0f, //1
-1.0f, +1.0f, //2
-1.0f, -1.0f, //3
+1.0f, -1.0f //4
};
size_t elements = sizeof( vertices ) / sizeof( GLfloat ) = 10
Note the added comma at the end of line 3
.
If vertices
only has 9
elements then when glDrawElements()
goes to try to read the fifth vertex only the X coordinate will be valid. The Y coordinate will contain garbage if you're lucky, a segfault if you're not.
Also, you shouldn't use the generic vertex attribute functions without specifying some shaders.
All together:
#include <GL/glew.h>
#include <GLFW/glfw3.h>
int main(int argc, char *argv[])
{
glfwInit();
GLFWwindow* window = glfwCreateWindow(640, 480, "Sample code does not display two triangles", NULL, NULL);
glfwMakeContextCurrent(window);
glewInit();
GLfloat vertices[] =
{
+0.0f, +0.0f, //0
+1.0f, +1.0f, //1
-1.0f, +1.0f, //2
-1.0f, -1.0f, //3
+1.0f, -1.0f, //4
};
GLuint vertexBufferID;
glGenBuffers(1, &vertexBufferID);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glEnableClientState( GL_VERTEX_ARRAY );
glVertexPointer( 2, GL_FLOAT, 0, 0 );
GLuint indexBufferID;
GLushort indices[] = { 0,1,2, 0,3,4 };
glGenBuffers(1, &indexBufferID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
while (!glfwWindowShouldClose(window))
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
return 0;
}
Upvotes: 7