From 37d2e4aabc6834eb6d5b7d104f41e6b47a170e89 Mon Sep 17 00:00:00 2001 From: karl Date: Sat, 20 Mar 2021 00:57:18 +0100 Subject: [PATCH] Lots of cleanup --- MCRenderer.cpp | 35 +++++++++++++++++++++-------------- MCRenderer.h | 12 +++++------- Shader/mc.vs | 34 +++++++++++++++++++++------------- Shader/noise.fs | 21 +++++++++++---------- Shader/noise.vs | 18 +++++++++--------- VertexBuffer.cpp | 22 ++++++++++++++-------- VertexBuffer.h | 5 +++-- main.cpp | 2 +- 8 files changed, 85 insertions(+), 64 deletions(-) diff --git a/MCRenderer.cpp b/MCRenderer.cpp index 46c38bb..f59a747 100644 --- a/MCRenderer.cpp +++ b/MCRenderer.cpp @@ -3,31 +3,33 @@ #include "VertexBuffer.h" #include -MCRenderer::MCRenderer() - : render_shader(Shader("Shader/mc.vs", "Shader/mc.fs", "Shader/mc.gs")), - noise_shader(Shader("Shader/noise.vs", "Shader/noise.fs")), noise(Framebuffer3D(64, 64, 64)), - camera(Camera(90, 1920, 1080, 0.1, 1000.0)) { +MCRenderer::MCRenderer(int size_x, int size_y, int size_z) + : size_x(size_x), size_y(size_y), size_z(size_z), + render_shader(Shader("Shader/mc.vs", "Shader/mc.fs", "Shader/mc.gs")), + noise_shader(Shader("Shader/noise.vs", "Shader/noise.fs")), + noise(Framebuffer3D(size_x, size_y, size_z)), camera(Camera(90, 1920, 1080, 0.1, 1000.0)) { + // Each noise layer needs vertices, so we define two triangles which span a rectangle float data[6][2] = {{-1.0f, -1.0f}, {-1.0, 1.0}, {1.0, -1.0}, {1.0f, 1.0f}, {-1.0, 1.0}, {1.0, -1.0}}; - // Move the camera a bit - camera.translate(glm::vec3(32.0, 32.0, 32.0)); + vertex_rectangle.set_data(sizeof(data), 2, data, GL_STATIC_DRAW); - vertex_rectangle.set_data(sizeof(data), data, GL_STATIC_DRAW); + // Move the camera to the center + camera.translate(glm::vec3(size_x / 2.0, size_z / 2.0, size_y / 2.0)); } void MCRenderer::render(float delta) { // Create the noise - glViewport(0, 0, 64, 64); + glViewport(0, 0, size_x, size_y); noise_shader.use(); noise.bind_and_clear(); noise_shader.setFloat("height", 0); - for (int i = 0; i < 64; i++) { + for (int i = 0; i < size_z; i++) { // Create one layer - noise_shader.setFloat("layer", i * (1.0f / 63.0f)); + noise_shader.setFloat("layer", i * (1.0f / (static_cast(size_z - 1)))); noise.bind_layer(i); // Each layer is made up of a rectangle of vertices @@ -52,13 +54,18 @@ void MCRenderer::render(float delta) { render_shader.setMat4("proj", camera.get_projection()); render_shader.setMat4("view", camera.get_view()); + // Set other variables + render_shader.setFloat("step", 1.0 / static_cast(size_z - 1)); + render_shader.setFloat("threshold", 0.4); + + render_shader.setInt("size_x", size_x); + render_shader.setInt("size_y", size_y); + render_shader.setInt("size_z", size_z); + // Bind the noise texture to the rendering shader noise.bind_to(0); // Draw all layers as polygons - mc_points.bind(); - glDrawArrays(GL_POINTS, 0, 64 * 64 * 64); + glDrawArrays(GL_POINTS, 0, size_x * size_y * size_z); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - - time_passed += delta; } \ No newline at end of file diff --git a/MCRenderer.h b/MCRenderer.h index 512758e..979da5d 100644 --- a/MCRenderer.h +++ b/MCRenderer.h @@ -7,22 +7,20 @@ class MCRenderer { public: - MCRenderer(); + MCRenderer(int size_x, int size_y, int size_z); void render(float delta); private: + int size_x; + int size_y; + int size_z; + Shader render_shader; Shader noise_shader; Framebuffer3D noise; VertexBuffer vertex_rectangle; - VertexBuffer mc_points; - Camera camera; - - float time_passed = 0.0; - - float *rectangle_data; }; diff --git a/Shader/mc.vs b/Shader/mc.vs index 670bc0b..4351547 100644 --- a/Shader/mc.vs +++ b/Shader/mc.vs @@ -2,29 +2,37 @@ layout (binding = 0) uniform sampler3D densities; +uniform float step; +uniform float threshold; + +uniform int size_x; +uniform int size_y; +uniform int size_z; + out vec3 varTexture; out int varIndex; -const float step = 1.0 / 63.0; - void main(void) { int id = gl_VertexID; - int x = id & 0x3F; - int y = (id >> 6) & 0x3F; - int z = (id >> 12) & 0x3F; + + // Could be optimized by using bit-wise '>>' and '&', but this is more generic + int x = id % size_x; + int y = (id / size_x) % size_y; + int z = (id / size_x / size_y) % size_z; vec3 xyz = vec3(x, y, z); gl_Position = vec4(xyz, 1.0); varTexture = xyz * step; - int b1 = int(texture(densities, varTexture).r < 0.5f); - int b2 = int(texture(densities, varTexture + vec3(step, 0.0, 0.0)).r < 0.5f); - int b3 = int(texture(densities, varTexture + vec3(step, 0.0, step)).r < 0.5f); - int b4 = int(texture(densities, varTexture + vec3(0.0, 0.0, step)).r < 0.5f); - int b5 = int(texture(densities, varTexture + vec3(0.0, step, 0.0)).r < 0.5f); - int b6 = int(texture(densities, varTexture + vec3(step, step, 0.0)).r < 0.5f); - int b7 = int(texture(densities, varTexture + vec3(step, step, step)).r < 0.5f); - int b8 = int(texture(densities, varTexture + vec3(0.0, step, step)).r < 0.5f); + int b1 = int(texture(densities, varTexture).r < threshold); + int b2 = int(texture(densities, varTexture + vec3(step, 0.0, 0.0)).r < threshold); + int b3 = int(texture(densities, varTexture + vec3(step, 0.0, step)).r < threshold); + int b4 = int(texture(densities, varTexture + vec3(0.0, 0.0, step)).r < threshold); + int b5 = int(texture(densities, varTexture + vec3(0.0, step, 0.0)).r < threshold); + int b6 = int(texture(densities, varTexture + vec3(step, step, 0.0)).r < threshold); + int b7 = int(texture(densities, varTexture + vec3(step, step, step)).r < threshold); + int b8 = int(texture(densities, varTexture + vec3(0.0, step, step)).r < threshold); + varIndex = (b1 << 7) | (b2 << 6) | (b3 << 5) | (b4 << 4) | (b5 << 3) | (b6 << 2) | (b7 << 1) | b8; } diff --git a/Shader/noise.fs b/Shader/noise.fs index cc29a58..e9bc6a8 100644 --- a/Shader/noise.fs +++ b/Shader/noise.fs @@ -1,13 +1,14 @@ - #version 430 +#version 430 - in vec3 varPosition; +in vec3 varPosition; - out float noise; +out float noise; - void main(void) { - float sinX = sin(varPosition.x * 5.8905); - float cosY = cos(varPosition.y * 5.8905); - float cosZ = cos(varPosition.z * 5.8905); - - noise = (sinX * sinX + cosY * cosY + cosZ * cosZ) * (1.0f / 3.0f); - } +void main(void) { + // Just to random stuff to the numbers until it looks nice + float f1 = sin((varPosition.x + varPosition.z) * 10.0); + float f2 = cos((varPosition.y + varPosition.x) * 7.0); + float f3 = cos((varPosition.z + varPosition.y) * 8.0); + + noise = (f1 * f1 + f2 * f2 + f3 * f3) * (1.0 / 3.0); +} diff --git a/Shader/noise.vs b/Shader/noise.vs index 61aca14..9ddb068 100644 --- a/Shader/noise.vs +++ b/Shader/noise.vs @@ -1,13 +1,13 @@ - #version 430 +#version 430 - layout (location = 0) in vec2 position; +layout (location = 0) in vec2 position; - uniform float layer; - uniform float height; +uniform float layer; +uniform float height; - out vec3 varPosition; +out vec3 varPosition; - void main(void) { - gl_Position = vec4(position, 0.0, 1.0); - varPosition = vec3(position.x, position.y + height, layer); - } +void main(void) { + gl_Position = vec4(position, 0.0, 1.0); + varPosition = vec3(position.x, position.y + height, layer); +} diff --git a/VertexBuffer.cpp b/VertexBuffer.cpp index 77c3f84..91cde95 100644 --- a/VertexBuffer.cpp +++ b/VertexBuffer.cpp @@ -5,27 +5,33 @@ VertexBuffer::VertexBuffer() { glGenBuffers(1, &vertex_buffer); } -void VertexBuffer::set_data(int size, const void *data, int flag) { +void VertexBuffer::set_data(int size, int dimension, const void *data, int flag) { + // We can't just do size = sizeof(data) here because of array to pointer decay! this->size = size; - glBindVertexArray(vertex_array); - glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); + bind_array(); + bind_buffer(); + // Create the data on the GPU glBufferData(GL_ARRAY_BUFFER, size, data, flag); - // TODO: Generalize - // This tells that the data consists of 2xfloat packets + // Specify the dimension of the vectors in the data, so that the GPU knows how much to read from + // it at a time. (Currently only one type of vector is supported) glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 2, GL_FLOAT, false, 2 * sizeof(float), 0); + glVertexAttribPointer(0, dimension, GL_FLOAT, false, dimension * sizeof(float), 0); glBindVertexArray(0); } -void VertexBuffer::bind() { +void VertexBuffer::bind_buffer() { + glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); +} + +void VertexBuffer::bind_array() { glBindVertexArray(vertex_array); } void VertexBuffer::draw() { - bind(); + bind_array(); glDrawArrays(GL_TRIANGLES, 0, size); } \ No newline at end of file diff --git a/VertexBuffer.h b/VertexBuffer.h index 53eae3e..20cb2ed 100644 --- a/VertexBuffer.h +++ b/VertexBuffer.h @@ -10,9 +10,10 @@ class VertexBuffer { public: VertexBuffer(); - void set_data(int size, const void *data, int flag); + void set_data(int size, int dimension, const void *data, int flag); - void bind(); + void bind_array(); + void bind_buffer(); void draw(); diff --git a/main.cpp b/main.cpp index d9018cc..2d8e250 100644 --- a/main.cpp +++ b/main.cpp @@ -49,7 +49,7 @@ int main() { glEnable(GL_DEPTH_TEST); // Setup the Marching Cubes renderer - MCRenderer renderer = MCRenderer(); + MCRenderer renderer = MCRenderer(128, 128, 128); // render loop // -----------