Draw the first triangle: NDC, Shader, VAO
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).
- 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);