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 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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
}
|
Loading…
Reference in a new issue