Try to solve task 2.2

This commit is contained in:
hodasemi 2018-11-26 09:59:16 +01:00
parent f86fc26703
commit 9a0df4e4ab
3 changed files with 125 additions and 61 deletions

View file

@ -3,6 +3,8 @@
// chair of the TU Dresden. Do not distribute! // chair of the TU Dresden. Do not distribute!
// Copyright (C) CGV TU Dresden - All Rights Reserved // Copyright (C) CGV TU Dresden - All Rights Reserved
in vec3 n;
out vec4 color; out vec4 color;
uniform vec3 cameraPos; uniform vec3 cameraPos;
@ -31,7 +33,7 @@ vec4 getBackgroundColor()
void main() void main()
{ {
//surface geometry //surface geometry
vec3 n = vec3(0, 1, 0); //vec3 n = vec3(0, 1, 0);
vec3 dirToViewer = vec3(0, 1, 0); vec3 dirToViewer = vec3(0, 1, 0);
//material properties //material properties

View file

@ -5,18 +5,31 @@
in vec4 position; in vec4 position;
out vec3 n;
uniform mat4 mvp; uniform mat4 mvp;
//Returns the height of the procedural terrain at a given xz position //Returns the height of the procedural terrain at a given xz position
float getTerrainHeight(vec2 p); float getTerrainHeight(vec2 p);
vec3 calculate_normal(vec4 terrain_position);
vec4 offset_point(vec4 base, vec2 offset);
const vec2 offsets[6] = vec2[6](
vec2(0.0, 0.0),
vec2(0.0, 1.0),
vec2(1.0, 0.0),
vec2(0.0, 1.0),
vec2(1.0, 0.0),
vec2(1.0, 1.0)
);
void main() void main()
{ {
gl_Position = mvp * position; vec4 terrain_position = vec4(position.x, getTerrainHeight(vec2(position.x, position.z)), position.z, position.w);
n = calculate_normal(position);
gl_Position = mvp * terrain_position;
} }
//source: https://gist.github.com/patriciogonzalezvivo/670c22f3966e662d2f83 //source: https://gist.github.com/patriciogonzalezvivo/670c22f3966e662d2f83
@ -56,3 +69,49 @@ float getTerrainHeight(vec2 p)
} }
return 15 * total / maxAmplitude; return 15 * total / maxAmplitude;
} }
vec4 offset_point(vec4 base, vec2 offset) {
float y = getTerrainHeight(vec2(base.x, base.z) + offset);
return vec4(base.x + offset.x, y, base.z + offset.y, base.w);
}
// calculate the position of the first vertex in this square
vec4 pos_to_base(vec4 pos, int v_id) {
return vec4(pos.x - offsets[v_id].x, pos.y, pos.z - offsets[v_id].y, pos.w);
}
// calculates the normal of terrain_position
// it generates the complete triangle based on the gl_VertexID and then normal math
vec3 calculate_normal(vec4 terrain_position) {
int offset_index = gl_VertexID % 6;
vec4 base_vertex = pos_to_base(terrain_position, offset_index);
// the other 2 points from the triangle
int points_index = 0;
vec4 points[2];
int iterator_offset = 0;
// second triangle offset
if (offset_index > 2) {
iterator_offset = 3;
}
for (int i = iterator_offset; i < (3 + iterator_offset); i++) {
// skip for current vertex
if (i == offset_index) {
continue;
}
points[points_index] = offset_point(base_vertex, offsets[i]);
points_index++;
}
// create connection vectors
vec3 p1 = (points[0] - terrain_position).xyz;
vec3 p2 = (points[1] - terrain_position).xyz;
// calculate normal
return normalize(cross(p1, p2));
}

View file

