Degenerated triangle strip and instancing

This commit is contained in:
hodasemi 2018-11-29 12:16:21 +01:00
parent a6705f6e6e
commit bd0175fcda
4 changed files with 100 additions and 100 deletions

View file

@ -16,6 +16,7 @@ uniform sampler2D rock;
uniform sampler2D alpha;
uniform sampler2D road;
uniform sampler2D specular_road;
uniform sampler2D normal_road;
uniform sampler2D background;
uniform vec2 screenSize;
@ -40,12 +41,11 @@ vec4 getBackgroundColor()
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);
color = mix(texture(grass, uv), texture(rock, uv), dot(n, dirToViewer));
float angle = acos(dot(n, dirToViewer));
color = mix(texture(grass, uv), texture(rock, uv), angle * angle);
color = mix(color, texture(road, road_uv), texture(alpha, uv).x);
float specular = texture(specular_road, road_uv).x;

View file

@ -4,6 +4,7 @@
// Copyright (C) CGV TU Dresden - All Rights Reserved
in vec4 position;
in vec2 offset;
out vec3 n;
out vec2 uv;
@ -28,11 +29,12 @@ const vec2 offsets[6] = vec2[6](
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 = 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];
gl_Position = mvp * terrain_position;

View file

@ -23,8 +23,6 @@ class Viewer : public nse::gui::AbstractViewer
private:
void RenderSky();
Counter counter;
Eigen::Matrix4f view, proj;
nse::gui::GLShader skyShader;
@ -35,9 +33,6 @@ class Viewer : public nse::gui::AbstractViewer
nse::gui::GLBuffer terrainPositions;
nse::gui::GLBuffer terrainIndices;
nse::gui::GLVertexArray referenceVAO;
nse::gui::GLBuffer referenceVB, referenceIB;
GLuint grassTexture, rockTexture, roadColorTexture, roadNormalMap, roadSpecularMap, alphaMap;
GLint grass_texture_location;
@ -45,8 +40,12 @@ class Viewer : public nse::gui::AbstractViewer
GLint alpha_texture_location;
GLint road_texture_location;
GLint road_specular_location;
GLint road_normal_location;
GLint offset_buffer_location;
nse::gui::GLBuffer offsetBuffer;
GLuint backgroundFBO, backgroundTexture;
std::vector<Eigen::Vector2f> offsets;
};

View file

@ -20,23 +20,13 @@
#include <sstream>
#include <cmath>
//using vec4 = Eigen::Vector4f;
/*
#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;
constexpr uint32_t PATCH_SIZE = 256; //number of vertices along one side of the terrain patch
constexpr int max_offset = 5;
Viewer::Viewer()
: AbstractViewer("CG1 Exercise 2"),
terrainPositions(nse::gui::VertexBuffer), terrainIndices(nse::gui::IndexBuffer),
offsetBuffer(nse::gui::VertexBuffer),
referenceVB(nse::gui::VertexBuffer), referenceIB(nse::gui::IndexBuffer),
counter(elements, 0.5)
offsetBuffer(nse::gui::VertexBuffer)
{
LoadShaders();
CreateGeometry();
@ -46,6 +36,8 @@ Viewer::Viewer()
alpha_texture_location = terrainShader.uniform("alpha");
road_texture_location = terrainShader.uniform("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
glGenFramebuffers(1, &backgroundFBO);
@ -57,6 +49,12 @@ Viewer::Viewer()
camera().Zoom(-30);
camera().RotateAroundFocusPointLocal(Eigen::AngleAxisf(-0.5f, Eigen::Vector3f::UnitY()) * Eigen::AngleAxisf(-0.05f, Eigen::Vector3f::UnitX()));
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 &)
@ -119,6 +117,7 @@ GLuint CreateTexture(const unsigned char *fileData, size_t fileLength, bool repe
}
else if (textureChannels == 2)
{
// wild assumption
provided_format = GL_RG;
}
else if (textureChannels == 3)
@ -129,6 +128,11 @@ GLuint CreateTexture(const unsigned char *fileData, size_t fileLength, bool repe
{
provided_format = GL_RGBA;
}
else
{
// not handled format
abort();
}
glGenTextures(1, &textureName);
glBindTexture(GL_TEXTURE_2D, textureName);
@ -141,8 +145,8 @@ GLuint CreateTexture(const unsigned char *fileData, size_t fileLength, bool repe
if (repeat)
{
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
}
else
{
@ -200,72 +204,51 @@ void Viewer::CreateGeometry()
}
}
// full x direction, we skip x = 255 inside the loop
// decrease y direction by 1
// full x direction, decreased y direction by 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++)
{
indices.emplace_back(current_index);
indices.emplace_back(current_index + PATCH_SIZE);
// skip creating triangles on last x in row
/*
int end_of_x = k % (PATCH_SIZE);
if (end_of_x == 0)
if (current_index == current_target)
{
continue;
}
*/
current_index += PATCH_SIZE;
current_column++;
indices.emplace_back(k);
indices.emplace_back(k + PATCH_SIZE);
//indices.emplace_back(k + 1);
//indices.emplace_back(k + 1 + PATCH_SIZE);
if (current_direction == -1)
{
current_target = (PATCH_SIZE - 1) + current_column * 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();
terrainPositions.uploadData(positions).bindToAttribute("position");
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
grassTexture = CreateTexture((unsigned char *)grass_jpg, grass_jpg_size);
rockTexture = CreateTexture((unsigned char *)rock_jpg, rock_jpg_size);
@ -335,21 +318,43 @@ void Viewer::drawContents()
Eigen::Matrix4f mvp = proj * view;
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();
//render terrain
glEnable(GL_DEPTH_TEST);
terrainVAO.bind();
if (REFERENCE)
{
referenceVAO.bind();
}
else
{
terrainVAO.bind();
}
offsetBuffer.bind();
offsetBuffer.uploadData(instances);
glVertexAttribDivisor(offset_buffer_location, instances.size());
terrainShader.bind();
@ -373,27 +378,21 @@ void Viewer::drawContents()
glBindTexture(GL_TEXTURE_2D, roadColorTexture);
glUniform1i(road_texture_location, 3);
/*
glActiveTexture(GL_TEXTURE4);
glBindTexture(GL_TEXTURE_2D, roadSpecularMap);
glUniform1i(road_specular_location, 4);
if (REFERENCE)
{
glDrawElements(GL_TRIANGLES, (PATCH_SIZE - 1) * (PATCH_SIZE - 1) * 6, GL_UNSIGNED_INT, 0);
}
else
{
int n = counter.get_counter();
glActiveTexture(GL_TEXTURE5);
glBindTexture(GL_TEXTURE_2D, roadNormalMap);
glUniform1i(road_specular_location, 5);
*/
std::cout << "current n: " << n << std::endl;
glPrimitiveRestartIndex(n);
glDrawElements(GL_TRIANGLE_STRIP, (PATCH_SIZE - 1) * PATCH_SIZE * 2, GL_UNSIGNED_INT, 0);
}
glDrawElementsInstanced(GL_TRIANGLE_STRIP, (PATCH_SIZE - 1) * PATCH_SIZE * 2, GL_UNSIGNED_INT, 0, instances.size());
//Render text
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);
nvgEndFrame(mNVGContext);
}