From 8cac3d4cc9137febfed58e1d3926e1371d0f2816 Mon Sep 17 00:00:00 2001 From: milek7 Date: Thu, 19 Jul 2018 15:35:05 +0200 Subject: [PATCH] alpha changes, mouse cursor changes, other changes --- application.cpp | 18 ++++-- application.h | 6 +- gl/framebuffer.cpp | 3 + imgui/imgui_impl_glfw.cpp | 53 ++++++++--------- imgui/imgui_impl_glfw.h | 4 +- renderer.cpp | 51 ++++++++-------- shaders/alphashadowmap.frag | 3 +- shaders/mat_colored.frag | 115 +++++++++++++++++++++++++++++++++++- shaders/mat_stars.frag | 4 +- shaders/vertex.vert | 2 + uilayer.cpp | 8 +-- 11 files changed, 192 insertions(+), 75 deletions(-) diff --git a/application.cpp b/application.cpp index 10911f02..573560ce 100644 --- a/application.cpp +++ b/application.cpp @@ -82,6 +82,9 @@ void cursor_pos_callback( GLFWwindow *window, double x, double y ) { glfwSetCursorPos( window, 0, 0 ); } + Application.m_cursor_pos.x = x; + Application.m_cursor_pos.y = y; + // give the potential event recipient a shot at it, in the virtual z order if( true == scene::Editor.on_mouse_move( x, y ) ) { return; } input::Mouse.move( x, y ); @@ -192,7 +195,7 @@ void scroll_callback( GLFWwindow* window, double xoffset, double yoffset ) void eu07_application::queue_screenshot() { - screenshot_queued = true; + m_screenshot_queued = true; } int @@ -267,9 +270,9 @@ eu07_application::run() if (!GfxRenderer.Render()) break; - if (screenshot_queued) + if (m_screenshot_queued) { - screenshot_queued = false; + m_screenshot_queued = false; screenshot_man.make_screenshot(); } @@ -328,10 +331,13 @@ eu07_application::set_cursor_pos( double const X, double const Y ) { void eu07_application::get_cursor_pos( double &X, double &Y ) const { + X = m_cursor_pos.x; + Y = m_cursor_pos.y; +} - if( m_window != nullptr ) { - glfwGetCursorPos( m_window, &X, &Y ); - } +glm::dvec2 eu07_application::get_cursor_pos() const +{ + return m_cursor_pos; } // private: diff --git a/application.h b/application.h index 71afd949..a73d6e48 100644 --- a/application.h +++ b/application.h @@ -27,6 +27,7 @@ public: set_cursor_pos( double const X, double const Y ); void get_cursor_pos( double &X, double &Y ) const; + glm::dvec2 get_cursor_pos() const; void queue_screenshot(); inline GLFWwindow * @@ -44,7 +45,10 @@ private: int init_audio(); // members GLFWwindow * m_window { nullptr }; - bool screenshot_queued = false; + bool m_screenshot_queued = false; + + friend void cursor_pos_callback( GLFWwindow *window, double x, double y ); + glm::dvec2 m_cursor_pos; }; extern eu07_application Application; diff --git a/gl/framebuffer.cpp b/gl/framebuffer.cpp index 91958932..d80ea22d 100644 --- a/gl/framebuffer.cpp +++ b/gl/framebuffer.cpp @@ -50,11 +50,14 @@ bool gl::framebuffer::is_complete() void gl::framebuffer::clear(GLbitfield mask) { bind(); + if (mask & GL_DEPTH_BUFFER_BIT) + glDepthMask(GL_TRUE); glClear(mask); } void gl::framebuffer::blit_to(framebuffer &other, int w, int h, GLbitfield mask) { + other.clear(mask); glBindFramebuffer(GL_READ_FRAMEBUFFER, *this); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, other); glBlitFramebuffer(0, 0, w, h, 0, 0, w, h, mask, GL_NEAREST); diff --git a/imgui/imgui_impl_glfw.cpp b/imgui/imgui_impl_glfw.cpp index 48d83ea2..b93bf9ef 100644 --- a/imgui/imgui_impl_glfw.cpp +++ b/imgui/imgui_impl_glfw.cpp @@ -29,6 +29,8 @@ #include "imgui.h" #include "imgui_impl_glfw.h" +#include "application.h" +#include "Globals.h" // GLFW #include @@ -101,15 +103,7 @@ void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) io.AddInputCharacter((unsigned short)c); } -void ImGui_ImplGlfw_InstallCallbacks(GLFWwindow* window) -{ - glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); - glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); - glfwSetKeyCallback(window, ImGui_ImplGlfw_KeyCallback); - glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); -} - -static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, GlfwClientApi client_api) +static bool ImGui_ImplGlfw_Init(GLFWwindow* window, GlfwClientApi client_api) { g_Window = window; g_Time = 0.0; @@ -157,22 +151,19 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw g_MouseCursors[ImGuiMouseCursor_ResizeNESW] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); // FIXME: GLFW doesn't have this. g_MouseCursors[ImGuiMouseCursor_ResizeNWSE] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); // FIXME: GLFW doesn't have this. g_MouseCursors[ImGuiMouseCursor_Hand] = glfwCreateStandardCursor(GLFW_HAND_CURSOR); - - if (install_callbacks) - ImGui_ImplGlfw_InstallCallbacks(window); g_ClientApi = client_api; return true; } -bool ImGui_ImplGlfw_InitForOpenGL(GLFWwindow* window, bool install_callbacks) +bool ImGui_ImplGlfw_InitForOpenGL(GLFWwindow* window) { - return ImGui_ImplGlfw_Init(window, install_callbacks, GlfwClientApi_OpenGL); + return ImGui_ImplGlfw_Init(window, GlfwClientApi_OpenGL); } -bool ImGui_ImplGlfw_InitForVulkan(GLFWwindow* window, bool install_callbacks) +bool ImGui_ImplGlfw_InitForVulkan(GLFWwindow* window) { - return ImGui_ImplGlfw_Init(window, install_callbacks, GlfwClientApi_Vulkan); + return ImGui_ImplGlfw_Init(window, GlfwClientApi_Vulkan); } void ImGui_ImplGlfw_Shutdown() @@ -199,18 +190,16 @@ static void ImGui_ImplGlfw_UpdateMousePosAndButtons() // Update mouse position const ImVec2 mouse_pos_backup = io.MousePos; io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); - if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) + + if (io.WantSetMousePos) { - if (io.WantSetMousePos) - { - glfwSetCursorPos(g_Window, (double)mouse_pos_backup.x, (double)mouse_pos_backup.y); - } - else - { - double mouse_x, mouse_y; - glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); - io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); - } + glfwSetCursorPos(g_Window, (double)mouse_pos_backup.x, (double)mouse_pos_backup.y); + } + else + { + double mouse_x, mouse_y; + Application.get_cursor_pos(mouse_x, mouse_y); + io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); } } @@ -221,12 +210,14 @@ static void ImGui_ImplGlfw_UpdateMouseCursor() return; ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor(); + static bool cursorModified = false; if (imgui_cursor == ImGuiMouseCursor_None || io.MouseDrawCursor) { // Hide OS mouse cursor if imgui is drawing it or if it wants no cursor glfwSetInputMode(g_Window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); + cursorModified = true; } - else + else if (cursorModified) { // Show OS mouse cursor // FIXME-PLATFORM: Unfocused windows seems to fail changing the mouse cursor with GLFW 3.2, but 3.3 works here. @@ -243,8 +234,10 @@ void ImGui_ImplGlfw_NewFrame() // Setup display size int w, h; int display_w, display_h; - glfwGetWindowSize(g_Window, &w, &h); - glfwGetFramebufferSize(g_Window, &display_w, &display_h); + w = Global.iWindowWidth; + h = Global.iWindowHeight; + display_w = w; + display_h = h; io.DisplaySize = ImVec2((float)w, (float)h); io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); diff --git a/imgui/imgui_impl_glfw.h b/imgui/imgui_impl_glfw.h index 8a68f447..0ff50da6 100644 --- a/imgui/imgui_impl_glfw.h +++ b/imgui/imgui_impl_glfw.h @@ -18,8 +18,8 @@ struct GLFWwindow; -IMGUI_IMPL_API bool ImGui_ImplGlfw_InitForOpenGL(GLFWwindow* window, bool install_callbacks); -IMGUI_IMPL_API bool ImGui_ImplGlfw_InitForVulkan(GLFWwindow* window, bool install_callbacks); +IMGUI_IMPL_API bool ImGui_ImplGlfw_InitForOpenGL(GLFWwindow* window); +IMGUI_IMPL_API bool ImGui_ImplGlfw_InitForVulkan(GLFWwindow* window); IMGUI_IMPL_API void ImGui_ImplGlfw_Shutdown(); IMGUI_IMPL_API void ImGui_ImplGlfw_NewFrame(); diff --git a/renderer.cpp b/renderer.cpp index 6fc636d9..10a53ff9 100644 --- a/renderer.cpp +++ b/renderer.cpp @@ -19,6 +19,7 @@ http://mozilla.org/MPL/2.0/. #include "Logs.h" #include "utilities.h" #include "simulationtime.h" +#include "application.h" opengl_renderer GfxRenderer; extern TWorld World; @@ -376,8 +377,7 @@ void opengl_renderer::Render_pass(rendermode const Mode) m_msaa_fb->bind(); glViewport(0, 0, Global.render_width, Global.render_height); - glEnable(GL_DEPTH_TEST); - glDepthMask(GL_TRUE); + glEnable(GL_DEPTH_TEST); auto const skydomecolour = World.Environment.m_skydome.GetAverageColor(); ::glClearColor(skydomecolour.x, skydomecolour.y, skydomecolour.z, 0.f); // kolor nieba @@ -428,7 +428,6 @@ void opengl_renderer::Render_pass(rendermode const Mode) setup_shadow_map(nullptr, m_renderpass); setup_env_map(nullptr); - m_main_fb->clear(GL_COLOR_BUFFER_BIT); m_msaa_fb->blit_to(*m_main_fb.get(), Global.render_width, Global.render_height, GL_COLOR_BUFFER_BIT); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); @@ -456,8 +455,7 @@ void opengl_renderer::Render_pass(rendermode const Mode) // glEnable(GL_POLYGON_OFFSET_FILL); // glPolygonOffset(1.0f, 1.0f); - glEnable(GL_DEPTH_TEST); - glDepthMask(GL_TRUE); + glEnable(GL_DEPTH_TEST); glViewport(0, 0, m_shadowbuffersize, m_shadowbuffersize); m_shadow_fb->bind(); @@ -468,7 +466,12 @@ void opengl_renderer::Render_pass(rendermode const Mode) scene_ubs.projection = OpenGLMatrices.data(GL_PROJECTION); scene_ubo->update(scene_ubs); - Render(simulation::Region); + Render(simulation::Region); + + //setup_drawing(true); + //glDepthMask(GL_TRUE); + //Render_Alpha(simulation::Region); + m_shadowpass = m_renderpass; // glDisable(GL_POLYGON_OFFSET_FILL); @@ -489,7 +492,6 @@ void opengl_renderer::Render_pass(rendermode const Mode) // glPolygonOffset(1.0f, 1.0f); glEnable(GL_DEPTH_TEST); - glDepthMask(GL_TRUE); glViewport(0, 0, m_shadowbuffersize, m_shadowbuffersize); m_cabshadows_fb->bind(); @@ -523,7 +525,6 @@ void opengl_renderer::Render_pass(rendermode const Mode) // NOTE: buffer attachment and viewport setup in this mode is handled by the wrapper method glEnable(GL_DEPTH_TEST); - glDepthMask(GL_TRUE); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); m_env_fb->clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); m_env_fb->bind(); @@ -562,8 +563,7 @@ void opengl_renderer::Render_pass(rendermode const Mode) glDebug("rendermode::pickcontrols"); - glEnable(GL_DEPTH_TEST); - glDepthMask(GL_TRUE); + glEnable(GL_DEPTH_TEST); glViewport(0, 0, EU07_PICKBUFFERSIZE, EU07_PICKBUFFERSIZE); m_pick_fb->bind(); m_pick_fb->clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -587,8 +587,7 @@ void opengl_renderer::Render_pass(rendermode const Mode) if (!World.InitPerformed()) break; - glEnable(GL_DEPTH_TEST); - glDepthMask(GL_TRUE); + glEnable(GL_DEPTH_TEST); glViewport(0, 0, EU07_PICKBUFFERSIZE, EU07_PICKBUFFERSIZE); m_pick_fb->bind(); m_pick_fb->clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -845,12 +844,14 @@ void opengl_renderer::setup_drawing(bool const Alpha) { if (Alpha) { - ::glEnable(GL_BLEND); + glEnable(GL_BLEND); + glDepthMask(GL_FALSE); m_blendingenabled = true; } else { - ::glDisable(GL_BLEND); + glDisable(GL_BLEND); + glDepthMask(GL_TRUE); m_blendingenabled = false; } @@ -967,8 +968,7 @@ bool opengl_renderer::Render(world_environment *Environment) } Bind_Material(null_handle); - ::glDisable(GL_DEPTH_TEST); - ::glDepthMask(GL_FALSE); + ::glDisable(GL_DEPTH_TEST); ::glPushMatrix(); model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW)); @@ -1023,8 +1023,7 @@ bool opengl_renderer::Render(world_environment *Environment) m_sunlight.apply_angle(); m_sunlight.apply_intensity(); - ::glPopMatrix(); - ::glDepthMask(GL_TRUE); + ::glPopMatrix(); ::glEnable(GL_DEPTH_TEST); return true; @@ -1117,13 +1116,10 @@ void opengl_renderer::Bind_Material(material_handle const Material, TSubModel *s model_ubs.param[entry.location][entry.offset + j] = src[j]; } - // if material don't have opacity set, guess it based on render phase if (std::isnan(material.opacity)) - model_ubs.opacity = m_blendingenabled ? 0.0f : 0.5f; + model_ubs.opacity = m_blendingenabled ? -1.0f : 0.5f; else - model_ubs.opacity = material.opacity; - - material.shader->bind(); + model_ubs.opacity = m_blendingenabled ? -1.0f : material.opacity; if (GLEW_ARB_multi_bind) { @@ -1157,6 +1153,8 @@ void opengl_renderer::Bind_Material(material_handle const Material, TSubModel *s unit++; } } + + material.shader->bind(); } else if (Material != m_invalid_material) Bind_Material(m_invalid_material); @@ -1566,7 +1564,7 @@ void opengl_renderer::Render(scene::shape_node const &Shape, bool const Ignorera break; } // render - model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW)); + model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW)); model_ubo->update(model_ubs); m_geometry.draw(data.geometry); @@ -2014,7 +2012,7 @@ void opengl_renderer::Render(TSubModel *Submodel) case rendermode::pickscenery: { m_pick_shader->bind(); - model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW)); + model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW)); model_ubo->update(model_ubs); m_geometry.draw(Submodel->m_geometry); break; @@ -2956,8 +2954,7 @@ TSubModel const *opengl_renderer::Update_Pick_Control() Render_pass(rendermode::pickcontrols); // determine point to examine - glm::dvec2 mousepos; - glfwGetCursorPos(m_window, &mousepos.x, &mousepos.y); + glm::dvec2 mousepos = Application.get_cursor_pos(); mousepos.y = Global.iWindowHeight - mousepos.y; // cursor coordinates are flipped compared to opengl glm::ivec2 pickbufferpos; diff --git a/shaders/alphashadowmap.frag b/shaders/alphashadowmap.frag index a0986579..66400676 100644 --- a/shaders/alphashadowmap.frag +++ b/shaders/alphashadowmap.frag @@ -7,5 +7,6 @@ uniform sampler2D tex1; void main() { - gl_FragDepth = gl_FragCoord.z + (1.0 - texture(tex1, f_coord).a); + if (texture(tex1, f_coord).a < 0.5f) + discard; } diff --git a/shaders/mat_colored.frag b/shaders/mat_colored.frag index f07d61ee..87316140 100644 --- a/shaders/mat_colored.frag +++ b/shaders/mat_colored.frag @@ -1,10 +1,123 @@ #version 330 +in vec3 f_normal; +in vec2 f_coord; +in vec3 f_pos; +in vec4 f_light_pos; + #include #param (color, 0, 0, 4, diffuse) +#param (diffuse, 1, 0, 1, one) +#param (specular, 1, 1, 1, specular) + +uniform sampler2DShadow shadowmap; +uniform samplerCube envmap; + +float calc_shadow() +{ + vec3 coords = f_light_pos.xyz / f_light_pos.w; + + // do something better + float bias = 0.0001f; + + //sampler PCF + //float shadow = texture(shadowmap, vec3(coords.xy, coords.z - bias)); + + //sampler PCF + PCF + float shadow = 0.0; + vec2 texel = 1.0 / textureSize(shadowmap, 0); + for (float y = -1.5; y <= 1.5; y += 1.0) + for (float x = -1.5; x <= 1.5; x += 1.0) + shadow += texture(shadowmap, coords.xyz + vec3(vec2(x, y) * texel, -bias)); + shadow /= 16.0; + + if (coords.z > 1.0f) + shadow = 1.0f; + + return shadow; +} + +vec3 apply_fog(vec3 color) +{ + float sun_amount = 0.0; + if (lights_count >= 1U && lights[0].type == LIGHT_DIR) + sun_amount = max(dot(normalize(f_pos), normalize(-lights[0].dir)), 0.0); + vec3 fog_color_v = mix(fog_color, lights[0].color, pow(sun_amount, 30.0)); + float fog_amount_v = 1.0 - min(1.0, exp(-length(f_pos) * fog_density)); + return mix(color, fog_color_v, fog_amount_v); +} + +float calc_light(vec3 light_dir) +{ + vec3 normal = normalize(f_normal); + vec3 view_dir = normalize(vec3(0.0f, 0.0f, 0.0f) - f_pos); + vec3 halfway_dir = normalize(light_dir + view_dir); + + float diffuse_v = max(dot(normal, light_dir), 0.0); + float specular_v = pow(max(dot(normal, halfway_dir), 0.0), 15.0); + + //return specular_v * param[1].y + diffuse_v * param[1].x; + return specular_v + diffuse_v; +} + +float calc_point_light(light_s light) +{ + vec3 light_dir = normalize(light.pos - f_pos); + float val = calc_light(light_dir); + + float distance = length(light.pos - f_pos); + float atten = 1.0f / (1.0f + light.linear * distance + light.quadratic * (distance * distance)); + + return val * atten; +} + +float calc_spot_light(light_s light) +{ + vec3 light_dir = normalize(light.pos - f_pos); + + float theta = dot(light_dir, normalize(-light.dir)); + float epsilon = light.in_cutoff - light.out_cutoff; + float intensity = clamp((theta - light.out_cutoff) / epsilon, 0.0, 1.0); + + float point = calc_point_light(light); + return point * intensity; +} + +float calc_dir_light(light_s light) +{ + vec3 light_dir = normalize(-light.dir); + return calc_light(light_dir); +} void main() { - gl_FragColor = param[0]; + vec4 tex_color = vec4(param[0].rgb, 1.0f); + + if (tex_color.a < opacity) + discard; + + vec3 envcolor = texture(envmap, reflect(f_pos, normalize(f_normal))).rgb; + + float shadow = calc_shadow(); + vec3 result = ambient * 0.3 + vec3(1.0) * emission; + for (uint i = 0U; i < lights_count; i++) + { + light_s light = lights[i]; + float part = 0.0; + + if (light.type == LIGHT_SPOT) + part = calc_spot_light(light); + else if (light.type == LIGHT_POINT) + part = calc_point_light(light); + else if (light.type == LIGHT_DIR) + part = calc_dir_light(light); + + if (i == 0U) + part *= shadow; + result += light.color * part;// * envcolor; + } + + vec3 c = apply_fog(result * tex_color.xyz); + gl_FragColor = vec4(c, tex_color.w); } diff --git a/shaders/mat_stars.frag b/shaders/mat_stars.frag index 1f16228d..b7db63cf 100644 --- a/shaders/mat_stars.frag +++ b/shaders/mat_stars.frag @@ -2,7 +2,7 @@ #include -in vec3 f_normal; +flat in vec3 f_normal_raw; void main() { @@ -13,5 +13,5 @@ void main() discard; // color data is shared with normals, ugh - gl_FragColor = vec4(f_normal, 1.0f); + gl_FragColor = vec4(f_normal_raw.bgr, 1.0f); } diff --git a/shaders/vertex.vert b/shaders/vertex.vert index 000d8026..0b221f36 100644 --- a/shaders/vertex.vert +++ b/shaders/vertex.vert @@ -6,6 +6,7 @@ layout(location = 2) in vec2 v_coord; layout(location = 3) in vec4 v_tangent; out vec3 f_normal; +flat out vec3 f_normal_raw; out vec2 f_coord; out vec3 f_pos; out mat3 f_tbn; @@ -18,6 +19,7 @@ void main() { gl_Position = (projection * modelview) * vec4(v_vert, 1.0f); f_normal = modelviewnormal * v_normal; + f_normal_raw = v_normal; f_coord = v_coord; f_tangent = v_tangent; f_pos = vec3(modelview * vec4(v_vert, 1.0f)); diff --git a/uilayer.cpp b/uilayer.cpp index d691d485..6e75de0a 100644 --- a/uilayer.cpp +++ b/uilayer.cpp @@ -38,7 +38,7 @@ ui_layer::init( GLFWwindow *Window ) { //imgui_io->ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; imgui_io->Fonts->AddFontFromFileTTF("DejaVuSansMono.ttf", 13.0f); - ImGui_ImplGlfw_InitForOpenGL(m_window, false); + ImGui_ImplGlfw_InitForOpenGL(m_window); ImGui_ImplOpenGL3_Init(); ImGui::StyleColorsClassic(); @@ -1122,8 +1122,7 @@ ui_layer::render() { ImGui::End(); } - glm::dvec2 mousepos; - glfwGetCursorPos( m_window, &mousepos.x, &mousepos.y ); + glm::dvec2 mousepos = Application.get_cursor_pos(); if (((Global.ControlPicking && mousepos.y < 50.0f) || imgui_io->WantCaptureMouse) && m_progress == 0.0f) { @@ -1224,8 +1223,7 @@ ui_layer::render_tooltip() { if( !m_cursorvisible || m_tooltip.empty() ) { return; } - glm::dvec2 mousepos; - glfwGetCursorPos( m_window, &mousepos.x, &mousepos.y ); + glm::dvec2 mousepos = Application.get_cursor_pos(); ImGui::BeginTooltip(); ImGui::TextUnformatted(m_tooltip.c_str());