Added new Exercise 2
This commit is contained in:
parent
af08aa43f8
commit
32e003c875
22 changed files with 473 additions and 10 deletions
|
@ -48,3 +48,4 @@ add_subdirectory(exercise1)
|
||||||
add_subdirectory(exercise2)
|
add_subdirectory(exercise2)
|
||||||
add_subdirectory(exercise3)
|
add_subdirectory(exercise3)
|
||||||
add_subdirectory(exercise4)
|
add_subdirectory(exercise4)
|
||||||
|
add_subdirectory(exercise5)
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace nse {
|
||||||
Eigen::Matrix4f &proj,
|
Eigen::Matrix4f &proj,
|
||||||
float customAspectRatio = 0) const;
|
float customAspectRatio = 0) const;
|
||||||
|
|
||||||
//Applies a zoom by scaling the scene. Positive values of amount increase object sizes.
|
//Applies a zoom by changing the view distance. Positive values of amount decrease the distance.
|
||||||
void Zoom(float amount);
|
void Zoom(float amount);
|
||||||
|
|
||||||
//Sets the extent of the scene, which is kept between znear/zfar.
|
//Sets the extent of the scene, which is kept between znear/zfar.
|
||||||
|
@ -64,6 +64,8 @@ namespace nse {
|
||||||
//Forwarded resize event.
|
//Forwarded resize event.
|
||||||
void resize(const Eigen::Vector2i & s);
|
void resize(const Eigen::Vector2i & s);
|
||||||
|
|
||||||
|
void FixClippingPlanes(float znear, float zfar);
|
||||||
|
|
||||||
//Returns the point that the camera focuses on
|
//Returns the point that the camera focuses on
|
||||||
const Eigen::Vector3f& GetFocusPoint() const;
|
const Eigen::Vector3f& GetFocusPoint() const;
|
||||||
|
|
||||||
|
@ -99,6 +101,8 @@ namespace nse {
|
||||||
|
|
||||||
Eigen::Vector3f modelTranslation_start = Eigen::Vector3f::Zero();
|
Eigen::Vector3f modelTranslation_start = Eigen::Vector3f::Zero();
|
||||||
Eigen::Vector2i translation_start; //mouse position on the screen where translation started
|
Eigen::Vector2i translation_start; //mouse position on the screen where translation started
|
||||||
|
|
||||||
|
float fixedZNear, fixedZFar;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -14,7 +14,7 @@
|
||||||
using namespace nse::gui;
|
using namespace nse::gui;
|
||||||
|
|
||||||
Camera::Camera(const nanogui::Widget & parent)
|
Camera::Camera(const nanogui::Widget & parent)
|
||||||
: parent(parent)
|
: parent(parent), fixedZNear(std::numeric_limits<float>::quiet_NaN())
|
||||||
{
|
{
|
||||||
params.arcball.setSize(parent.size());
|
params.arcball.setSize(parent.size());
|
||||||
}
|
}
|
||||||
|
@ -27,8 +27,17 @@ void Camera::ComputeCameraMatrices(Eigen::Matrix4f & view, Eigen::Matrix4f & pro
|
||||||
|
|
||||||
float depthOfSceneCenter = (params.sceneCenter - cameraPosition).dot(viewDirection);
|
float depthOfSceneCenter = (params.sceneCenter - cameraPosition).dot(viewDirection);
|
||||||
float minZNear = 0.001f * params.sceneRadius;
|
float minZNear = 0.001f * params.sceneRadius;
|
||||||
float znear = std::max(minZNear, depthOfSceneCenter - params.sceneRadius);
|
float znear, zfar;
|
||||||
float zfar = std::max(znear + minZNear, depthOfSceneCenter + params.sceneRadius);
|
if (std::isnan(fixedZNear))
|
||||||
|
{
|
||||||
|
znear = std::max(minZNear, depthOfSceneCenter - params.sceneRadius);
|
||||||
|
zfar = std::max(znear + minZNear, depthOfSceneCenter + params.sceneRadius);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
znear = fixedZNear;
|
||||||
|
zfar = fixedZFar;
|
||||||
|
}
|
||||||
|
|
||||||
float fH = std::tan(params.fovy / 360.0f * (float)M_PI) * znear;
|
float fH = std::tan(params.fovy / 360.0f * (float)M_PI) * znear;
|
||||||
float aspectRatio = customAspectRatio == 0 ? (float)parent.width() / parent.height() : customAspectRatio;
|
float aspectRatio = customAspectRatio == 0 ? (float)parent.width() / parent.height() : customAspectRatio;
|
||||||
|
@ -46,6 +55,7 @@ void Camera::Zoom(float amount)
|
||||||
|
|
||||||
void Camera::SetSceneExtent(const nse::math::BoundingBox<float, 3>& bbox)
|
void Camera::SetSceneExtent(const nse::math::BoundingBox<float, 3>& bbox)
|
||||||
{
|
{
|
||||||
|
fixedZNear = std::numeric_limits<float>::quiet_NaN();
|
||||||
params.sceneCenter = 0.5f * (bbox.min + bbox.max);
|
params.sceneCenter = 0.5f * (bbox.min + bbox.max);
|
||||||
params.sceneRadius = bbox.diagonal().norm() / 2.0f;
|
params.sceneRadius = bbox.diagonal().norm() / 2.0f;
|
||||||
}
|
}
|
||||||
|
@ -174,4 +184,10 @@ bool Camera::HandleMouseMove(const Eigen::Vector2i & p, const Eigen::Vector2i &
|
||||||
void Camera::resize(const Eigen::Vector2i & s)
|
void Camera::resize(const Eigen::Vector2i & s)
|
||||||
{
|
{
|
||||||
params.arcball.setSize(s);
|
params.arcball.setSize(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::FixClippingPlanes(float znear, float zfar)
|
||||||
|
{
|
||||||
|
fixedZNear = znear;
|
||||||
|
fixedZFar = zfar;
|
||||||
}
|
}
|
31
exercise2/CMakeLists.txt
Normal file
31
exercise2/CMakeLists.txt
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
set(GLSL_FILES sky.vert sky.frag
|
||||||
|
terrain.vert terrain.frag)
|
||||||
|
|
||||||
|
ProcessGLSLFiles(GLSL_FILES)
|
||||||
|
|
||||||
|
set(TEXTURE_FILES grass.jpg rock.jpg roadColor.jpg roadNormals.jpg roadSpecular.jpg alpha.jpg)
|
||||||
|
PREPEND(TEXTURE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/resources/" ${TEXTURE_FILES})
|
||||||
|
JOIN("${TEXTURE_FILES}" "," texture_string)
|
||||||
|
set(bin2c_cmdline
|
||||||
|
-DOUTPUT_C=textures.cpp
|
||||||
|
-DOUTPUT_H=textures.h
|
||||||
|
"-DINPUT_FILES=${texture_string}"
|
||||||
|
-P "${NANOGUI_DIR}/resources/bin2c.cmake")
|
||||||
|
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT textures.cpp textures.h
|
||||||
|
COMMAND ${CMAKE_COMMAND} ARGS ${bin2c_cmdline}
|
||||||
|
DEPENDS ${TEXTURE_FILES}
|
||||||
|
COMMENT "Running bin2c"
|
||||||
|
PRE_BUILD VERBATIM)
|
||||||
|
|
||||||
|
include_directories( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include )
|
||||||
|
|
||||||
|
add_executable(Exercise2 MACOSX_BUNDLE
|
||||||
|
glsl.cpp
|
||||||
|
textures.cpp
|
||||||
|
src/main.cpp
|
||||||
|
src/Viewer.cpp include/Viewer.h
|
||||||
|
${GLSL_FILES})
|
||||||
|
|
||||||
|
target_link_libraries(Exercise2 CG1Common ${LIBS})
|
21
exercise2/glsl/sky.frag
Normal file
21
exercise2/glsl/sky.frag
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
// This source code is property of the Computer Graphics and Visualization
|
||||||
|
// chair of the TU Dresden. Do not distribute!
|
||||||
|
// Copyright (C) CGV TU Dresden - All Rights Reserved
|
||||||
|
#version 330
|
||||||
|
|
||||||
|
out vec4 color;
|
||||||
|
|
||||||
|
in vec4 clipPos;
|
||||||
|
|
||||||
|
const vec4 horizon = vec4(0.85, 0.85, 0.8, 1.0);
|
||||||
|
const vec4 floor = vec4(0.1, 0.1, 0.1, 1.0);
|
||||||
|
const vec4 sky = vec4(0.5, 0.6, 0.8, 1.0);
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
float h = normalize(clipPos.xyz).y;
|
||||||
|
if(h < 0)
|
||||||
|
color = mix(horizon, floor, pow(-h, 0.5));
|
||||||
|
else
|
||||||
|
color = mix(horizon, sky, pow(h, 0.9));
|
||||||
|
}
|
19
exercise2/glsl/sky.vert
Normal file
19
exercise2/glsl/sky.vert
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// This source code is property of the Computer Graphics and Visualization
|
||||||
|
// chair of the TU Dresden. Do not distribute!
|
||||||
|
// Copyright (C) CGV TU Dresden - All Rights Reserved
|
||||||
|
#version 330
|
||||||
|
|
||||||
|
uniform mat4 mvp;
|
||||||
|
|
||||||
|
out vec4 clipPos;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
clipPos = vec4( float((gl_VertexID << 1) & 2) - 1.0,
|
||||||
|
float((gl_VertexID + 1) & 2) - 1.0,
|
||||||
|
float( gl_VertexID & 2) - 1.0,
|
||||||
|
1.0);
|
||||||
|
|
||||||
|
gl_Position = mvp * clipPos;
|
||||||
|
gl_Position.z = 0.5 * gl_Position.w;
|
||||||
|
}
|
49
exercise2/glsl/terrain.frag
Normal file
49
exercise2/glsl/terrain.frag
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
// This source code is property of the Computer Graphics and Visualization
|
||||||
|
// chair of the TU Dresden. Do not distribute!
|
||||||
|
// Copyright (C) CGV TU Dresden - All Rights Reserved
|
||||||
|
#version 330
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
out vec4 color;
|
||||||
|
|
||||||
|
uniform vec3 cameraPos;
|
||||||
|
|
||||||
|
|
||||||
|
uniform sampler2D background;
|
||||||
|
uniform vec2 screenSize;
|
||||||
|
|
||||||
|
const vec3 dirToLight = normalize(vec3(1, 3, 1));
|
||||||
|
|
||||||
|
//Calculates the visible surface color based on the Blinn-Phong illumination model
|
||||||
|
vec4 calculateLighting(vec4 materialColor, float specularIntensity, vec3 normalizedNormal, vec3 directionToViewer)
|
||||||
|
{
|
||||||
|
vec4 color = materialColor;
|
||||||
|
vec3 h = normalize(dirToLight + directionToViewer);
|
||||||
|
color.xyz *= 0.9 * max(dot(normalizedNormal, dirToLight), 0) + 0.1;
|
||||||
|
color.xyz += specularIntensity * pow(max(dot(h, normalizedNormal), 0), 50);
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 getBackgroundColor()
|
||||||
|
{
|
||||||
|
return texture(background, gl_FragCoord.xy / screenSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
//surface geometry
|
||||||
|
vec3 n = vec3(0, 1, 0);
|
||||||
|
vec3 dirToViewer = vec3(0, 1, 0);
|
||||||
|
|
||||||
|
//material properties
|
||||||
|
color = vec4(0.6, 0.6, 0.6, 1);
|
||||||
|
float specular = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Calculate light
|
||||||
|
color = calculateLighting(color, specular, n, dirToViewer);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
58
exercise2/glsl/terrain.vert
Normal file
58
exercise2/glsl/terrain.vert
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
// This source code is property of the Computer Graphics and Visualization
|
||||||
|
// chair of the TU Dresden. Do not distribute!
|
||||||
|
// Copyright (C) CGV TU Dresden - All Rights Reserved
|
||||||
|
#version 330
|
||||||
|
|
||||||
|
in vec4 position;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uniform mat4 mvp;
|
||||||
|
|
||||||
|
//Returns the height of the procedural terrain at a given xz position
|
||||||
|
float getTerrainHeight(vec2 p);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = mvp * position;
|
||||||
|
}
|
||||||
|
|
||||||
|
//source: https://gist.github.com/patriciogonzalezvivo/670c22f3966e662d2f83
|
||||||
|
float rand(vec2 c)
|
||||||
|
{
|
||||||
|
return 2 * fract(sin(dot(c.xy ,vec2(12.9898,78.233))) * 43758.5453) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
float perlinNoise(vec2 p )
|
||||||
|
{
|
||||||
|
vec2 ij = floor(p);
|
||||||
|
vec2 xy = p - ij;
|
||||||
|
//xy = 3.*xy*xy-2.*xy*xy*xy;
|
||||||
|
xy = .5*(1.-cos(3.1415926 * xy));
|
||||||
|
float a = rand((ij+vec2(0.,0.)));
|
||||||
|
float b = rand((ij+vec2(1.,0.)));
|
||||||
|
float c = rand((ij+vec2(0.,1.)));
|
||||||
|
float d = rand((ij+vec2(1.,1.)));
|
||||||
|
float x1 = mix(a, b, xy.x);
|
||||||
|
float x2 = mix(c, d, xy.x);
|
||||||
|
return mix(x1, x2, xy.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
//based on https://www.seedofandromeda.com/blogs/58-procedural-heightmap-terrain-generation
|
||||||
|
float getTerrainHeight(vec2 p)
|
||||||
|
{
|
||||||
|
float total = 0.0;
|
||||||
|
float maxAmplitude = 0.0;
|
||||||
|
float amplitude = 1.0;
|
||||||
|
float frequency = 0.02;
|
||||||
|
for (int i = 0; i < 11; i++)
|
||||||
|
{
|
||||||
|
total += ((1.0 - abs(perlinNoise(p * frequency))) * 2.0 - 1.0) * amplitude;
|
||||||
|
frequency *= 2.0;
|
||||||
|
maxAmplitude += amplitude;
|
||||||
|
amplitude *= 0.45;
|
||||||
|
}
|
||||||
|
return 15 * total / maxAmplitude;
|
||||||
|
}
|
42
exercise2/include/Viewer.h
Normal file
42
exercise2/include/Viewer.h
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
// This source code is property of the Computer Graphics and Visualization
|
||||||
|
// chair of the TU Dresden. Do not distribute!
|
||||||
|
// Copyright (C) CGV TU Dresden - All Rights Reserved
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <gui/AbstractViewer.h>
|
||||||
|
#include <gui/GLShader.h>
|
||||||
|
#include <gui/GLBuffer.h>
|
||||||
|
#include <gui/GLVertexArray.h>
|
||||||
|
|
||||||
|
class Viewer : public nse::gui::AbstractViewer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Viewer();
|
||||||
|
|
||||||
|
void LoadShaders();
|
||||||
|
void CreateGeometry();
|
||||||
|
|
||||||
|
void drawContents();
|
||||||
|
bool resizeEvent(const Eigen::Vector2i&);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void RenderSky();
|
||||||
|
|
||||||
|
Eigen::Matrix4f view, proj;
|
||||||
|
|
||||||
|
nse::gui::GLShader skyShader;
|
||||||
|
nse::gui::GLVertexArray emptyVAO;
|
||||||
|
|
||||||
|
nse::gui::GLShader terrainShader;
|
||||||
|
nse::gui::GLVertexArray terrainVAO;
|
||||||
|
nse::gui::GLBuffer terrainPositions;
|
||||||
|
nse::gui::GLBuffer terrainIndices;
|
||||||
|
|
||||||
|
GLuint grassTexture, rockTexture, roadColorTexture, roadNormalMap, roadSpecularMap, alphaMap;
|
||||||
|
|
||||||
|
nse::gui::GLBuffer offsetBuffer;
|
||||||
|
|
||||||
|
GLuint backgroundFBO, backgroundTexture;
|
||||||
|
};
|
BIN
exercise2/resources/alpha.jpg
Normal file
BIN
exercise2/resources/alpha.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
BIN
exercise2/resources/grass.jpg
Normal file
BIN
exercise2/resources/grass.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 1,016 KiB |
BIN
exercise2/resources/roadColor.jpg
Normal file
BIN
exercise2/resources/roadColor.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 403 KiB |
BIN
exercise2/resources/roadNormals.jpg
Normal file
BIN
exercise2/resources/roadNormals.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 672 KiB |
BIN
exercise2/resources/roadSpecular.jpg
Normal file
BIN
exercise2/resources/roadSpecular.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 572 KiB |
BIN
exercise2/resources/rock.jpg
Normal file
BIN
exercise2/resources/rock.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 MiB |
186
exercise2/src/Viewer.cpp
Normal file
186
exercise2/src/Viewer.cpp
Normal file
|
@ -0,0 +1,186 @@
|
||||||
|
// This source code is property of the Computer Graphics and Visualization
|
||||||
|
// chair of the TU Dresden. Do not distribute!
|
||||||
|
// Copyright (C) CGV TU Dresden - All Rights Reserved
|
||||||
|
|
||||||
|
#include "Viewer.h"
|
||||||
|
|
||||||
|
#include <nanogui/window.h>
|
||||||
|
#include <nanogui/layout.h>
|
||||||
|
#include <nanogui/checkbox.h>
|
||||||
|
|
||||||
|
#include <gui/SliderHelper.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <stb_image.h>
|
||||||
|
|
||||||
|
#include "glsl.h"
|
||||||
|
#include "textures.h"
|
||||||
|
|
||||||
|
const uint32_t PATCH_SIZE = 256; //number of vertices along one side of the terrain patch
|
||||||
|
|
||||||
|
Viewer::Viewer()
|
||||||
|
: AbstractViewer("CG1 Exercise 2"),
|
||||||
|
terrainPositions(nse::gui::VertexBuffer), terrainIndices(nse::gui::IndexBuffer),
|
||||||
|
offsetBuffer(nse::gui::VertexBuffer)
|
||||||
|
{
|
||||||
|
LoadShaders();
|
||||||
|
CreateGeometry();
|
||||||
|
|
||||||
|
//Create a texture and framebuffer for the background
|
||||||
|
glGenFramebuffers(1, &backgroundFBO);
|
||||||
|
glGenTextures(1, &backgroundTexture);
|
||||||
|
|
||||||
|
//Align camera to view a reasonable part of the terrain
|
||||||
|
camera().SetSceneExtent(nse::math::BoundingBox<float, 3>(Eigen::Vector3f(0, 0, 0), Eigen::Vector3f(PATCH_SIZE - 1, 0, PATCH_SIZE - 1)));
|
||||||
|
camera().FocusOnPoint(0.5f * Eigen::Vector3f(PATCH_SIZE - 1, 15, PATCH_SIZE - 1));
|
||||||
|
camera().Zoom(-30);
|
||||||
|
camera().RotateAroundFocusPointLocal(Eigen::AngleAxisf(-0.5f, Eigen::Vector3f::UnitY()) * Eigen::AngleAxisf(-0.05f, Eigen::Vector3f::UnitX()));
|
||||||
|
camera().FixClippingPlanes(0.1, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Viewer::resizeEvent(const Eigen::Vector2i&)
|
||||||
|
{
|
||||||
|
//Re-generate the texture and FBO for the background
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, backgroundFBO);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, backgroundTexture);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width(), height(), 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, backgroundTexture, 0);
|
||||||
|
auto fboStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||||
|
if (fboStatus != GL_FRAMEBUFFER_COMPLETE)
|
||||||
|
std::cout << "Warning: Background framebuffer is not complete: " << fboStatus << std::endl;
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Viewer::LoadShaders()
|
||||||
|
{
|
||||||
|
skyShader.init("Sky Shader", std::string((const char*)sky_vert, sky_vert_size), std::string((const char*)sky_frag, sky_frag_size));
|
||||||
|
terrainShader.init("Terrain Shader", std::string((const char*)terrain_vert, terrain_vert_size), std::string((const char*)terrain_frag, terrain_frag_size));
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint CreateTexture(const unsigned char* fileData, size_t fileLength, bool repeat = true)
|
||||||
|
{
|
||||||
|
GLuint textureName;
|
||||||
|
int textureWidth, textureHeight, textureChannels;
|
||||||
|
auto pixelData = stbi_load_from_memory(fileData, fileLength, &textureWidth, &textureHeight, &textureChannels, 3);
|
||||||
|
textureName = 0;
|
||||||
|
stbi_image_free(pixelData);
|
||||||
|
return textureName;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Viewer::CreateGeometry()
|
||||||
|
{
|
||||||
|
//empty VAO for sky
|
||||||
|
emptyVAO.generate();
|
||||||
|
|
||||||
|
//terrain VAO
|
||||||
|
terrainVAO.generate();
|
||||||
|
terrainVAO.bind();
|
||||||
|
|
||||||
|
std::vector<Eigen::Vector4f> positions;
|
||||||
|
std::vector<uint32_t> indices;
|
||||||
|
|
||||||
|
/*Generate positions and indices for a terrain patch with a
|
||||||
|
single triangle strip */
|
||||||
|
|
||||||
|
terrainShader.bind();
|
||||||
|
terrainPositions.uploadData(positions).bindToAttribute("position");
|
||||||
|
terrainIndices.uploadData(indices.size() * sizeof(uint32_t), indices.data());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//textures
|
||||||
|
grassTexture = CreateTexture((unsigned char*)grass_jpg, grass_jpg_size);
|
||||||
|
rockTexture = CreateTexture((unsigned char*)rock_jpg, rock_jpg_size);
|
||||||
|
roadColorTexture = CreateTexture((unsigned char*)roadcolor_jpg, roadcolor_jpg_size);
|
||||||
|
roadNormalMap = CreateTexture((unsigned char*)roadnormals_jpg, roadnormals_jpg_size);
|
||||||
|
roadSpecularMap = CreateTexture((unsigned char*)roadspecular_jpg, roadspecular_jpg_size);
|
||||||
|
alphaMap = CreateTexture((unsigned char*)alpha_jpg, alpha_jpg_size, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Viewer::RenderSky()
|
||||||
|
{
|
||||||
|
Eigen::Matrix4f skyView = view;
|
||||||
|
for (int i = 0; i < 3; ++i)
|
||||||
|
skyView.col(i).normalize();
|
||||||
|
skyView.col(3).head<3>().setZero();
|
||||||
|
Eigen::Matrix4f skyMvp = proj * skyView;
|
||||||
|
glDepthMask(GL_FALSE);
|
||||||
|
glEnable(GL_DEPTH_CLAMP);
|
||||||
|
emptyVAO.bind();
|
||||||
|
skyShader.bind();
|
||||||
|
skyShader.setUniform("mvp", skyMvp);
|
||||||
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 6);
|
||||||
|
glDisable(GL_DEPTH_CLAMP);
|
||||||
|
glDepthMask(GL_TRUE);
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, backgroundFBO);
|
||||||
|
glBlitFramebuffer(0, 0, width(), height(), 0, 0, width(), height(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||||
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
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[1] = (mvp.row(3) - mvp.row(0)).transpose();
|
||||||
|
frustumPlanes[2] = (mvp.row(3) + mvp.row(1)).transpose();
|
||||||
|
frustumPlanes[3] = (mvp.row(3) - mvp.row(1)).transpose();
|
||||||
|
frustumPlanes[4] = (mvp.row(3) + mvp.row(2)).transpose();
|
||||||
|
frustumPlanes[5] = (mvp.row(3) - mvp.row(2)).transpose();
|
||||||
|
|
||||||
|
Eigen::Matrix4f invMvp = mvp.inverse();
|
||||||
|
bbox.reset();
|
||||||
|
for(int x = -1; x <= 1; x += 2)
|
||||||
|
for(int y = -1; y <= 1; y += 2)
|
||||||
|
for (int z = -1; z <= 1; z += 2)
|
||||||
|
{
|
||||||
|
Eigen::Vector4f corner = invMvp * Eigen::Vector4f(x, y, z, 1);
|
||||||
|
corner /= corner.w();
|
||||||
|
bbox.expand(corner.head<3>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsBoxCompletelyBehindPlane(const Eigen::Vector3f& boxMin, const Eigen::Vector3f& boxMax, const Eigen::Vector4f& plane)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
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(), 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(), 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Viewer::drawContents()
|
||||||
|
{
|
||||||
|
camera().ComputeCameraMatrices(view, proj);
|
||||||
|
|
||||||
|
Eigen::Matrix4f mvp = proj * view;
|
||||||
|
Eigen::Vector3f cameraPosition = view.inverse().col(3).head<3>();
|
||||||
|
int visiblePatches = 0;
|
||||||
|
|
||||||
|
RenderSky();
|
||||||
|
|
||||||
|
//render terrain
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
terrainVAO.bind();
|
||||||
|
terrainShader.bind();
|
||||||
|
|
||||||
|
terrainShader.setUniform("screenSize", Eigen::Vector2f(width(), height()), false);
|
||||||
|
terrainShader.setUniform("mvp", mvp);
|
||||||
|
terrainShader.setUniform("cameraPos", cameraPosition, false);
|
||||||
|
|
||||||
|
/* Task: Render the terrain */
|
||||||
|
|
||||||
|
|
||||||
|
//Render text
|
||||||
|
nvgBeginFrame(mNVGContext, width(), height(), mPixelRatio);
|
||||||
|
std::string text = "Patches visible: " + std::to_string(visiblePatches);
|
||||||
|
nvgText(mNVGContext, 10, 20, text.c_str(), nullptr);
|
||||||
|
nvgEndFrame(mNVGContext);
|
||||||
|
}
|
36
exercise2/src/main.cpp
Normal file
36
exercise2/src/main.cpp
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
// This source code is property of the Computer Graphics and Visualization
|
||||||
|
// chair of the TU Dresden. Do not distribute!
|
||||||
|
// Copyright (C) CGV TU Dresden - All Rights Reserved
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <util/GLDebug.h>
|
||||||
|
|
||||||
|
#include "Viewer.h"
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
nanogui::init();
|
||||||
|
|
||||||
|
{
|
||||||
|
nanogui::ref<Viewer> viewer = new Viewer();
|
||||||
|
viewer->setVisible(true);
|
||||||
|
|
||||||
|
nse::util::GLDebug::SetupDebugCallback();
|
||||||
|
nse::util::GLDebug::IgnoreGLError(131185); //buffer usage info
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
nanogui::mainloop();
|
||||||
|
}
|
||||||
|
catch (std::runtime_error& e)
|
||||||
|
{
|
||||||
|
std::cerr << e.what() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
nanogui::shutdown();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
include_directories( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include )
|
include_directories( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include )
|
||||||
|
|
||||||
add_executable(Exercise2 MACOSX_BUNDLE
|
add_executable(Exercise3 MACOSX_BUNDLE
|
||||||
src/main.cpp
|
src/main.cpp
|
||||||
src/Viewer.cpp include/Viewer.h
|
src/Viewer.cpp include/Viewer.h
|
||||||
src/Primitives.cpp include/Primitives.h
|
src/Primitives.cpp include/Primitives.h
|
||||||
|
@ -11,4 +11,4 @@ add_executable(Exercise2 MACOSX_BUNDLE
|
||||||
src/Stripification.cpp include/Stripification.h
|
src/Stripification.cpp include/Stripification.h
|
||||||
include/sample_set.h)
|
include/sample_set.h)
|
||||||
|
|
||||||
target_link_libraries(Exercise2 CG1Common ${LIBS})
|
target_link_libraries(Exercise3 CG1Common ${LIBS})
|
|
@ -1,6 +1,6 @@
|
||||||
include_directories( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include )
|
include_directories( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include )
|
||||||
|
|
||||||
add_executable(Exercise3 MACOSX_BUNDLE
|
add_executable(Exercise4 MACOSX_BUNDLE
|
||||||
src/main.cpp
|
src/main.cpp
|
||||||
src/Viewer.cpp include/Viewer.h
|
src/Viewer.cpp include/Viewer.h
|
||||||
src/AABBTree.cpp include/AABBTree.h
|
src/AABBTree.cpp include/AABBTree.h
|
||||||
|
@ -13,4 +13,4 @@ add_executable(Exercise3 MACOSX_BUNDLE
|
||||||
src/GridTraverser.cpp include/GridTraverser.h
|
src/GridTraverser.cpp include/GridTraverser.h
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(Exercise3 CG1Common ${LIBS})
|
target_link_libraries(Exercise4 CG1Common ${LIBS})
|
|
@ -1,10 +1,10 @@
|
||||||
include_directories( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include )
|
include_directories( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include )
|
||||||
|
|
||||||
add_executable(Exercise4 MACOSX_BUNDLE
|
add_executable(Exercise5 MACOSX_BUNDLE
|
||||||
src/main.cpp
|
src/main.cpp
|
||||||
src/Viewer.cpp include/Viewer.h
|
src/Viewer.cpp include/Viewer.h
|
||||||
src/Parametrization.cpp include/Parametrization.h
|
src/Parametrization.cpp include/Parametrization.h
|
||||||
src/Registration.cpp include/Registration.h
|
src/Registration.cpp include/Registration.h
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(Exercise4 CG1Common ${LIBS})
|
target_link_libraries(Exercise5 CG1Common ${LIBS})
|
BIN
solution/linux/Exercise2
Normal file
BIN
solution/linux/Exercise2
Normal file
Binary file not shown.
BIN
solution/win/Exercise2.exe
Normal file
BIN
solution/win/Exercise2.exe
Normal file
Binary file not shown.
Loading…
Reference in a new issue