@ -23,8 +23,8 @@ const uint32_t PATCH_SIZE = 256; //number of vertices along one side of the terr
Viewer::Viewer() Viewer::Viewer()
: AbstractViewer("CG1 Exercise 2"), : AbstractViewer("CG1 Exercise 2"),
terrainPositions(nse::gui::VertexBuffer), terrainIndices(nse::gui::IndexBuffer), terrainPositions(nse::gui::VertexBuffer), terrainIndices(nse::gui::IndexBuffer),
offsetBuffer(nse::gui::VertexBuffer) offsetBuffer(nse::gui::VertexBuffer)
{ {
LoadShaders(); LoadShaders();
CreateGeometry(); CreateGeometry();
@ -41,7 +41,7 @@ Viewer::Viewer()
camera().FixClippingPlanes(0.1, 1000); camera().FixClippingPlanes(0.1, 1000);
} }
bool Viewer::resizeEvent(const Eigen::Vector2i&) bool Viewer::resizeEvent(const Eigen::Vector2i &)
{ {
//Re-generate the texture and FBO for the background //Re-generate the texture and FBO for the background
glBindFramebuffer(GL_FRAMEBUFFER, backgroundFBO); glBindFramebuffer(GL_FRAMEBUFFER, backgroundFBO);
@ -87,7 +87,7 @@ void Viewer::LoadShaders()
terrainShader.init("Terrain Shader", terrain_vs, terrain_fs); terrainShader.init("Terrain Shader", terrain_vs, terrain_fs);
} }
GLuint CreateTexture(const unsigned char* fileData, size_t fileLength, bool repeat = true) GLuint CreateTexture(const unsigned char *fileData, size_t fileLength, bool repeat = true)
{ {
GLuint textureName; GLuint textureName;
int textureWidth, textureHeight, textureChannels; int textureWidth, textureHeight, textureChannels;
@ -112,22 +112,26 @@ void Viewer::CreateGeometry()
/*Generate positions and indices for a terrain patch with a /*Generate positions and indices for a terrain patch with a
single triangle strip */ single triangle strip */
for (int i = 0; i < PATCH_SIZE; i++) { for (int i = 0; i < PATCH_SIZE; i++)
for (int j = 0; j < PATCH_SIZE; j++) { {
for (int j = 0; j < PATCH_SIZE; j++)
{
positions.emplace_back((float)i, 0.0f, (float)j, 1.0f); positions.emplace_back((float)i, 0.0f, (float)j, 1.0f);
} }
} }
// full x direction, we skip x = 255 inside the loop // full x direction, we skip x = 255 inside the loop
// decrease y direction by 1 // decrease y direction by 1
int count = (PATCH_SIZE) * (PATCH_SIZE-1); int count = (PATCH_SIZE) * (PATCH_SIZE - 1);
for (int k = 0; k < count; k++) { for (int k = 0; k < count; k++)
{
// skip creating triangles on last x in row // skip creating triangles on last x in row
int end_of_x = k % (PATCH_SIZE-1); int end_of_x = k % (PATCH_SIZE - 1);
if (end_of_x == 0) { if (end_of_x == 0)
{
continue; continue;
} }
@ -142,12 +146,12 @@ void Viewer::CreateGeometry()
terrainIndices.uploadData(indices.size() * sizeof(uint32_t), indices.data()); terrainIndices.uploadData(indices.size() * sizeof(uint32_t), indices.data());
//textures //textures
grassTexture = CreateTexture((unsigned char*)grass_jpg, grass_jpg_size); grassTexture = CreateTexture((unsigned char *)grass_jpg, grass_jpg_size);
rockTexture = CreateTexture((unsigned char*)rock_jpg, rock_jpg_size); rockTexture = CreateTexture((unsigned char *)rock_jpg, rock_jpg_size);
roadColorTexture = CreateTexture((unsigned char*)roadcolor_jpg, roadcolor_jpg_size); roadColorTexture = CreateTexture((unsigned char *)roadcolor_jpg, roadcolor_jpg_size);
roadNormalMap = CreateTexture((unsigned char*)roadnormals_jpg, roadnormals_jpg_size); roadNormalMap = CreateTexture((unsigned char *)roadnormals_jpg, roadnormals_jpg_size);
roadSpecularMap = CreateTexture((unsigned char*)roadspecular_jpg, roadspecular_jpg_size); roadSpecularMap = CreateTexture((unsigned char *)roadspecular_jpg, roadspecular_jpg_size);
alphaMap = CreateTexture((unsigned char*)alpha_jpg, alpha_jpg_size, false); alphaMap = CreateTexture((unsigned char *)alpha_jpg, alpha_jpg_size, false);
} }
void Viewer::RenderSky() void Viewer::RenderSky()
@ -171,7 +175,7 @@ void Viewer::RenderSky()
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
} }
void CalculateViewFrustum(const Eigen::Matrix4f& mvp, Eigen::Vector4f* frustumPlanes, nse::math::BoundingBox<float, 3>& bbox) void CalculateViewFrustum(const Eigen::Matrix4f &mvp, Eigen::Vector4f *frustumPlanes, nse::math::BoundingBox<float, 3> &bbox)
{ {
frustumPlanes[0] = (mvp.row(3) + mvp.row(0)).transpose(); frustumPlanes[0] = (mvp.row(3) + mvp.row(0)).transpose();
frustumPlanes[1] = (mvp.row(3) - mvp.row(0)).transpose(); frustumPlanes[1] = (mvp.row(3) - mvp.row(0)).transpose();
@ -182,27 +186,26 @@ void CalculateViewFrustum(const Eigen::Matrix4f& mvp, Eigen::Vector4f* frustumPl
Eigen::Matrix4f invMvp = mvp.inverse(); Eigen::Matrix4f invMvp = mvp.inverse();
bbox.reset(); bbox.reset();
for(int x = -1; x <= 1; x += 2) for (int x = -1; x <= 1; x += 2)
for(int y = -1; y <= 1; y += 2) for (int y = -1; y <= 1; y += 2)
for (int z = -1; z <= 1; z += 2) for (int z = -1; z <= 1; z += 2)
{ {
Eigen::Vector4f corner = invMvp * Eigen::Vector4f(x, y, z, 1); Eigen::Vector4f corner = invMvp * Eigen::Vector4f(x, y, z, 1);
corner /= corner.w(); corner /= corner.w();
bbox.expand(corner.head<3>()); bbox.expand(corner.head<3>());
} }
} }
bool IsBoxCompletelyBehindPlane(const Eigen::Vector3f& boxMin, const Eigen::Vector3f& boxMax, const Eigen::Vector4f& plane) bool IsBoxCompletelyBehindPlane(const Eigen::Vector3f &boxMin, const Eigen::Vector3f &boxMax, const Eigen::Vector4f &plane)
{ {
return return plane.dot(Eigen::Vector4f(boxMin.x(), boxMin.y(), boxMin.z(), 1)) < 0 &&
plane.dot(Eigen::Vector4f(boxMin.x(), boxMin.y(), boxMin.z(), 1)) < 0 && plane.dot(Eigen::Vector4f(boxMin.x(), boxMin.y(), boxMax.z(), 1)) < 0 &&
plane.dot(Eigen::Vector4f(boxMin.x(), boxMin.y(), boxMax.z(), 1)) < 0 && plane.dot(Eigen::Vector4f(boxMin.x(), boxMax.y(), boxMin.z(), 1)) < 0 &&
plane.dot(Eigen::Vector4f(boxMin.x(), boxMax.y(), boxMin.z(), 1)) < 0 && plane.dot(Eigen::Vector4f(boxMin.x(), boxMax.y(), boxMin.z(), 1)) < 0 &&
plane.dot(Eigen::Vector4f(boxMin.x(), boxMax.y(), boxMin.z(), 1)) < 0 && plane.dot(Eigen::Vector4f(boxMax.x(), boxMin.y(), boxMin.z(), 1)) < 0 &&
plane.dot(Eigen::Vector4f(boxMax.x(), boxMin.y(), boxMin.z(), 1)) < 0 && plane.dot(Eigen::Vector4f(boxMax.x(), boxMin.y(), boxMax.z(), 1)) < 0 &&
plane.dot(Eigen::Vector4f(boxMax.x(), boxMin.y(), boxMax.z(), 1)) < 0 && plane.dot(Eigen::Vector4f(boxMax.x(), boxMax.y(), boxMin.z(), 1)) < 0 &&
plane.dot(Eigen::Vector4f(boxMax.x(), boxMax.y(), boxMin.z(), 1)) < 0 && plane.dot(Eigen::Vector4f(boxMax.x(), boxMax.y(), boxMin.z(), 1)) < 0;
plane.dot(Eigen::Vector4f(boxMax.x(), boxMax.y(), boxMin.z(), 1)) < 0;
} }
void Viewer::drawContents() void Viewer::drawContents()
@ -225,8 +228,8 @@ void Viewer::drawContents()
terrainShader.setUniform("cameraPos", cameraPosition, false); terrainShader.setUniform("cameraPos", cameraPosition, false);
/* Task: Render the terrain */ /* Task: Render the terrain */
//glPrimitiveRestartIndex(255); glPrimitiveRestartIndex(512);
glDrawElements(GL_TRIANGLE_STRIP, (PATCH_SIZE-1) * (PATCH_SIZE-1) * 4, GL_UNSIGNED_INT, 0); glDrawElements(GL_TRIANGLE_STRIP, (PATCH_SIZE - 1) * (PATCH_SIZE - 1) * 4, GL_UNSIGNED_INT, 0);
//Render text //Render text
nvgBeginFrame(mNVGContext, width(), height(), mPixelRatio); nvgBeginFrame(mNVGContext, width(), height(), mPixelRatio);