Vertex Buffers and Drawing a Triangle in OpenGL - hls333555/OpenGL GitHub Wiki

To draw a triangle in legacy OpenGL, the code is as little as below:

// Put these below glClear()
glBegin(GL_TRIANGLES);
glVertex2f(-0.5f, -0.5f);
glVertex2f(0.f, 0.5f);
glVertex2f(0.5f, -0.5f);
glEnd();

However, for modern OpenGL, there are a lot more setups you need to do to draw a triangle. Primarily speaking, you need to:

  • Create a vertex buffer - array of bytes of GPU memory(VRAM)
  • Create a shader

The basic concept is that we define a bunch of data which represents the triangle and put it into the GPU's VRAM and then we want to issue a draw call which is basically a draw command - read those data from VRAM and draw it on the screen, after that we need to tell the GPU how to interpret the data(interpret it as like a bunch of positions on the screen and draw them up into a triangle), that's what shader is.

OpenGL specifically operates like a state machine. You set a series of states and then if you want to draw a triangle, which is very contextual, you do not need to pass all OpenGL needs to draw a triangle, in fact, OpenGL knows what it needs to draw a triangle because it is part of the state. Basically, you just need to tell OpenGL to select a buffer, then select a shader and finally draw the triangle. Based on which buffer and which shader you've selected, that's going to determine what triangle gets drawn and where etc.

Since our triangle will not morph and the data will not change in game, we just put the buffer outside the game loop, here is the code to give OpenGL the triangle data, you can go to OpenGL API Documentation for those detail usages:

float positions[6] = {
    -0.5f, -0.5f,
     0.f,   0.5f,
     0.5f, -0.5f
};

// Vertex buffer object
unsigned int vbo;
// Generate vertex buffer object names
glGenBuffers(1, &vbo);
// Bind a named vertex buffer object
glBindBuffer(GL_ARRAY_BUFFER, vbo);
// Create and initialize a vertex buffer object's data store
glBufferData(GL_ARRAY_BUFFER, 3 * 2 * sizeof(float), positions, GL_STATIC_DRAW);

Next is to issue a draw call to actually draw the triangle by calling the following code inside the game loop:

// Issue a draw call
glDrawArrays(GL_TRIANGLES, 0, 3);

Due to the state machine mechanism, if you bind no buffer by calling glBindBuffer(GL_ARRAY_BUFFER, 0);, it will not draw the triangle because you select something else(no buffer). Just imagine the layers in PS, if you select a layer and then draw something on that layer using a paint brush, it is going to affect that layer; however if you have nothing selected, obviously it is not going to affect the layer you are going to draw on.

The triangle will not show up when you run the program because we have not created a shader yet.