Course list http://www.c-jump.com/bcc/
Download c262_lab11.zip and unzip it under the labs subdirectory:
C:\bcc\GL262Labs\labs\c262_lab11
Open Visual Studio project
C:\bcc\GL262Labs\labs\c262_lab10\c262_lab11.sln
and compile the executable:
Build -> Build Solution
(or simply press F7.)
In this lab we model planets and a galaxy view. Open c262_lab11.cpp and apply the following changes:
Replace bitmaps from the previous labs with the new ones:
//#define BMP_OBJ_FILE_PATH "../../Models/Lab8/BMP/scales.bmp" // old //#define BMP_GRASS_FILE_PATH "../../Models/Lab8/BMP/grass.bmp" // old #define BMP_EARTH_PATH "../../Models/Lab8/PlanetTextures/earthmap.bmp" // new #define BMP_MOON_PATH "../../Models/Lab8/PlanetTextures/moonmap1k.bmp" // new
Replace plane and dragon models from the previous lab with the sphere:
//#define MODEL_OBJ_FILENAME "../../Models/Lab8/OBJ/dragon.obj" // old //#define MODEL_PLANE_FILENAME "../../Models/Lab8/OBJ/plane.obj" // old #define MODEL_OBJ_FILENAME "../../Models/Lab8/OBJ/sphere.obj" // new
Search for old BMP_OBJ_FILE_PATH and replace it with
//object_model->upload_bitmap_texture( BMP_OBJ_FILE_PATH ); // old
object_model->upload_bitmap_texture( BMP_EARTH_PATH ); // new
Likewise, search for the old BMP_GRASS_FILE_PATH and replace it with
//plane_model->upload_bitmap_texture( BMP_GRASS_FILE_PATH ); // old
plane_model->upload_bitmap_texture( BMP_MOON_PATH ); // new
Since both the Earth and the Moon are using the sphere mesh, replace the old code accordingly:
///plane_model->load_OBJ_file( MODEL_PLANE_FILENAME ); // old
plane_model->load_OBJ_file( MODEL_OBJ_FILENAME ); // new
Also, since the Earth is predominantly blue, update the material and light colors to blue:
// Directional light parameters:
GLfloat light_pos[] = {0.0f, 100.0f, 100.0f, 0.0f};
GLfloat light_ambient[] = {0.3f, 0.3f, 0.3f, 1.0f};
GLfloat light_diffuse[] = {0.7f, 0.7f, 0.9f, 1.0f};
GLfloat light_specular[] = {0.2f, 0.2f, 0.9f, 1.0f};
GLfloat material_ambient[] = {0.2f, 0.2f, 0.5f, 1.0f};
GLfloat material_diffuse[] = {0.2f, 0.2f, 0.7f, 1.0f};
GLfloat material_specular[] = {0.1f, 0.1f, 1.0f, 1.0f};
The light position light_pos has also been moved to the top of the world and slightly behind the original camera position.
Search for render() function and locate the line where we set the camera perspective for the Moon. Add call to the Light::set_shader_light_position() to make sure the light is set for this object:
camera->set_uniform_view_perspective(plane_model->shader->program_ID);
// Sets the light position for the object model's shader:
light->set_shader_light_position(plane_model->shader->program_ID);
Open Skybox.cpp and replace the old sky background with the galaxy background images:
#define BMP_NEG_X_FILE_PATH "../../Models/Lab8/GalaxyMap/Galaxy_lf.bmp" #define BMP_POS_X_FILE_PATH "../../Models/Lab8/GalaxyMap/Galaxy_rt.bmp" #define BMP_NEG_Y_FILE_PATH "../../Models/Lab8/GalaxyMap/Galaxy_dn.bmp" #define BMP_POS_Y_FILE_PATH "../../Models/Lab8/GalaxyMap/Galaxy_up.bmp" #define BMP_NEG_Z_FILE_PATH "../../Models/Lab8/GalaxyMap/Galaxy_ft.bmp" #define BMP_POS_Z_FILE_PATH "../../Models/Lab8/GalaxyMap/Galaxy_bk.bmp"
Open existing fragment shader TextureShader_f.c and save it as BumpTextureShader_f.c. Make Earth use the new shader:
Open c262_lab11.cpp. Add
#define BCC_FRAGMENT_TEXTURE_BUMP_SHADER BCC_ROOT_PATH BCC_PROJECT_NAME "/Shaders/BumpTextureShader_f.c"
next to the BCC_FRAGMENT_TEXTURE_SHADER definition.
Find the code that creates the shader program objects and add the new texture_bump_shader
Shader* texture_bump_shader = new Shader( BCC_VERTEX_TEXTURE_SHADER, BCC_FRAGMENT_TEXTURE_BUMP_SHADER );
Have the Earth use the new shader:
object_model = new Model( texture_bump_shader );
Open the new BumpTextureShader_f.c file and modify it as follows:
//...
void main () {
//vec3 N = normalize (fN); // the Normal
vec3 bumpN = texture2D(texture, texCoord).xyz;
vec3 N = normalize (fN+bumpN*5); // the Normal
vec3 L = normalize (fL); // the Light direction
vec3 E = normalize (-fE); // the vertex position
vec3 H = normalize (L + E); // the Half vector
// Calculate the diffuse part - but don't go negative!
float Kd = max (dot(N, L), 0.0); // Intensity
vec4 dif = Kd*diffuse; // ... and then color
// Calculate the specular part.
float Ks = pow (max(dot(N, H), 0.0), shininess*5); // Intensity
vec4 spec = Ks*specular; // ... and then color
if (dot(N, L) < 0.0) { // But only if the light is in front!
spec = vec4(0.0, 0.0, 0.0, 1.0);
}
// The final color is a combination of all of these
//fColor = ambient*0.5 + dif*0.5 + spec*0.5 + 0.5*texture2D(texture, texCoord);
fColor = ambient*0.5 + dif*0.4 + spec*0.9;// + 0.5*texture2D(texture, texCoord);
fColor.a = 1.0;
}
Notice that for the final fColor we compute only ambient, diffuse, and specular light components -- without texture. Run the program. Notice that the mapping of the planet's continents and the oceans are still visible! But why?
It is becase we have disturbed the normal vector N by some value, in our case - a value from the Earth texture. The fragment shader interprets color simply as a vector of three components. The light on the surface is calculated based on the relationship between the normal and the light vector. so if the normal vector changes, we see the image which makes an impression of a 3D surface. A new variable, bumpN (a bump normal) uses the texel color from the texture as a vector and adds it to the normal vector. This technique is called a bump mapping.
A model may benefit from having access to multiple textures. For example, the first texture can provide the image, while the second texture can provide a bump mapping info. In this part of our lab we extend the Model class by adding features that allow the fragment shader to access multiple textures.
Download c262_lab11_solution.zip and unzip it under the labs subdirectory:
C:\bcc\GL262Labs\labs\c262_lab11_solution
Compile and run the program. Observe new details on the surface of the Earth. Use WinMerge to compare the previous and the new versions of the lab 11 project. What are the changes? Here is a brief overview of the differences:
I added the second texture sampler, texture_bump to the fragment shader BumpTextureShader_f.c. The bumpN is now computed from the second texture. The final color is a combination of "bumped" illumination colors and the Earth texture.
In Model.h I added the <vector> header and changed tex_buffer_ID to be a dynamic array (C++ vector) of numbers. Similarly, the old texture handler for the texture sampler in the fragment shader has now become a vector of numbers named texture_sampler_ID.
New version of the Model::upload_bitmap_texture() function in Model.cpp populates the tex_buffer_ID and texture_sampler_ID with the values corresponding to the specific bitmap image. The function also takes new parameter, sampler_name, which is the name of the sampler variable in the fragment shader. To upload multiple textures, the client simply calls Model::upload_bitmap_texture() multiple times.
New version of the Model::render() in Model.cpp uses the values from tex_buffer_ID and texture_sampler_ID to activate a sequence of texture units and bind textures to the corresponding units.
When the client program in c262_lab11_solution.cpp makes Model::upload_bitmap_texture() calls, it has to specify the fragment shader's texture sampler name as a second parameter to the function.
Skybox::upload_CubeMap_images() in Skybox.cpp also uses Model's texture buffer to upload the cube's textures. An updated version of this function adds the newly generated buffer id to the tex_buffer_ID vector and passes it to glGenTextures() as a parameter.
The planets are shown rotated at theta radians (the angle keeps changing in the animate() function.)
I was thinking about spaceship cockpit and decided to use the car model. It is managed by the spaceship_model in the main source file. I made some changes to draw the car as a see-through wireframe. To keep the cockpit stationary, I added FPSCamera::set_spaceship_uniform_view_perspective(). I also changed the SolidShader_f.c fragment shader to show the wireframe in a hardcoded white color. To display the wireframe, you need to uncomment the line
//spaceship_model->render();
in the render() function of the main source file.
There are no files to submit.
Demonstrate a working c262_lab11 program to your instructor.