Draw the first triangle: NDC, Shader, VAO

Jack Cho
jack06215researchnotes
2 min readMar 28, 2018

Example program: https://github.com/opengl-tutorials/ogl/blob/master/tutorial02_red_triangle/tutorial02.cpp

Vertex, triangle, model

  • In computer graphics it is commonly to use triangles to represent the structure of a 3D model. A triangle has three vertice, which is a 3D point represented by (x,y,z).
  • Putting many triangles together, it forms what is called meshes, or more commonly, a model.

Screen Coodrinate: Normalised Device Coordinate (NDC)

Introduction to Shader

Shader is a modern approach in OpenGL to handle the loading of a model at the graphic card level. A shader is a program:

  • has source code
  • Cg, HLSL and GLSL
  • is compiled into a program
  • upon successful setup, it return an ID (uint type)

There are two types of shader:

Vertex shader

  • Changes the position of a vertex (trans/rot/skew)
  • Determine color of the vertex, though it is uncommonly practice.

Fragment shader

  • Determine the color of a pixel
  • Uses lighting, materials, normalsm and so forth.

Making a shader program

The following procedure roughly walk through on how to configure and run a shader program in OpenGL

  • Compile a vertex shader (get an vertexShaderID)
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);  
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
  • Compile a fragment shader (get an fragmentShaderID)
glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL);
glCompileShader(VertexShaderID);
  • Check for compilation errors
glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);  glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);  if ( InfoLogLength > 0 ){   
std::vector<char> VertexShaderErrorMessage(InfoLogLength+1);
glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]); printf("%s\n", &VertexShaderErrorMessage[0]);
}
  • Link those shaders together (get an programID)
GLuint ProgramID = glCreateProgram();  
glAttachShader(ProgramID, VertexShaderID); glAttachShader(ProgramID, FragmentShaderID); glLinkProgram(ProgramID);

Vertex Array Object (VAO)

Since OpenGL 3.2, the traditional pipeline of programmable shader were replaced by a new approach, VBO. A Vertex Array Object (VAO) is an object which contains one or more Vertex Buffer Objects and is designed to store the information for a complete rendered object. For this example, let’s say our render model is a 2D triangle that consist of two piece of information: a 3D coordinate(3 bytes) and the colour (RGBA; 4 bytes).

  1. Create the VAO to as an entry point to handle data
glGenVertexArrays(1, &vao)
glBindVertexArray(vao);

2. Create a buffer and bind it as active

glGenBuffers(1, &vao);
glBindBuffer(GL_ARRAY_BUFFER, vao);

3. Create space and load the buffer

glBufferData(GL_ARRAY_BUFFER, 7*3*sizeof(GLfloat), GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, 3*3sizeof(GLfloat), vertices);
glBufferSubData(GL_ARRAY_BUFFER, 3*3sizeof(GLfloat), 3*3sizeof(GLfloat), colors);

4. Find the position of the variable in the shader

positionID = glGetAttribLocation(shaderProgramID, "vPosition");
colorID = glGetAttribLocation(shaderProgramID, "vColor");

5. Tell the shader variables where to find the data

glVertexAttribPointer(positionID, 3, GL_FLOAT, GL_FALSE, 0, 0);
glVertexAttribPointer(colorID, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(3*3*sizeof(GLfloat)));
glEnableVertexAttribArray(positionID);
glEnableVertexAttribArray(colorID);

--

--