From a0deddb660b5fe8258cfcc68eb2549e475a78416 Mon Sep 17 00:00:00 2001 From: Adrian Scripca Date: Sun, 24 Apr 2022 09:00:55 +0300 Subject: [PATCH] Working version, no shadows --- main.cpp | 53 +++++++++----------- src/peripherals_glfw.cpp | 3 +- src/scene_renderer.cpp | 101 +++++++++++++++++++++++++++++++++++---- src/shader.cpp | 77 ++++++++++++++++++++++------- src/shader_constants.h | 14 +++--- 5 files changed, 182 insertions(+), 66 deletions(-) diff --git a/main.cpp b/main.cpp index 7c8f350..e249ba7 100644 --- a/main.cpp +++ b/main.cpp @@ -1,3 +1,5 @@ +#include + #include "peripherals_glfw.h" #include "demo/demo_engine.h" #include "timer.h" @@ -10,6 +12,7 @@ INITIALIZE_EASYLOGGINGPP int main() { acidrain::peripherals_glfw peripherals; peripherals.init(); + LOG(INFO) << "peripherals initialized"; glDisable(GL_DEPTH_TEST); @@ -33,7 +36,7 @@ int main() { demo_data::meshes.push_back(mesh_generator::grid(30, 30)); demo_data::meshes.push_back(mesh_generator::cube()); - auto mat = shared_ptr(new material()); + auto mat = std::make_shared(); mat->ambient = glm::vec4(0, 0, 0.15, 1); mat->diffuse = glm::vec4(1, 1, 1, 1); // material->diffuse = glm::vec4(1, 0, 0, 1); @@ -102,10 +105,10 @@ int main() { demoPartScene.cameraName = "cam1"; demoPartScene.lightName = "light1"; - scene *scene1 = new scene(); + auto *scene1 = new scene(); demoPartScene.scene_ = shared_ptr(scene1); - auto smallSphere = shared_ptr(new mesh_node()); + auto smallSphere = std::make_shared(); smallSphere->mesh_ = demo_data::meshes[1]; smallSphere->material_ = demo_data::materials[0]; smallSphere->position = glm::vec3(0, 0, 0); @@ -201,26 +204,26 @@ int main() { glBindFramebuffer(GL_FRAMEBUFFER, 0); - timer timer1; while (!peripherals.should_close() && timer1.seconds_since_start() < DEMO_LENGTH_IN_SECONDS) { double elapsedSeconds = timer1.seconds_since_start(); -// bigSphere->mesh_ = mesh_generator::extrude(mesh_generator::sphere(50, 50), {200, 201, 100, 101, 400, 401}, 0.05, -// (int) ((sin(elapsedSeconds) + 0.5) * 40)); -// -// smallSphere->position = glm::vec3(0, sin(2 * M_PI * 0.13 * elapsedSeconds) * 2.0 + 0.5, 0); -//// meshNode->position = glm::vec3(0, 0.001, 0); -// // camNode->target = glm::vec3(0, 0.0001, 0); -// // camNode->position = glm::vec3(0, 5, -10); -// lightNode2->position = glm::vec3(5 * sin(2 * M_PI * 0.15 * elapsedSeconds), 2, -// 5 * cos(2 * M_PI * 0.15 * elapsedSeconds)); -// lightNode->position = glm::vec3(5 * cos(2 * M_PI * 0.75 * elapsedSeconds), 2, -// 5 * sin(2 * M_PI * 0.75 * elapsedSeconds)); -// -// lightMeshNode->position = lightNode2->position; -// -// bigSphere->rotation *= angleAxis((float) (M_PI / 4.0 * timer1.lap()), normalize(glm::vec3(0.2, 0.5, 0.3))); + bigSphere->mesh_ = mesh_generator::extrude(mesh_generator::sphere(50, 50), {200, 201, 100, 101, 400, 401}, 0.05, + (int) ((sin(elapsedSeconds) + 0.5) * 40)); + + smallSphere->position = glm::vec3(0, sin(2 * M_PI * 0.13 * elapsedSeconds) * 2.0 + 0.5, 0); +// meshNode->position = glm::vec3(0, 0.001, 0); + // camNode->target = glm::vec3(0, 0.0001, 0); + // camNode->position = glm::vec3(0, 5, -10); + lightNode2->position = glm::vec3(5 * sin(2 * M_PI * 0.15 * elapsedSeconds), 2, + 5 * cos(2 * M_PI * 0.15 * elapsedSeconds)); + lightNode->position = glm::vec3(5 * cos(2 * M_PI * 0.75 * elapsedSeconds), 2, + 5 * sin(2 * M_PI * 0.75 * elapsedSeconds)); + + lightMeshNode->position = lightNode2->position; + + bigSphere->rotation *= angleAxis((float) (M_PI / 4.0 * timer1.lap()), normalize(glm::vec3(0.2, 0.5, 0.3))); + demoPartClear.process(demoPartClear.normalizeTime(elapsedSeconds)); demoPartScene.process(demoPartScene.normalizeTime(elapsedSeconds)); @@ -228,16 +231,4 @@ int main() { peripherals.swap_buffers(); peripherals.poll_events(); } - -// double alpha = 0.0; -// while (!peripherals.should_close()) { -// alpha += 0.01; -// if (alpha > 1.0) alpha = 0.0; -// -// glClearColor(0.0 * alpha, 0.1 * alpha, 1.0 * alpha, 1 * alpha); -// glClear(GL_COLOR_BUFFER_BIT); -// -// peripherals.swap_buffers(); -// peripherals.poll_events(); -// } } diff --git a/src/peripherals_glfw.cpp b/src/peripherals_glfw.cpp index 54850e3..204203b 100644 --- a/src/peripherals_glfw.cpp +++ b/src/peripherals_glfw.cpp @@ -1,6 +1,7 @@ #include "peripherals_glfw.h" #include #include +#include "demo_data.h" BEGIN_NAMESPACE @@ -28,7 +29,7 @@ bool peripherals_glfw::init() { glfwSetErrorCallback(error_callback); - window = glfwCreateWindow(1024, 768, "Demo", nullptr, nullptr); + window = glfwCreateWindow(demo_data::screen_width, demo_data::screen_height, "Demo", nullptr, nullptr); if (window == nullptr) { std::cerr << "Unable to create window!" << std::endl; return false; diff --git a/src/scene_renderer.cpp b/src/scene_renderer.cpp index bdb2349..d4f20df 100644 --- a/src/scene_renderer.cpp +++ b/src/scene_renderer.cpp @@ -10,7 +10,7 @@ BEGIN_NAMESPACE static const char *vs = R"( - #version 150 core + #version 330 core uniform mat4 mmtx; uniform mat4 wlmtx; @@ -26,7 +26,7 @@ static const char *vs = R"( )"; static const char *ps = R"( - #version 150 core + #version 330 core out vec4 colorOut; @@ -36,7 +36,7 @@ static const char *ps = R"( )"; static const char *vs2 = R"( - #version 150 core + #version 330 core uniform mat4 mmtx; uniform mat4 vmtx; @@ -71,7 +71,7 @@ static const char *vs2 = R"( )"; static const char *ps2 = R"( - #version 150 core + #version 330 core out vec4 outColor; uniform sampler2DShadow shadowMap1; @@ -191,6 +191,87 @@ static const char *ps2 = R"( } )"; +static const char *vs3 = R"( +#version 330 core + +uniform mat4 mmtx; +uniform mat4 vmtx; +uniform mat3 nmtx; +uniform mat4 pmtx; + +in vec3 position; +in vec3 normal; +in vec2 texCoords; + +out vec3 vEyeSpaceNormal; +out vec3 vEyeSpacePosition; +out vec2 vTexCoords; + +void main() { + gl_Position = pmtx * vmtx * mmtx * vec4(position, 1); + vEyeSpacePosition = (vmtx * mmtx * vec4(position, 1)).xyz; + vEyeSpaceNormal = normalize(nmtx * normal); + vTexCoords = texCoords; +})"; + +static const char *ps3 = R"( + #version 330 core + out vec4 FragColor; + + uniform vec3 lPosEye[4]; + uniform vec4 matAmbientCol; + uniform vec4 matDiffuseCol; + uniform vec4 matSpecularCol; + uniform float matShininess; + uniform int numLights; + + uniform sampler2D diffuseMap; + + struct Light { + int type; + vec3 position; + vec3 target; + float spotCutoff; + float spotExponent; + vec3 attenuation; + vec4 ambient; + vec4 diffuse; + vec4 specular; + }; + + uniform Light light[4]; + + const vec2 texmapscale = vec2(1.0f/1024.0f, 1.0f/1024.0f); + + in vec3 vEyeSpaceNormal; + in vec3 vEyeSpacePosition; + in vec2 vTexCoords; + + void main() { + vec4 finalColor = vec4(0); + vec3 normal = normalize(vEyeSpaceNormal); + vec4 diffuseColor = matDiffuseCol * texture(diffuseMap, vTexCoords); + + for (int i = 0; i < numLights; i++) { + vec3 L = (light[i].position - vEyeSpacePosition); + float d = length(L); + L = normalize(L); + float diffuse = max(0.0, dot(normal, L)); + + vec3 E = normalize(-vEyeSpacePosition); + vec3 R = normalize(-reflect(L, vEyeSpaceNormal)); + float specular = pow(max(dot(R, E), 0.0), 0.3*matShininess); + + float shadow = 1.0f; + finalColor += matAmbientCol * matDiffuseCol; + finalColor += diffuseColor * diffuse * light[i].diffuse * shadow; + finalColor += matSpecularCol * specular * shadow; + } + + FragColor = finalColor; + } +)"; + scene_renderer::scene_renderer() : fbo_id{0} { @@ -206,7 +287,7 @@ scene_renderer::scene_renderer() first_pass_shadow_material->cull_faces = true; first_pass_shadow_material->cull_front_faces = false; - second_pass_shadow_shader = std::make_shared(vs2, ps2); + second_pass_shadow_shader = std::make_shared(vs3, ps3); second_pass_shadow_material = std::make_shared(); second_pass_shadow_material->shader_ = second_pass_shadow_shader; @@ -225,11 +306,11 @@ void scene_renderer::attach_depth_texture(texture &text) const { } void scene_renderer::render(const scene_tree &scene, const std::string &cameraName) { - for (auto &node: scene.lights) { - light_node &light = node->as_light_node(); - glActiveTexture(GL_TEXTURE0); - render_shadow_map(scene, light); - } +// for (auto &node: scene.lights) { +// light_node &light = node->as_light_node(); +// glActiveTexture(GL_TEXTURE0); +// render_shadow_map(scene, light); +// } std::shared_ptr camNode = scene.nodeByNameAndType(cameraName, scene_node_type::camera); camera_node &camera = camNode->as_camera_node(); diff --git a/src/shader.cpp b/src/shader.cpp index 0ce2f2c..892c222 100644 --- a/src/shader.cpp +++ b/src/shader.cpp @@ -3,32 +3,32 @@ BEGIN_NAMESPACE -void check_compile_error(GLuint shaderId) { +void check_compile_error(GLuint shader_id) { GLint isCompiled = 0; - glGetShaderiv(shaderId, GL_COMPILE_STATUS, &isCompiled); - if (isCompiled == GL_FALSE) { + glGetShaderiv(shader_id, GL_COMPILE_STATUS, &isCompiled); + if (!isCompiled) { GLint maxLength = 0; - glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &maxLength); + glGetShaderiv(shader_id, GL_INFO_LOG_LENGTH, &maxLength); //The maxLength includes the NULL character char errorLog[maxLength]; - glGetShaderInfoLog(shaderId, maxLength, &maxLength, &errorLog[0]); + glGetShaderInfoLog(shader_id, maxLength, &maxLength, &errorLog[0]); - LOG(ERROR) << "Shader compile error: " << "(id: " << shaderId << ", code: " << isCompiled << ", bytes: " + LOG(ERROR) << "Shader compile error: " << "(id: " << shader_id << ", code: " << isCompiled << ", bytes: " << maxLength << ") - " << std::string(errorLog, maxLength); //Provide the infolog in whatever manor you deem best. //Exit with failure. - glDeleteShader(shaderId); //Don't leak the shader. + glDeleteShader(shader_id); //Don't leak the shader. } else { - LOG(INFO) << "Shader successfully compiled"; + LOG(INFO) << "Shader " << shader_id << " successfully compiled"; } } void check_link_error(GLuint program_id) { GLint is_linked = 0; glGetShaderiv(program_id, GL_LINK_STATUS, &is_linked); - if (is_linked == GL_FALSE) { + if (!is_linked) { GLint maxLength = 0; glGetShaderiv(program_id, GL_INFO_LOG_LENGTH, &maxLength); @@ -43,35 +43,78 @@ void check_link_error(GLuint program_id) { //Exit with failure. glDeleteShader(program_id); //Don't leak the program shader. } else { - LOG(INFO) << "Shader program successfully linked"; + LOG(INFO) << "Shader program " << program_id << " successfully linked"; } } +shader::shader(const char *vs_content, const char *ps_content) + : shader_ids{0, 0}, + program_id{0} { + -shader::shader(const char *vs_content, const char *ps_content) { shader_ids[0] = glCreateShader(GL_VERTEX_SHADER); - glShaderSource(shader_ids[0], 1, &vs_content, nullptr); + glShaderSource(shader_ids[0], 1, &vs_content, NULL); glCompileShader(shader_ids[0]); - check_compile_error(shader_ids[0]); + int success; + char infoLog[512]; + glGetShaderiv(shader_ids[0], GL_COMPILE_STATUS, &success); + if (!success) { + glGetShaderInfoLog(shader_ids[0], 512, NULL, infoLog); + std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; + } shader_ids[1] = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(shader_ids[1], 1, &ps_content, nullptr); + glShaderSource(shader_ids[1], 1, &ps_content, NULL); glCompileShader(shader_ids[1]); - check_compile_error(shader_ids[1]); + glGetShaderiv(shader_ids[1], GL_COMPILE_STATUS, &success); + if (!success) { + glGetShaderInfoLog(shader_ids[1], 512, NULL, infoLog); + std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl; + } program_id = glCreateProgram(); glAttachShader(program_id, shader_ids[0]); glAttachShader(program_id, shader_ids[1]); - // TODO Adrian: these should come from an external enumeration glBindAttribLocation(program_id, 0, "position"); glBindAttribLocation(program_id, 1, "normal"); glBindAttribLocation(program_id, 2, "texCoords"); glLinkProgram(program_id); - check_link_error(program_id); + + glGetProgramiv(program_id, GL_LINK_STATUS, &success); + if (!success) { + glGetProgramInfoLog(program_id, 512, NULL, infoLog); + std::cout << "ERROR::SHADER::PROGRAM::COMPILATION_FAILED\n" << infoLog << std::endl; + } glUseProgram(program_id); +// glDeleteShader(shader_ids[0]); +// glDeleteShader(shader_ids[1]); + +// shader_ids[0] = glCreateShader(GL_VERTEX_SHADER); +// glShaderSource(shader_ids[0], 1, &vs_content, nullptr); +// glCompileShader(shader_ids[0]); +// check_compile_error(shader_ids[0]); +// +// shader_ids[1] = glCreateShader(GL_FRAGMENT_SHADER); +// glShaderSource(shader_ids[1], 1, &ps_content, nullptr); +// glCompileShader(shader_ids[1]); +// check_compile_error(shader_ids[1]); +// +// program_id = glCreateProgram(); +// glAttachShader(program_id, shader_ids[0]); +// glAttachShader(program_id, shader_ids[1]); + + // TODO Adrian: these should come from an external enumeration +// glBindAttribLocation(program_id, 0, "position"); +// glBindAttribLocation(program_id, 1, "normal"); +// glBindAttribLocation(program_id, 2, "texCoords"); + +// glLinkProgram(program_id); +// check_link_error(program_id); + +// glUseProgram(program_id); } shader::~shader() { diff --git a/src/shader_constants.h b/src/shader_constants.h index c6694c7..4ff5d3b 100644 --- a/src/shader_constants.h +++ b/src/shader_constants.h @@ -140,25 +140,25 @@ public: type = shader_constant_type::decimal; } - void apply_to(shader &shader, const char *uniform_name) { + void apply_to(shader &sh, const char *uniform_name) { switch (type) { case shader_constant_type::vec3: - shader.setVec3Uniform(glm::value_ptr(vec3Val), uniform_name); + sh.setVec3Uniform(glm::value_ptr(vec3Val), uniform_name); break; case shader_constant_type::vec4: - shader.setVec4Uniform(glm::value_ptr(vec4Val), uniform_name); + sh.setVec4Uniform(glm::value_ptr(vec4Val), uniform_name); break; case shader_constant_type::mat3: - shader.setMatrix3Uniform(glm::value_ptr(mat3Val), uniform_name); + sh.setMatrix3Uniform(glm::value_ptr(mat3Val), uniform_name); break; case shader_constant_type::mat4: - shader.setMatrix4Uniform(glm::value_ptr(mat4Val), uniform_name); + sh.setMatrix4Uniform(glm::value_ptr(mat4Val), uniform_name); break; case shader_constant_type::integer: - shader.setIntUniform(intVal, uniform_name); + sh.setIntUniform(intVal, uniform_name); break; case shader_constant_type::decimal: - shader.setFloatUniform(floatVal, uniform_name); + sh.setFloatUniform(floatVal, uniform_name); break; } }