Course list http://www.c-jump.com/bcc/
In this lab we begin using realistic lighting of our models. To understand the input data and calculations, we start by looking at material properties. In our program, we want to distinguish between
Ambient illumination -- simulates light reflected from the environment. We have seen an example of ambient light in the previous lab. If only ambient light is used on a model, it will appear as a silhouette. Ambient illumination is based on a minimal color an object emits even if no light is present. For us, this is an easiest light component to implement.
Diffuse light -- shows how the light bounces off an object in all directions. In OpenGL diffuse lighting is calculated from the relationship between the light direction and the normals of the object's surface. We can calculate diffuse light intensity as a dot product between these two vectors for every vertex or fragment.
Specular light -- illuminates the shiny spots on objects with a smooth surface. The size of each shiny spot is controlled by the "shininess" factor. The higher the shininess, the smaller the shiny spots will be. The specular highlights indicate how hard or how soft the material will appear to the viewer.
Our plan is to compose data for a material of an object by providing colors of each of the lighting components and pass that information to our shaders.
Download c262_lab07.zip and unzip it under the labs subdirectory:
C:\bcc\GL262Labs\labs\c262_lab07
Open Visual Studio project
C:\bcc\GL262Labs\labs\c262_lab07\c262_lab07.sln
and compile the executable:
Build -> Build Solution
(or simply press F7.)
Observe the following project updates in this lab:
The vertex shader now includes lightPosition input variable.
The Light C++ class is added to the source code:
Shader* myShader = new Shader( BCC_VERTEX_SHADER, BCC_FRAGMENT_SHADER );
//...
light = new Light( light_pos, light_ambient, light_diffuse, light_specular, myShader );
myModel = new Model( myShader );
//...
myModel->set_material( material_ambient, material_diffuse, material_specular, shininess );
myModel->set_light( light );
Here, most of the parameters are arrays of 4 GLfloats.
The shininess is in range 1 to 255.
The render() function also calls
light->set_shader_light_position();
because the light position can move around.
The Model::render() function combines all light components and uploads them to OpenGL.
In the vertex shader the are three new out variables:
fN represents rotated normal vector for each vertex. The normal rotation matrix is calculated by render():
// Compute the model matrix:
// The order here is important!
//myModel->mM = mtx_trans * mtx_scale * myModel->mR; // rotate first
myModel->mM = mtx_trans * myModel->mR * mtx_scale; // scale first
// Compute the matrix for rotation of normals:
myModel->mR = glm::transpose( glm::inverse( myModel->mM ));
It is importand that transposed inversed model matrix myModel->mR includes all scaling and rotations of the model. This matrix properly rotates normals in the vertex shader Shaders\vertexProgram_v.c:
fN = (mR*vNormal).xyz;
The fN vector gets smoothly interpolated in the fragment shader and has to be normalized before the lighting calculations take place.
fE represents the vector connecting position of the vertex and the eye (or the camera)
fL represents the vector connecting position of the vertex and the light position. This vector is adjusted if it's not a directional "sun" light, but a "lamp" source instead. In the latter case the light source is transformed into the model.
In the fragment shader,
the three in vectors are normalized
the ambient, diffuse, and specular inputs are passed from Model::render()
the intensity of diffuse light is computed
the intensity of specular light is computed
the final color is computed as a combination of all three components
Understand everything that was discussed so far in this lab. Now is the time to ask questions!
Make necessary changes to display objects in a bright red color with purple specular highligts.
Download c262_lab07_x2.zip and unzip it under the labs subdirectory:
C:\bcc\GL262Labs\labs\c262_lab07_x2
Open Visual Studio project
C:\bcc\GL262Labs\labs\c262_lab07_x2\c262_lab07_x2.sln
and compile the executable:
Build -> Build Solution
(or simply press F7.)
Configuration window is using Open Source FLTK library to create a GUI window.
Notice that the project contains a new subdirectory:
C:\bcc\GL262Labs\labs\c262_lab07_x2\fluid_project
The GUI window is constructed by FLUID (Fast Light User Interface Designer.) FLUID is distributed with FLTK. The window enables to interactively load, scale, rotate, and translate object models at run-time.
There is also new a header file, src\ConfigWindow.h, which has the code to handle user input and update the OpenGL view accordingly.
Use WinMerge to compare the previous and the new versions of the lab 7 project file:
labs\c262_lab07\lab01.vcxproj
labs\c262_lab07_x2\lab01.vcxproj
The project settings were updated as described in CIS-255
FLTK Library and Visual Studio C++ Project Configuration
Laboratory.
The ConfigWindow.h is #included from the main application source file, src\c262_lab07_x2.cpp. The changes in the main file also include
// FLTK window support
ConfigWindow config_window( &theta );
config_window.show();
glutMainLoop();
The code creates the config window and makes it visible before calling glutMainLoop().
The config window allows to load, scale, rotate, and move object models.
There are no files to submit.
Demonstrate a working c262_lab07 program to your instructor.