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
|
||||
// chair of the TU Dresden. Do not distribute in modified or unmodified form!
|
||||
// This source code is property of the Computer Graphics and Visualization
|
||||
// chair of the TU Dresden. Do not distribute in modified or unmodified form!
|
||||
// Copyright (C) 2016 CGV TU Dresden - All Rights Reserved
|
||||
//
|
||||
/*************************************************************************
|
||||
Terrain.
|
||||
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.
|
||||
During rendering the normals needed for lighting are calculated.
|
||||
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".
|
||||
Depending on the settings (that can be changed using "set_show_solid",
|
||||
"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_terrain" method.
|
||||
*************************************************************************/
|
||||
|
@ -92,7 +92,10 @@ private:
|
|||
// Create height lines for the level "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"
|
||||
bool load_heightmap(const char *filename);
|
||||
// Return the width of the height map
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// This source code is property of the Computer Graphics and Visualization
|
||||
// chair of the TU Dresden. Do not distribute in modified or unmodified form!
|
||||
// This source code is property of the Computer Graphics and Visualization
|
||||
// chair of the TU Dresden. Do not distribute in modified or unmodified form!
|
||||
// Copyright (C) 2016 CGV TU Dresden - All Rights Reserved
|
||||
//
|
||||
#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
|
||||
glColor3d(1, 1, 1);
|
||||
|
@ -123,7 +124,7 @@ void terrain::render_solid_terrain()
|
|||
// Disable texture mapping
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
// Disable support for depth buffer offsets
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
// Disable lighting
|
||||
glDisable(GL_LIGHTING);
|
||||
}
|
||||
|
@ -141,13 +142,18 @@ void terrain::render_wireframe_terrain()
|
|||
// Set the color to black
|
||||
glColor3d(0, 0, 0);
|
||||
// Render the terrain
|
||||
render_terrain();
|
||||
render_terrain();
|
||||
|
||||
// Set the draw mode to fill polygons
|
||||
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
|
||||
void terrain::render_terrain()
|
||||
|
@ -175,7 +181,7 @@ void terrain::render_terrain()
|
|||
and translated to use the values of the variables "x" and "y"
|
||||
defined below directly as coordinates. The initial height of
|
||||
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
|
||||
X-Z-Ebene erstreckt. Erstellen Sie dieses Gitter, indem Sie
|
||||
zeilenweise Dreiecksstreifen definieren. Das Koordinatensystem
|
||||
|
@ -184,23 +190,23 @@ void terrain::render_terrain()
|
|||
als Koordinaten einsetzen koennen. Das Gitter soll zunaechst
|
||||
eine Hoehe von 0 besitzen.
|
||||
|
||||
|
||||
|
||||
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)".
|
||||
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)".
|
||||
|
||||
|
||||
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".
|
||||
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.
|
||||
|
||||
|
||||
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
|
||||
this method using "glTexCoord2d".
|
||||
this method using "glTexCoord2d".
|
||||
Aufgabe 2.2.4. Aktivieren Sie Texturmapping und binden Sie eine Textur in der
|
||||
Methode "render_solid_terrain". Spezifizieren Sie in dieser Methode pro
|
||||
Vertex eine Texturkoordinate mittels der Methode "glTexCoord2d".
|
||||
|
@ -214,8 +220,8 @@ void terrain::render_terrain()
|
|||
|
||||
// Draw one strip
|
||||
for (int x = 0; x < map_width; x++) {
|
||||
glVertex3f(static_cast<float>(x), get_heightmap_value(x, y), static_cast<float>(y));
|
||||
glVertex3f(static_cast<float>(x), get_heightmap_value(x, y + 1), static_cast<float>(y) + 1.0f);
|
||||
push_point(x, y);
|
||||
push_point(x, y + 1);
|
||||
}
|
||||
|
||||
glEnd();
|
||||
|
@ -224,8 +230,30 @@ void terrain::render_terrain()
|
|||
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)
|
||||
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,
|
||||
backward differences or central differences. The latter will give
|
||||
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
|
||||
is perpendicular to both. You find some examples for vector operations in
|
||||
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
|
||||
this project below. Do not forget to pass the normal to OpenGL using
|
||||
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
|
||||
gebildet und anschliessend mittels Vektoroperationen ein zu beiden Vektoren
|
||||
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.
|
||||
|
||||
// Create a vector
|
||||
|
@ -270,6 +298,22 @@ void terrain::set_normal(int x, int y)
|
|||
double y = vec3.y();
|
||||
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)
|
||||
{
|
||||
/********
|
||||
Additional Task: Find iso lines with the "Marching Squares" algorithm for the
|
||||
height value "level". Store the start and end points of the
|
||||
Additional Task: Find iso lines with the "Marching Squares" algorithm for the
|
||||
height value "level". Store the start and end points of the
|
||||
found lines in the list "level_lines".
|
||||
Zusatzaufgabe: Finden Sie Hoehenlinien mittels des "Marching Squares"-Algorithmus
|
||||
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_SPECULAR, specular_color);
|
||||
|
||||
glLightf(GL_LIGHT0,GL_SPOT_EXPONENT, 10.0f);
|
||||
glLightf(GL_LIGHT0,GL_SPOT_EXPONENT, 10.0f);
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
|
@ -403,7 +447,7 @@ void terrain::set_show_solid(bool state)
|
|||
void terrain::set_show_wireframe(bool state)
|
||||
{
|
||||
show_wireframe = state;
|
||||
// The current display list is outdated now
|
||||
// The current display list is outdated now
|
||||
dl_valid = false;
|
||||
}
|
||||
|
||||
|
@ -442,7 +486,7 @@ bool terrain::load_heightmap(const char *filename)
|
|||
}
|
||||
|
||||
// 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
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||
// 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
|
||||
free(data);
|
||||
|
|
Loading…
Reference in a new issue