Create normals and actually use texture
This commit is contained in:
parent
71c1b73ec3
commit
9737818f81
2 changed files with 76 additions and 29 deletions
|
@ -1,12 +1,12 @@
|
||||||
//
|
//
|
||||||
// This source code is property of the Computer Graphics and Visualization
|
// This source code is property of the Computer Graphics and Visualization
|
||||||
// chair of the TU Dresden. Do not distribute in modified or unmodified form!
|
// chair of the TU Dresden. Do not distribute in modified or unmodified form!
|
||||||
// Copyright (C) 2016 CGV TU Dresden - All Rights Reserved
|
// Copyright (C) 2016 CGV TU Dresden - All Rights Reserved
|
||||||
//
|
//
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
Terrain.
|
Terrain.
|
||||||
This class represents a textured and shaded terrain. Both, the texture
|
This class represents a textured and shaded terrain. Both, the texture
|
||||||
and the height map is read from a bmp file (in the constructor).
|
and the height map is read from a bmp file (in the constructor).
|
||||||
The height map is mapped to a regular grid consisting of triangle strips.
|
The height map is mapped to a regular grid consisting of triangle strips.
|
||||||
During rendering the normals needed for lighting are calculated.
|
During rendering the normals needed for lighting are calculated.
|
||||||
There are some additional rendering modes:
|
There are some additional rendering modes:
|
||||||
|
@ -18,7 +18,7 @@ The rendering is done in the "render" method which sets the projection
|
||||||
and view via "setup_projection" and the light via "setup_light".
|
and view via "setup_projection" and the light via "setup_light".
|
||||||
Depending on the settings (that can be changed using "set_show_solid",
|
Depending on the settings (that can be changed using "set_show_solid",
|
||||||
"set_show_wireframe" and "set_show_levels") different passes are rendered
|
"set_show_wireframe" and "set_show_levels") different passes are rendered
|
||||||
using the appropriate rendering method ("render_solid_terrain",
|
using the appropriate rendering method ("render_solid_terrain",
|
||||||
"render_wireframe_terrain", "render_level_lines"). They call the
|
"render_wireframe_terrain", "render_level_lines"). They call the
|
||||||
"render_terrain" method.
|
"render_terrain" method.
|
||||||
*************************************************************************/
|
*************************************************************************/
|
||||||
|
@ -92,7 +92,10 @@ private:
|
||||||
// Create height lines for the level "level"
|
// Create height lines for the level "level"
|
||||||
void create_level_line(int level);
|
void create_level_line(int level);
|
||||||
|
|
||||||
|
void push_point(int x, int y);
|
||||||
|
vec3d create_point(int x, int y);
|
||||||
|
vec2d texture_coord(int x, int y);
|
||||||
|
|
||||||
// Load the height map from the file "filename"
|
// Load the height map from the file "filename"
|
||||||
bool load_heightmap(const char *filename);
|
bool load_heightmap(const char *filename);
|
||||||
// Return the width of the height map
|
// Return the width of the height map
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// This source code is property of the Computer Graphics and Visualization
|
// This source code is property of the Computer Graphics and Visualization
|
||||||
// chair of the TU Dresden. Do not distribute in modified or unmodified form!
|
// chair of the TU Dresden. Do not distribute in modified or unmodified form!
|
||||||
// Copyright (C) 2016 CGV TU Dresden - All Rights Reserved
|
// Copyright (C) 2016 CGV TU Dresden - All Rights Reserved
|
||||||
//
|
//
|
||||||
#include "terrain.h"
|
#include "terrain.h"
|
||||||
|
@ -112,8 +112,9 @@ void terrain::render_solid_terrain()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE0, texture_handle);
|
||||||
|
|
||||||
// Set the material color to white
|
// Set the material color to white
|
||||||
glColor3d(1, 1, 1);
|
glColor3d(1, 1, 1);
|
||||||
|
@ -123,7 +124,7 @@ void terrain::render_solid_terrain()
|
||||||
// Disable texture mapping
|
// Disable texture mapping
|
||||||
glDisable(GL_TEXTURE_2D);
|
glDisable(GL_TEXTURE_2D);
|
||||||
// Disable support for depth buffer offsets
|
// Disable support for depth buffer offsets
|
||||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||||
// Disable lighting
|
// Disable lighting
|
||||||
glDisable(GL_LIGHTING);
|
glDisable(GL_LIGHTING);
|
||||||
}
|
}
|
||||||
|
@ -141,13 +142,18 @@ void terrain::render_wireframe_terrain()
|
||||||
// Set the color to black
|
// Set the color to black
|
||||||
glColor3d(0, 0, 0);
|
glColor3d(0, 0, 0);
|
||||||
// Render the terrain
|
// Render the terrain
|
||||||
render_terrain();
|
render_terrain();
|
||||||
|
|
||||||
// Set the draw mode to fill polygons
|
// Set the draw mode to fill polygons
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void terrain::push_point(int x, int y)
|
||||||
|
{
|
||||||
|
set_normal(x, y);
|
||||||
|
glTexCoord2dv(texture_coord(x, y));
|
||||||
|
glVertex3dv(create_point(x, y));
|
||||||
|
}
|
||||||
|
|
||||||
// Render the terrain
|
// Render the terrain
|
||||||
void terrain::render_terrain()
|
void terrain::render_terrain()
|
||||||
|
@ -175,7 +181,7 @@ void terrain::render_terrain()
|
||||||
and translated to use the values of the variables "x" and "y"
|
and translated to use the values of the variables "x" and "y"
|
||||||
defined below directly as coordinates. The initial height of
|
defined below directly as coordinates. The initial height of
|
||||||
the grid shall be 0.
|
the grid shall be 0.
|
||||||
Aufgabe 2.2.1. Vervollstaendigen Sie den nachfolgenden Quelltext um die
|
Aufgabe 2.2.1. Vervollstaendigen Sie den nachfolgenden Quelltext um die
|
||||||
Erstellung eines regelmaessigen Gitters das sich ueber die
|
Erstellung eines regelmaessigen Gitters das sich ueber die
|
||||||
X-Z-Ebene erstreckt. Erstellen Sie dieses Gitter, indem Sie
|
X-Z-Ebene erstreckt. Erstellen Sie dieses Gitter, indem Sie
|
||||||
zeilenweise Dreiecksstreifen definieren. Das Koordinatensystem
|
zeilenweise Dreiecksstreifen definieren. Das Koordinatensystem
|
||||||
|
@ -184,23 +190,23 @@ void terrain::render_terrain()
|
||||||
als Koordinaten einsetzen koennen. Das Gitter soll zunaechst
|
als Koordinaten einsetzen koennen. Das Gitter soll zunaechst
|
||||||
eine Hoehe von 0 besitzen.
|
eine Hoehe von 0 besitzen.
|
||||||
|
|
||||||
|
|
||||||
Task 2.2.2. Now elevate the height of the vertices to create the grid terrain
|
Task 2.2.2. Now elevate the height of the vertices to create the grid terrain
|
||||||
that corresponds to the height map. Use "get_heightmap_value(x, y)".
|
that corresponds to the height map. Use "get_heightmap_value(x, y)".
|
||||||
Aufgabe 2.2.2. Heben Sie jetzt die Vertices an um ein Drahtgitterterrain zu erstellen,
|
Aufgabe 2.2.2. Heben Sie jetzt die Vertices an um ein Drahtgitterterrain zu erstellen,
|
||||||
das zur Hoehenkarte korrespondiert. Nutzen Sie die Methode
|
das zur Hoehenkarte korrespondiert. Nutzen Sie die Methode
|
||||||
"get_heightmap_value(x, y)".
|
"get_heightmap_value(x, y)".
|
||||||
|
|
||||||
|
|
||||||
Task 2.2.3. Make sure to call "set_normal" for every vertex and continue this
|
Task 2.2.3. Make sure to call "set_normal" for every vertex and continue this
|
||||||
task in "set_normal".
|
task in "set_normal".
|
||||||
Aufgabe 2.2.3. Stellen Sie sicher, dass Sie "set_normal" f<EFBFBD>r jeden Vertex aufrufen
|
Aufgabe 2.2.3. Stellen Sie sicher, dass Sie "set_normal" f<EFBFBD>r jeden Vertex aufrufen
|
||||||
und fahren Sie in "set_normal" mit der Aufgabe fort.
|
und fahren Sie in "set_normal" mit der Aufgabe fort.
|
||||||
|
|
||||||
|
|
||||||
Task 2.2.4. Activate texture mapping and bind the texture in the method
|
Task 2.2.4. Activate texture mapping and bind the texture in the method
|
||||||
"render_solid_terrain". Provide 2D texture coordinates per vertex in
|
"render_solid_terrain". Provide 2D texture coordinates per vertex in
|
||||||
this method using "glTexCoord2d".
|
this method using "glTexCoord2d".
|
||||||
Aufgabe 2.2.4. Aktivieren Sie Texturmapping und binden Sie eine Textur in der
|
Aufgabe 2.2.4. Aktivieren Sie Texturmapping und binden Sie eine Textur in der
|
||||||
Methode "render_solid_terrain". Spezifizieren Sie in dieser Methode pro
|
Methode "render_solid_terrain". Spezifizieren Sie in dieser Methode pro
|
||||||
Vertex eine Texturkoordinate mittels der Methode "glTexCoord2d".
|
Vertex eine Texturkoordinate mittels der Methode "glTexCoord2d".
|
||||||
|
@ -214,8 +220,8 @@ void terrain::render_terrain()
|
||||||
|
|
||||||
// Draw one strip
|
// Draw one strip
|
||||||
for (int x = 0; x < map_width; x++) {
|
for (int x = 0; x < map_width; x++) {
|
||||||
glVertex3f(static_cast<float>(x), get_heightmap_value(x, y), static_cast<float>(y));
|
push_point(x, y);
|
||||||
glVertex3f(static_cast<float>(x), get_heightmap_value(x, y + 1), static_cast<float>(y) + 1.0f);
|
push_point(x, y + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
glEnd();
|
glEnd();
|
||||||
|
@ -224,8 +230,30 @@ void terrain::render_terrain()
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec2d terrain::texture_coord(int x, int y)
|
||||||
|
{
|
||||||
|
return vec2d(
|
||||||
|
static_cast<double>(x) / static_cast<double>(get_heightmap_width()),
|
||||||
|
static_cast<double>(y) / static_cast<double>(get_heightmap_height())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3d terrain::create_point(int x, int y)
|
||||||
|
{
|
||||||
|
return vec3d(
|
||||||
|
static_cast<double>(x),
|
||||||
|
static_cast<double>(get_heightmap_value(x, y)),
|
||||||
|
static_cast<double>(y)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3d calculate_normal(vec3d middle, vec3d p0, vec3d p1)
|
||||||
|
{
|
||||||
|
vec3d v0 = middle - p0;
|
||||||
|
vec3d v1 = p1 - middle;
|
||||||
|
|
||||||
|
return cross(v0, v1);
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate and set the normal for height map entry (x,y)
|
// Calculate and set the normal for height map entry (x,y)
|
||||||
void terrain::set_normal(int x, int y)
|
void terrain::set_normal(int x, int y)
|
||||||
|
@ -235,8 +263,8 @@ void terrain::set_normal(int x, int y)
|
||||||
the height map value (x, y). You can either use forward differences,
|
the height map value (x, y). You can either use forward differences,
|
||||||
backward differences or central differences. The latter will give
|
backward differences or central differences. The latter will give
|
||||||
the best results. The calculation is done by first determining direction
|
the best results. The calculation is done by first determining direction
|
||||||
vectors in X and Z and then using vector operations to get a vector that
|
vectors in X and Z and then using vector operations to get a vector that
|
||||||
is perpendicular to both. You find some examples for vector operations in
|
is perpendicular to both. You find some examples for vector operations in
|
||||||
this project below. Do not forget to pass the normal to OpenGL using
|
this project below. Do not forget to pass the normal to OpenGL using
|
||||||
the command glNormal3d.
|
the command glNormal3d.
|
||||||
|
|
||||||
|
@ -246,7 +274,7 @@ void terrain::set_normal(int x, int y)
|
||||||
Fuer die Berechnung werden zunaechst Richtungvektoren in X- und Z-Richtung
|
Fuer die Berechnung werden zunaechst Richtungvektoren in X- und Z-Richtung
|
||||||
gebildet und anschliessend mittels Vektoroperationen ein zu beiden Vektoren
|
gebildet und anschliessend mittels Vektoroperationen ein zu beiden Vektoren
|
||||||
senkrechter Vektor berechnet. Nachfolgend ein paar Beispiele fuer Vektor-
|
senkrechter Vektor berechnet. Nachfolgend ein paar Beispiele fuer Vektor-
|
||||||
rechnungen in diesem Projekt. Vergessen Sie nicht die Normale nach der
|
rechnungen in diesem Projekt. Vergessen Sie nicht die Normale nach der
|
||||||
Berechnung mittels glNormal3d an OpenGL zu senden.
|
Berechnung mittels glNormal3d an OpenGL zu senden.
|
||||||
|
|
||||||
// Create a vector
|
// Create a vector
|
||||||
|
@ -270,6 +298,22 @@ void terrain::set_normal(int x, int y)
|
||||||
double y = vec3.y();
|
double y = vec3.y();
|
||||||
double z = vec3.z();
|
double z = vec3.z();
|
||||||
*****************/
|
*****************/
|
||||||
|
|
||||||
|
vec3d middle = create_point(x, y);
|
||||||
|
|
||||||
|
vec3d right = create_point(x + 1, y);
|
||||||
|
vec3d top = create_point(x, y + 1);
|
||||||
|
vec3d left = create_point(x - 1, y);
|
||||||
|
vec3d bottom = create_point(x, y - 1);
|
||||||
|
|
||||||
|
vec3d normal0 = calculate_normal(middle, right, top);
|
||||||
|
vec3d normal1 = calculate_normal(middle, top, left);
|
||||||
|
vec3d normal2 = calculate_normal(middle, left, bottom);
|
||||||
|
vec3d normal3 = calculate_normal(middle, bottom, right);
|
||||||
|
|
||||||
|
vec3d final_normal = (normal0 + normal1 + normal2 + normal3) / 4;
|
||||||
|
|
||||||
|
glNormal3dv(final_normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -312,8 +356,8 @@ void terrain::render_level_lines()
|
||||||
void terrain::create_level_line(int level)
|
void terrain::create_level_line(int level)
|
||||||
{
|
{
|
||||||
/********
|
/********
|
||||||
Additional Task: Find iso lines with the "Marching Squares" algorithm for the
|
Additional Task: Find iso lines with the "Marching Squares" algorithm for the
|
||||||
height value "level". Store the start and end points of the
|
height value "level". Store the start and end points of the
|
||||||
found lines in the list "level_lines".
|
found lines in the list "level_lines".
|
||||||
Zusatzaufgabe: Finden Sie Hoehenlinien mittels des "Marching Squares"-Algorithmus
|
Zusatzaufgabe: Finden Sie Hoehenlinien mittels des "Marching Squares"-Algorithmus
|
||||||
fuer den Hoehenwert "level". Legen Sie die Start- und Endpunkte
|
fuer den Hoehenwert "level". Legen Sie die Start- und Endpunkte
|
||||||
|
@ -350,7 +394,7 @@ void terrain::setup_light()
|
||||||
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse_color);
|
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse_color);
|
||||||
glLightfv(GL_LIGHT0, GL_SPECULAR, specular_color);
|
glLightfv(GL_LIGHT0, GL_SPECULAR, specular_color);
|
||||||
|
|
||||||
glLightf(GL_LIGHT0,GL_SPOT_EXPONENT, 10.0f);
|
glLightf(GL_LIGHT0,GL_SPOT_EXPONENT, 10.0f);
|
||||||
|
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
|
||||||
|
@ -403,7 +447,7 @@ void terrain::set_show_solid(bool state)
|
||||||
void terrain::set_show_wireframe(bool state)
|
void terrain::set_show_wireframe(bool state)
|
||||||
{
|
{
|
||||||
show_wireframe = state;
|
show_wireframe = state;
|
||||||
// The current display list is outdated now
|
// The current display list is outdated now
|
||||||
dl_valid = false;
|
dl_valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,7 +486,7 @@ bool terrain::load_heightmap(const char *filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
// All went well...
|
// All went well...
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -476,7 +520,7 @@ bool terrain::load_texture(const char *filename, GLuint *handle)
|
||||||
// Clamp the texture at the borders
|
// Clamp the texture at the borders
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||||
// Transfer the image data to the graphics card.
|
// Transfer the image data to the graphics card.
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, BMP_GetWidth(bitmap), BMP_GetHeight(bitmap), 0, GL_RGB, GL_UNSIGNED_BYTE, data);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, BMP_GetWidth(bitmap), BMP_GetHeight(bitmap), 0, GL_RGB, GL_UNSIGNED_BYTE, data);
|
||||||
|
|
||||||
// Not needed anymore
|
// Not needed anymore
|
||||||
free(data);
|
free(data);
|
||||||
|
|
Loading…
Reference in a new issue