#include "Gedeng/DirectionalLight.h" #include "Gedeng/Input.h" #include "Gedeng/Logger.h" #include "Gedeng/ObjMesh.h" #include "Gedeng/ParticleSystem.h" #include "Gedeng/QuadMesh.h" #include "Gedeng/Shader.h" #include "Gedeng/TextLabel.h" #include "Gedeng/Vector3.h" #include #define GEDENG_MAIN #include // For Debugging unsigned int quadVAO = 0; unsigned int quadVBO; void renderQuad() { if (quadVAO == 0) { float quadVertices[] = { // positions // texture Coords -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, }; // setup plane VAO glGenVertexArrays(1, &quadVAO); glGenBuffers(1, &quadVBO); glBindVertexArray(quadVAO); glBindBuffer(GL_ARRAY_BUFFER, quadVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void *)0); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void *)(3 * sizeof(float))); } glBindVertexArray(quadVAO); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glBindVertexArray(0); } class ShadowApp : public Gedeng::Application { public: ShadowApp(unsigned long ms_per_update, unsigned int window_size_x, unsigned int window_size_y, Gedeng::String window_name) : Application(ms_per_update, window_size_x, window_size_y, window_name), particle_interval(0.2), number_of_steps(10.0), number_of_refinement_steps(10.0), bump_depth(0.1), render_shader(Gedeng::Shader("Shader/bump.vs", "Shader/bump.fs")), debug_shader(Gedeng::Shader("Shader/depth-debug.vs", "Shader/depth-debug.fs")), camera(Gedeng::FPSCamera(90, 1920, 1080, 0.1, 1000.0)), albedo("Resources/Textures/PavingStones/PavingStones070_2K_Color.jpg", Gedeng::Texture::Settings()), bump("Resources/Textures/PavingStones/PavingStones070_2K_Displacement.jpg", Gedeng::Texture::Settings()), normal("Resources/Textures/PavingStones/PavingStones070_2K_Normal.jpg", Gedeng::Texture::Settings()), particle_tex1("Resources/Textures/Particles/circle.png", Gedeng::Texture::Settings()), particle_tex2("Resources/Textures/Particles/magic.png", Gedeng::Texture::Settings()), particle_tex3("Resources/Textures/Particles/smoke.png", Gedeng::Texture::Settings()), quad_mesh(Gedeng::QuadMesh(10.0)), light(glm::vec3(0.57735, -0.57735, 0.57735)), monkey_mesh("Resources/Meshes/Monkey.obj", Gedeng::ObjMesh::Settings()) { particles.set_position(glm::vec3(0.0f, 0.0f, -10.0f)); particles.set_velocity(glm::vec3(-2, 4, -2), glm::vec3(2, 6, 2)); particles.set_gravity(glm::vec3(0, -4, 0)); particles.set_color(glm::vec3(0.0f, 0.5f, 1.0f)); particles.set_lifetime(1.0f, 1.5f); particles.set_size(0.1); particles.set_interval(particle_interval); particles.set_number_of_particles(1); particles.set_textures(&particle_tex1, &particle_tex2, &particle_tex3); camera.translate(glm::vec3(0.0, 2.0, 1.0)); // camera.rotate(30, glm::vec3(1.0, 0.0, 0.0)); monkey_mesh.translate(glm::vec3(2.0, 3.0, -2.0)); } ~ShadowApp() = default; void fixed_update(double delta) override { camera.update(delta); if (Gedeng::Input::is_mouse_down(GLFW_MOUSE_BUTTON_LEFT)) particles.set_position(camera.get_view_ray().get_plane_collision().collision_position); if (Gedeng::Input::is_key_down(GLFW_KEY_2)) particle_interval = fmax(particle_interval + 0.1 * delta, 0.02); if (Gedeng::Input::is_key_down(GLFW_KEY_1)) particle_interval = fmax(particle_interval - 0.1 * delta, 0.02); particles.set_interval(particle_interval); } void dynamic_update(double delta) override { // Shadows light.clear_shadows(); light.render_shadow(monkey_mesh); light.render_shadow(quad_mesh); glViewport(0, 0, 1920, 1080); glClearColor(0.1, 0.1f, 0.1, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); render_shader.use(); // Camera render_shader.setMat4("projection", camera.get_projection()); render_shader.setMat4("view", camera.get_view()); render_shader.setVec3("viewPos", camera.get_translation()); // Lighting light.set_in_shader(render_shader); render_shader.setFloat("number_of_steps", glm::max(0.0f, number_of_steps)); render_shader.setFloat("number_of_refinement_steps", glm::max(0.0f, number_of_refinement_steps)); render_shader.setFloat("bump_depth", glm::max(0.0f, bump_depth)); // Textures albedo.bind_to(0); normal.bind_to(1); bump.bind_to(2); light.bind_depth_map_to(3); // Quad which is rendered onto quad_mesh.render(render_shader); // Particles particles.set_camera(camera); particles.update(delta); particles.render(); // Props render_shader.use(); monkey_mesh.render(render_shader); /* // Render the light's depth map to a quad for debugging debug_shader.use(); light.bind_depth_map_to(0); renderQuad(); */ } private: float particle_interval; float number_of_steps; float number_of_refinement_steps; float bump_depth; Gedeng::Shader render_shader; Gedeng::Shader debug_shader; Gedeng::VertexBuffer vertex_rectangle; Gedeng::FPSCamera camera; Gedeng::Texture albedo; Gedeng::Texture bump; Gedeng::Texture normal; Gedeng::Texture particle_tex1; Gedeng::Texture particle_tex2; Gedeng::Texture particle_tex3; Gedeng::QuadMesh quad_mesh; Gedeng::ParticleSystem particles; Gedeng::DirectionalLight light; Gedeng::ObjMesh monkey_mesh; }; Gedeng::Application *Gedeng::create_application() { GG_CLIENT_INFO("Creating Application"); return new ShadowApp(20, 1920, 1080, String("Parallax Demo")); }