Degenerated triangle strip and instancing
This commit is contained in:
parent
a6705f6e6e
commit
bd0175fcda
4 changed files with 100 additions and 100 deletions
|
@ -16,6 +16,7 @@ uniform sampler2D rock;
|
||||||
uniform sampler2D alpha;
|
uniform sampler2D alpha;
|
||||||
uniform sampler2D road;
|
uniform sampler2D road;
|
||||||
uniform sampler2D specular_road;
|
uniform sampler2D specular_road;
|
||||||
|
uniform sampler2D normal_road;
|
||||||
|
|
||||||
uniform sampler2D background;
|
uniform sampler2D background;
|
||||||
uniform vec2 screenSize;
|
uniform vec2 screenSize;
|
||||||
|
@ -40,12 +41,11 @@ vec4 getBackgroundColor()
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
//surface geometry
|
//surface geometry
|
||||||
//vec3 n = vec3(0, 1, 0);
|
|
||||||
vec3 dirToViewer = vec3(0, 1, 0);
|
vec3 dirToViewer = vec3(0, 1, 0);
|
||||||
|
|
||||||
//material properties
|
//material properties
|
||||||
//color = vec4(0.6, 0.6, 0.6, 1);
|
float angle = acos(dot(n, dirToViewer));
|
||||||
color = mix(texture(grass, uv), texture(rock, uv), dot(n, dirToViewer));
|
color = mix(texture(grass, uv), texture(rock, uv), angle * angle);
|
||||||
color = mix(color, texture(road, road_uv), texture(alpha, uv).x);
|
color = mix(color, texture(road, road_uv), texture(alpha, uv).x);
|
||||||
|
|
||||||
float specular = texture(specular_road, road_uv).x;
|
float specular = texture(specular_road, road_uv).x;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
// Copyright (C) CGV TU Dresden - All Rights Reserved
|
// Copyright (C) CGV TU Dresden - All Rights Reserved
|
||||||
|
|
||||||
in vec4 position;
|
in vec4 position;
|
||||||
|
in vec2 offset;
|
||||||
|
|
||||||
out vec3 n;
|
out vec3 n;
|
||||||
out vec2 uv;
|
out vec2 uv;
|
||||||
|
@ -28,11 +29,12 @@ const vec2 offsets[6] = vec2[6](
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec4 terrain_position = vec4(position.x, getTerrainHeight(vec2(position.x, position.z)), position.z, position.w);
|
vec2 instanced_pos = vec2(position.x + offset.x, position.z + offset.y);
|
||||||
|
vec4 terrain_position = vec4(instanced_pos.x, getTerrainHeight(instanced_pos), instanced_pos.y, position.w);
|
||||||
n = calculate_normal(terrain_position);
|
n = calculate_normal(terrain_position);
|
||||||
//n = vec3(0.0, 1.0, 0.0);
|
//n = vec3(0.0, 1.0, 0.0);
|
||||||
|
|
||||||
uv = vec2(terrain_position.x / 255.0, terrain_position.z / 255.0);
|
uv = vec2(terrain_position.x / 25.5, terrain_position.z / 25.5);
|
||||||
road_uv = offsets[gl_VertexID % 6];
|
road_uv = offsets[gl_VertexID % 6];
|
||||||
|
|
||||||
gl_Position = mvp * terrain_position;
|
gl_Position = mvp * terrain_position;
|
||||||
|
|
|
@ -23,8 +23,6 @@ class Viewer : public nse::gui::AbstractViewer
|
||||||
private:
|
private:
|
||||||
void RenderSky();
|
void RenderSky();
|
||||||
|
|
||||||
Counter counter;
|
|
||||||
|
|
||||||
Eigen::Matrix4f view, proj;
|
Eigen::Matrix4f view, proj;
|
||||||
|
|
||||||
nse::gui::GLShader skyShader;
|
nse::gui::GLShader skyShader;
|
||||||
|
@ -35,9 +33,6 @@ class Viewer : public nse::gui::AbstractViewer
|
||||||
nse::gui::GLBuffer terrainPositions;
|
nse::gui::GLBuffer terrainPositions;
|
||||||
nse::gui::GLBuffer terrainIndices;
|
nse::gui::GLBuffer terrainIndices;
|
||||||
|
|
||||||
nse::gui::GLVertexArray referenceVAO;
|
|
||||||
nse::gui::GLBuffer referenceVB, referenceIB;
|
|
||||||
|
|
||||||
GLuint grassTexture, rockTexture, roadColorTexture, roadNormalMap, roadSpecularMap, alphaMap;
|
GLuint grassTexture, rockTexture, roadColorTexture, roadNormalMap, roadSpecularMap, alphaMap;
|
||||||
|
|
||||||
GLint grass_texture_location;
|
GLint grass_texture_location;
|
||||||
|
@ -45,8 +40,12 @@ class Viewer : public nse::gui::AbstractViewer
|
||||||
GLint alpha_texture_location;
|
GLint alpha_texture_location;
|
||||||
GLint road_texture_location;
|
GLint road_texture_location;
|
||||||
GLint road_specular_location;
|
GLint road_specular_location;
|
||||||
|
GLint road_normal_location;
|
||||||
|
GLint offset_buffer_location;
|
||||||
|
|
||||||
nse::gui::GLBuffer offsetBuffer;
|
nse::gui::GLBuffer offsetBuffer;
|
||||||
|
|
||||||
GLuint backgroundFBO, backgroundTexture;
|
GLuint backgroundFBO, backgroundTexture;
|
||||||
|
|
||||||
|
std::vector<Eigen::Vector2f> offsets;
|
||||||
};
|
};
|
||||||
|
|
|
@ -20,23 +20,13 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
//using vec4 = Eigen::Vector4f;
|
constexpr uint32_t PATCH_SIZE = 256; //number of vertices along one side of the terrain patch
|
||||||
/*
|
constexpr int max_offset = 5;
|
||||||
#define Eigen::Vector4f vec4
|
|
||||||
#define Eigen::Vector3f vec3
|
|
||||||
#define Eigen::Vector2f vec2
|
|
||||||
*/
|
|
||||||
|
|
||||||
constexpr bool REFERENCE = false;
|
|
||||||
constexpr uint32_t PATCH_SIZE = 32; //number of vertices along one side of the terrain patch
|
|
||||||
constexpr int elements = PATCH_SIZE * 12;
|
|
||||||
|
|
||||||
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)
|
||||||
referenceVB(nse::gui::VertexBuffer), referenceIB(nse::gui::IndexBuffer),
|
|
||||||
counter(elements, 0.5)
|
|
||||||
{
|
{
|
||||||
LoadShaders();
|
LoadShaders();
|
||||||
CreateGeometry();
|
CreateGeometry();
|
||||||
|
@ -46,6 +36,8 @@ Viewer::Viewer()
|
||||||
alpha_texture_location = terrainShader.uniform("alpha");
|
alpha_texture_location = terrainShader.uniform("alpha");
|
||||||
road_texture_location = terrainShader.uniform("road");
|
road_texture_location = terrainShader.uniform("road");
|
||||||
road_specular_location = terrainShader.uniform("specular_road");
|
road_specular_location = terrainShader.uniform("specular_road");
|
||||||
|
offset_buffer_location = terrainShader.attrib("offset");
|
||||||
|
road_normal_location = terrainShader.attrib("normal_road");
|
||||||
|
|
||||||
//Create a texture and framebuffer for the background
|
//Create a texture and framebuffer for the background
|
||||||
glGenFramebuffers(1, &backgroundFBO);
|
glGenFramebuffers(1, &backgroundFBO);
|
||||||
|
@ -57,6 +49,12 @@ Viewer::Viewer()
|
||||||
camera().Zoom(-30);
|
camera().Zoom(-30);
|
||||||
camera().RotateAroundFocusPointLocal(Eigen::AngleAxisf(-0.5f, Eigen::Vector3f::UnitY()) * Eigen::AngleAxisf(-0.05f, Eigen::Vector3f::UnitX()));
|
camera().RotateAroundFocusPointLocal(Eigen::AngleAxisf(-0.5f, Eigen::Vector3f::UnitY()) * Eigen::AngleAxisf(-0.05f, Eigen::Vector3f::UnitX()));
|
||||||
camera().FixClippingPlanes(0.1, 1000);
|
camera().FixClippingPlanes(0.1, 1000);
|
||||||
|
|
||||||
|
for (int j = -max_offset; j < max_offset; j++)
|
||||||
|
for (int i = -max_offset; i < max_offset; i++)
|
||||||
|
{
|
||||||
|
offsets.emplace_back((float)(i * PATCH_SIZE), (float)(j * PATCH_SIZE));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Viewer::resizeEvent(const Eigen::Vector2i &)
|
bool Viewer::resizeEvent(const Eigen::Vector2i &)
|
||||||
|
@ -119,6 +117,7 @@ GLuint CreateTexture(const unsigned char *fileData, size_t fileLength, bool repe
|
||||||
}
|
}
|
||||||
else if (textureChannels == 2)
|
else if (textureChannels == 2)
|
||||||
{
|
{
|
||||||
|
// wild assumption
|
||||||
provided_format = GL_RG;
|
provided_format = GL_RG;
|
||||||
}
|
}
|
||||||
else if (textureChannels == 3)
|
else if (textureChannels == 3)
|
||||||
|
@ -129,6 +128,11 @@ GLuint CreateTexture(const unsigned char *fileData, size_t fileLength, bool repe
|
||||||
{
|
{
|
||||||
provided_format = GL_RGBA;
|
provided_format = GL_RGBA;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// not handled format
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
glGenTextures(1, &textureName);
|
glGenTextures(1, &textureName);
|
||||||
glBindTexture(GL_TEXTURE_2D, textureName);
|
glBindTexture(GL_TEXTURE_2D, textureName);
|
||||||
|
@ -141,8 +145,8 @@ GLuint CreateTexture(const unsigned char *fileData, size_t fileLength, bool repe
|
||||||
|
|
||||||
if (repeat)
|
if (repeat)
|
||||||
{
|
{
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -200,72 +204,51 @@ void Viewer::CreateGeometry()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// full x direction, we skip x = 255 inside the loop
|
// full x direction, decreased y direction by 1
|
||||||
// decrease y direction by 1
|
|
||||||
int count = (PATCH_SIZE) * (PATCH_SIZE - 1);
|
int count = (PATCH_SIZE) * (PATCH_SIZE - 1);
|
||||||
|
|
||||||
|
int current_target = PATCH_SIZE - 1;
|
||||||
|
// our increment value
|
||||||
|
int current_direction = 1;
|
||||||
|
int current_index = 0;
|
||||||
|
int current_column = 0;
|
||||||
|
|
||||||
for (int k = 0; k < count; k++)
|
for (int k = 0; k < count; k++)
|
||||||
{
|
{
|
||||||
|
indices.emplace_back(current_index);
|
||||||
|
indices.emplace_back(current_index + PATCH_SIZE);
|
||||||
|
|
||||||
// skip creating triangles on last x in row
|
if (current_index == current_target)
|
||||||
/*
|
|
||||||
int end_of_x = k % (PATCH_SIZE);
|
|
||||||
|
|
||||||
if (end_of_x == 0)
|
|
||||||
{
|
{
|
||||||
continue;
|
current_index += PATCH_SIZE;
|
||||||
}
|
current_column++;
|
||||||
*/
|
|
||||||
|
|
||||||
indices.emplace_back(k);
|
if (current_direction == -1)
|
||||||
indices.emplace_back(k + PATCH_SIZE);
|
{
|
||||||
//indices.emplace_back(k + 1);
|
current_target = (PATCH_SIZE - 1) + current_column * PATCH_SIZE;
|
||||||
//indices.emplace_back(k + 1 + PATCH_SIZE);
|
}
|
||||||
|
else if (current_direction == 1)
|
||||||
|
{
|
||||||
|
current_target += 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// we've done something wrong
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
current_direction = -current_direction;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
current_index += current_direction;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
terrainShader.bind();
|
terrainShader.bind();
|
||||||
terrainPositions.uploadData(positions).bindToAttribute("position");
|
terrainPositions.uploadData(positions).bindToAttribute("position");
|
||||||
terrainIndices.uploadData(indices.size() * sizeof(uint32_t), indices.data());
|
terrainIndices.uploadData(indices.size() * sizeof(uint32_t), indices.data());
|
||||||
|
|
||||||
referenceVAO.generate();
|
|
||||||
referenceVAO.bind();
|
|
||||||
|
|
||||||
std::vector<Eigen::Vector4f> ref_pos;
|
|
||||||
std::vector<uint32_t> ref_ind;
|
|
||||||
|
|
||||||
for (int i = 0; i < PATCH_SIZE; i++)
|
|
||||||
{
|
|
||||||
for (int j = 0; j < PATCH_SIZE; j++)
|
|
||||||
{
|
|
||||||
ref_pos.emplace_back((float)j, 0.0f, (float)i, 1.0f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int index_width = PATCH_SIZE - 1;
|
|
||||||
|
|
||||||
for (int i = 0; i < index_width; i++)
|
|
||||||
{
|
|
||||||
for (int j = 0; j < index_width; j++)
|
|
||||||
{
|
|
||||||
int p1 = i + (PATCH_SIZE * j);
|
|
||||||
int p2 = i + (PATCH_SIZE * j) + 1;
|
|
||||||
int p3 = i + (PATCH_SIZE * (j + 1));
|
|
||||||
int p4 = i + (PATCH_SIZE * (j + 1)) + 1;
|
|
||||||
|
|
||||||
ref_ind.emplace_back(p1);
|
|
||||||
ref_ind.emplace_back(p3);
|
|
||||||
ref_ind.emplace_back(p2);
|
|
||||||
|
|
||||||
ref_ind.emplace_back(p3);
|
|
||||||
ref_ind.emplace_back(p2);
|
|
||||||
ref_ind.emplace_back(p4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
referenceVB.uploadData(ref_pos)
|
|
||||||
.bindToAttribute("position");
|
|
||||||
referenceIB.uploadData(ref_ind.size() * sizeof(uint32_t), ref_ind.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);
|
||||||
|
@ -335,21 +318,43 @@ void Viewer::drawContents()
|
||||||
|
|
||||||
Eigen::Matrix4f mvp = proj * view;
|
Eigen::Matrix4f mvp = proj * view;
|
||||||
Eigen::Vector3f cameraPosition = view.inverse().col(3).head<3>();
|
Eigen::Vector3f cameraPosition = view.inverse().col(3).head<3>();
|
||||||
int visiblePatches = 0;
|
|
||||||
|
Eigen::Vector4f frustum_planes[6];
|
||||||
|
nse::math::BoundingBox<float, 3> bbox;
|
||||||
|
|
||||||
|
CalculateViewFrustum(mvp, frustum_planes, bbox);
|
||||||
|
|
||||||
|
std::vector<Eigen::Vector2f> instances;
|
||||||
|
|
||||||
|
for (Eigen::Vector2f v : offsets)
|
||||||
|
{
|
||||||
|
Eigen::Vector3f min(v.x(), v.y(), 0.0f);
|
||||||
|
Eigen::Vector3f max(v.x() + (float)PATCH_SIZE, v.y() + (float)PATCH_SIZE, 15.0f);
|
||||||
|
|
||||||
|
bool is_inside = false;
|
||||||
|
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
if (IsBoxCompletelyBehindPlane(min, max, frustum_planes[i]))
|
||||||
|
{
|
||||||
|
is_inside = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_inside)
|
||||||
|
instances.emplace_back(v);
|
||||||
|
}
|
||||||
|
|
||||||
RenderSky();
|
RenderSky();
|
||||||
|
|
||||||
//render terrain
|
//render terrain
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
terrainVAO.bind();
|
||||||
|
|
||||||
if (REFERENCE)
|
offsetBuffer.bind();
|
||||||
{
|
offsetBuffer.uploadData(instances);
|
||||||
referenceVAO.bind();
|
glVertexAttribDivisor(offset_buffer_location, instances.size());
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
terrainVAO.bind();
|
|
||||||
}
|
|
||||||
|
|
||||||
terrainShader.bind();
|
terrainShader.bind();
|
||||||
|
|
||||||
|
@ -373,27 +378,21 @@ void Viewer::drawContents()
|
||||||
glBindTexture(GL_TEXTURE_2D, roadColorTexture);
|
glBindTexture(GL_TEXTURE_2D, roadColorTexture);
|
||||||
glUniform1i(road_texture_location, 3);
|
glUniform1i(road_texture_location, 3);
|
||||||
|
|
||||||
|
/*
|
||||||
glActiveTexture(GL_TEXTURE4);
|
glActiveTexture(GL_TEXTURE4);
|
||||||
glBindTexture(GL_TEXTURE_2D, roadSpecularMap);
|
glBindTexture(GL_TEXTURE_2D, roadSpecularMap);
|
||||||
glUniform1i(road_specular_location, 4);
|
glUniform1i(road_specular_location, 4);
|
||||||
|
|
||||||
if (REFERENCE)
|
glActiveTexture(GL_TEXTURE5);
|
||||||
{
|
glBindTexture(GL_TEXTURE_2D, roadNormalMap);
|
||||||
glDrawElements(GL_TRIANGLES, (PATCH_SIZE - 1) * (PATCH_SIZE - 1) * 6, GL_UNSIGNED_INT, 0);
|
glUniform1i(road_specular_location, 5);
|
||||||
}
|
*/
|
||||||
else
|
|
||||||
{
|
|
||||||
int n = counter.get_counter();
|
|
||||||
|
|
||||||
std::cout << "current n: " << n << std::endl;
|
glDrawElementsInstanced(GL_TRIANGLE_STRIP, (PATCH_SIZE - 1) * PATCH_SIZE * 2, GL_UNSIGNED_INT, 0, instances.size());
|
||||||
|
|
||||||
glPrimitiveRestartIndex(n);
|
|
||||||
glDrawElements(GL_TRIANGLE_STRIP, (PATCH_SIZE - 1) * PATCH_SIZE * 2, GL_UNSIGNED_INT, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Render text
|
//Render text
|
||||||
nvgBeginFrame(mNVGContext, width(), height(), mPixelRatio);
|
nvgBeginFrame(mNVGContext, width(), height(), mPixelRatio);
|
||||||
std::string text = "Patches visible: " + std::to_string(visiblePatches);
|
std::string text = "Patches visible: " + std::to_string(instances.size());
|
||||||
nvgText(mNVGContext, 10, 20, text.c_str(), nullptr);
|
nvgText(mNVGContext, 10, 20, text.c_str(), nullptr);
|
||||||
nvgEndFrame(mNVGContext);
|
nvgEndFrame(mNVGContext);
|
||||||
}
|
}
|
Loading…
Reference in a new issue