diff --git a/src/DivaGL/gl_state.cpp b/src/DivaGL/gl_state.cpp index 6cb73c4..5088a95 100644 --- a/src/DivaGL/gl_state.cpp +++ b/src/DivaGL/gl_state.cpp @@ -41,9 +41,11 @@ void gl_state_active_texture(size_t index, bool force) { } void gl_state_bind_framebuffer(GLuint framebuffer, bool force) { - if (force || gl_state.read_framebuffer_binding != framebuffer + if (force || gl_state.framebuffer_binding != framebuffer + || gl_state.read_framebuffer_binding != framebuffer || gl_state.draw_framebuffer_binding != framebuffer) { glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); + gl_state.framebuffer_binding = framebuffer; gl_state.read_framebuffer_binding = framebuffer; gl_state.draw_framebuffer_binding = framebuffer; } @@ -307,6 +309,7 @@ void gl_state_get() { glGetIntegervDLL(GL_BLEND_EQUATION_RGB, (GLint*)&gl_state.blend_mode_rgb); glGetIntegervDLL(GL_BLEND_EQUATION_ALPHA, (GLint*)&gl_state.blend_mode_alpha); + glGetIntegervDLL(GL_FRAMEBUFFER_BINDING, (GLint*)&gl_state.framebuffer_binding); glGetIntegervDLL(GL_READ_FRAMEBUFFER_BINDING, (GLint*)&gl_state.read_framebuffer_binding); glGetIntegervDLL(GL_DRAW_FRAMEBUFFER_BINDING, (GLint*)&gl_state.draw_framebuffer_binding); glGetIntegervDLL(GL_VERTEX_ARRAY_BINDING, (GLint*)&gl_state.vertex_array_binding); @@ -333,18 +336,24 @@ void gl_state_get() { glGetBooleanvDLL(GL_DEPTH_TEST, &gl_state.depth_test); glGetIntegervDLL(GL_DEPTH_FUNC, (GLint*)&gl_state.depth_func); glGetBooleanvDLL(GL_DEPTH_WRITEMASK, &gl_state.depth_mask); + glGetFloatvDLL(GL_LINE_WIDTH, &gl_state.line_width); glGetBooleanvDLL(GL_MULTISAMPLE, &gl_state.multisample); glGetBooleanvDLL(GL_PRIMITIVE_RESTART, &gl_state.primitive_restart); glGetIntegervDLL(GL_PRIMITIVE_RESTART_INDEX, (GLint*)&gl_state.primitive_restart_index); glGetIntegervDLL(GL_SCISSOR_BOX, (GLint*)&gl_state.scissor_box); glGetBooleanvDLL(GL_SCISSOR_TEST, &gl_state.scissor_test); glGetBooleanvDLL(GL_STENCIL_TEST, &gl_state.stencil_test); + glGetIntegervDLL(GL_STENCIL_FUNC, (GLint*)&gl_state.stencil_func); + glGetIntegervDLL(GL_STENCIL_VALUE_MASK, (GLint*)&gl_state.stencil_value_mask); + glGetIntegervDLL(GL_STENCIL_FAIL, (GLint*)&gl_state.stencil_fail); + glGetIntegervDLL(GL_STENCIL_PASS_DEPTH_FAIL, (GLint*)&gl_state.stencil_dpfail); + glGetIntegervDLL(GL_STENCIL_PASS_DEPTH_PASS, (GLint*)&gl_state.stencil_dppass); + glGetIntegervDLL(GL_STENCIL_REF, &gl_state.stencil_ref); glGetIntegervDLL(GL_STENCIL_WRITEMASK, (GLint*)&gl_state.stencil_mask); glGetIntegervDLL(GL_VIEWPORT, (GLint*)&gl_state.viewport); glPolygonModeDLL(GL_FRONT_AND_BACK, GL_FILL); - gl_state.polygon_front_face_mode = GL_FILL; - gl_state.polygon_back_face_mode = GL_FILL; + gl_state.polygon_mode = GL_FILL; } void gl_state_get_all_gl_errors() { @@ -458,34 +467,32 @@ void gl_state_set_depth_mask(GLboolean flag, bool force) { } } +void gl_state_set_line_width(GLfloat width, bool force) { + if (force || gl_state.line_width != width) { + glLineWidthDLL(width); + gl_state.line_width = width; + } +} + void gl_state_set_polygon_mode(GLenum face, GLenum mode, bool force) { switch (face) { case GL_FRONT: - if (force || gl_state.polygon_front_face_mode != mode) { + if (force || gl_state.polygon_mode != mode) { glPolygonModeDLL(GL_FRONT, mode); - gl_state.polygon_front_face_mode = mode; + gl_state.polygon_mode = mode; } break; case GL_BACK: - if (force || gl_state.polygon_back_face_mode != mode) { + if (force || gl_state.polygon_mode != mode) { glPolygonModeDLL(GL_BACK, mode); - gl_state.polygon_back_face_mode = mode; + gl_state.polygon_mode = mode; } break; case GL_FRONT_AND_BACK: - if (force || gl_state.polygon_front_face_mode != mode - && gl_state.polygon_back_face_mode != mode) { + if (force || gl_state.polygon_mode != mode) { glPolygonModeDLL(GL_FRONT_AND_BACK, mode); - gl_state.polygon_front_face_mode = mode; - gl_state.polygon_back_face_mode = mode; - } - else if (gl_state.polygon_front_face_mode != mode) { - glPolygonModeDLL(GL_FRONT, mode); - gl_state.polygon_front_face_mode = mode; - } - else if (gl_state.polygon_back_face_mode != mode) { - glPolygonModeDLL(GL_BACK, mode); - gl_state.polygon_back_face_mode = mode; + gl_state.polygon_mode = mode; + gl_state.polygon_mode = mode; } break; } @@ -517,6 +524,16 @@ void gl_state_set_scissor(GLint x, GLint y, GLsizei width, GLsizei height, bool } } +void gl_state_set_stencil_func(GLenum func, GLint ref, GLuint mask, bool force) { + if (force || gl_state.stencil_func != func + || gl_state.stencil_ref != ref || gl_state.stencil_value_mask != mask) { + glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask); + gl_state.stencil_func = func; + gl_state.stencil_ref = ref; + gl_state.stencil_value_mask = mask; + } +} + void gl_state_set_stencil_mask(GLuint mask, bool force) { if (force || gl_state.stencil_mask != mask) { glStencilMask(mask); @@ -524,6 +541,16 @@ void gl_state_set_stencil_mask(GLuint mask, bool force) { } } +void gl_state_set_stencil_op(GLenum sfail, GLenum dpfail, GLenum dppass, bool force) { + if (force || gl_state.stencil_fail != sfail + || gl_state.stencil_dpfail != dpfail || gl_state.stencil_dppass != dppass) { + glStencilOpSeparate(GL_FRONT_AND_BACK, sfail, dpfail, dppass); + gl_state.stencil_fail = sfail; + gl_state.stencil_dpfail = dpfail; + gl_state.stencil_dppass = dppass; + } +} + void gl_state_set_viewport(const gl_state_rect& rect, bool force) { if (force || gl_state.viewport.x != rect.x || gl_state.viewport.y != rect.y || gl_state.viewport.width != rect.width || gl_state.viewport.height != rect.height) { diff --git a/src/DivaGL/gl_state.hpp b/src/DivaGL/gl_state.hpp index eeafef7..5bfc412 100644 --- a/src/DivaGL/gl_state.hpp +++ b/src/DivaGL/gl_state.hpp @@ -29,6 +29,7 @@ struct gl_state_struct { GLenum blend_dst_alpha; GLenum blend_mode_rgb; GLenum blend_mode_alpha; + GLuint framebuffer_binding; GLuint read_framebuffer_binding; GLuint draw_framebuffer_binding; GLuint vertex_array_binding; @@ -48,15 +49,21 @@ struct gl_state_struct { GLboolean depth_test; GLenum depth_func; GLboolean depth_mask; - GLenum polygon_front_face_mode; - GLenum polygon_back_face_mode; + GLfloat line_width; + GLenum polygon_mode; GLboolean multisample; GLboolean primitive_restart; GLuint primitive_restart_index; gl_state_rect scissor_box; GLboolean scissor_test; GLboolean stencil_test; + GLenum stencil_func; + GLenum stencil_fail; + GLenum stencil_dpfail; + GLenum stencil_dppass; GLuint stencil_mask; + GLint stencil_ref; + GLuint stencil_value_mask; gl_state_rect viewport; }; @@ -122,11 +129,14 @@ extern void gl_state_set_color_mask(GLboolean red, GLboolean green, extern void gl_state_set_cull_face_mode(GLenum mode, bool force = false); extern void gl_state_set_depth_func(GLenum func, bool force = false); extern void gl_state_set_depth_mask(GLboolean flag, bool force = false); +extern void gl_state_set_line_width(GLfloat width, bool force = false); extern void gl_state_set_polygon_mode(GLenum face, GLenum mode, bool force = false); extern void gl_state_set_primitive_restart_index(GLuint index, bool force = false); extern void gl_state_set_scissor(const gl_state_rect& rect, bool force = false); extern void gl_state_set_scissor(GLint x, GLint y, GLsizei width, GLsizei height, bool force = false); +extern void gl_state_set_stencil_func(GLenum func, GLint ref, GLuint mask, bool force = false); extern void gl_state_set_stencil_mask(GLuint mask, bool force = false); +extern void gl_state_set_stencil_op(GLenum sfail, GLenum dpfail, GLenum dppass, bool force = false); extern void gl_state_set_viewport(const gl_state_rect& rect, bool force = false); extern void gl_state_set_viewport(GLint x, GLint y, GLsizei width, GLsizei height, bool force = false); extern void gl_state_use_program(GLuint program, bool force = false); diff --git a/src/DivaGL/mdl/disp_manager.cpp b/src/DivaGL/mdl/disp_manager.cpp index 26deb12..457b1d3 100644 --- a/src/DivaGL/mdl/disp_manager.cpp +++ b/src/DivaGL/mdl/disp_manager.cpp @@ -2066,7 +2066,7 @@ namespace mdl { case OBJ_TYPE_REFRACT_TRANSPARENT: alpha_test = 1; min_alpha = 0.1f; - alpha_threshold = 0.0f; + alpha_threshold = 0.5f; break; case OBJ_TYPE_SSS: func = draw_sub_mesh_sss; diff --git a/src/DivaGL/mdl/draw_object.cpp b/src/DivaGL/mdl/draw_object.cpp index 0c6b236..5159ae2 100644 --- a/src/DivaGL/mdl/draw_object.cpp +++ b/src/DivaGL/mdl/draw_object.cpp @@ -119,11 +119,11 @@ namespace mdl { shaders_ft.draw_elements(GL_TRIANGLES, etc->count, GL_UNSIGNED_INT, 0); break; case mdl::ETC_OBJ_GRID: - glLineWidthDLL(0.2f); + gl_state_set_line_width(0.2f); shaders_ft.draw_arrays(GL_LINES, 0, etc->count); - glLineWidthDLL(2.0f); + gl_state_set_line_width(2.0f); shaders_ft.draw_arrays(GL_LINES, (GLint)etc->count, 4); - glLineWidthDLL(1.0f); + gl_state_set_line_width(1.0f); break; case mdl::ETC_OBJ_CUBE: if (etc->data.sphere.wire) @@ -855,20 +855,20 @@ static void draw_object_material_set_parameter(const obj_material_data* mat_data float_t inv_bump_depth; bool has_specular; if (draw_state.use_global_material) { - bump_depth = draw_state.bump_depth; - intensity = draw_state.intensity; - reflect_uv_scale = draw_state.reflect_uv_scale; - refract_uv_scale = draw_state.refract_uv_scale; - inv_bump_depth = (1.0f - draw_state.bump_depth) * 64.0f + 1.0f; + bump_depth = draw_state.global_material.bump_depth; + intensity = draw_state.global_material.intensity; + reflect_uv_scale = draw_state.global_material.reflect_uv_scale; + refract_uv_scale = draw_state.global_material.refract_uv_scale; + inv_bump_depth = (1.0f - draw_state.global_material.bump_depth) * 64.0f + 1.0f; specular = mat_data->material.color.specular; - specular.w = draw_state.reflectivity; + specular.w = draw_state.global_material.reflectivity; has_specular = true; } else { bump_depth = mat_data->material.bump_depth; - reflect_uv_scale = 0.1f; intensity = mat_data->material.color.intensity; + reflect_uv_scale = 0.1f; refract_uv_scale = 0.1f; inv_bump_depth = (1.0f - bump_depth) * 256.0f + 1.0f; has_specular = false; diff --git a/src/DivaGL/render_context.hpp b/src/DivaGL/render_context.hpp index d7ea7f4..5aa9930 100644 --- a/src/DivaGL/render_context.hpp +++ b/src/DivaGL/render_context.hpp @@ -54,6 +54,16 @@ struct sss_data { static_assert(sizeof(sss_data) == 0xD8, "\"sss_data\" struct should have a size of 0xD8"); +struct global_material_struct { + float_t bump_depth; + float_t intensity; + float_t reflectivity; + float_t reflect_uv_scale; + float_t refract_uv_scale; +}; + +static_assert(sizeof(global_material_struct) == 0x14, "\"global_material_struct\" struct should have a size of 0x14"); + struct draw_state_struct { draw_state_stats stats; draw_state_stats stats_prev; @@ -68,11 +78,7 @@ struct draw_state_struct { bool back_display; int32_t shader_index; int32_t show; - float_t bump_depth; - float_t intensity; - float_t reflectivity; - float_t reflect_uv_scale; - float_t refract_uv_scale; + global_material_struct global_material; int32_t field_68; void* curr_obj_sub_mesh_args; float_t fresnel;