From 1b10e2fed628b3290e5bbc42a7de6d83faaf9db3 Mon Sep 17 00:00:00 2001 From: Jack Christensen Date: Mon, 26 Aug 2024 03:32:58 +0000 Subject: [PATCH] Update uniform handling --- CHANGELOG.md | 3 + CMakeLists.txt | 2 +- include/{Uniforms.h => uniforms.h} | 21 +- shaders/fragment.glsl | 6 - shaders/tessellation_ctrl.glsl | 38 +- shaders/tessellation_eval.glsl | 20 +- shaders/vertex.glsl | 8 +- source/InitShader.cpp | 615 +++++++++++++------------- source/scene.cpp | 12 +- source/{Uniforms.cpp => uniforms.cpp} | 40 +- 10 files changed, 406 insertions(+), 359 deletions(-) create mode 100644 CHANGELOG.md rename include/{Uniforms.h => uniforms.h} (78%) rename source/{Uniforms.cpp => uniforms.cpp} (51%) diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..db9c632 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,3 @@ +## [v0.1.1] - 2024-08-25 +### Changed +- Refactored uniform handling in the initial geometry pass to improve maintainability. \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 6ca157c..eac312b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.10) -project(TerraVisor VERSION 0.0.1) +project(TerraVisor VERSION 0.0.2) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) diff --git a/include/Uniforms.h b/include/uniforms.h similarity index 78% rename from include/Uniforms.h rename to include/uniforms.h index 352e0a9..daedeed 100644 --- a/include/Uniforms.h +++ b/include/uniforms.h @@ -2,6 +2,7 @@ #include #include +#include namespace Uniforms { @@ -15,6 +16,17 @@ namespace Uniforms glm::vec4 eye_w = glm::vec4(0.0f, 0.0f, 3.0f, 1.0f); //world-space eye position }; + struct GeoUniforms + { + glm::mat4 PV; + glm::mat4 M; + + float minTessellation = 1.0f; + float maxTessellation = 32.0f; + float displacementScale = 0.007f; + int gridDensity = 16; + }; + struct LightUniforms { glm::vec4 La = glm::vec4(0.5f, 0.5f, 0.55f, 1.0f); //ambient light color @@ -34,11 +46,13 @@ namespace Uniforms extern SceneUniforms SceneData; extern LightUniforms LightData; extern MaterialUniforms MaterialData; + extern GeoUniforms GeoData; //IDs for the buffer objects holding the uniform block data - extern GLuint scene_ubo; - extern GLuint light_ubo; - extern GLuint material_ubo; + extern GLuint sceneUbo; + extern GLuint lightUbo; + extern GLuint materialUbo; + extern GLuint geoUbo; namespace UboBinding { @@ -46,6 +60,7 @@ namespace Uniforms extern int scene; extern int light; extern int material; + extern int geo; }; //Locations for the uniforms which are not in uniform blocks diff --git a/shaders/fragment.glsl b/shaders/fragment.glsl index b6927a1..56dd793 100644 --- a/shaders/fragment.glsl +++ b/shaders/fragment.glsl @@ -9,12 +9,6 @@ in TE_OUT { vec3 normal; } fs_in; -layout(std140, binding = 0) uniform SceneUniforms -{ - mat4 PV; //camera projection * view matrix - vec4 eye_w; //world-space eye position -}; - layout(location = 0) out vec4 albedoGbuffer; layout(location = 1) out vec4 positionGbuffer; layout(location = 2) out vec4 normalGbuffer; diff --git a/shaders/tessellation_ctrl.glsl b/shaders/tessellation_ctrl.glsl index 0c35921..94d8dd3 100644 --- a/shaders/tessellation_ctrl.glsl +++ b/shaders/tessellation_ctrl.glsl @@ -2,6 +2,20 @@ layout(vertices = 4) out; +layout(binding = 0) uniform sampler2D heightTexture; +uniform float tessellationFactor; + +layout(std140, binding = 4) uniform GeoUniforms +{ + mat4 PV; + mat4 M; + + float minTessellation; + float maxTessellation; + float displacementScale; + int gridDensity; +}; + in VS_OUT { vec3 position; vec2 texCoord; @@ -12,21 +26,19 @@ out TC_OUT { vec2 texCoord; } tc_out[]; -uniform float tessellationFactor; - void main() { - // Set tessellation levels - if (gl_InvocationID == 0) { - gl_TessLevelOuter[0] = tessellationFactor; // Level of tessellation along one edge - gl_TessLevelOuter[1] = tessellationFactor; // Level of tessellation along another edge - gl_TessLevelOuter[2] = tessellationFactor; // Level of tessellation along the other edge - gl_TessLevelOuter[3] = tessellationFactor; // Level of tessellation along the other edge - - gl_TessLevelInner[0] = tessellationFactor; // Level of tessellation for the inner part - gl_TessLevelInner[1] = tessellationFactor; // Level of tessellation for the inner part - } - // Pass through position and texture coordinates to the tessellation evaluation shader tc_out[gl_InvocationID].position = tc_in[gl_InvocationID].position; tc_out[gl_InvocationID].texCoord = tc_in[gl_InvocationID].texCoord; + + // Set tessellation levels + if (gl_InvocationID == 0) { + gl_TessLevelOuter[0] = maxTessellation; + gl_TessLevelOuter[1] = maxTessellation; + gl_TessLevelOuter[2] = maxTessellation; + gl_TessLevelOuter[3] = maxTessellation; + + gl_TessLevelInner[0] = maxTessellation; + gl_TessLevelInner[1] = maxTessellation; + } } \ No newline at end of file diff --git a/shaders/tessellation_eval.glsl b/shaders/tessellation_eval.glsl index 4c40f68..e3a197f 100644 --- a/shaders/tessellation_eval.glsl +++ b/shaders/tessellation_eval.glsl @@ -3,15 +3,16 @@ layout(quads, fractional_even_spacing, cw) in; layout(binding = 0) uniform sampler2D heightTexture; -layout(location = 0) uniform mat4 M; -uniform float displacementScale = 0.025f; -uniform float tessellationFactor; - -layout(std140, binding = 0) uniform SceneUniforms +layout(std140, binding = 4) uniform GeoUniforms { - mat4 PV; //camera projection * view matrix - vec4 eye_w; //world-space eye position + mat4 PV; + mat4 M; + + float minTessellation; + float maxTessellation; + float displacementScale; + int gridDensity; }; in TC_OUT { @@ -30,13 +31,16 @@ float getHeight(vec2 uv) { } vec3 calculateSmoothNormal(vec3 pos, vec2 coord) { - float step = 1.0f / (16.0f * tessellationFactor + 1.0f); + // Currently hardcoded to match patch density + float step = 1.0f / (float(gridDensity) * maxTessellation + 1.0f); + // Find surrounding heights float hLeft = getHeight(coord + vec2(-step, 0.0f)); float hRight = getHeight(coord + vec2(step, 0.0f)); float hUp = getHeight(coord + vec2(0.0f, step)); float hDown = getHeight(coord + vec2(0.0f, -step)); + // Calculate tangents vec3 tangentX = normalize(vec3(step, hRight - hLeft, 0.0)); vec3 tangentY = normalize(vec3(0.0, hUp - hDown, step)); diff --git a/shaders/vertex.glsl b/shaders/vertex.glsl index e53a640..7eb47a2 100644 --- a/shaders/vertex.glsl +++ b/shaders/vertex.glsl @@ -1,7 +1,7 @@ #version 450 core -layout(location = 0) in vec3 inPosition; -layout(location = 1) in vec2 inTexCoord; +layout(location = 0) in vec3 posAttrib; +layout(location = 1) in vec2 texCoordAttrib; out VS_OUT { vec3 position; @@ -9,6 +9,6 @@ out VS_OUT { } vs_out; void main() { - vs_out.position = (vec4(inPosition, 1.0f)).xyz; - vs_out.texCoord = inTexCoord; + vs_out.position = (vec4(posAttrib, 1.0f)).xyz; + vs_out.texCoord = texCoordAttrib; } \ No newline at end of file diff --git a/source/InitShader.cpp b/source/InitShader.cpp index 57c20c1..98dc399 100644 --- a/source/InitShader.cpp +++ b/source/InitShader.cpp @@ -10,106 +10,106 @@ using namespace std; // Create a NULL-terminated string by reading the provided file static char* readShaderSource(const char* shaderFile) { - ifstream ifs(shaderFile, ios::in | ios::binary | ios::ate); - if (ifs.is_open()) - { - unsigned int filesize = static_cast(ifs.tellg()); - ifs.seekg(0, ios::beg); - char* bytes = new char[filesize + 1]; - memset(bytes, 0, filesize + 1); - ifs.read(bytes, filesize); - ifs.close(); - return bytes; - } - return NULL; + ifstream ifs(shaderFile, ios::in | ios::binary | ios::ate); + if (ifs.is_open()) + { + unsigned int filesize = static_cast(ifs.tellg()); + ifs.seekg(0, ios::beg); + char* bytes = new char[filesize + 1]; + memset(bytes, 0, filesize + 1); + ifs.read(bytes, filesize); + ifs.close(); + return bytes; + } + return NULL; } void printShaderCompileError(GLuint shader) { - GLint logSize; - glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logSize); - char* logMsg = new char[logSize]; - glGetShaderInfoLog(shader, logSize, NULL, logMsg); - std::cerr << logMsg << std::endl; - delete[] logMsg; + GLint logSize; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logSize); + char* logMsg = new char[logSize]; + glGetShaderInfoLog(shader, logSize, NULL, logMsg); + std::cerr << logMsg << std::endl; + delete[] logMsg; } void printProgramLinkError(GLuint program) { - GLint logSize; - glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logSize); - char* logMsg = new char[logSize]; - glGetProgramInfoLog(program, logSize, NULL, logMsg); - std::cerr << logMsg << std::endl; - delete[] logMsg; + GLint logSize; + glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logSize); + char* logMsg = new char[logSize]; + glGetProgramInfoLog(program, logSize, NULL, logMsg); + std::cerr << logMsg << std::endl; + delete[] logMsg; } GLuint InitShader(const char* computeShaderFile) { - bool error = false; - struct Shader - { - const char* filename; - GLenum type; - GLchar* source; - } shaders[1] = - { - { computeShaderFile, GL_COMPUTE_SHADER, NULL } - }; + bool error = false; + struct Shader + { + const char* filename; + GLenum type; + GLchar* source; + } shaders[1] = + { + { computeShaderFile, GL_COMPUTE_SHADER, NULL } + }; - GLuint program = glCreateProgram(); + GLuint program = glCreateProgram(); - for (int i = 0; i < 1; ++i) - { - Shader& s = shaders[i]; - s.source = readShaderSource(s.filename); - if (shaders[i].source == NULL) - { - std::cerr << "Failed to read " << s.filename << std::endl; - error = true; - } + for (int i = 0; i < 1; ++i) + { + Shader& s = shaders[i]; + s.source = readShaderSource(s.filename); + if (shaders[i].source == NULL) + { + std::cerr << "Failed to read " << s.filename << std::endl; + error = true; + } - GLuint shader = glCreateShader(s.type); - glShaderSource(shader, 1, (const GLchar**)&s.source, NULL); - glCompileShader(shader); + GLuint shader = glCreateShader(s.type); + glShaderSource(shader, 1, (const GLchar**)&s.source, NULL); + glCompileShader(shader); - GLint compiled; - glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); - if (!compiled) - { - std::cerr << s.filename << " failed to compile:" << std::endl; - printShaderCompileError(shader); - error = true; - } + GLint compiled; + glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); + if (!compiled) + { + std::cerr << s.filename << " failed to compile:" << std::endl; + printShaderCompileError(shader); + error = true; + } - delete[] s.source; + delete[] s.source; - glAttachShader(program, shader); - } + glAttachShader(program, shader); + } - /* link and error check */ - glLinkProgram(program); + /* link and error check */ + glLinkProgram(program); - GLint linked; - glGetProgramiv(program, GL_LINK_STATUS, &linked); - if (!linked) - { - std::cerr << "Shader program failed to link" << std::endl; - printProgramLinkError(program); + GLint linked; + glGetProgramiv(program, GL_LINK_STATUS, &linked); + if (!linked) + { + std::cerr << "Shader program failed to link" << std::endl; + printProgramLinkError(program); - error = true; - } + error = true; + } - if (error == true) - { - return -1; - } + if (error == true) + { + return -1; + } - /* use program object */ - glUseProgram(program); + /* use program object */ + glUseProgram(program); - return program; + return program; } @@ -117,294 +117,301 @@ GLuint InitShader(const char* computeShaderFile) GLuint InitShader(const char* vShaderFile, const char* fShaderFile) { - bool error = false; - struct Shader - { - const char* filename; - GLenum type; - GLchar* source; - } shaders[2] = - { - { vShaderFile, GL_VERTEX_SHADER, NULL }, - { fShaderFile, GL_FRAGMENT_SHADER, NULL } - }; + bool error = false; + struct Shader + { + const char* filename; + GLenum type; + GLchar* source; + } shaders[2] = + { + { vShaderFile, GL_VERTEX_SHADER, NULL }, + { fShaderFile, GL_FRAGMENT_SHADER, NULL } + }; - GLuint program = glCreateProgram(); + GLuint program = glCreateProgram(); - for (int i = 0; i < 2; ++i) - { - Shader& s = shaders[i]; - s.source = readShaderSource(s.filename); - if (shaders[i].source == NULL) - { - std::cerr << "Failed to read " << s.filename << std::endl; - error = true; - } + for (int i = 0; i < 2; ++i) + { + Shader& s = shaders[i]; + s.source = readShaderSource(s.filename); + if (shaders[i].source == NULL) + { + std::cerr << "Failed to read " << s.filename << std::endl; + error = true; + } - GLuint shader = glCreateShader(s.type); - glShaderSource(shader, 1, (const GLchar**)&s.source, NULL); - glCompileShader(shader); + GLuint shader = glCreateShader(s.type); + glShaderSource(shader, 1, (const GLchar**)&s.source, NULL); + glCompileShader(shader); - GLint compiled; - glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); - if (!compiled) - { - std::cerr << s.filename << " failed to compile:" << std::endl; - printShaderCompileError(shader); - error = true; - } + GLint compiled; + glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); + if (!compiled) + { + std::cerr << s.filename << " failed to compile:" << std::endl; + printShaderCompileError(shader); + error = true; + } - delete[] s.source; + delete[] s.source; - glAttachShader(program, shader); - } + glAttachShader(program, shader); + } - //set shader attrib locations - const int pos_loc = 0; - const int tex_coord_loc = 1; - const int normal_loc = 2; + //set shader attrib locations + const int posLoc = 0; + const int texCoordLoc = 1; + const int normalLoc = 2; - glBindAttribLocation(program, pos_loc, "pos_attrib"); - glBindAttribLocation(program, tex_coord_loc, "tex_coord_attrib"); - glBindAttribLocation(program, normal_loc, "normal_attrib"); + glBindAttribLocation(program, posLoc, "posAttrib"); + glBindAttribLocation(program, texCoordLoc, "texCoordAttrib"); + glBindAttribLocation(program, normalLoc, "normalAttrib"); - /* link and error check */ - glLinkProgram(program); + /* link and error check */ + glLinkProgram(program); - GLint linked; - glGetProgramiv(program, GL_LINK_STATUS, &linked); - if (!linked) - { - std::cerr << "Shader program failed to link" << std::endl; - printProgramLinkError(program); + GLint linked; + glGetProgramiv(program, GL_LINK_STATUS, &linked); + if (!linked) + { + std::cerr << "Shader program failed to link" << std::endl; + printProgramLinkError(program); - error = true; - } + error = true; + } - if (error == true) - { - return -1; - } + if (error == true) + { + return -1; + } - /* use program object */ - glUseProgram(program); - return program; + /* use program object */ + glUseProgram(program); + return program; } // Create a GLSL program object from vertex and fragment shader files GLuint InitShader(const char* vShaderFile, const char* gShaderFile, const char* fShaderFile) { - bool error = false; - struct Shader - { - const char* filename; - GLenum type; - GLchar* source; - } shaders[3] = - { - { vShaderFile, GL_VERTEX_SHADER, NULL }, - { gShaderFile, GL_GEOMETRY_SHADER, NULL }, - { fShaderFile, GL_FRAGMENT_SHADER, NULL } - }; + bool error = false; + struct Shader + { + const char* filename; + GLenum type; + GLchar* source; + } shaders[3] = + { + { vShaderFile, GL_VERTEX_SHADER, NULL }, + { gShaderFile, GL_GEOMETRY_SHADER, NULL }, + { fShaderFile, GL_FRAGMENT_SHADER, NULL } + }; - GLuint program = glCreateProgram(); + GLuint program = glCreateProgram(); - for (int i = 0; i < 3; ++i) - { - Shader& s = shaders[i]; - s.source = readShaderSource(s.filename); - if (shaders[i].source == NULL) - { - std::cerr << "Failed to read " << s.filename << std::endl; - error = true; - } + for (int i = 0; i < 3; ++i) + { + Shader& s = shaders[i]; + s.source = readShaderSource(s.filename); + if (shaders[i].source == NULL) + { + std::cerr << "Failed to read " << s.filename << std::endl; + error = true; + } - GLuint shader = glCreateShader(s.type); - glShaderSource(shader, 1, (const GLchar**)&s.source, NULL); - glCompileShader(shader); + GLuint shader = glCreateShader(s.type); + glShaderSource(shader, 1, (const GLchar**)&s.source, NULL); + glCompileShader(shader); - GLint compiled; - glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); - if (!compiled) - { - std::cerr << s.filename << " failed to compile:" << std::endl; - printShaderCompileError(shader); - error = true; - } + GLint compiled; + glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); + if (!compiled) + { + std::cerr << s.filename << " failed to compile:" << std::endl; + printShaderCompileError(shader); + error = true; + } - delete[] s.source; + delete[] s.source; - glAttachShader(program, shader); - } + glAttachShader(program, shader); + } - //set shader attrib locations - const int pos_loc = 0; - const int tex_coord_loc = 1; - const int normal_loc = 2; + //set shader attrib locations + const int posLoc = 0; + const int texCoordLoc = 1; + const int normalLoc = 2; - glBindAttribLocation(program, pos_loc, "pos_attrib"); - glBindAttribLocation(program, tex_coord_loc, "tex_coord_attrib"); - glBindAttribLocation(program, normal_loc, "normal_attrib"); + glBindAttribLocation(program, posLoc, "posAttrib"); + glBindAttribLocation(program, texCoordLoc, "texCoordAttrib"); + glBindAttribLocation(program, normalLoc, "normalAttrib"); - /* link and error check */ - glLinkProgram(program); + /* link and error check */ + glLinkProgram(program); - GLint linked; - glGetProgramiv(program, GL_LINK_STATUS, &linked); - if (!linked) - { - std::cerr << "Shader program failed to link" << std::endl; - printProgramLinkError(program); + GLint linked; + glGetProgramiv(program, GL_LINK_STATUS, &linked); + if (!linked) + { + std::cerr << "Shader program failed to link" << std::endl; + printProgramLinkError(program); - error = true; - } + error = true; + } - if (error == true) - { - return -1; - } + if (error == true) + { + return -1; + } - /* use program object */ - glUseProgram(program); + /* use program object */ + glUseProgram(program); - return program; + return program; } GLuint InitShader( const char* vShaderFile, const char* tcShader, const char* teShader, const char* fShaderFile ) { - bool error = false; - struct Shader - { - const char* filename; - GLenum type; - std::string source; - } shaders[4] = - { - { vShaderFile, GL_VERTEX_SHADER, "" }, - { tcShader, GL_TESS_CONTROL_SHADER, "" }, - { teShader, GL_TESS_EVALUATION_SHADER, "" }, - { fShaderFile, GL_FRAGMENT_SHADER, "" } - }; + bool error = false; + struct Shader + { + const char* filename; + GLenum type; + std::string source; + } shaders[4] = + { + { vShaderFile, GL_VERTEX_SHADER, "" }, + { tcShader, GL_TESS_CONTROL_SHADER, "" }, + { teShader, GL_TESS_EVALUATION_SHADER, "" }, + { fShaderFile, GL_FRAGMENT_SHADER, "" } + }; - GLuint program = glCreateProgram(); + GLuint program = glCreateProgram(); - for ( int i = 0; i < 4; ++i ) - { - Shader& s = shaders[i]; - s.source = readShaderSource(s.filename); - if ( shaders[i].source.length() == 0 ) - { - std::cerr << "Failed to read " << s.filename << std::endl; - error = true; - } + for ( int i = 0; i < 4; ++i ) + { + Shader& s = shaders[i]; + s.source = readShaderSource(s.filename); + if ( shaders[i].source.length() == 0 ) + { + std::cerr << "Failed to read " << s.filename << std::endl; + error = true; + } - GLuint shader = glCreateShader( s.type ); - const char *c_str = s.source.c_str(); - glShaderSource(shader, 1, (const GLchar**)&c_str, NULL); - glCompileShader( shader ); + GLuint shader = glCreateShader( s.type ); + const char *c_str = s.source.c_str(); + glShaderSource(shader, 1, (const GLchar**)&c_str, NULL); + glCompileShader( shader ); - GLint compiled; - glGetShaderiv( shader, GL_COMPILE_STATUS, &compiled ); - if ( !compiled ) - { - std::cerr << s.filename << " failed to compile:" << std::endl; - printShaderCompileError(shader); - error = true; - } + GLint compiled; + glGetShaderiv( shader, GL_COMPILE_STATUS, &compiled ); + if ( !compiled ) + { + std::cerr << s.filename << " failed to compile:" << std::endl; + printShaderCompileError(shader); + error = true; + } - glAttachShader( program, shader ); - } + glAttachShader( program, shader ); + } - /* link and error check */ - glLinkProgram(program); + //set shader attrib locations + const int posLoc = 0; + const int texCoordLoc = 1; - GLint linked; - glGetProgramiv( program, GL_LINK_STATUS, &linked ); - if ( !linked ) - { - std::cerr << "Shader program failed to link" << std::endl; - printProgramLinkError(program); + glBindAttribLocation(program, posLoc, "posAttrib"); + glBindAttribLocation(program, texCoordLoc, "texCoordAttrib"); - error = true; - } + /* link and error check */ + glLinkProgram(program); - if(error == true) - { - return -1; - } + GLint linked; + glGetProgramiv( program, GL_LINK_STATUS, &linked ); + if ( !linked ) + { + std::cerr << "Shader program failed to link" << std::endl; + printProgramLinkError(program); - /* use program object */ - glUseProgram(program); + error = true; + } - return program; + if(error == true) + { + return -1; + } + + /* use program object */ + glUseProgram(program); + + return program; } GLuint InitShader( const char* vShaderFile, const char* tcShader, const char* teShader, const char* gShaderFile, const char* fShaderFile ) { - bool error = false; - struct Shader - { - const char* filename; - GLenum type; - std::string source; - } shaders[5] = - { - { vShaderFile, GL_VERTEX_SHADER, "" }, - { tcShader, GL_TESS_CONTROL_SHADER, "" }, - { teShader, GL_TESS_EVALUATION_SHADER, "" }, - { gShaderFile, GL_GEOMETRY_SHADER, "" }, - { fShaderFile, GL_FRAGMENT_SHADER, "" } - }; + bool error = false; + struct Shader + { + const char* filename; + GLenum type; + std::string source; + } shaders[5] = + { + { vShaderFile, GL_VERTEX_SHADER, "" }, + { tcShader, GL_TESS_CONTROL_SHADER, "" }, + { teShader, GL_TESS_EVALUATION_SHADER, "" }, + { gShaderFile, GL_GEOMETRY_SHADER, "" }, + { fShaderFile, GL_FRAGMENT_SHADER, "" } + }; - GLuint program = glCreateProgram(); - - for ( int i = 0; i < 5; ++i ) - { - Shader& s = shaders[i]; - s.source = readShaderSource(s.filename); - if ( shaders[i].source.length() == 0 ) - { - std::cerr << "Failed to read " << s.filename << std::endl; - error = true; - } + GLuint program = glCreateProgram(); + + for ( int i = 0; i < 5; ++i ) + { + Shader& s = shaders[i]; + s.source = readShaderSource(s.filename); + if ( shaders[i].source.length() == 0 ) + { + std::cerr << "Failed to read " << s.filename << std::endl; + error = true; + } - GLuint shader = glCreateShader( s.type ); - const char *c_str = s.source.c_str(); - glShaderSource( shader, 1, (const GLchar**) &c_str, NULL ); - glCompileShader( shader ); + GLuint shader = glCreateShader( s.type ); + const char *c_str = s.source.c_str(); + glShaderSource( shader, 1, (const GLchar**) &c_str, NULL ); + glCompileShader( shader ); - GLint compiled; - glGetShaderiv( shader, GL_COMPILE_STATUS, &compiled ); - if ( !compiled ) - { - std::cerr << s.filename << " failed to compile:" << std::endl; - printShaderCompileError(shader); - error = true; - } + GLint compiled; + glGetShaderiv( shader, GL_COMPILE_STATUS, &compiled ); + if ( !compiled ) + { + std::cerr << s.filename << " failed to compile:" << std::endl; + printShaderCompileError(shader); + error = true; + } - glAttachShader( program, shader ); - } + glAttachShader( program, shader ); + } - /* link and error check */ - glLinkProgram(program); + /* link and error check */ + glLinkProgram(program); - GLint linked; - glGetProgramiv( program, GL_LINK_STATUS, &linked ); - if ( !linked ) - { - std::cerr << "Shader program failed to link" << std::endl; - printProgramLinkError(program); + GLint linked; + glGetProgramiv( program, GL_LINK_STATUS, &linked ); + if ( !linked ) + { + std::cerr << "Shader program failed to link" << std::endl; + printProgramLinkError(program); - error = true; - } + error = true; + } - if(error == true) - { - return -1; - } + if(error == true) + { + return -1; + } - /* use program object */ - glUseProgram(program); + /* use program object */ + glUseProgram(program); - return program; + return program; } \ No newline at end of file diff --git a/source/scene.cpp b/source/scene.cpp index 428747d..ef0db75 100644 --- a/source/scene.cpp +++ b/source/scene.cpp @@ -25,7 +25,7 @@ #include "scene.h" #include "camera.h" -#include "Uniforms.h" +#include "uniforms.h" #include "InitShader.h" #include "DebugCallback.h" #include "load_texture.h" @@ -139,7 +139,7 @@ void Scene::GenerateGrid(int divisions, std::vector& verts, std::vector< // Currently creates a test triangle and initializes its buffers void Scene::InitBuffers() { - int divisions = 16; // Number of divisions along one axis of the grid + int divisions = Uniforms::GeoData.gridDensity; // Number of divisions along one axis of the grid GenerateGrid(divisions, vertices, indices); // Create and bind VAO, VBO, and EBO, and pass the data to OpenGL @@ -225,11 +225,10 @@ void Scene::Display(GLFWwindow* window) { //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - Uniforms::SceneData.PV = projection_matrix_ * CameraControls::GetViewMatrix(activeCamera_); // Projection-View matrix + Uniforms::GeoData.PV = projection_matrix_ * CameraControls::GetViewMatrix(activeCamera_); // Projection-View matrix Uniforms::BufferSceneData(); - glm::mat4 model_matrix = glm::rotate(angle_, glm::vec3(1.0f, 0.0f, 0.0f)) * glm::scale(glm::vec3(scale_)); - glUniformMatrix4fv(Uniforms::UniformLocs::M, 1, false, glm::value_ptr(model_matrix)); + Uniforms::GeoData.M = glm::rotate(angle_, glm::vec3(1.0f, 0.0f, 0.0f)) * glm::scale(glm::vec3(scale_)); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, tex_id); @@ -336,7 +335,8 @@ void Scene::DrawGui(GLFWwindow* window) { ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); - ImGui::SliderFloat("Tessellation Level", &tessellationFactor, 1.0f, 64.0f); + ImGui::SliderFloat("Tessellation Level", &Uniforms::GeoData.maxTessellation, 1.0f, 64.0f); + ImGui::SliderInt("Patch Grid Density", &Uniforms::GeoData.gridDensity, 1, 24); ImGui::End(); // Draw FBO to ImGui window diff --git a/source/Uniforms.cpp b/source/uniforms.cpp similarity index 51% rename from source/Uniforms.cpp rename to source/uniforms.cpp index 04d6c71..fad77a9 100644 --- a/source/Uniforms.cpp +++ b/source/uniforms.cpp @@ -1,4 +1,4 @@ -#include "Uniforms.h" +#include "uniforms.h" #include namespace Uniforms @@ -6,11 +6,13 @@ namespace Uniforms SceneUniforms SceneData; LightUniforms LightData; MaterialUniforms MaterialData; + GeoUniforms GeoData; //IDs for the buffer objects holding the uniform block data - GLuint scene_ubo = -1; - GLuint light_ubo = -1; - GLuint material_ubo = -1; + GLuint sceneUbo = 0; + GLuint lightUbo = 0; + GLuint materialUbo = 0; + GLuint geoUbo = 0; namespace UboBinding { @@ -18,6 +20,7 @@ namespace Uniforms int scene = 0; int light = 1; int material = 2; + int geometry = 4; }; //Locations for the uniforms which are not in uniform blocks @@ -30,28 +33,37 @@ namespace Uniforms void Init() { //Create and initialize uniform buffers - glGenBuffers(1, &Uniforms::scene_ubo); - glBindBuffer(GL_UNIFORM_BUFFER, scene_ubo); + glGenBuffers(1, &Uniforms::sceneUbo); + glBindBuffer(GL_UNIFORM_BUFFER, sceneUbo); glBufferData(GL_UNIFORM_BUFFER, sizeof(SceneUniforms), nullptr, GL_STREAM_DRAW); //Allocate memory for the buffer, but don't copy (since pointer is null). - glBindBufferBase(GL_UNIFORM_BUFFER, UboBinding::scene, scene_ubo); //Associate this uniform buffer with the uniform block in the shader that has the same binding. + glBindBufferBase(GL_UNIFORM_BUFFER, UboBinding::scene, sceneUbo); //Associate this uniform buffer with the uniform block in the shader that has the same binding. - glGenBuffers(1, &light_ubo); - glBindBuffer(GL_UNIFORM_BUFFER, light_ubo); + glGenBuffers(1, &lightUbo); + glBindBuffer(GL_UNIFORM_BUFFER, lightUbo); glBufferData(GL_UNIFORM_BUFFER, sizeof(LightUniforms), &LightData, GL_STREAM_DRAW); //Allocate memory for the buffer, but don't copy (since pointer is null). - glBindBufferBase(GL_UNIFORM_BUFFER, UboBinding::light, light_ubo); //Associate this uniform buffer with the uniform block in the shader that has the same binding. + glBindBufferBase(GL_UNIFORM_BUFFER, UboBinding::light, lightUbo); //Associate this uniform buffer with the uniform block in the shader that has the same binding. - glGenBuffers(1, &material_ubo); - glBindBuffer(GL_UNIFORM_BUFFER, material_ubo); + glGenBuffers(1, &materialUbo); + glBindBuffer(GL_UNIFORM_BUFFER, materialUbo); glBufferData(GL_UNIFORM_BUFFER, sizeof(MaterialUniforms), &MaterialData, GL_STREAM_DRAW); //Allocate memory for the buffer, but don't copy (since pointer is null). - glBindBufferBase(GL_UNIFORM_BUFFER, UboBinding::material, material_ubo); //Associate this uniform buffer with the uniform block in the shader that has the same binding. + glBindBufferBase(GL_UNIFORM_BUFFER, UboBinding::material, materialUbo); //Associate this uniform buffer with the uniform block in the shader that has the same binding. + + glGenBuffers(1, &geoUbo); + glBindBuffer(GL_UNIFORM_BUFFER, geoUbo); + glBufferData(GL_UNIFORM_BUFFER, sizeof(GeoUniforms), &GeoData, GL_STREAM_DRAW); //Allocate memory for the buffer, but don't copy (since pointer is null). + glBindBufferBase(GL_UNIFORM_BUFFER, UboBinding::geometry, geoUbo); //Associate this uniform buffer with the uniform block in the shader that has the same binding. glBindBuffer(GL_UNIFORM_BUFFER, 0); } void BufferSceneData() { - glBindBuffer(GL_UNIFORM_BUFFER, scene_ubo); //Bind the OpenGL UBO before we update the data. + glBindBuffer(GL_UNIFORM_BUFFER, sceneUbo); //Bind the OpenGL UBO before we update the data. glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(SceneData), &SceneData); //Upload the new uniform values. glBindBuffer(GL_UNIFORM_BUFFER, 0); //unbind the ubo + + glBindBuffer(GL_UNIFORM_BUFFER, geoUbo); //Bind the OpenGL UBO before we update the data. + glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(GeoData), &GeoData); //Upload the new uniform values. + glBindBuffer(GL_UNIFORM_BUFFER, 0); //unbind the ubo } };