diff --git a/src/CRE/Vulkan/gl_wrap.cpp b/src/CRE/Vulkan/gl_wrap.cpp index 1e67c352..3eb75bd8 100644 --- a/src/CRE/Vulkan/gl_wrap.cpp +++ b/src/CRE/Vulkan/gl_wrap.cpp @@ -114,6 +114,7 @@ namespace Vulkan { static void gl_wrap_manager_bind_framebuffer(GLenum target, GLuint framebuffer); static void gl_wrap_manager_bind_sampler(GLuint unit, GLuint sampler); static void gl_wrap_manager_bind_texture(GLenum target, GLuint texture); + static void gl_wrap_manager_bind_texture_unit(GLuint unit, GLuint texture); static void gl_wrap_manager_bind_vertex_array(GLuint array); static void gl_wrap_manager_blend_func(GLenum sfactor, GLenum dfactor); static void gl_wrap_manager_blend_func_separate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); @@ -920,6 +921,8 @@ namespace Vulkan { viewport.width = 0; viewport.height = 0; polygon_mode = GL_FILL; + + viewport_set = false; } gl_storage_buffer::gl_storage_buffer() : copy_working_buffer() { @@ -1365,6 +1368,7 @@ namespace Vulkan { glBindFramebuffer = gl_wrap_manager_bind_framebuffer; glBindSampler = gl_wrap_manager_bind_sampler; glBindTexture = gl_wrap_manager_bind_texture; + glBindTextureUnit = gl_wrap_manager_bind_texture_unit; glBindVertexArray = gl_wrap_manager_bind_vertex_array; glBlendFunc = gl_wrap_manager_blend_func; glBlendFuncSeparate = gl_wrap_manager_blend_func_separate; @@ -2307,6 +2311,8 @@ namespace Vulkan { } vk_vb->working_buffer.Reset(); } + + gl_state.viewport_set = false; } static bool gl_wrap_manager_prepare_pipeline_draw(GLenum mode, GLenum type, const void* indices) { @@ -3106,6 +3112,10 @@ namespace Vulkan { vkCmdBindPipeline(Vulkan::current_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); + if (!gl_state.viewport_set) + gl_wrap_manager_viewport(gl_state.viewport.x, gl_state.viewport.y, + gl_state.viewport.width, gl_state.viewport.height); + if (query) Vulkan::gl_query::get(query)->query.Begin(Vulkan::current_command_buffer); @@ -3253,6 +3263,7 @@ namespace Vulkan { } } + gl_state.uniform_buffer_binding = buffer; gl_state.uniform_buffer_bindings[index] = buffer; gl_state.uniform_buffer_offsets[index] = 0; gl_state.uniform_buffer_sizes[index] = -1; @@ -3277,6 +3288,7 @@ namespace Vulkan { } } + gl_state.shader_storage_buffer_binding = buffer; gl_state.shader_storage_buffer_bindings[index] = buffer; gl_state.shader_storage_buffer_offsets[index] = 0; gl_state.shader_storage_buffer_sizes[index] = -1; @@ -3325,6 +3337,7 @@ namespace Vulkan { return; } + gl_state.uniform_buffer_binding = buffer; gl_state.uniform_buffer_bindings[index] = buffer; gl_state.uniform_buffer_offsets[index] = offset; gl_state.uniform_buffer_sizes[index] = size; @@ -3365,6 +3378,7 @@ namespace Vulkan { return; } + gl_state.shader_storage_buffer_binding = buffer; gl_state.shader_storage_buffer_bindings[index] = buffer; gl_state.shader_storage_buffer_offsets[index] = offset; gl_state.shader_storage_buffer_sizes[index] = size; @@ -3459,6 +3473,34 @@ namespace Vulkan { } } + static void gl_wrap_manager_bind_texture_unit(GLuint unit, GLuint texture) { + if (unit >= Vulkan::MAX_COMBINED_TEXTURE_IMAGE_UNITS) { + gl_wrap_manager_ptr->push_error(GL_INVALID_ENUM); + return; + } + + if (texture) { + gl_texture* vk_tex = gl_texture::get(texture, false); + if (!vk_tex) { + gl_wrap_manager_ptr->push_error(GL_INVALID_VALUE); + return; + } + + switch (vk_tex->target) { + case GL_TEXTURE_2D: + gl_state.texture_binding_2d[unit] = texture; + break; + case GL_TEXTURE_CUBE_MAP: + gl_state.texture_binding_cube_map[unit] = texture; + break; + } + } + else { + gl_state.texture_binding_2d[unit] = 0; + gl_state.texture_binding_cube_map[unit] = 0; + } + } + static void gl_wrap_manager_bind_vertex_array(GLuint array) { if (array) { gl_vertex_array* vk_vao = gl_vertex_array::get(array); @@ -5071,6 +5113,9 @@ namespace Vulkan { case GL_DEPTH_FUNC: *data = gl_state.depth_func; break; + case GL_STENCIL_CLEAR_VALUE: + *data = gl_state.clear_stencil; + break; case GL_STENCIL_FUNC: *data = gl_state.stencil_func; break; @@ -6874,6 +6919,7 @@ namespace Vulkan { viewport.maxDepth = 1.0f; vkCmdSetViewport(Vulkan::current_command_buffer, 0, 1, &viewport); + gl_state.viewport_set = true; if (!gl_state.scissor_test && memcmp(&gl_state.viewport, &gl_state.scissor_box, sizeof(gl_state_rect))) { diff --git a/src/CRE/Vulkan/gl_wrap.hpp b/src/CRE/Vulkan/gl_wrap.hpp index 0dcda5ed..4abd046b 100644 --- a/src/CRE/Vulkan/gl_wrap.hpp +++ b/src/CRE/Vulkan/gl_wrap.hpp @@ -203,6 +203,7 @@ namespace Vulkan { GLint stencil_ref; GLuint stencil_value_mask; gl_state_rect viewport; + bool viewport_set; gl_state_struct(); }; diff --git a/src/CRE/clear_color.cpp b/src/CRE/clear_color.cpp index d9bdffb6..7be984f2 100644 --- a/src/CRE/clear_color.cpp +++ b/src/CRE/clear_color.cpp @@ -4,14 +4,14 @@ */ #include "clear_color.hpp" -#include "gl.hpp" +#include "gl_rend_state.hpp" color4u8 clear_color; bool set_clear_color; -void clear_color_set_gl() { +void clear_color_set_gl(p_gl_rend_state& p_gl_rend_st) { vec4 color = 0.0f; if (set_clear_color) color = clear_color; - glClearColor(color.x, color.y, color.z, color.w); + p_gl_rend_st.clear_color(color.x, color.y, color.z, color.w); } diff --git a/src/CRE/clear_color.hpp b/src/CRE/clear_color.hpp index b0cc0351..5eefd4bb 100644 --- a/src/CRE/clear_color.hpp +++ b/src/CRE/clear_color.hpp @@ -12,4 +12,4 @@ extern color4u8 clear_color; extern bool set_clear_color; -extern void clear_color_set_gl(); +extern void clear_color_set_gl(struct p_gl_rend_state& p_gl_rend_st); diff --git a/src/CRE/effect.cpp b/src/CRE/effect.cpp index 68841fbe..657d5d44 100644 --- a/src/CRE/effect.cpp +++ b/src/CRE/effect.cpp @@ -2297,8 +2297,8 @@ void EffectFogRing::draw(render_data_context& rend_data_ctx, const cam_data& cam rend_data_ctx.state.set_viewport(0, 0, rt.color_texture->get_width_align_mip_level(), rt.color_texture->get_height_align_mip_level()); - glClearColor(density_offset, density_offset, density_offset, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + rend_data_ctx.state.clear_color(density_offset, density_offset, density_offset, 1.0f); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if (rctx->disp_manager->get_obj_count(mdl::OBJ_TYPE_USER)) rctx->disp_manager->draw(rend_data_ctx, mdl::OBJ_TYPE_USER, cam); rend_data_ctx.state.bind_framebuffer(0); @@ -3152,7 +3152,7 @@ void EffectRipple::draw(render_data_context& rend_data_ctx, const cam_data& cam) rend_data_ctx.state.set_viewport(1, 1, width - 2, height - 2); - glClear(GL_DEPTH_BUFFER_BIT); + rend_data_ctx.state.clear(GL_DEPTH_BUFFER_BIT); if (rctx->disp_manager->get_obj_count(mdl::OBJ_TYPE_USER)) { rend_data_ctx.state.active_bind_texture_2d(7, rt[counter % 3]->GetColorTex()); rctx->disp_manager->draw(rend_data_ctx, mdl::OBJ_TYPE_USER, cam); @@ -4960,7 +4960,7 @@ void star_catalog_milky_way::create_buffers(int32_t subdivs, float_t uv_rec_scal (void*)offsetof(star_catalog_vertex, texcoord)); ebo.Create(gl_state, sizeof(uint16_t) * ebo_count, ebo_data); - gl_state.bind_element_array_buffer(ebo); + gl_state.bind_element_array_buffer(ebo, true); gl_state.bind_vertex_array(0); gl_state.bind_array_buffer(0); @@ -5716,7 +5716,7 @@ static void leaf_particle_init(bool change_stage) { (void*)offsetof(leaf_particle_vertex_data, normal)); leaf_ptcl_ebo.Create(gl_state, sizeof(uint32_t) * ebo_count, ebo_data); - gl_state.bind_element_array_buffer(leaf_ptcl_ebo); + gl_state.bind_element_array_buffer(leaf_ptcl_ebo, true); gl_state.bind_vertex_array(0); gl_state.bind_array_buffer(0); diff --git a/src/CRE/gl_rend_state.cpp b/src/CRE/gl_rend_state.cpp index a904f6e9..f0fba79f 100644 --- a/src/CRE/gl_rend_state.cpp +++ b/src/CRE/gl_rend_state.cpp @@ -4,373 +4,518 @@ */ #include "gl_rend_state.hpp" +#include "shared.hpp" + +enum gl_rend_state_update_flags : uint32_t { + GL_REND_STATE_UPDATE_PROGRAM = 1u << 0, + GL_REND_STATE_UPDATE_TEXTURE = 1u << 1, + GL_REND_STATE_UPDATE_ACTIVE_TEXTURE = 1u << 2, + GL_REND_STATE_UPDATE_SAMPLER = 1u << 3, + GL_REND_STATE_UPDATE_BLEND = 1u << 4, + GL_REND_STATE_UPDATE_BLEND_FUNC = 1u << 5, + GL_REND_STATE_UPDATE_BLEND_EQUATION = 1u << 6, + GL_REND_STATE_UPDATE_READ_FRAMEBUFFER = 1u << 7, + GL_REND_STATE_UPDATE_DRAW_FRAMEBUFFER = 1u << 8, + GL_REND_STATE_UPDATE_VERTEX_ARRAY = 1u << 9, + GL_REND_STATE_UPDATE_UNIFORM_BUFFER = 1u << 10, + GL_REND_STATE_UPDATE_SHADER_STORAGE_BUFFER = 1u << 11, + GL_REND_STATE_UPDATE_COLOR_MASK = 1u << 12, + GL_REND_STATE_UPDATE_CULL_FACE = 1u << 13, + GL_REND_STATE_UPDATE_CULL_FACE_MODE = 1u << 14, + GL_REND_STATE_UPDATE_DEPTH_TEST = 1u << 15, + GL_REND_STATE_UPDATE_DEPTH_MASK = 1u << 16, + GL_REND_STATE_UPDATE_DEPTH_FUNC = 1u << 17, + GL_REND_STATE_UPDATE_LINE_WIDTH = 1u << 18, + GL_REND_STATE_UPDATE_MULTISAMPLE = 1u << 19, + GL_REND_STATE_UPDATE_PRIMITIVE_RESTART = 1u << 20, + GL_REND_STATE_UPDATE_PRIMITIVE_RESTART_INDEX = 1u << 21, + GL_REND_STATE_UPDATE_SCISSOR_TEST = 1u << 22, + GL_REND_STATE_UPDATE_SCISSOR = 1u << 23, + GL_REND_STATE_UPDATE_STENCIL_TEST = 1u << 24, + GL_REND_STATE_UPDATE_STENCIL_MASK = 1u << 25, + GL_REND_STATE_UPDATE_STENCIL_FUNC = 1u << 26, + GL_REND_STATE_UPDATE_STENCIL_OP = 1u << 27, + GL_REND_STATE_UPDATE_VIEWPORT = 1u << 28, + GL_REND_STATE_UPDATE_CLEAR_COLOR = 1u << 29, + GL_REND_STATE_UPDATE_CLEAR_DEPTH = 1u << 30, + GL_REND_STATE_UPDATE_CLEAR_STENCIL = 1u << 31, +}; + +enum gl_rend_state_flags { + GL_REND_STATE_EXECUTE = 1u << 0, +}; struct gl_rend_state { + gl_rend_state_index index; + + GLuint curr_program; GLuint program; + + GLuint curr_active_texture_index; GLuint active_texture_index; + + int32_t texture_binding_start_index; + int32_t texture_binding_end_index; + GLuint curr_texture_binding_2d[32]; GLuint texture_binding_2d[32]; + GLuint curr_texture_binding_cube_map[32]; GLuint texture_binding_cube_map[32]; + + int32_t sampler_binding_start_index; + int32_t sampler_binding_end_index; + GLuint curr_sampler_binding[32]; GLuint sampler_binding[32]; + + GLboolean curr_blend; GLboolean blend; + GLenum curr_blend_src_rgb; GLenum blend_src_rgb; + GLenum curr_blend_src_alpha; GLenum blend_src_alpha; + GLenum curr_blend_dst_rgb; GLenum blend_dst_rgb; + GLenum curr_blend_dst_alpha; GLenum blend_dst_alpha; + GLenum curr_blend_mode_rgb; GLenum blend_mode_rgb; + GLenum curr_blend_mode_alpha; GLenum blend_mode_alpha; + + GLuint curr_read_framebuffer_binding; GLuint read_framebuffer_binding; + GLuint curr_draw_framebuffer_binding; GLuint draw_framebuffer_binding; + + GLuint curr_vertex_array_binding; GLuint vertex_array_binding; + GLuint array_buffer_binding; GLuint element_array_buffer_binding; + GLuint uniform_buffer_binding; + + int32_t uniform_buffer_start_index; + int32_t uniform_buffer_end_index; + GLuint curr_uniform_buffer_bindings[14]; GLuint uniform_buffer_bindings[14]; + GLintptr curr_uniform_buffer_offsets[14]; GLintptr uniform_buffer_offsets[14]; + GLsizeiptr curr_uniform_buffer_sizes[14]; GLsizeiptr uniform_buffer_sizes[14]; + GLuint shader_storage_buffer_binding; + + int32_t shader_storage_buffer_start_index; + int32_t shader_storage_buffer_end_index; + GLuint curr_shader_storage_buffer_bindings[14]; GLuint shader_storage_buffer_bindings[14]; + GLintptr curr_shader_storage_buffer_offsets[14]; GLintptr shader_storage_buffer_offsets[14]; + GLsizeiptr curr_shader_storage_buffer_sizes[14]; GLsizeiptr shader_storage_buffer_sizes[14]; + + GLboolean curr_color_mask[4]; GLboolean color_mask[4]; + + GLboolean curr_cull_face; GLboolean cull_face; + GLenum curr_cull_face_mode; GLenum cull_face_mode; + + GLboolean curr_depth_test; GLboolean depth_test; + GLenum curr_depth_func; GLenum depth_func; + GLboolean curr_depth_mask; GLboolean depth_mask; + + GLfloat curr_line_width; GLfloat line_width; - GLenum polygon_mode; + + GLboolean curr_multisample; GLboolean multisample; + + GLboolean curr_primitive_restart; GLboolean primitive_restart; + GLuint curr_primitive_restart_index; GLuint primitive_restart_index; + + gl_rend_state_rect curr_scissor_box; gl_rend_state_rect scissor_box; + GLboolean curr_scissor_test; GLboolean scissor_test; + + GLboolean curr_stencil_test; GLboolean stencil_test; + GLenum curr_stencil_func; GLenum stencil_func; + GLenum curr_stencil_fail; GLenum stencil_fail; + GLenum curr_stencil_dpfail; GLenum stencil_dpfail; + GLenum curr_stencil_dppass; GLenum stencil_dppass; + GLuint curr_stencil_mask; GLuint stencil_mask; + GLint curr_stencil_ref; GLint stencil_ref; + GLuint curr_stencil_value_mask; GLuint stencil_value_mask; + + gl_rend_state_rect curr_viewport; gl_rend_state_rect viewport; - void active_bind_texture_2d(int32_t index, GLuint texture, bool force = false); - void active_bind_texture_cube_map(int32_t index, GLuint texture, bool force = false); - void active_texture(size_t index, bool force = false); + GLfloat curr_clear_color_value[4]; + GLfloat clear_color_value[4]; + + GLfloat curr_clear_depth_value; + GLfloat clear_depth_value; + + GLint curr_clear_stencil_value; + GLint clear_stencil_value; + + gl_rend_state_flags flags; + gl_rend_state_update_flags update_flags; + + void active_bind_texture_2d(int32_t index, GLuint texture); + void active_bind_texture_cube_map(int32_t index, GLuint texture); + void active_texture(int32_t index); void begin_event(const char* message, int32_t length); - void bind_framebuffer(GLuint framebuffer, bool force = false); - void bind_read_framebuffer(GLuint framebuffer, bool force = false); - void bind_draw_framebuffer(GLuint framebuffer, bool force = false); - void bind_vertex_array(GLuint array, bool force = false); - void bind_array_buffer(GLuint buffer, bool force = false); - void bind_element_array_buffer(GLuint buffer, bool force = false); - void bind_uniform_buffer(GLuint buffer, bool force = false); - void bind_uniform_buffer_base(GLuint index, GLuint buffer, bool force = false); + void bind_framebuffer(GLuint framebuffer); + void bind_read_framebuffer(GLuint framebuffer); + void bind_draw_framebuffer(GLuint framebuffer); + void bind_vertex_array(GLuint array); + void bind_array_buffer(GLuint buffer); + void bind_element_array_buffer(GLuint buffer); + void bind_uniform_buffer(GLuint buffer); + void bind_uniform_buffer_base(GLuint index, GLuint buffer); void bind_uniform_buffer_range(GLuint index, - GLuint buffer, GLintptr offset, GLsizeiptr size, bool force = false); - void bind_shader_storage_buffer(GLuint buffer, bool force = false); - void bind_shader_storage_buffer_base(GLuint index, GLuint buffer, bool force = false); + GLuint buffer, GLintptr offset, GLsizeiptr size); + void bind_shader_storage_buffer(GLuint buffer); + void bind_shader_storage_buffer_base(GLuint index, GLuint buffer); void bind_shader_storage_buffer_range(GLuint index, - GLuint buffer, GLintptr offset, GLsizeiptr size, bool force = false); - void bind_texture_2d(GLuint texture, bool force = false); - void bind_texture_cube_map(GLuint texture, bool force = false); - void bind_sampler(int32_t index, GLuint sampler, bool force = false); - bool check_uniform_buffer_binding(); - bool check_uniform_buffer_binding_base(size_t index); - bool check_shader_storage_buffer_binding(); - bool check_shader_storage_buffer_binding_base(size_t index); - bool check_texture_binding_2d(size_t index); - bool check_texture_binding_cube_map(size_t index); - bool check_sampler_binding(int32_t index, GLuint sampler); - void disable_blend(bool force = false); - void disable_cull_face(bool force = false); - void disable_depth_test(bool force = false); - void disable_multisample(bool force = false); - void disable_primitive_restart(bool force = false); - void disable_scissor_test(bool force = false); - void disable_stencil_test(bool force = false); - void enable_blend(bool force = false); - void enable_cull_face(bool force = false); - void enable_depth_test(bool force = false); - void enable_multisample(bool force = false); - void enable_primitive_restart(bool force = false); - void enable_scissor_test(bool force = false); - void enable_stencil_test(bool force = false); + GLuint buffer, GLintptr offset, GLsizeiptr size); + void bind_texture_2d(GLuint texture); + void bind_texture_cube_map(GLuint texture); + void bind_sampler(int32_t index, GLuint sampler); + void blit_framebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, + GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); + GLenum check_framebuffer_status(GLenum target); + void clear(GLbitfield mask); + void clear_buffer(GLenum buffer, GLint drawbuffer, const GLfloat* value); + void clear_color(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); + void clear_depth(GLfloat depth); + void clear_stencil(GLint stencil); + void copy_image_sub_data(GLuint srcName, GLenum srcTarget, GLint srcLevel, + GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, + GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); + void copy_tex_sub_image_2d(GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); + void disable_blend(); + void disable_cull_face(); + void disable_depth_test(); + void disable_multisample(); + void disable_primitive_restart(); + void disable_scissor_test(); + void disable_stencil_test(); + void draw_arrays(GLenum mode, GLint first, GLsizei count); + void draw_elements(GLenum mode, + GLsizei count, GLenum type, const void* indices); + void draw_range_elements(GLenum mode, + GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices); + void enable_blend(); + void enable_cull_face(); + void enable_depth_test(); + void enable_multisample(); + void enable_primitive_restart(); + void enable_scissor_test(); + void enable_stencil_test(); void end_event(); + void generate_mipmap(GLenum target); + void generate_texture_mipmap(GLuint texture); void get(); + void get_clear_color(GLfloat& red, GLfloat& green, GLfloat& blue, GLfloat& alpha); GLuint get_program(); gl_rend_state_rect get_scissor(); void get_scissor(GLint& x, GLint& y, GLsizei& width, GLsizei& height); gl_rend_state_rect get_viewport(); void get_viewport(GLint& x, GLint& y, GLsizei& width, GLsizei& height); - void set_blend_func(GLenum src, GLenum dst, bool force = false); + void set_blend_func(GLenum src, GLenum dst); void set_blend_func_separate(GLenum src_rgb, GLenum dst_rgb, - GLenum src_alpha, GLenum dst_alpha, bool force = false); - void set_blend_equation(GLenum mode, bool force = false); + GLenum src_alpha, GLenum dst_alpha); + void set_blend_equation(GLenum mode); void set_blend_equation_separate( - GLenum mode_rgb, GLenum mode_alpha, bool force = false); - void set_color_mask(GLboolean red, GLboolean green, - GLboolean blue, GLboolean alpha, bool force = false); - void set_cull_face_mode(GLenum mode, bool force = false); - void set_depth_func(GLenum func, bool force = false); - void set_depth_mask(GLboolean flag, bool force = false); - void set_line_width(GLfloat width, bool force = false); - void set_polygon_mode(GLenum face, GLenum mode, bool force = false); - void set_primitive_restart_index(GLuint index, bool force = false); - void set_scissor(const gl_rend_state_rect& rect, bool force = false); - void set_scissor(GLint x, GLint y, GLsizei width, GLsizei height, bool force = false); - void set_stencil_func(GLenum func, GLint ref, GLuint mask, bool force = false); - void set_stencil_mask(GLuint mask, bool force = false); - void set_stencil_op(GLenum sfail, GLenum dpfail, GLenum dppass, bool force = false); - void set_viewport(const gl_rend_state_rect& rect, bool force = false); - void set_viewport(GLint x, GLint y, GLsizei width, GLsizei height, bool force = false); - void use_program(GLuint program, bool force = false); + GLenum mode_rgb, GLenum mode_alpha); + void set_color_mask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); + void set_cull_face_mode(GLenum mode); + void set_depth_func(GLenum func); + void set_depth_mask(GLboolean flag); + void set_line_width(GLfloat width); + void set_primitive_restart_index(GLuint index); + void set_scissor(const gl_rend_state_rect& rect); + void set_scissor(GLint x, GLint y, GLsizei width, GLsizei height); + void set_stencil_func(GLenum func, GLint ref, GLuint mask); + void set_stencil_mask(GLuint mask); + void set_stencil_op(GLenum sfail, GLenum dpfail, GLenum dppass); + void set_viewport(const gl_rend_state_rect& rect); + void set_viewport(GLint x, GLint y, GLsizei width, GLsizei height); + void update(); + void update_program(); + void update_active_texture(); + void update_curr_active_texture(); + void update_texture(); + void update_sampler(); + void update_blend(); + void update_blend_func(); + void update_blend_equation(); + void update_read_framebuffer(); + void update_draw_framebuffer(); + void update_vertex_array(); + void update_uniform_buffer(); + void update_shader_storage_buffer(); + void update_color_mask(); + void update_cull_face(); + void update_cull_face_mode(); + void update_depth_test(); + void update_depth_mask(); + void update_depth_func(); + void update_line_width(); + void update_multisample(); + void update_primitive_restart(); + void update_primitive_restart_index(); + void update_scissor_test(); + void update_scissor(); + void update_stencil_test(); + void update_stencil_mask(); + void update_stencil_func(); + void update_stencil_op(); + void update_viewport(); + void update_clear_color(); + void update_clear_depth(); + void update_clear_stencil(); + void use_program(GLuint program); }; -gl_rend_state gl_state_data[GL_REND_STATE_COUNT]; +gl_rend_state gl_rend_state_data[GL_REND_STATE_COUNT] = { + { GL_REND_STATE_PRE_3D }, + { GL_REND_STATE_3D }, + { GL_REND_STATE_2D }, + { GL_REND_STATE_POST_2D }, +}; -p_gl_rend_state::p_gl_rend_state(gl_rend_state_index index) : ptr(gl_state_data[index]) { +p_gl_rend_state::p_gl_rend_state(gl_rend_state_index index) : ptr(gl_rend_state_data[index]) { } -void p_gl_rend_state::active_bind_texture_2d(int32_t index, GLuint texture, bool force) { - ptr.active_bind_texture_2d(index, texture, force); +void p_gl_rend_state::active_bind_texture_2d(int32_t index, GLuint texture) { + ptr.active_bind_texture_2d(index, texture); } -void p_gl_rend_state::active_bind_texture_cube_map(int32_t index, GLuint texture, bool force) { - ptr.active_bind_texture_cube_map(index, texture, force); +void p_gl_rend_state::active_bind_texture_cube_map(int32_t index, GLuint texture) { + ptr.active_bind_texture_cube_map(index, texture); } -void p_gl_rend_state::active_texture(size_t index, bool force) { - ptr.active_texture(index, force); +void p_gl_rend_state::active_texture(int32_t index) { + ptr.active_texture(index); } void p_gl_rend_state::begin_event(const char* message, int32_t length) { ptr.begin_event(message, length); } -void p_gl_rend_state::bind_framebuffer(GLuint framebuffer, bool force) { - ptr.bind_framebuffer(framebuffer, force); +void p_gl_rend_state::bind_framebuffer(GLuint framebuffer) { + ptr.bind_framebuffer(framebuffer); } -void p_gl_rend_state::bind_read_framebuffer(GLuint framebuffer, bool force) { - ptr.bind_read_framebuffer(framebuffer, force); +void p_gl_rend_state::bind_read_framebuffer(GLuint framebuffer) { + ptr.bind_read_framebuffer(framebuffer); } -void p_gl_rend_state::bind_draw_framebuffer(GLuint framebuffer, bool force) { - ptr.bind_draw_framebuffer(framebuffer, force); +void p_gl_rend_state::bind_draw_framebuffer(GLuint framebuffer) { + ptr.bind_draw_framebuffer(framebuffer); } -void p_gl_rend_state::bind_vertex_array(GLuint array, bool force) { - ptr.bind_vertex_array(array, force); +void p_gl_rend_state::bind_vertex_array(GLuint array) { + ptr.bind_vertex_array(array); } -void p_gl_rend_state::bind_array_buffer(GLuint buffer, bool force) { - ptr.bind_array_buffer(buffer, force); +void p_gl_rend_state::bind_array_buffer(GLuint buffer) { + ptr.bind_array_buffer(buffer); } -void p_gl_rend_state::bind_element_array_buffer(GLuint buffer, bool force) { - ptr.bind_element_array_buffer(buffer, force); +void p_gl_rend_state::bind_element_array_buffer(GLuint buffer) { + ptr.bind_element_array_buffer(buffer); } -void p_gl_rend_state::bind_uniform_buffer(GLuint buffer, bool force) { - ptr.bind_uniform_buffer(buffer, force); +void p_gl_rend_state::bind_uniform_buffer(GLuint buffer) { + ptr.bind_uniform_buffer(buffer); } -void p_gl_rend_state::bind_uniform_buffer_base(GLuint index, GLuint buffer, bool force) { - ptr.bind_uniform_buffer_base(index, buffer, force); +void p_gl_rend_state::bind_uniform_buffer_base(GLuint index, GLuint buffer) { + ptr.bind_uniform_buffer_base(index, buffer); } void p_gl_rend_state::bind_uniform_buffer_range(GLuint index, - GLuint buffer, GLintptr offset, GLsizeiptr size, bool force) { - ptr.bind_uniform_buffer_range(index, buffer, offset, size, force); + GLuint buffer, GLintptr offset, GLsizeiptr size) { + ptr.bind_uniform_buffer_range(index, buffer, offset, size); } -void p_gl_rend_state::bind_shader_storage_buffer(GLuint buffer, bool force) { - ptr.bind_shader_storage_buffer(buffer, force); +void p_gl_rend_state::bind_shader_storage_buffer(GLuint buffer) { + ptr.bind_shader_storage_buffer(buffer); } -void p_gl_rend_state::bind_shader_storage_buffer_base(GLuint index, GLuint buffer, bool force) { - ptr.bind_shader_storage_buffer_base(index, buffer, force); +void p_gl_rend_state::bind_shader_storage_buffer_base(GLuint index, GLuint buffer) { + ptr.bind_shader_storage_buffer_base(index, buffer); } void p_gl_rend_state::bind_shader_storage_buffer_range(GLuint index, - GLuint buffer, GLintptr offset, GLsizeiptr size, bool force) { - ptr.bind_shader_storage_buffer_range(index, buffer, offset, size, force); + GLuint buffer, GLintptr offset, GLsizeiptr size) { + ptr.bind_shader_storage_buffer_range(index, buffer, offset, size); } -void p_gl_rend_state::bind_texture_2d(GLuint texture, bool force) { - ptr.bind_texture_2d(texture, force); +void p_gl_rend_state::bind_texture_2d(GLuint texture) { + ptr.bind_texture_2d(texture); } -void p_gl_rend_state::bind_texture_cube_map(GLuint texture, bool force) { - ptr.bind_texture_cube_map(texture, force); +void p_gl_rend_state::bind_texture_cube_map(GLuint texture) { + ptr.bind_texture_cube_map(texture); } -void p_gl_rend_state::bind_sampler(int32_t index, GLuint sampler, bool force) { - ptr.bind_sampler(index, sampler, force); +void p_gl_rend_state::bind_sampler(int32_t index, GLuint sampler) { + ptr.bind_sampler(index, sampler); } -bool p_gl_rend_state::check_uniform_buffer_binding() { - return ptr.check_uniform_buffer_binding(); +void p_gl_rend_state::blit_framebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, + GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { + ptr.blit_framebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); } -bool p_gl_rend_state::check_uniform_buffer_binding_base(size_t index) { - return ptr.check_uniform_buffer_binding_base(index); +GLenum p_gl_rend_state::check_framebuffer_status(GLenum target) { + return ptr.check_framebuffer_status(target); } -bool p_gl_rend_state::check_shader_storage_buffer_binding() { - return ptr.check_shader_storage_buffer_binding(); +void p_gl_rend_state::clear(GLbitfield mask) { + ptr.clear(mask); } -bool p_gl_rend_state::check_shader_storage_buffer_binding_base(size_t index) { - return ptr.check_shader_storage_buffer_binding_base(index); +void p_gl_rend_state::clear_buffer(GLenum buffer, GLint drawbuffer, const GLfloat* value) { + ptr.clear_buffer(buffer, drawbuffer, value); } -bool p_gl_rend_state::check_texture_binding_2d(size_t index) { - return ptr.check_texture_binding_2d(index); +void p_gl_rend_state::clear_color(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { + ptr.clear_color(red, green, blue, alpha); } -bool p_gl_rend_state::check_texture_binding_cube_map(size_t index) { - return ptr.check_texture_binding_cube_map(index); +void p_gl_rend_state::clear_depth(GLfloat depth) { + ptr.clear_depth(depth); } -bool p_gl_rend_state::check_sampler_binding(int32_t index, GLuint sampler) { - return ptr.check_sampler_binding(index, sampler); +void p_gl_rend_state::clear_stencil(GLint stencil) { + ptr.clear_stencil(stencil); } -void p_gl_rend_state::disable_blend(bool force) { - ptr.disable_blend(force); +void p_gl_rend_state::copy_image_sub_data(GLuint srcName, GLenum srcTarget, GLint srcLevel, + GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, + GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth) { + ptr.copy_image_sub_data(srcName, srcTarget, srcLevel, srcX, srcY, srcZ, + dstName, dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight, srcDepth); } -void p_gl_rend_state::disable_cull_face(bool force) { - ptr.disable_cull_face(force); +void p_gl_rend_state::copy_tex_sub_image_2d(GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) { + ptr.copy_tex_sub_image_2d(target, level, xoffset, yoffset, x, y, width, height); } -void p_gl_rend_state::disable_depth_test(bool force) { - ptr.disable_depth_test(force); +void p_gl_rend_state::disable_blend() { + ptr.disable_blend(); } -void p_gl_rend_state::disable_multisample(bool force) { - ptr.disable_multisample(force); +void p_gl_rend_state::disable_cull_face() { + ptr.disable_cull_face(); } -void p_gl_rend_state::disable_primitive_restart(bool force) { - ptr.disable_primitive_restart(force); +void p_gl_rend_state::disable_depth_test() { + ptr.disable_depth_test(); } -void p_gl_rend_state::disable_scissor_test(bool force) { - ptr.disable_scissor_test(force); +void p_gl_rend_state::disable_multisample() { + ptr.disable_multisample(); } -void p_gl_rend_state::disable_stencil_test(bool force) { - ptr.disable_stencil_test(force); +void p_gl_rend_state::disable_primitive_restart() { + ptr.disable_primitive_restart(); +} + +void p_gl_rend_state::disable_scissor_test() { + ptr.disable_scissor_test(); +} + +void p_gl_rend_state::disable_stencil_test() { + ptr.disable_stencil_test(); } void p_gl_rend_state::draw_arrays(GLenum mode, GLint first, GLsizei count) { - glDrawArrays(mode, first, count); + ptr.draw_arrays(mode, first, count); } void p_gl_rend_state::draw_elements(GLenum mode, GLsizei count, GLenum type, const void* indices) { - switch (mode) { - case GL_TRIANGLE_STRIP: - uint32_t index; - switch (type) { - case GL_UNSIGNED_BYTE: - index = 0xFF; - break; - case GL_UNSIGNED_SHORT: - index = 0xFFFF; - break; - case GL_UNSIGNED_INT: - default: - index = 0xFFFFFFFF; - break; - } - - enable_primitive_restart(); - set_primitive_restart_index(index); - break; - } - - glDrawElements(mode, count, type, indices); - - switch (mode) { - case GL_TRIANGLE_STRIP: - disable_primitive_restart(); - break; - } + ptr.draw_elements(mode, count, type, indices); } void p_gl_rend_state::draw_range_elements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices) { - switch (mode) { - case GL_TRIANGLE_STRIP: - uint32_t index; - switch (type) { - case GL_UNSIGNED_BYTE: - index = 0xFF; - break; - case GL_UNSIGNED_SHORT: - index = 0xFFFF; - break; - case GL_UNSIGNED_INT: - default: - index = 0xFFFFFFFF; - break; - } - - enable_primitive_restart(); - set_primitive_restart_index(index); - break; - } - - glDrawRangeElements(mode, start, end, count, type, indices); - - switch (mode) { - case GL_TRIANGLE_STRIP: - disable_primitive_restart(); - break; - } + ptr.draw_range_elements(mode, start, end, count, type, indices); } -void p_gl_rend_state::enable_blend(bool force) { - ptr.enable_blend(force); +void p_gl_rend_state::enable_blend() { + ptr.enable_blend(); } -void p_gl_rend_state::enable_cull_face(bool force) { - ptr.enable_cull_face(force); +void p_gl_rend_state::enable_cull_face() { + ptr.enable_cull_face(); } -void p_gl_rend_state::enable_depth_test(bool force) { - ptr.enable_depth_test(force); +void p_gl_rend_state::enable_depth_test() { + ptr.enable_depth_test(); } -void p_gl_rend_state::enable_multisample(bool force) { - ptr.enable_multisample(force); +void p_gl_rend_state::enable_multisample() { + ptr.enable_multisample(); } -void p_gl_rend_state::enable_primitive_restart(bool force) { - ptr.enable_primitive_restart(force); +void p_gl_rend_state::enable_primitive_restart() { + ptr.enable_primitive_restart(); } -void p_gl_rend_state::enable_scissor_test(bool force) { - ptr.enable_scissor_test(force); +void p_gl_rend_state::enable_scissor_test() { + ptr.enable_scissor_test(); } -void p_gl_rend_state::enable_stencil_test(bool force) { - ptr.enable_stencil_test(force); +void p_gl_rend_state::enable_stencil_test() { + ptr.enable_stencil_test(); } void p_gl_rend_state::end_event() { ptr.end_event(); } +void p_gl_rend_state::generate_mipmap(GLenum target) { + ptr.generate_mipmap(target); +} + +void p_gl_rend_state::generate_texture_mipmap(GLuint texture) { + ptr.generate_texture_mipmap(texture); +} + void p_gl_rend_state::get() { ptr.get(); } +void p_gl_rend_state::get_clear_color(GLfloat& red, GLfloat& green, GLfloat& blue, GLfloat& alpha) { + ptr.get_clear_color(red, green, blue, alpha); +} + GLuint p_gl_rend_state::get_program() { return ptr.get_program(); } @@ -391,375 +536,491 @@ void p_gl_rend_state::get_viewport(GLint& x, GLint& y, GLsizei& width, GLsizei& ptr.get_viewport(x, y, width, height); } -void p_gl_rend_state::set_blend_func(GLenum src, GLenum dst, bool force) { - ptr.set_blend_func(src, dst, force); +void p_gl_rend_state::set_blend_func(GLenum src, GLenum dst) { + ptr.set_blend_func(src, dst); } void p_gl_rend_state::set_blend_func_separate(GLenum src_rgb, GLenum dst_rgb, - GLenum src_alpha, GLenum dst_alpha, bool force) { - ptr.set_blend_func_separate(src_rgb, dst_rgb, src_alpha, dst_alpha, force); + GLenum src_alpha, GLenum dst_alpha) { + ptr.set_blend_func_separate(src_rgb, dst_rgb, src_alpha, dst_alpha); } -void p_gl_rend_state::set_blend_equation(GLenum mode, bool force) { - ptr.set_blend_equation(mode, force); +void p_gl_rend_state::set_blend_equation(GLenum mode) { + ptr.set_blend_equation(mode); } void p_gl_rend_state::set_blend_equation_separate( - GLenum mode_rgb, GLenum mode_alpha, bool force) { - ptr.set_blend_equation_separate(mode_rgb, mode_alpha, force); + GLenum mode_rgb, GLenum mode_alpha) { + ptr.set_blend_equation_separate(mode_rgb, mode_alpha); } -void p_gl_rend_state::set_color_mask(GLboolean red, GLboolean green, - GLboolean blue, GLboolean alpha, bool force) { - ptr.set_color_mask(red, green, blue, alpha, force); +void p_gl_rend_state::set_color_mask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) { + ptr.set_color_mask(red, green, blue, alpha); } -void p_gl_rend_state::set_cull_face_mode(GLenum mode, bool force) { - ptr.set_cull_face_mode(mode, force); +void p_gl_rend_state::set_cull_face_mode(GLenum mode) { + ptr.set_cull_face_mode(mode); } -void p_gl_rend_state::set_depth_func(GLenum func, bool force) { - ptr.set_depth_func(func, force); +void p_gl_rend_state::set_depth_func(GLenum func) { + ptr.set_depth_func(func); } -void p_gl_rend_state::set_depth_mask(GLboolean flag, bool force) { - ptr.set_depth_mask(flag, force); +void p_gl_rend_state::set_depth_mask(GLboolean flag) { + ptr.set_depth_mask(flag); } -void p_gl_rend_state::set_line_width(GLfloat width, bool force) { - ptr.set_line_width(width, force); +void p_gl_rend_state::set_line_width(GLfloat width) { + ptr.set_line_width(width); } -void p_gl_rend_state::set_polygon_mode(GLenum face, GLenum mode, bool force) { - ptr.set_polygon_mode(face, mode, force); +void p_gl_rend_state::set_primitive_restart_index(GLuint index) { + ptr.set_primitive_restart_index(index); } -void p_gl_rend_state::set_primitive_restart_index(GLuint index, bool force) { - ptr.set_primitive_restart_index(index, force); +void p_gl_rend_state::set_scissor(const gl_rend_state_rect& rect) { + ptr.set_scissor(rect); } -void p_gl_rend_state::set_scissor(const gl_rend_state_rect& rect, bool force) { - ptr.set_scissor(rect, force); +void p_gl_rend_state::set_scissor(GLint x, GLint y, GLsizei width, GLsizei height) { + ptr.set_scissor(x, y, width, height); } -void p_gl_rend_state::set_scissor(GLint x, GLint y, GLsizei width, GLsizei height, bool force) { - ptr.set_scissor(x, y, width, height, force); +void p_gl_rend_state::set_stencil_func(GLenum func, GLint ref, GLuint mask) { + ptr.set_stencil_func(func, ref, mask); } -void p_gl_rend_state::set_stencil_func(GLenum func, GLint ref, GLuint mask, bool force) { - ptr.set_stencil_func(func, ref, mask, force); +void p_gl_rend_state::set_stencil_mask(GLuint mask) { + ptr.set_stencil_mask(mask); } -void p_gl_rend_state::set_stencil_mask(GLuint mask, bool force) { - ptr.set_stencil_mask(mask, force); +void p_gl_rend_state::set_stencil_op(GLenum sfail, GLenum dpfail, GLenum dppass) { + ptr.set_stencil_op(sfail, dpfail, dppass); } -void p_gl_rend_state::set_stencil_op(GLenum sfail, GLenum dpfail, GLenum dppass, bool force) { - ptr.set_stencil_op(sfail, dpfail, dppass, force); +void p_gl_rend_state::set_viewport(const gl_rend_state_rect& rect) { + ptr.set_viewport(rect); } -void p_gl_rend_state::set_viewport(const gl_rend_state_rect& rect, bool force) { - ptr.set_viewport(rect, force); +void p_gl_rend_state::set_viewport(GLint x, GLint y, GLsizei width, GLsizei height) { + ptr.set_viewport(x, y, width, height); } -void p_gl_rend_state::set_viewport(GLint x, GLint y, GLsizei width, GLsizei height, bool force) { - ptr.set_viewport(x, y, width, height, force); +void p_gl_rend_state::update() { + ptr.update(); } -void p_gl_rend_state::use_program(GLuint program, bool force) { - ptr.use_program(program, force); +void p_gl_rend_state::use_program(GLuint program) { + ptr.use_program(program); } -void gl_rend_state::active_bind_texture_2d(int32_t index, GLuint texture, bool force) { - if (force || texture_binding_2d[index] != texture) { - if (force || active_texture_index != index) { - glActiveTexture((GLenum)(GL_TEXTURE0 + index)); - active_texture_index = (GLuint)index; - } - glBindTexture(GL_TEXTURE_2D, texture); - texture_binding_2d[index] = texture; - } +inline void gl_rend_state::active_bind_texture_2d(int32_t index, GLuint texture) { + active_texture(index); + bind_texture_2d(texture); } -void gl_rend_state::active_bind_texture_cube_map(int32_t index, GLuint texture, bool force) { - if (force || texture_binding_cube_map[index] != texture) { - if (force || active_texture_index != index) { - glActiveTexture((GLenum)(GL_TEXTURE0 + index)); - active_texture_index = (GLuint)index; - } - glBindTexture(GL_TEXTURE_CUBE_MAP, texture); - texture_binding_cube_map[index] = texture; - } +inline void gl_rend_state::active_bind_texture_cube_map(int32_t index, GLuint texture) { + active_texture(index); + bind_texture_cube_map(texture); } -void gl_rend_state::active_texture(size_t index, bool force) { - if (force || active_texture_index != index) { - glActiveTexture((GLenum)(GL_TEXTURE0 + index)); - active_texture_index = (GLuint)index; - } +inline void gl_rend_state::active_texture(int32_t index) { + active_texture_index = index; + enum_or(update_flags, GL_REND_STATE_UPDATE_ACTIVE_TEXTURE); } -void gl_rend_state::begin_event(const char* message, int32_t length) { - glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, (GLsizei)length, message); +inline void gl_rend_state::begin_event(const char* message, int32_t length) { + if (GLAD_GL_VERSION_4_3) + glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, (GLsizei)length, message); } -void gl_rend_state::bind_framebuffer(GLuint framebuffer, bool force) { - if (force || read_framebuffer_binding != framebuffer - || draw_framebuffer_binding != framebuffer) { - glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); - read_framebuffer_binding = framebuffer; - draw_framebuffer_binding = framebuffer; - } +inline void gl_rend_state::bind_framebuffer(GLuint framebuffer) { + read_framebuffer_binding = framebuffer; + draw_framebuffer_binding = framebuffer; + enum_or(update_flags, GL_REND_STATE_UPDATE_DRAW_FRAMEBUFFER + | GL_REND_STATE_UPDATE_READ_FRAMEBUFFER); } -void gl_rend_state::bind_read_framebuffer(GLuint framebuffer, bool force) { - if (force || read_framebuffer_binding != framebuffer) { - glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer); - read_framebuffer_binding = framebuffer; - } +inline void gl_rend_state::bind_read_framebuffer(GLuint framebuffer) { + read_framebuffer_binding = framebuffer; + enum_or(update_flags, GL_REND_STATE_UPDATE_READ_FRAMEBUFFER); } -void gl_rend_state::bind_draw_framebuffer(GLuint framebuffer, bool force) { - if (force || draw_framebuffer_binding != framebuffer) { - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer); - draw_framebuffer_binding = framebuffer; - } +inline void gl_rend_state::bind_draw_framebuffer(GLuint framebuffer) { + draw_framebuffer_binding = framebuffer; + enum_or(update_flags, GL_REND_STATE_UPDATE_DRAW_FRAMEBUFFER); } -void gl_rend_state::bind_vertex_array(GLuint array, bool force) { - if (force || vertex_array_binding != array) { - glBindVertexArray(array); - vertex_array_binding = array; - } +inline void gl_rend_state::bind_vertex_array(GLuint array) { + vertex_array_binding = array; + enum_or(update_flags, GL_REND_STATE_UPDATE_VERTEX_ARRAY); } -void gl_rend_state::bind_array_buffer(GLuint buffer, bool force) { - if (force || array_buffer_binding != buffer) { +inline void gl_rend_state::bind_array_buffer(GLuint buffer) { + if (array_buffer_binding != buffer) { glBindBuffer(GL_ARRAY_BUFFER, buffer); array_buffer_binding = buffer; } } -void gl_rend_state::bind_element_array_buffer(GLuint buffer, bool force) { - if (force || element_array_buffer_binding != buffer) { +inline void gl_rend_state::bind_element_array_buffer(GLuint buffer) { + if (element_array_buffer_binding != buffer) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer); element_array_buffer_binding = buffer; } } -void gl_rend_state::bind_uniform_buffer(GLuint buffer, bool force) { - if (force || uniform_buffer_binding != buffer) { +inline void gl_rend_state::bind_uniform_buffer(GLuint buffer) { + if (uniform_buffer_binding != buffer) { glBindBuffer(GL_UNIFORM_BUFFER, buffer); uniform_buffer_binding = buffer; } } -void gl_rend_state::bind_uniform_buffer_base(GLuint index, GLuint buffer, bool force) { - if (force || uniform_buffer_bindings[index] != buffer) { - glBindBufferBase(GL_UNIFORM_BUFFER, index, buffer); - uniform_buffer_binding = buffer; - uniform_buffer_bindings[index] = buffer; - uniform_buffer_offsets[index] = 0; - uniform_buffer_sizes[index] = -1; - } +inline void gl_rend_state::bind_uniform_buffer_base(GLuint index, GLuint buffer) { + uniform_buffer_bindings[index] = buffer; + uniform_buffer_offsets[index] = 0; + uniform_buffer_sizes[index] = -1; + uniform_buffer_start_index = min_def(uniform_buffer_start_index, (int32_t)index); + uniform_buffer_end_index = max_def(uniform_buffer_end_index, (int32_t)index); + enum_or(update_flags, GL_REND_STATE_UPDATE_UNIFORM_BUFFER); } -void gl_rend_state::bind_uniform_buffer_range(GLuint index, - GLuint buffer, GLintptr offset, GLsizeiptr size, bool force) { - if (force || uniform_buffer_bindings[index] != buffer - || uniform_buffer_offsets[index] != offset - || uniform_buffer_sizes[index] != size) { - glBindBufferRange(GL_UNIFORM_BUFFER, index, buffer, offset, size); - uniform_buffer_binding = buffer; - uniform_buffer_bindings[index] = buffer; - uniform_buffer_offsets[index] = offset; - uniform_buffer_sizes[index] = size; - } +inline void gl_rend_state::bind_uniform_buffer_range(GLuint index, + GLuint buffer, GLintptr offset, GLsizeiptr size) { + uniform_buffer_bindings[index] = buffer; + uniform_buffer_offsets[index] = offset; + uniform_buffer_sizes[index] = size; + uniform_buffer_start_index = min_def(uniform_buffer_start_index, (int32_t)index); + uniform_buffer_end_index = max_def(uniform_buffer_end_index, (int32_t)index); + enum_or(update_flags, GL_REND_STATE_UPDATE_UNIFORM_BUFFER); } -void gl_rend_state::bind_shader_storage_buffer(GLuint buffer, bool force) { - if (force || shader_storage_buffer_binding != buffer) { +inline void gl_rend_state::bind_shader_storage_buffer(GLuint buffer) { + if (shader_storage_buffer_binding != buffer) { glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer); shader_storage_buffer_binding = buffer; } } -void gl_rend_state::bind_shader_storage_buffer_base(GLuint index, GLuint buffer, bool force) { - if (force || shader_storage_buffer_bindings[index] != buffer) { - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, index, buffer); - shader_storage_buffer_binding = buffer; - shader_storage_buffer_bindings[index] = buffer; - shader_storage_buffer_offsets[index] = 0; - shader_storage_buffer_sizes[index] = -1; +inline void gl_rend_state::bind_shader_storage_buffer_base(GLuint index, GLuint buffer) { + shader_storage_buffer_bindings[index] = buffer; + shader_storage_buffer_offsets[index] = 0; + shader_storage_buffer_sizes[index] = -1; + shader_storage_buffer_start_index = min_def(shader_storage_buffer_start_index, (int32_t)index); + shader_storage_buffer_end_index = max_def(shader_storage_buffer_end_index, (int32_t)index); + enum_or(update_flags, GL_REND_STATE_UPDATE_SHADER_STORAGE_BUFFER); +} + +inline void gl_rend_state::bind_shader_storage_buffer_range(GLuint index, + GLuint buffer, GLintptr offset, GLsizeiptr size) { + shader_storage_buffer_bindings[index] = buffer; + shader_storage_buffer_offsets[index] = offset; + shader_storage_buffer_sizes[index] = size; + shader_storage_buffer_start_index = min_def(shader_storage_buffer_start_index, (int32_t)index); + shader_storage_buffer_end_index = max_def(shader_storage_buffer_end_index, (int32_t)index); + enum_or(update_flags, GL_REND_STATE_UPDATE_SHADER_STORAGE_BUFFER); +} + +inline void gl_rend_state::bind_texture_2d(GLuint texture) { + texture_binding_2d[active_texture_index] = texture; + texture_binding_start_index = min_def(texture_binding_start_index, (int32_t)active_texture_index); + texture_binding_end_index = max_def(texture_binding_end_index, (int32_t)active_texture_index); + enum_or(update_flags, GL_REND_STATE_UPDATE_TEXTURE); +} + +inline void gl_rend_state::bind_texture_cube_map(GLuint texture) { + texture_binding_cube_map[active_texture_index] = texture; + texture_binding_start_index = min_def(texture_binding_start_index, (int32_t)active_texture_index); + texture_binding_end_index = max_def(texture_binding_end_index, (int32_t)active_texture_index); + enum_or(update_flags, GL_REND_STATE_UPDATE_TEXTURE); +} + +inline void gl_rend_state::bind_sampler(int32_t index, GLuint sampler) { + sampler_binding[index] = sampler; + sampler_binding_start_index = min_def(sampler_binding_start_index, (int32_t)index); + sampler_binding_end_index = max_def(sampler_binding_end_index, (int32_t)index); + enum_or(update_flags, GL_REND_STATE_UPDATE_SAMPLER); +} + +inline void gl_rend_state::blit_framebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, + GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { + update_read_framebuffer(); + update_draw_framebuffer(); + + if (mask & GL_COLOR_BUFFER_BIT) + update_color_mask(); + + if (mask & GL_DEPTH_BUFFER_BIT) { + update_depth_test(); + update_depth_mask(); + } + + if (mask & GL_STENCIL_BUFFER_BIT) { + update_stencil_test(); + update_stencil_mask(); + } + + glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); +} + +inline GLenum gl_rend_state::check_framebuffer_status(GLenum target) { + switch (target) { + case GL_READ_FRAMEBUFFER: + update_read_framebuffer(); + break; + case GL_DRAW_FRAMEBUFFER: + case GL_FRAMEBUFFER: + update_draw_framebuffer(); + break; + } + + return glCheckFramebufferStatus(target); +} + +inline void gl_rend_state::clear(GLbitfield mask) { + update_draw_framebuffer(); + + if (mask & GL_COLOR_BUFFER_BIT) + update_color_mask(); + + if (mask & GL_DEPTH_BUFFER_BIT) { + update_depth_test(); + update_depth_mask(); + } + + update_scissor_test(); + update_scissor(); + + if (mask & GL_STENCIL_BUFFER_BIT) { + update_stencil_test(); + update_stencil_mask(); + } + + if (mask & GL_COLOR_BUFFER_BIT) + update_clear_color(); + + if (mask & GL_DEPTH_BUFFER_BIT) + update_clear_depth(); + + if (mask & GL_STENCIL_BUFFER_BIT) + update_clear_stencil(); + + glClear(mask); + enum_or(flags, GL_REND_STATE_EXECUTE); +} + +inline void gl_rend_state::clear_buffer(GLenum buffer, GLint drawbuffer, const GLfloat* value) { + update_draw_framebuffer(); + + glClearBufferfv(buffer, drawbuffer, value); + enum_or(flags, GL_REND_STATE_EXECUTE); +} + +inline void gl_rend_state::clear_color(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { + clear_color_value[0] = red; + clear_color_value[1] = green; + clear_color_value[2] = blue; + clear_color_value[3] = alpha; + enum_or(update_flags, GL_REND_STATE_UPDATE_CLEAR_COLOR); +} + +inline void gl_rend_state::clear_depth(GLfloat depth) { + clear_depth_value = depth; + enum_or(update_flags, GL_REND_STATE_UPDATE_CLEAR_DEPTH); +} + +inline void gl_rend_state::clear_stencil(GLint stencil) { + clear_stencil_value = stencil; + enum_or(update_flags, GL_REND_STATE_UPDATE_CLEAR_STENCIL); +} + +inline void gl_rend_state::copy_image_sub_data(GLuint srcName, GLenum srcTarget, GLint srcLevel, + GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, + GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth) { + glCopyImageSubData(srcName, srcTarget, srcLevel, srcX, srcY, srcZ, + dstName, dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight, srcDepth); + enum_or(flags, GL_REND_STATE_EXECUTE); +} + +inline void gl_rend_state::copy_tex_sub_image_2d(GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) { + update_active_texture(); + update_curr_active_texture(); + update_read_framebuffer(); + glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); + enum_or(flags, GL_REND_STATE_EXECUTE); +} + +inline void gl_rend_state::disable_blend() { + blend = GL_FALSE; + enum_or(update_flags, GL_REND_STATE_UPDATE_BLEND); +} + +inline void gl_rend_state::disable_cull_face() { + cull_face = GL_FALSE; + enum_or(update_flags, GL_REND_STATE_UPDATE_CULL_FACE); +} + +inline void gl_rend_state::disable_depth_test() { + depth_test = GL_FALSE; + enum_or(update_flags, GL_REND_STATE_UPDATE_DEPTH_TEST); +} + +inline void gl_rend_state::disable_multisample() { + multisample = GL_FALSE; + enum_or(update_flags, GL_REND_STATE_UPDATE_MULTISAMPLE); +} + +inline void gl_rend_state::disable_primitive_restart() { + primitive_restart = GL_FALSE; + enum_or(update_flags, GL_REND_STATE_UPDATE_PRIMITIVE_RESTART); +} + +inline void gl_rend_state::disable_scissor_test() { + scissor_test = GL_FALSE; + enum_or(update_flags, GL_REND_STATE_UPDATE_SCISSOR_TEST); +} + +inline void gl_rend_state::disable_stencil_test() { + stencil_test = GL_FALSE; + enum_or(update_flags, GL_REND_STATE_UPDATE_STENCIL_TEST); +} + +inline void gl_rend_state::draw_arrays(GLenum mode, GLint first, GLsizei count) { + update(); + glDrawArrays(mode, first, count); +} + +inline void gl_rend_state::draw_elements(GLenum mode, + GLsizei count, GLenum type, const void* indices) { + switch (mode) { + case GL_TRIANGLE_STRIP: + uint32_t index; + switch (type) { + case GL_UNSIGNED_BYTE: + index = 0xFF; + break; + case GL_UNSIGNED_SHORT: + index = 0xFFFF; + break; + case GL_UNSIGNED_INT: + default: + index = 0xFFFFFFFF; + break; + } + + enable_primitive_restart(); + set_primitive_restart_index(index); + break; + } + + update(); + glDrawElements(mode, count, type, indices); + + switch (mode) { + case GL_TRIANGLE_STRIP: + disable_primitive_restart(); + break; } } -void gl_rend_state::bind_shader_storage_buffer_range(GLuint index, - GLuint buffer, GLintptr offset, GLsizeiptr size, bool force) { - if (force || shader_storage_buffer_bindings[index] != buffer - || shader_storage_buffer_offsets[index] != offset - || shader_storage_buffer_sizes[index] != size) { - glBindBufferRange(GL_SHADER_STORAGE_BUFFER, index, buffer, offset, size); - shader_storage_buffer_binding = buffer; - shader_storage_buffer_bindings[index] = buffer; - shader_storage_buffer_offsets[index] = offset; - shader_storage_buffer_sizes[index] = size; +inline void gl_rend_state::draw_range_elements(GLenum mode, + GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices) { + switch (mode) { + case GL_TRIANGLE_STRIP: + uint32_t index; + switch (type) { + case GL_UNSIGNED_BYTE: + index = 0xFF; + break; + case GL_UNSIGNED_SHORT: + index = 0xFFFF; + break; + case GL_UNSIGNED_INT: + default: + index = 0xFFFFFFFF; + break; + } + + enable_primitive_restart(); + set_primitive_restart_index(index); + break; + } + + update(); + glDrawRangeElements(mode, start, end, count, type, indices); + + switch (mode) { + case GL_TRIANGLE_STRIP: + disable_primitive_restart(); + break; } } -void gl_rend_state::bind_texture_2d(GLuint texture, bool force) { - if (texture_binding_2d[active_texture_index] != texture) { - glBindTexture(GL_TEXTURE_2D, texture); - texture_binding_2d[active_texture_index] = texture; - } +inline void gl_rend_state::enable_blend() { + blend = GL_TRUE; + enum_or(update_flags, GL_REND_STATE_UPDATE_BLEND); } -void gl_rend_state::bind_texture_cube_map(GLuint texture, bool force) { - if (force || texture_binding_cube_map[active_texture_index] != texture) { - glBindTexture(GL_TEXTURE_CUBE_MAP, texture); - texture_binding_cube_map[active_texture_index] = texture; - } +inline void gl_rend_state::enable_cull_face() { + cull_face = GL_TRUE; + enum_or(update_flags, GL_REND_STATE_UPDATE_CULL_FACE); } -void gl_rend_state::bind_sampler(int32_t index, GLuint sampler, bool force) { - if (force || sampler_binding[index] != sampler) { - glBindSampler(index, sampler); - sampler_binding[index] = sampler; - } +inline void gl_rend_state::enable_depth_test() { + depth_test = GL_TRUE; + enum_or(update_flags, GL_REND_STATE_UPDATE_DEPTH_TEST); } -bool gl_rend_state::check_uniform_buffer_binding() { - return uniform_buffer_binding != 0; +inline void gl_rend_state::enable_multisample() { + multisample = GL_TRUE; + enum_or(update_flags, GL_REND_STATE_UPDATE_MULTISAMPLE); } -bool gl_rend_state::check_uniform_buffer_binding_base(size_t index) { - return uniform_buffer_bindings[index] != 0; +inline void gl_rend_state::enable_primitive_restart() { + primitive_restart = GL_TRUE; + enum_or(update_flags, GL_REND_STATE_UPDATE_PRIMITIVE_RESTART); } -bool gl_rend_state::check_shader_storage_buffer_binding() { - return shader_storage_buffer_binding != 0; +inline void gl_rend_state::enable_scissor_test() { + scissor_test = GL_TRUE; + enum_or(update_flags, GL_REND_STATE_UPDATE_SCISSOR_TEST); } -bool gl_rend_state::check_shader_storage_buffer_binding_base(size_t index) { - return shader_storage_buffer_bindings[index] != 0; +inline void gl_rend_state::enable_stencil_test() { + stencil_test = GL_TRUE; + enum_or(update_flags, GL_REND_STATE_UPDATE_STENCIL_TEST); } -bool gl_rend_state::check_texture_binding_2d(size_t index) { - return texture_binding_2d[index] != 0; +inline void gl_rend_state::end_event() { + if (GLAD_GL_VERSION_4_3) + glPopDebugGroup(); } -bool gl_rend_state::check_texture_binding_cube_map(size_t index) { - return texture_binding_cube_map[index] != 0; +inline void gl_rend_state::generate_mipmap(GLenum target) { + update_curr_active_texture(); + glGenerateMipmap(target); + enum_or(flags, GL_REND_STATE_EXECUTE); } -bool gl_rend_state::check_sampler_binding(int32_t index, GLuint sampler) { - return sampler_binding[index] != 0; -} - -void gl_rend_state::disable_blend(bool force) { - if (force || blend) { - glDisable(GL_BLEND); - blend = GL_FALSE; - } -} - -void gl_rend_state::disable_cull_face(bool force) { - if (force || cull_face) { - glDisable(GL_CULL_FACE); - cull_face = GL_FALSE; - } -} - -void gl_rend_state::disable_depth_test(bool force) { - if (force || depth_test) { - glDisable(GL_DEPTH_TEST); - depth_test = GL_FALSE; - } -} - -void gl_rend_state::disable_multisample(bool force) { - if (force || multisample) { - glDisable(GL_MULTISAMPLE); - multisample = GL_FALSE; - } -} - -void gl_rend_state::disable_primitive_restart(bool force) { - if (force || primitive_restart) { - glDisable(GL_PRIMITIVE_RESTART); - primitive_restart = GL_FALSE; - } -} - -void gl_rend_state::disable_scissor_test(bool force) { - if (force || scissor_test) { - glDisable(GL_SCISSOR_TEST); - scissor_test = GL_FALSE; - } -} - -void gl_rend_state::disable_stencil_test(bool force) { - if (force || stencil_test) { - glDisable(GL_STENCIL_TEST); - stencil_test = GL_FALSE; - } -} - -void gl_rend_state::enable_blend(bool force) { - if (force || !blend) { - glEnable(GL_BLEND); - blend = GL_TRUE; - } -} - -void gl_rend_state::enable_cull_face(bool force) { - if (force || !cull_face) { - glEnable(GL_CULL_FACE); - cull_face = GL_TRUE; - } -} - -void gl_rend_state::enable_depth_test(bool force) { - if (force || !depth_test) { - glEnable(GL_DEPTH_TEST); - depth_test = GL_TRUE; - } -} - -void gl_rend_state::enable_multisample(bool force) { - if (force || !multisample) { - glEnable(GL_MULTISAMPLE); - multisample = GL_TRUE; - } -} - -void gl_rend_state::enable_primitive_restart(bool force) { - if (force || !primitive_restart) { - glEnable(GL_PRIMITIVE_RESTART); - primitive_restart = GL_TRUE; - } -} - -void gl_rend_state::enable_scissor_test(bool force) { - if (force || !scissor_test) { - glEnable(GL_SCISSOR_TEST); - scissor_test = GL_TRUE; - } -} - -void gl_rend_state::enable_stencil_test(bool force) { - if (force || !stencil_test) { - glEnable(GL_STENCIL_TEST); - stencil_test = GL_TRUE; - } +inline void gl_rend_state::generate_texture_mipmap(GLuint texture) { + glGenerateTextureMipmap(texture); + enum_or(flags, GL_REND_STATE_EXECUTE); } void gl_rend_state::get() { glGetIntegerv(GL_CURRENT_PROGRAM, (GLint*)&program); + GLenum active_texture = GL_TEXTURE0; glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint*)&active_texture); active_texture_index = active_texture - GL_TEXTURE0; + texture_binding_start_index = 32; + texture_binding_end_index = -1; + sampler_binding_start_index = 32; + sampler_binding_end_index = -1; + if (GLAD_GL_VERSION_4_5) { for (GLuint i = 0; i < 32; i++) { glGetIntegeri_v(GL_TEXTURE_BINDING_2D, i, (GLint*)&texture_binding_2d[i]); @@ -787,10 +1048,15 @@ void gl_rend_state::get() { glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, (GLint*)&read_framebuffer_binding); glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, (GLint*)&draw_framebuffer_binding); + glGetIntegerv(GL_VERTEX_ARRAY_BINDING, (GLint*)&vertex_array_binding); + glGetIntegerv(GL_ARRAY_BUFFER_BINDING, (GLint*)&array_buffer_binding); glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, (GLint*)&element_array_buffer_binding); + uniform_buffer_start_index = 14; + uniform_buffer_end_index = -1; + glGetIntegerv(GL_UNIFORM_BUFFER_BINDING, (GLint*)&uniform_buffer_binding); for (GLuint i = 0; i < 14; i++) { glGetIntegeri_v(GL_UNIFORM_BUFFER_BINDING, i, (GLint*)&uniform_buffer_bindings[i]); @@ -798,6 +1064,9 @@ void gl_rend_state::get() { glGetInteger64i_v(GL_UNIFORM_BUFFER_SIZE, i, (GLint64*)&uniform_buffer_sizes[i]); } + shader_storage_buffer_start_index = 14; + shader_storage_buffer_end_index = -1; + glGetIntegerv(GL_SHADER_STORAGE_BUFFER_BINDING, (GLint*)&shader_storage_buffer_binding); for (GLuint i = 0; i < 14; i++) { glGetIntegeri_v(GL_SHADER_STORAGE_BUFFER_BINDING, i, (GLint*)&shader_storage_buffer_bindings[i]); @@ -806,17 +1075,24 @@ void gl_rend_state::get() { } glGetBooleanv(GL_COLOR_WRITEMASK, color_mask); + glGetBooleanv(GL_CULL_FACE, &cull_face); glGetIntegerv(GL_CULL_FACE_MODE, (GLint*)&cull_face_mode); + glGetBooleanv(GL_DEPTH_TEST, &depth_test); glGetIntegerv(GL_DEPTH_FUNC, (GLint*)&depth_func); glGetBooleanv(GL_DEPTH_WRITEMASK, &depth_mask); + glGetFloatv(GL_LINE_WIDTH, &line_width); + glGetBooleanv(GL_MULTISAMPLE, &multisample); + glGetBooleanv(GL_PRIMITIVE_RESTART, &primitive_restart); glGetIntegerv(GL_PRIMITIVE_RESTART_INDEX, (GLint*)&primitive_restart_index); + glGetIntegerv(GL_SCISSOR_BOX, (GLint*)&scissor_box); glGetBooleanv(GL_SCISSOR_TEST, &scissor_test); + glGetBooleanv(GL_STENCIL_TEST, &stencil_test); glGetIntegerv(GL_STENCIL_FUNC, (GLint*)&stencil_func); glGetIntegerv(GL_STENCIL_VALUE_MASK, (GLint*)&stencil_value_mask); @@ -825,217 +1101,711 @@ void gl_rend_state::get() { glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, (GLint*)&stencil_dppass); glGetIntegerv(GL_STENCIL_REF, &stencil_ref); glGetIntegerv(GL_STENCIL_WRITEMASK, (GLint*)&stencil_mask); + glGetIntegerv(GL_VIEWPORT, (GLint*)&viewport); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - polygon_mode = GL_FILL; + glGetFloatv(GL_COLOR_CLEAR_VALUE, clear_color_value); + + glGetFloatv(GL_DEPTH_CLEAR_VALUE, &clear_depth_value); + + glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &clear_stencil_value); + + curr_program = program; + + curr_active_texture_index = active_texture_index; + + for (GLuint i = 0; i < 32; i++) { + curr_texture_binding_2d[i] = texture_binding_2d[i]; + curr_texture_binding_cube_map[i] = texture_binding_cube_map[i]; + curr_sampler_binding[i] = sampler_binding[i]; + } + + curr_blend = blend; + curr_blend_src_rgb = blend_src_rgb; + curr_blend_src_alpha = blend_src_alpha; + curr_blend_dst_rgb = blend_dst_rgb; + curr_blend_dst_alpha = blend_dst_alpha; + curr_blend_mode_rgb = blend_mode_rgb; + curr_blend_mode_alpha = blend_mode_alpha; + + curr_read_framebuffer_binding = read_framebuffer_binding; + curr_draw_framebuffer_binding = draw_framebuffer_binding; + + curr_vertex_array_binding = vertex_array_binding; + + for (GLuint i = 0; i < 14; i++) { + curr_uniform_buffer_bindings[i] = uniform_buffer_bindings[i]; + curr_uniform_buffer_offsets[i] = uniform_buffer_offsets[i]; + curr_uniform_buffer_sizes[i] = uniform_buffer_sizes[i]; + } + + for (GLuint i = 0; i < 14; i++) { + curr_shader_storage_buffer_bindings[i] = shader_storage_buffer_bindings[i]; + curr_shader_storage_buffer_offsets[i] = shader_storage_buffer_offsets[i]; + curr_shader_storage_buffer_sizes[i] = shader_storage_buffer_sizes[i]; + } + + memcpy(curr_color_mask, color_mask, sizeof(GLboolean) * 4); + + curr_cull_face = cull_face; + curr_cull_face_mode = cull_face_mode; + + curr_depth_test = depth_test; + curr_depth_func = depth_func; + curr_depth_mask = depth_mask; + + curr_line_width = line_width; + curr_multisample = multisample; + + curr_primitive_restart = primitive_restart; + curr_primitive_restart_index = primitive_restart_index; + + curr_scissor_box = scissor_box; + curr_scissor_test = scissor_test; + + curr_stencil_test = stencil_test; + curr_stencil_func = stencil_func; + curr_stencil_value_mask = stencil_value_mask; + curr_stencil_fail = stencil_fail; + curr_stencil_dpfail = stencil_dpfail; + curr_stencil_dppass = stencil_dppass; + curr_stencil_ref = stencil_ref; + curr_stencil_mask = stencil_mask; + + curr_viewport = viewport; + + memcpy(curr_clear_color_value, clear_color_value, sizeof(GLboolean) * 4); + curr_clear_depth_value = clear_depth_value; + curr_clear_stencil_value = clear_stencil_value; + + flags = (gl_rend_state_flags)0; + update_flags = (gl_rend_state_update_flags)0; } -void gl_rend_state::end_event() { - glPopDebugGroup(); +inline void gl_rend_state::get_clear_color(GLfloat& red, GLfloat& green, GLfloat& blue, GLfloat& alpha) { + red = clear_color_value[0]; + green = clear_color_value[1]; + blue = clear_color_value[2]; + alpha = clear_color_value[3]; } -GLuint gl_rend_state::get_program() { +inline GLuint gl_rend_state::get_program() { return program; } -gl_rend_state_rect gl_rend_state::get_scissor() { +inline gl_rend_state_rect gl_rend_state::get_scissor() { return scissor_box; } -void gl_rend_state::get_scissor(GLint& x, GLint& y, GLsizei& width, GLsizei& height) { +inline void gl_rend_state::get_scissor(GLint& x, GLint& y, GLsizei& width, GLsizei& height) { x = scissor_box.x; y = scissor_box.y; width = scissor_box.width; height = scissor_box.height; } -gl_rend_state_rect gl_rend_state::get_viewport() { +inline gl_rend_state_rect gl_rend_state::get_viewport() { return viewport; } -void gl_rend_state::get_viewport(GLint& x, GLint& y, GLsizei& width, GLsizei& height) { +inline void gl_rend_state::get_viewport(GLint& x, GLint& y, GLsizei& width, GLsizei& height) { x = viewport.x; y = viewport.y; width = viewport.width; height = viewport.height; } -void gl_rend_state::set_blend_func(GLenum src, GLenum dst, bool force) { - if (force || blend_src_rgb != src || blend_dst_rgb != dst - || blend_src_alpha != GL_ONE || blend_dst_alpha != GL_ONE_MINUS_SRC_ALPHA) { - glBlendFuncSeparate(src, dst, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - blend_src_rgb = src; - blend_dst_rgb = dst; - blend_src_alpha = GL_ONE; - blend_dst_alpha = GL_ONE_MINUS_SRC_ALPHA; - } +inline void gl_rend_state::set_blend_func(GLenum src, GLenum dst) { + blend_src_rgb = src; + blend_dst_rgb = dst; + blend_src_alpha = GL_ONE; + blend_dst_alpha = GL_ONE_MINUS_SRC_ALPHA; + enum_or(update_flags, GL_REND_STATE_UPDATE_BLEND_FUNC); } -void gl_rend_state::set_blend_func_separate(GLenum src_rgb, GLenum dst_rgb, - GLenum src_alpha, GLenum dst_alpha, bool force) { - if (force || blend_src_rgb != src_rgb || blend_dst_rgb != dst_rgb - || blend_src_alpha != src_alpha || blend_dst_alpha != dst_alpha) { - glBlendFuncSeparate(src_rgb, dst_rgb, src_alpha, dst_alpha); - blend_src_rgb = src_rgb; - blend_dst_rgb = dst_rgb; - blend_src_alpha = src_alpha; - blend_dst_alpha = dst_alpha; - } +inline void gl_rend_state::set_blend_func_separate(GLenum src_rgb, GLenum dst_rgb, + GLenum src_alpha, GLenum dst_alpha) { + blend_src_rgb = src_rgb; + blend_dst_rgb = dst_rgb; + blend_src_alpha = src_alpha; + blend_dst_alpha = dst_alpha; + enum_or(update_flags, GL_REND_STATE_UPDATE_BLEND_FUNC); } -void gl_rend_state::set_blend_equation(GLenum mode, bool force) { - if (force || blend_mode_rgb != mode || blend_mode_alpha != mode) { - glBlendEquationSeparate(mode, mode); - blend_mode_rgb = mode; - blend_mode_alpha = mode; - } +inline void gl_rend_state::set_blend_equation(GLenum mode) { + blend_mode_rgb = mode; + blend_mode_alpha = mode; + enum_or(update_flags, GL_REND_STATE_UPDATE_BLEND_EQUATION); } -void gl_rend_state::set_blend_equation_separate(GLenum mode_rgb, GLenum mode_alpha, bool force) { - if (force || blend_mode_rgb != mode_rgb || blend_mode_alpha != mode_alpha) { - glBlendEquationSeparate(mode_rgb, mode_alpha); - blend_mode_rgb = mode_rgb; - blend_mode_alpha = mode_alpha; - } +inline void gl_rend_state::set_blend_equation_separate(GLenum mode_rgb, GLenum mode_alpha) { + blend_mode_rgb = mode_rgb; + blend_mode_alpha = mode_alpha; + enum_or(update_flags, GL_REND_STATE_UPDATE_BLEND_EQUATION); } -void gl_rend_state::set_color_mask(GLboolean red, GLboolean green, - GLboolean blue, GLboolean alpha, bool force) { - if (force || color_mask[0] != red || color_mask[1] != green - || color_mask[2] != blue || color_mask[3] != alpha) { - glColorMask(red, green, blue, alpha); - color_mask[0] = red; - color_mask[1] = green; - color_mask[2] = blue; - color_mask[3] = alpha; - } +inline void gl_rend_state::set_color_mask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) { + color_mask[0] = red; + color_mask[1] = green; + color_mask[2] = blue; + color_mask[3] = alpha; + enum_or(update_flags, GL_REND_STATE_UPDATE_COLOR_MASK); } -void gl_rend_state::set_cull_face_mode(GLenum mode, bool force) { - if (force || cull_face_mode != mode) { - glCullFace(mode); - cull_face_mode = mode; - } +inline void gl_rend_state::set_cull_face_mode(GLenum mode) { + cull_face_mode = mode; + enum_or(update_flags, GL_REND_STATE_UPDATE_CULL_FACE_MODE); } -void gl_rend_state::set_depth_func(GLenum func, bool force) { - if (force || depth_func != func) { - glDepthFunc(func); - depth_func = func; - } +inline void gl_rend_state::set_depth_func(GLenum func) { + depth_func = func; + enum_or(update_flags, GL_REND_STATE_UPDATE_DEPTH_FUNC); } -void gl_rend_state::set_depth_mask(GLboolean flag, bool force) { - if (force || depth_mask != flag) { - glDepthMask(flag); - depth_mask = flag; - } +inline void gl_rend_state::set_depth_mask(GLboolean flag) { + depth_mask = flag; + enum_or(update_flags, GL_REND_STATE_UPDATE_DEPTH_MASK); } -void gl_rend_state::set_line_width(GLfloat width, bool force) { - if (force || line_width != width) { - glLineWidth(width); - line_width = width; - } +inline void gl_rend_state::set_line_width(GLfloat width) { + line_width = width; + enum_or(update_flags, GL_REND_STATE_UPDATE_LINE_WIDTH); } -void gl_rend_state::set_polygon_mode(GLenum face, GLenum mode, bool force) { - switch (face) { - case GL_FRONT: - if (force || polygon_mode != mode) { - glPolygonMode(GL_FRONT, mode); - polygon_mode = mode; +inline void gl_rend_state::set_primitive_restart_index(GLuint index) { + primitive_restart_index = index; + enum_or(update_flags, GL_REND_STATE_UPDATE_PRIMITIVE_RESTART_INDEX); +} + +inline void gl_rend_state::set_scissor(const gl_rend_state_rect& rect) { + scissor_box = rect; + enum_or(update_flags, GL_REND_STATE_UPDATE_SCISSOR); +} + +inline void gl_rend_state::set_scissor(GLint x, GLint y, GLsizei width, GLsizei height) { + scissor_box.x = x; + scissor_box.y = y; + scissor_box.width = width; + scissor_box.height = height; + enum_or(update_flags, GL_REND_STATE_UPDATE_SCISSOR); +} + +inline void gl_rend_state::set_stencil_func(GLenum func, GLint ref, GLuint mask) { + stencil_func = func; + stencil_ref = ref; + stencil_value_mask = mask; + enum_or(update_flags, GL_REND_STATE_UPDATE_STENCIL_FUNC); +} + +inline void gl_rend_state::set_stencil_mask(GLuint mask) { + stencil_mask = mask; + enum_or(update_flags, GL_REND_STATE_UPDATE_STENCIL_MASK); +} + +inline void gl_rend_state::set_stencil_op(GLenum sfail, GLenum dpfail, GLenum dppass) { + stencil_fail = sfail; + stencil_dpfail = dpfail; + stencil_dppass = dppass; + enum_or(update_flags, GL_REND_STATE_UPDATE_STENCIL_OP); +} + +inline void gl_rend_state::set_viewport(const gl_rend_state_rect& rect) { + viewport = rect; + enum_or(update_flags, GL_REND_STATE_UPDATE_VIEWPORT); +} + +inline void gl_rend_state::set_viewport(GLint x, GLint y, GLsizei width, GLsizei height) { + viewport.x = x; + viewport.y = y; + viewport.width = width; + viewport.height = height; + enum_or(update_flags, GL_REND_STATE_UPDATE_VIEWPORT); +} + +void gl_rend_state::update() { + if (!update_flags) + return; + + update_program(); + update_texture(); + update_active_texture(); + update_sampler(); + update_blend(); + update_blend_func(); + update_blend_equation(); + update_read_framebuffer(); + update_draw_framebuffer(); + update_vertex_array(); + update_uniform_buffer(); + update_shader_storage_buffer(); + update_color_mask(); + update_cull_face(); + update_cull_face_mode(); + update_depth_test(); + update_depth_mask(); + update_depth_func(); + update_line_width(); + update_multisample(); + update_primitive_restart(); + update_primitive_restart_index(); + update_scissor_test(); + update_scissor(); + update_stencil_test(); + update_stencil_mask(); + update_stencil_func(); + update_stencil_op(); + update_viewport(); + update_clear_color(); + update_clear_depth(); + update_clear_stencil(); + + enum_or(flags, GL_REND_STATE_EXECUTE); +} + +inline void gl_rend_state::update_program() { + if (update_flags & GL_REND_STATE_UPDATE_PROGRAM) { + if (curr_program != program) { + glUseProgram(program); + curr_program = program; } - break; - case GL_BACK: - if (force || polygon_mode != mode) { - glPolygonMode(GL_BACK, mode); - polygon_mode = mode; + enum_and(update_flags, ~GL_REND_STATE_UPDATE_PROGRAM); + } +} + +inline void gl_rend_state::update_active_texture() { + if (update_flags & GL_REND_STATE_UPDATE_ACTIVE_TEXTURE) { + if (curr_active_texture_index != active_texture_index) { + glActiveTexture((GLenum)(GL_TEXTURE0 + active_texture_index)); + curr_active_texture_index = active_texture_index; } - break; - case GL_FRONT_AND_BACK: - if (force || polygon_mode != mode) { - glPolygonMode(GL_FRONT_AND_BACK, mode); - polygon_mode = mode; + enum_and(update_flags, ~GL_REND_STATE_UPDATE_ACTIVE_TEXTURE); + } +} + +inline void gl_rend_state::update_curr_active_texture() { + if (update_flags & GL_REND_STATE_UPDATE_TEXTURE) { + GLuint index = curr_active_texture_index; + bool bind = false; + if (curr_texture_binding_2d[index] != texture_binding_2d[index]) { + glBindTexture(GL_TEXTURE_2D, texture_binding_2d[curr_active_texture_index]); + curr_texture_binding_2d[index] = texture_binding_2d[index]; + bind = true; + } + else if (curr_texture_binding_cube_map[index] != texture_binding_cube_map[index]) { + glBindTexture(GL_TEXTURE_CUBE_MAP, texture_binding_cube_map[index]); + curr_texture_binding_cube_map[index] = texture_binding_cube_map[index]; + bind = true; + } + + if (bind) { + if (texture_binding_start_index == curr_active_texture_index) + texture_binding_start_index++; + else if (texture_binding_end_index == curr_active_texture_index) + texture_binding_end_index--; + + if (texture_binding_start_index > texture_binding_end_index) { + texture_binding_start_index = 32; + texture_binding_end_index = -1; + enum_and(update_flags, ~GL_REND_STATE_UPDATE_TEXTURE); + } } - break; } } -void gl_rend_state::set_primitive_restart_index(GLuint index, bool force) { - if (force || primitive_restart_index != index) { - glPrimitiveRestartIndex(index); - primitive_restart_index = index; +inline void gl_rend_state::update_texture() { + if (update_flags & GL_REND_STATE_UPDATE_TEXTURE) { + for (int32_t index = texture_binding_start_index; + index <= texture_binding_end_index; index++) + if (curr_texture_binding_2d[index] != texture_binding_2d[index]) { + if (GLAD_GL_VERSION_4_5) + glBindTextureUnit(index, texture_binding_2d[index]); + else { + if (curr_active_texture_index != index) + glActiveTexture((GLenum)(GL_TEXTURE0 + index)); + + glBindTexture(GL_TEXTURE_2D, texture_binding_2d[index]); + curr_active_texture_index = index; + } + curr_texture_binding_2d[index] = texture_binding_2d[index]; + } + else if (curr_texture_binding_cube_map[index] != texture_binding_cube_map[index]) { + if (GLAD_GL_VERSION_4_5) + glBindTextureUnit(index, texture_binding_cube_map[index]); + else { + if (curr_active_texture_index != index) + glActiveTexture((GLenum)(GL_TEXTURE0 + index)); + + glBindTexture(GL_TEXTURE_CUBE_MAP, texture_binding_cube_map[index]); + curr_active_texture_index = index; + } + curr_texture_binding_cube_map[index] = texture_binding_cube_map[index]; + } + + texture_binding_start_index = 32; + texture_binding_end_index = -1; + enum_and(update_flags, ~GL_REND_STATE_UPDATE_TEXTURE); } } -void gl_rend_state::set_scissor(const gl_rend_state_rect& rect, bool force) { - if (force || scissor_box.x != rect.x || scissor_box.y != rect.y - || scissor_box.width != rect.width || scissor_box.height != rect.height) { - glScissor(rect.x, rect.y, rect.width, rect.height); - scissor_box = rect; +inline void gl_rend_state::update_sampler() { + if (update_flags & GL_REND_STATE_UPDATE_SAMPLER) { + for (int32_t index = sampler_binding_start_index; + index <= sampler_binding_end_index; index++) + if (curr_sampler_binding[index] != sampler_binding[index]) { + glBindSampler(index, sampler_binding[index]); + curr_sampler_binding[index] = sampler_binding[index]; + } + + sampler_binding_start_index = 32; + sampler_binding_end_index = -1; + enum_and(update_flags, ~GL_REND_STATE_UPDATE_SAMPLER); } } -void gl_rend_state::set_scissor(GLint x, GLint y, GLsizei width, GLsizei height, bool force) { - if (force || scissor_box.x != x || scissor_box.y != y - || scissor_box.width != width || scissor_box.height != height) { - glScissor(x, y, width, height); - scissor_box.x = x; - scissor_box.y = y; - scissor_box.width = width; - scissor_box.height = height; +inline void gl_rend_state::update_blend() { + if (update_flags & GL_REND_STATE_UPDATE_BLEND) { + if (curr_blend != blend) { + (blend ? glEnable : glDisable)(GL_BLEND); + curr_blend = blend; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_BLEND); } } -void gl_rend_state::set_stencil_func(GLenum func, GLint ref, GLuint mask, bool force) { - if (force || stencil_func != func || stencil_ref != ref || stencil_value_mask != mask) { - glStencilFunc(func, ref, mask); - stencil_func = func; - stencil_ref = ref; - stencil_value_mask = mask; +inline void gl_rend_state::update_blend_func() { + if (curr_blend && (update_flags & GL_REND_STATE_UPDATE_BLEND_FUNC)) { + if (curr_blend_src_rgb != blend_src_rgb || curr_blend_dst_rgb != blend_dst_rgb + || curr_blend_src_alpha != blend_src_alpha || curr_blend_dst_alpha != blend_dst_alpha) { + glBlendFuncSeparate(blend_src_rgb, blend_dst_rgb, blend_src_alpha, blend_dst_alpha); + curr_blend_src_rgb = blend_src_rgb; + curr_blend_dst_rgb = blend_dst_rgb; + curr_blend_src_alpha = blend_src_alpha; + curr_blend_dst_alpha = blend_dst_alpha; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_BLEND_FUNC); } } -void gl_rend_state::set_stencil_mask(GLuint mask, bool force) { - if (force || stencil_mask != mask) { - glStencilMask(mask); - stencil_mask = mask; +inline void gl_rend_state::update_blend_equation() { + if (curr_blend && (update_flags & GL_REND_STATE_UPDATE_BLEND_EQUATION)) { + if (curr_blend_mode_rgb != blend_mode_rgb || curr_blend_mode_alpha != blend_mode_alpha) { + glBlendEquationSeparate(blend_mode_rgb, blend_mode_alpha); + curr_blend_mode_rgb = blend_mode_rgb; + curr_blend_mode_alpha = blend_mode_alpha; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_BLEND_EQUATION); } } -void gl_rend_state::set_stencil_op(GLenum sfail, GLenum dpfail, GLenum dppass, bool force) { - if (force || stencil_fail != sfail || stencil_dpfail != dpfail || stencil_dppass != dppass) { - glStencilOp(sfail, dpfail, dppass); - stencil_fail = sfail; - stencil_dpfail = dpfail; - stencil_dppass = dppass; +inline void gl_rend_state::update_read_framebuffer() { + if (update_flags & GL_REND_STATE_UPDATE_READ_FRAMEBUFFER) { + if (curr_read_framebuffer_binding != read_framebuffer_binding) { + glBindFramebuffer(GL_READ_FRAMEBUFFER, read_framebuffer_binding); + if (read_framebuffer_binding) { + GLenum status = glCheckFramebufferStatus(GL_READ_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) + printf_debug("GL Error: Bind Read Framebuffer Status - 0x%04X\n", status); + gl_get_error_print(); + } + curr_read_framebuffer_binding = read_framebuffer_binding; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_READ_FRAMEBUFFER); } } -void gl_rend_state::set_viewport(const gl_rend_state_rect& rect, bool force) { - if (force || viewport.x != rect.x || viewport.y != rect.y - || viewport.width != rect.width || viewport.height != rect.height) { - glViewport(rect.x, rect.y, rect.width, rect.height); - viewport = rect; +inline void gl_rend_state::update_draw_framebuffer() { + if (update_flags & GL_REND_STATE_UPDATE_DRAW_FRAMEBUFFER) { + if (curr_draw_framebuffer_binding != draw_framebuffer_binding) { + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, draw_framebuffer_binding); + if (draw_framebuffer_binding) { + GLenum status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) + printf_debug("GL Error: Bind Draw Framebuffer Status - 0x%04X\n", status); + gl_get_error_print(); + } + curr_draw_framebuffer_binding = draw_framebuffer_binding; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_DRAW_FRAMEBUFFER); } } -void gl_rend_state::set_viewport(GLint x, GLint y, GLsizei width, GLsizei height, bool force) { - if (force || viewport.x != x || viewport.y != y - || viewport.width != width || viewport.height != height) { - glViewport(x, y, width, height); - viewport.x = x; - viewport.y = y; - viewport.width = width; - viewport.height = height; +inline void gl_rend_state::update_vertex_array() { + if (update_flags & GL_REND_STATE_UPDATE_VERTEX_ARRAY) { + if (curr_vertex_array_binding != vertex_array_binding) { + glBindVertexArray(vertex_array_binding); + curr_vertex_array_binding = vertex_array_binding; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_VERTEX_ARRAY); } } -void gl_rend_state::use_program(GLuint program, bool force) { - if (force || this->program != program) { - glUseProgram(program); - this->program = program; +inline void gl_rend_state::update_uniform_buffer() { + if (update_flags & GL_REND_STATE_UPDATE_UNIFORM_BUFFER) { + for (int32_t index = uniform_buffer_start_index; + index <= uniform_buffer_end_index; index++) { + if (curr_uniform_buffer_bindings[index] == uniform_buffer_bindings[index] + && curr_uniform_buffer_offsets[index] == uniform_buffer_offsets[index] + && curr_uniform_buffer_sizes[index] == uniform_buffer_sizes[index]) + continue; + + if (uniform_buffer_offsets[index] == 0 && uniform_buffer_sizes[index] == -1) + glBindBufferBase(GL_UNIFORM_BUFFER, index, uniform_buffer_bindings[index]); + else + glBindBufferRange(GL_UNIFORM_BUFFER, index, uniform_buffer_bindings[index], + uniform_buffer_offsets[index], uniform_buffer_sizes[index]); + uniform_buffer_binding = uniform_buffer_bindings[index]; + curr_uniform_buffer_bindings[index] = uniform_buffer_bindings[index]; + curr_uniform_buffer_offsets[index] = uniform_buffer_offsets[index]; + curr_uniform_buffer_sizes[index] = uniform_buffer_sizes[index]; + } + + uniform_buffer_start_index = 14; + uniform_buffer_end_index = -1; + enum_and(update_flags, ~GL_REND_STATE_UPDATE_UNIFORM_BUFFER); } } + +inline void gl_rend_state::update_shader_storage_buffer() { + if (update_flags & GL_REND_STATE_UPDATE_SHADER_STORAGE_BUFFER) { + for (int32_t index = shader_storage_buffer_start_index; + index <= shader_storage_buffer_end_index; index++) { + if (curr_shader_storage_buffer_bindings[index] == shader_storage_buffer_bindings[index] + && curr_shader_storage_buffer_offsets[index] == shader_storage_buffer_offsets[index] + && curr_shader_storage_buffer_sizes[index] == shader_storage_buffer_sizes[index]) + continue; + + if (shader_storage_buffer_offsets[index] == 0 && shader_storage_buffer_sizes[index] == -1) + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, index, shader_storage_buffer_bindings[index]); + else + glBindBufferRange(GL_SHADER_STORAGE_BUFFER, index, shader_storage_buffer_bindings[index], + shader_storage_buffer_offsets[index], shader_storage_buffer_sizes[index]); + shader_storage_buffer_binding = shader_storage_buffer_bindings[index]; + curr_shader_storage_buffer_bindings[index] = shader_storage_buffer_bindings[index]; + curr_shader_storage_buffer_offsets[index] = shader_storage_buffer_offsets[index]; + curr_shader_storage_buffer_sizes[index] = shader_storage_buffer_sizes[index]; + } + + shader_storage_buffer_start_index = 14; + shader_storage_buffer_end_index = -1; + enum_and(update_flags, ~GL_REND_STATE_UPDATE_SHADER_STORAGE_BUFFER); + } +} + +inline void gl_rend_state::update_color_mask() { + if (update_flags & GL_REND_STATE_UPDATE_COLOR_MASK) { + if (memcmp(&curr_color_mask, &color_mask, sizeof(GLboolean) * 4)) { + glColorMask(color_mask[0], color_mask[1], color_mask[2], color_mask[3]); + memcpy(&curr_color_mask, &color_mask, sizeof(GLboolean) * 4); + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_COLOR_MASK); + } +} + +inline void gl_rend_state::update_cull_face() { + if (update_flags & GL_REND_STATE_UPDATE_CULL_FACE) { + if (curr_cull_face != cull_face) { + (cull_face ? glEnable : glDisable)(GL_CULL_FACE); + curr_cull_face = cull_face; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_CULL_FACE); + } +} + +inline void gl_rend_state::update_cull_face_mode() { + if (curr_cull_face && (update_flags & GL_REND_STATE_UPDATE_CULL_FACE_MODE)) { + if (curr_cull_face_mode != cull_face_mode) { + glCullFace(cull_face_mode); + curr_cull_face_mode = cull_face_mode; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_CULL_FACE_MODE); + } +} + +inline void gl_rend_state::update_depth_test() { + if (update_flags & GL_REND_STATE_UPDATE_DEPTH_TEST) { + if (curr_depth_test != depth_test) { + (depth_test ? glEnable : glDisable)(GL_DEPTH_TEST); + curr_depth_test = depth_test; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_DEPTH_TEST); + } +} + +inline void gl_rend_state::update_depth_mask() { + if (curr_depth_test && (update_flags & GL_REND_STATE_UPDATE_DEPTH_MASK)) { + if (curr_depth_mask != depth_mask) { + glDepthMask(depth_mask); + curr_depth_mask = depth_mask; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_DEPTH_MASK); + } +} + +inline void gl_rend_state::update_depth_func() { + if (curr_depth_test && (update_flags & GL_REND_STATE_UPDATE_DEPTH_FUNC)) { + if (curr_depth_func != depth_func) { + glDepthFunc(depth_func); + curr_depth_func = depth_func; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_DEPTH_FUNC); + } +} + +inline void gl_rend_state::update_line_width() { + if (update_flags & GL_REND_STATE_UPDATE_LINE_WIDTH) { + if (curr_line_width != line_width) { + glLineWidth(line_width); + curr_line_width = line_width; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_LINE_WIDTH); + } +} + +inline void gl_rend_state::update_multisample() { + if (update_flags & GL_REND_STATE_UPDATE_MULTISAMPLE) { + if (curr_multisample != multisample) { + (multisample ? glEnable : glDisable)(GL_MULTISAMPLE); + curr_multisample = multisample; + } + + enum_and(update_flags, ~GL_REND_STATE_UPDATE_MULTISAMPLE); + } +} + +inline void gl_rend_state::update_primitive_restart() { + if (update_flags & GL_REND_STATE_UPDATE_PRIMITIVE_RESTART) { + if (curr_primitive_restart != primitive_restart) { + (primitive_restart ? glEnable : glDisable)(GL_PRIMITIVE_RESTART); + curr_primitive_restart = primitive_restart; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_PRIMITIVE_RESTART); + } +} + +inline void gl_rend_state::update_primitive_restart_index() { + if (curr_primitive_restart && (update_flags & GL_REND_STATE_UPDATE_PRIMITIVE_RESTART_INDEX)) { + if (curr_primitive_restart_index != primitive_restart_index) { + glPrimitiveRestartIndex(primitive_restart_index); + curr_primitive_restart_index = primitive_restart_index; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_PRIMITIVE_RESTART_INDEX); + } +} + +inline void gl_rend_state::update_scissor_test() { + if (update_flags & GL_REND_STATE_UPDATE_SCISSOR_TEST) { + if (curr_scissor_test != scissor_test) { + (scissor_test ? glEnable : glDisable)(GL_SCISSOR_TEST); + curr_scissor_test = scissor_test; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_SCISSOR_TEST); + } +} + +inline void gl_rend_state::update_scissor() { + if (curr_scissor_test && (update_flags & GL_REND_STATE_UPDATE_SCISSOR)) { + if (memcmp(&curr_scissor_box, &scissor_box, sizeof(gl_rend_state_rect))) { + glScissor(scissor_box.x, scissor_box.y, scissor_box.width, scissor_box.height); + curr_scissor_box = scissor_box; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_SCISSOR); + } +} + +inline void gl_rend_state::update_stencil_test() { + if (update_flags & GL_REND_STATE_UPDATE_STENCIL_TEST) { + if (curr_stencil_test != stencil_test) { + (stencil_test ? glEnable : glDisable)(GL_STENCIL_TEST); + curr_stencil_test = stencil_test; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_STENCIL_TEST); + } +} + +inline void gl_rend_state::update_stencil_mask() { + if (curr_stencil_test && (update_flags & GL_REND_STATE_UPDATE_STENCIL_MASK)) { + if (curr_stencil_mask != stencil_mask) { + glStencilMask(stencil_mask); + curr_stencil_mask = stencil_mask; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_STENCIL_MASK); + } +} + +inline void gl_rend_state::update_stencil_func() { + if (curr_stencil_test && (update_flags & GL_REND_STATE_UPDATE_STENCIL_FUNC)) { + if (curr_stencil_func != stencil_func || curr_stencil_ref != stencil_ref + || curr_stencil_value_mask != stencil_value_mask) { + glStencilFunc(stencil_func, stencil_ref, stencil_ref); + curr_stencil_func = stencil_func; + curr_stencil_ref = stencil_ref; + curr_stencil_value_mask = stencil_value_mask; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_STENCIL_FUNC); + } +} + +inline void gl_rend_state::update_stencil_op() { + if (curr_stencil_test && (update_flags & GL_REND_STATE_UPDATE_STENCIL_OP)) { + if (curr_stencil_fail != stencil_fail || curr_stencil_dpfail != stencil_dpfail + || curr_stencil_dppass != stencil_dppass) { + glStencilOp(stencil_fail, stencil_dpfail, stencil_dppass); + curr_stencil_fail = stencil_fail; + curr_stencil_dpfail = stencil_dpfail; + curr_stencil_dppass = stencil_dppass; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_STENCIL_OP); + } +} + +inline void gl_rend_state::update_viewport() { + if (update_flags & GL_REND_STATE_UPDATE_VIEWPORT) { + if (memcmp(&curr_viewport, &viewport, sizeof(gl_rend_state_rect))) { + glViewport(viewport.x, viewport.y, viewport.width, viewport.height); + curr_viewport = viewport; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_VIEWPORT); + } +} + +inline void gl_rend_state::update_clear_color() { + if (update_flags & GL_REND_STATE_UPDATE_CLEAR_COLOR) { + if (curr_clear_color_value[0] != clear_color_value[0] + || curr_clear_color_value[1] != clear_color_value[1] + || curr_clear_color_value[2] != clear_color_value[2] + || curr_clear_color_value[3] != clear_color_value[3]) { + glClearColor(clear_color_value[0], clear_color_value[1], + clear_color_value[2], clear_color_value[3]); + curr_clear_color_value[0] = clear_color_value[0]; + curr_clear_color_value[1] = clear_color_value[1]; + curr_clear_color_value[2] = clear_color_value[2]; + curr_clear_color_value[3] = clear_color_value[3]; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_CLEAR_COLOR); + } +} + +inline void gl_rend_state::update_clear_depth() { + if (update_flags & GL_REND_STATE_UPDATE_CLEAR_DEPTH) { + if (curr_clear_depth_value != clear_depth_value) { + glClearDepthf(clear_depth_value); + curr_clear_depth_value = clear_depth_value; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_CLEAR_DEPTH); + } +} + +inline void gl_rend_state::update_clear_stencil() { + if (update_flags & GL_REND_STATE_UPDATE_CLEAR_STENCIL) { + if (curr_clear_stencil_value != clear_stencil_value) { + glClearStencil(clear_stencil_value); + curr_clear_stencil_value = clear_stencil_value; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_CLEAR_STENCIL); + } +} + +inline void gl_rend_state::use_program(GLuint program) { + this->program = program; + enum_or(update_flags, GL_REND_STATE_UPDATE_PROGRAM); +} diff --git a/src/CRE/gl_rend_state.hpp b/src/CRE/gl_rend_state.hpp index 94f80617..90e7cee1 100644 --- a/src/CRE/gl_rend_state.hpp +++ b/src/CRE/gl_rend_state.hpp @@ -28,82 +28,90 @@ struct p_gl_rend_state { p_gl_rend_state(gl_rend_state_index index); - void active_bind_texture_2d(int32_t index, GLuint texture, bool force = false); - void active_bind_texture_cube_map(int32_t index, GLuint texture, bool force = false); - void active_texture(size_t index, bool force = false); + void active_bind_texture_2d(int32_t index, GLuint texture); + void active_bind_texture_cube_map(int32_t index, GLuint texture); + void active_texture(int32_t index); void begin_event(const char* message, int32_t length); - void bind_framebuffer(GLuint framebuffer, bool force = false); - void bind_read_framebuffer(GLuint framebuffer, bool force = false); - void bind_draw_framebuffer(GLuint framebuffer, bool force = false); - void bind_vertex_array(GLuint array, bool force = false); - void bind_array_buffer(GLuint buffer, bool force = false); - void bind_element_array_buffer(GLuint buffer, bool force = false); - void bind_uniform_buffer(GLuint buffer, bool force = false); - void bind_uniform_buffer_base(GLuint index, GLuint buffer, bool force = false); + void bind_framebuffer(GLuint framebuffer); + void bind_read_framebuffer(GLuint framebuffer); + void bind_draw_framebuffer(GLuint framebuffer); + void bind_vertex_array(GLuint array); + void bind_array_buffer(GLuint buffer); + void bind_element_array_buffer(GLuint buffer); + void bind_uniform_buffer(GLuint buffer); + void bind_uniform_buffer_base(GLuint index, GLuint buffer); void bind_uniform_buffer_range(GLuint index, - GLuint buffer, GLintptr offset, GLsizeiptr size, bool force = false); - void bind_shader_storage_buffer(GLuint buffer, bool force = false); - void bind_shader_storage_buffer_base(GLuint index, GLuint buffer, bool force = false); + GLuint buffer, GLintptr offset, GLsizeiptr size); + void bind_shader_storage_buffer(GLuint buffer); + void bind_shader_storage_buffer_base(GLuint index, GLuint buffer); void bind_shader_storage_buffer_range(GLuint index, - GLuint buffer, GLintptr offset, GLsizeiptr size, bool force = false); - void bind_texture_2d(GLuint texture, bool force = false); - void bind_texture_cube_map(GLuint texture, bool force = false); - void bind_sampler(int32_t index, GLuint sampler, bool force = false); - bool check_uniform_buffer_binding(); - bool check_uniform_buffer_binding_base(size_t index); - bool check_shader_storage_buffer_binding(); - bool check_shader_storage_buffer_binding_base(size_t index); - bool check_texture_binding_2d(size_t index); - bool check_texture_binding_cube_map(size_t index); - bool check_sampler_binding(int32_t index, GLuint sampler); - void disable_blend(bool force = false); - void disable_cull_face(bool force = false); - void disable_depth_test(bool force = false); - void disable_multisample(bool force = false); - void disable_primitive_restart(bool force = false); - void disable_scissor_test(bool force = false); - void disable_stencil_test(bool force = false); + GLuint buffer, GLintptr offset, GLsizeiptr size); + void bind_texture_2d(GLuint texture); + void bind_texture_cube_map(GLuint texture); + void bind_sampler(int32_t index, GLuint sampler); + void blit_framebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, + GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); + GLenum check_framebuffer_status(GLenum target); + void clear(GLbitfield mask); + void clear_buffer(GLenum buffer, GLint drawbuffer, const GLfloat* value); + void clear_color(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); + void clear_depth(GLfloat depth); + void clear_stencil(GLint stencil); + void copy_image_sub_data(GLuint srcName, GLenum srcTarget, GLint srcLevel, + GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, + GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); + void copy_tex_sub_image_2d(GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); + void disable_blend(); + void disable_cull_face(); + void disable_depth_test(); + void disable_multisample(); + void disable_primitive_restart(); + void disable_scissor_test(); + void disable_stencil_test(); void draw_arrays(GLenum mode, GLint first, GLsizei count); void draw_elements(GLenum mode, GLsizei count, GLenum type, const void* indices); void draw_range_elements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices); - void enable_blend(bool force = false); - void enable_cull_face(bool force = false); - void enable_depth_test(bool force = false); - void enable_multisample(bool force = false); - void enable_primitive_restart(bool force = false); - void enable_scissor_test(bool force = false); - void enable_stencil_test(bool force = false); + void enable_blend(); + void enable_cull_face(); + void enable_depth_test(); + void enable_multisample(); + void enable_primitive_restart(); + void enable_scissor_test(); + void enable_stencil_test(); void end_event(); + void generate_mipmap(GLenum target); + void generate_texture_mipmap(GLuint texture); void get(); + void get_clear_color(GLfloat& red, GLfloat& green, GLfloat& blue, GLfloat& alpha); GLuint get_program(); gl_rend_state_rect get_scissor(); void get_scissor(GLint& x, GLint& y, GLsizei& width, GLsizei& height); gl_rend_state_rect get_viewport(); void get_viewport(GLint& x, GLint& y, GLsizei& width, GLsizei& height); - void set_blend_func(GLenum src, GLenum dst, bool force = false); + void set_blend_func(GLenum src, GLenum dst); void set_blend_func_separate(GLenum src_rgb, GLenum dst_rgb, - GLenum src_alpha, GLenum dst_alpha, bool force = false); - void set_blend_equation(GLenum mode, bool force = false); + GLenum src_alpha, GLenum dst_alpha); + void set_blend_equation(GLenum mode); void set_blend_equation_separate( - GLenum mode_rgb, GLenum mode_alpha, bool force = false); - void set_color_mask(GLboolean red, GLboolean green, - GLboolean blue, GLboolean alpha, bool force = false); - void set_cull_face_mode(GLenum mode, bool force = false); - void set_depth_func(GLenum func, bool force = false); - void set_depth_mask(GLboolean flag, bool force = false); - void set_line_width(GLfloat width, bool force = false); - void set_polygon_mode(GLenum face, GLenum mode, bool force = false); - void set_primitive_restart_index(GLuint index, bool force = false); - void set_scissor(const gl_rend_state_rect& rect, bool force = false); - void set_scissor(GLint x, GLint y, GLsizei width, GLsizei height, bool force = false); - void set_stencil_func(GLenum func, GLint ref, GLuint mask, bool force = false); - void set_stencil_mask(GLuint mask, bool force = false); - void set_stencil_op(GLenum sfail, GLenum dpfail, GLenum dppass, bool force = false); - void set_viewport(const gl_rend_state_rect& rect, bool force = false); - void set_viewport(GLint x, GLint y, GLsizei width, GLsizei height, bool force = false); - void use_program(GLuint program, bool force = false); + GLenum mode_rgb, GLenum mode_alpha); + void set_color_mask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); + void set_cull_face_mode(GLenum mode); + void set_depth_func(GLenum func); + void set_depth_mask(GLboolean flag); + void set_line_width(GLfloat width); + void set_primitive_restart_index(GLuint index); + void set_scissor(const gl_rend_state_rect& rect); + void set_scissor(GLint x, GLint y, GLsizei width, GLsizei height); + void set_stencil_func(GLenum func, GLint ref, GLuint mask); + void set_stencil_mask(GLuint mask); + void set_stencil_op(GLenum sfail, GLenum dpfail, GLenum dppass); + void set_viewport(const gl_rend_state_rect& rect); + void set_viewport(GLint x, GLint y, GLsizei width, GLsizei height); + void update(); + void use_program(GLuint program); template inline void begin_event(const char(&str)[size]) { diff --git a/src/CRE/render.cpp b/src/CRE/render.cpp index b3f15cad..860f5f6c 100644 --- a/src/CRE/render.cpp +++ b/src/CRE/render.cpp @@ -1466,7 +1466,8 @@ namespace rndr { 1.0f, 1.0f, 0.0f, 0.0f, scale, 1.0f, 1.0f, 1.0f, 1.0f); rend_data_ctx.state.active_bind_texture_2d(0, reduce_tex[i]->glid); rend_data_ctx.state.bind_sampler(0, rctx->render_samplers[2]); - glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, reduce_width[i], reduce_height[i]); + rend_data_ctx.state.copy_tex_sub_image_2d(GL_TEXTURE_2D, + 0, 0, 0, 0, 0, reduce_width[i], reduce_height[i]); } } @@ -1856,9 +1857,11 @@ namespace rndr { rend_data_ctx.state.active_bind_texture_2d(0, exposure_history->glid); if (reset_exposure) - glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 32, 1); + rend_data_ctx.state.copy_tex_sub_image_2d(GL_TEXTURE_2D, + 0, 0, 0, 0, 0, 32, 1); else - glCopyTexSubImage2D(GL_TEXTURE_2D, 0, exposure_history_counter, 0, 0, 0, 1, 1); + rend_data_ctx.state.copy_tex_sub_image_2d(GL_TEXTURE_2D, + 0, exposure_history_counter, 0, 0, 0, 1, 1); exposure_history_counter = (exposure_history_counter + 1) % 32; } @@ -2100,7 +2103,8 @@ namespace rndr { rend_data_ctx.state.bind_sampler(0, rctx->render_samplers[2]); draw_quad(rend_data_ctx, reduce_width[i], reduce_height[i], 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f); - glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, reduce_width[i], reduce_height[i]); + rend_data_ctx.state.copy_tex_sub_image_2d(GL_TEXTURE_2D, + 0, 0, 0, 0, 0, reduce_width[i], reduce_height[i]); } for (int32_t i = 1; i < 4; i++) { @@ -2109,7 +2113,8 @@ namespace rndr { rend_data_ctx.state.bind_sampler(0, rctx->render_samplers[2]); draw_quad(rend_data_ctx, reduce_width[i], reduce_height[i], 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f); - glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, reduce_width[i], reduce_height[i]); + rend_data_ctx.state.copy_tex_sub_image_2d(GL_TEXTURE_2D, + 0, 0, 0, 0, 0, reduce_width[i], reduce_height[i]); } rend_data_ctx.shader_flags.arr[U_GAUSS] = 1; diff --git a/src/CRE/render_context.cpp b/src/CRE/render_context.cpp index 77310667..016f25f5 100644 --- a/src/CRE/render_context.cpp +++ b/src/CRE/render_context.cpp @@ -161,8 +161,8 @@ bool light_proj::set(render_data_context& rend_data_ctx, cam_data& cam) { rend_data_ctx.state.set_viewport(0, 0, 2048, 512); rend_data_ctx.state.enable_depth_test(); rend_data_ctx.state.set_depth_mask(GL_TRUE); - glClearBufferfv(GL_COLOR, 0, (float_t*)&color_clear); - glClearBufferfv(GL_DEPTH, 0, &depth_clear); + rend_data_ctx.state.clear_buffer(GL_COLOR, 0, (float_t*)&color_clear); + rend_data_ctx.state.clear_buffer(GL_DEPTH, 0, &depth_clear); if (set_mat(rend_data_ctx, cam, false)) { rctx_ptr->draw_state->rend_data[rend_data_ctx.index].shader_index = SHADER_FT_SIL; @@ -174,8 +174,8 @@ bool light_proj::set(render_data_context& rend_data_ctx, cam_data& cam) { draw_texture.SetViewport(rend_data_ctx.state); rend_data_ctx.state.enable_depth_test(); rend_data_ctx.state.set_depth_mask(GL_TRUE); - glClearBufferfv(GL_COLOR, 0, (float_t*)&color_clear); - glClearBufferfv(GL_DEPTH, 0, &depth_clear); + rend_data_ctx.state.clear_buffer(GL_COLOR, 0, (float_t*)&color_clear); + rend_data_ctx.state.clear_buffer(GL_DEPTH, 0, &depth_clear); } return false; } diff --git a/src/CRE/render_manager.cpp b/src/CRE/render_manager.cpp index beb058bd..19449692 100644 --- a/src/CRE/render_manager.cpp +++ b/src/CRE/render_manager.cpp @@ -287,6 +287,7 @@ namespace rndr { } void RenderManager::render_all() { + gl_state.get(); sprite_manager_pre_draw(); static const vec4 color_clear = 0.0f; @@ -295,7 +296,7 @@ namespace rndr { render_data_context rend_data_ctx(GL_REND_STATE_PRE_3D); rend_data_ctx.state.get(); rend_data_ctx.state.bind_framebuffer(0); - glClearBufferfv(GL_COLOR, 0, (float_t*)&color_clear); + rend_data_ctx.state.clear_buffer(GL_COLOR, 0, (float_t*)&color_clear); rend_data_ctx.set_scene_framebuffer_size(render->render_width[0], render->render_height[0], render->render_width[0], render->render_height[0]); @@ -308,11 +309,11 @@ namespace rndr { { render_data_context rend_data_ctx(GL_REND_STATE_PRE_3D); - rend_data_ctx.state.get(); rend_data_ctx.state.begin_event("rndpass_render_all_pass::Caller::execute_pre3d"); for (int32_t i = RND_PASSID_SHADOW; i <= RND_PASSID_CLEAR; i++) RenderManager::render_single_pass(rend_data_ctx, (RenderPassID)i); rend_data_ctx.state.end_event(); + rend_data_ctx.state.update(); } { @@ -322,6 +323,7 @@ namespace rndr { for (int32_t i = RND_PASSID_PRE_SPRITE; i <= RND_PASSID_3D; i++) RenderManager::render_single_pass(rend_data_ctx, (RenderPassID)i); rend_data_ctx.state.end_event(); + rend_data_ctx.state.update(); } { @@ -331,6 +333,7 @@ namespace rndr { for (int32_t i = RND_PASSID_SHOW_VECTOR; i <= RND_PASSID_12; i++) RenderManager::render_single_pass(rend_data_ctx, (RenderPassID)i); rend_data_ctx.state.end_event(); + rend_data_ctx.state.update(); } rctx_ptr->disp_manager->check_vertex_arrays(); @@ -542,8 +545,8 @@ namespace rndr { // rend_data_ctx.state.set_viewport(0, 0, 640, 360); //} - glClearColor(sss->param.x, sss->param.y, sss->param.z, 0.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + rend_data_ctx.state.clear_color(sss->param.x, sss->param.y, sss->param.z, 0.0f); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); for (int32_t i = LIGHT_SET_MAIN; i < LIGHT_SET_MAX; i++) rctx->light_set[i].data_set(rend_data_ctx, rctx->face, (light_set_id)i); @@ -575,7 +578,7 @@ namespace rndr { else if (npr) { refl_tex.Bind(rend_data_ctx.state); refl_tex.SetViewport(rend_data_ctx.state); - glClear(GL_DEPTH_BUFFER_BIT); + rend_data_ctx.state.clear(GL_DEPTH_BUFFER_BIT); rctx->draw_state->rend_data[rend_data_ctx.index].shader_index = SHADER_FT_SSS_SKIN; rend_data_ctx.state.enable_depth_test(); rend_data_ctx.state.set_depth_mask(GL_TRUE); @@ -631,8 +634,8 @@ namespace rndr { // rend_data_ctx.state.set_viewport(0, 0, 640, 360); //} - glClearColor(sss->param.x, sss->param.y, sss->param.z, 0.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + rend_data_ctx.state.clear_color(sss->param.x, sss->param.y, sss->param.z, 0.0f); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); for (int32_t i = LIGHT_SET_MAIN; i < LIGHT_SET_MAX; i++) rctx->light_set[i].data_set(rend_data_ctx, rctx->face, (light_set_id)i); @@ -662,7 +665,7 @@ namespace rndr { else if (npr) { rend->rend_texture[0].Bind(rend_data_ctx.state); rend->rend_texture[0].SetViewport(rend_data_ctx.state); - glClear(GL_DEPTH_BUFFER_BIT); + rend_data_ctx.state.clear(GL_DEPTH_BUFFER_BIT); rctx->draw_state->rend_data[rend_data_ctx.index].shader_index = SHADER_FT_SSS_SKIN; rend_data_ctx.state.enable_depth_test(); rend_data_ctx.state.set_depth_mask(GL_TRUE); @@ -731,11 +734,11 @@ namespace rndr { for (int32_t i = FOG_DEPTH; i < FOG_BUMP; i++) rctx->fog[i].data_set(rend_data_ctx, (fog_id)i); - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + rend_data_ctx.state.clear_color(0.0f, 0.0f, 0.0f, 0.0f); if (sv_better_reflect && rctx->disp_manager->get_obj_count(mdl::OBJ_TYPE_SSS)) - glClear(GL_COLOR_BUFFER_BIT); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT); else - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); rctx->draw_state->rend_data[rend_data_ctx.index].shader_index = SHADER_FT_S_REFL; @@ -835,10 +838,10 @@ namespace rndr { } else { vec4 clear_color; - glGetFloatv(GL_COLOR_CLEAR_VALUE, (GLfloat*)&clear_color); - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClear(GL_COLOR_BUFFER_BIT); - glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + rend_data_ctx.state.get_clear_color(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + rend_data_ctx.state.clear_color(0.0f, 0.0f, 0.0f, 0.0f); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT); + rend_data_ctx.state.clear_color(clear_color.x, clear_color.y, clear_color.z, clear_color.w); } shader::unbind(rend_data_ctx.state); rend_data_ctx.state.bind_framebuffer(0); @@ -862,10 +865,10 @@ namespace rndr { rctx->fog[i].data_set(rend_data_ctx, (fog_id)i); vec4 clear_color; - glGetFloatv(GL_COLOR_CLEAR_VALUE, (GLfloat*)&clear_color); - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + rend_data_ctx.state.get_clear_color(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + rend_data_ctx.state.clear_color(0.0f, 0.0f, 0.0f, 0.0f); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + rend_data_ctx.state.clear_color(clear_color.x, clear_color.y, clear_color.z, clear_color.w); rctx->draw_state->rend_data[rend_data_ctx.index].shader_index = SHADER_FT_S_REFR; rend_data_ctx.state.enable_depth_test(); @@ -879,10 +882,10 @@ namespace rndr { } else { vec4 clear_color; - glGetFloatv(GL_COLOR_CLEAR_VALUE, (GLfloat*)&clear_color); - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClear(GL_COLOR_BUFFER_BIT); - glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + rend_data_ctx.state.get_clear_color(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + rend_data_ctx.state.clear_color(0.0f, 0.0f, 0.0f, 0.0f); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT); + rend_data_ctx.state.clear_color(clear_color.x, clear_color.y, clear_color.z, clear_color.w); } shader::unbind(rend_data_ctx.state); rend_data_ctx.state.bind_framebuffer(0); @@ -904,9 +907,9 @@ namespace rndr { rend_data_ctx.state.begin_event("pass_clear"); if (clear) { rctx->screen_buffer.Bind(rend_data_ctx.state); - clear_color_set_gl(); - //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glClear(GL_COLOR_BUFFER_BIT); + clear_color_set_gl(rend_data_ctx.state); + //rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT); rend_data_ctx.state.bind_framebuffer(0); } @@ -914,32 +917,32 @@ namespace rndr { if (!rctx->sss_data->enable || !rctx->sss_data->npr_contour) { rend->bind_render_texture(rend_data_ctx.state); if (sprite_manager_get_reqlist_count(2)) { - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClearDepthf(1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + rend_data_ctx.state.clear_color(0.0f, 0.0f, 0.0f, 0.0f); + rend_data_ctx.state.clear_depth(1.0f); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); rend_data_ctx.state.bind_framebuffer(0); } else { - clear_color_set_gl(); - glClearDepthf(1.0f); + clear_color_set_gl(rend_data_ctx.state); + rend_data_ctx.state.clear_depth(1.0f); if (clear) - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); else - glClear(GL_DEPTH_BUFFER_BIT); + rend_data_ctx.state.clear(GL_DEPTH_BUFFER_BIT); rend_data_ctx.state.bind_framebuffer(0); } } else { if (sprite_manager_get_reqlist_count(2)) { rend->bind_render_texture(rend_data_ctx.state); - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClear(GL_COLOR_BUFFER_BIT); + rend_data_ctx.state.clear_color(0.0f, 0.0f, 0.0f, 0.0f); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT); rend_data_ctx.state.bind_framebuffer(0); } else if (clear) { rend->bind_render_texture(rend_data_ctx.state); - clear_color_set_gl(); - glClear(GL_COLOR_BUFFER_BIT); + clear_color_set_gl(rend_data_ctx.state); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT); rend_data_ctx.state.bind_framebuffer(0); } } @@ -957,8 +960,8 @@ namespace rndr { rend_data_ctx.state.begin_event("pass_pre_sprite"); rndr::Render* rend = render; rend->bind_render_texture(rend_data_ctx.state, true); - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClear(GL_COLOR_BUFFER_BIT); + rend_data_ctx.state.clear_color(0.0f, 0.0f, 0.0f, 0.0f); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT); rend_data_ctx.state.set_depth_mask(GL_FALSE); rend_data_ctx.state.disable_depth_test(); rend_data_ctx.state.enable_blend(); @@ -982,7 +985,7 @@ namespace rndr { if (!rctx->sss_data->enable || !rctx->sss_data->npr_contour || draw_pass_3d_get_translucent_count(rctx)) { rend_data_ctx.state.set_depth_mask(GL_TRUE); - glClear(GL_DEPTH_BUFFER_BIT); + rend_data_ctx.state.clear(GL_DEPTH_BUFFER_BIT); } rend_data_ctx.state.set_depth_func(GL_LEQUAL); @@ -1193,8 +1196,8 @@ namespace rndr { if (!Vulkan::use && multisample && multisample_framebuffer) { rend_data_ctx.state.bind_framebuffer(multisample_framebuffer); rend_data_ctx.state.enable_multisample(); - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClear(GL_COLOR_BUFFER_BIT); + rend_data_ctx.state.clear_color(0.0f, 0.0f, 0.0f, 0.0f); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT); } else rctx->screen_buffer.Bind(rend_data_ctx.state); @@ -1215,7 +1218,7 @@ namespace rndr { rend_data_ctx.state.bind_framebuffer(rctx->screen_buffer.fbos[0]); rend_data_ctx.state.disable_multisample(); rend_data_ctx.state.bind_read_framebuffer(multisample_framebuffer); - glBlitFramebuffer(0, 0, width, height, + rend_data_ctx.state.blit_framebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST); rend_data_ctx.state.bind_read_framebuffer(0); } @@ -1375,11 +1378,11 @@ static void draw_pass_shadow_begin_make_shadowmap(Shadow* shad, texture* tex = shad->curr_render_textures[0]->color_texture; rend_data_ctx.state.set_viewport(1, 1, tex->width - 2, tex->width - 2); rend_data_ctx.state.enable_depth_test(); - glClearColor(1.0, 1.0, 1.0, 1.0); + rend_data_ctx.state.clear_color(1.0f, 1.0f, 1.0f, 1.0f); if (!a3) - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); else if (shad->separate) - glClear(GL_COLOR_BUFFER_BIT); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT); float_t shadow_range = shad->get_shadow_range(); float_t offset; @@ -1432,14 +1435,18 @@ static void draw_pass_shadow_end_make_shadowmap(Shadow* shad, } else { rend_buf_tex.Bind(rend_data_ctx.state); - glClearColor(1.0f, 1.0f, 1.0f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT); + rend_data_ctx.state.clear_color(1.0f, 1.0f, 1.0f, 1.0f); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT); } rend_data_ctx.state.bind_framebuffer(0); - rend_data_ctx.state.bind_texture_2d(rend_tex->GetColorTex()); - glGenerateMipmap(GL_TEXTURE_2D); - rend_data_ctx.state.bind_texture_2d(0); + if (GLAD_GL_VERSION_4_5) + rend_data_ctx.state.generate_texture_mipmap(rend_tex->GetColorTex()); + else { + rend_data_ctx.state.bind_texture_2d(rend_tex->GetColorTex()); + rend_data_ctx.state.generate_mipmap(GL_TEXTURE_2D); + rend_data_ctx.state.bind_texture_2d(0); + } } static void draw_pass_shadow_filter(render_data_context& rend_data_ctx, @@ -1566,9 +1573,9 @@ static bool draw_pass_shadow_litproj(render_data_context& rend_data_ctx, light_p litproj->draw_texture.Bind(rend_data_ctx.state); litproj->draw_texture.SetViewport(rend_data_ctx.state); rend_data_ctx.state.enable_depth_test(); - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClearDepthf(1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + rend_data_ctx.state.clear_color(0.0f, 0.0f, 0.0f, 0.0f); + rend_data_ctx.state.clear_depth(1.0f); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if (!light_proj::set_mat(rend_data_ctx, cam, true)) { rend_data_ctx.state.bind_framebuffer(0); @@ -1977,7 +1984,7 @@ static void draw_pass_reflect_full(render_data_context& rend_data_ctx, rndr::Ren refl_tex.SetViewport(rend_data_ctx.state); if (!rctx->sss_data->enable || !rctx->sss_data->npr_contour) - glClear(GL_DEPTH_BUFFER_BIT); + rend_data_ctx.state.clear(GL_DEPTH_BUFFER_BIT); rend_data_ctx.state.set_depth_func(GL_LEQUAL); @@ -1986,11 +1993,11 @@ static void draw_pass_reflect_full(render_data_context& rend_data_ctx, rndr::Ren for (int32_t i = FOG_DEPTH; i < FOG_BUMP; i++) rctx->fog[i].data_set(rend_data_ctx, (fog_id)i); - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + rend_data_ctx.state.clear_color(0.0f, 0.0f, 0.0f, 0.0f); if (rctx->disp_manager->get_obj_count(mdl::OBJ_TYPE_SSS)) - glClear(GL_COLOR_BUFFER_BIT); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT); else - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); rend_data_ctx.state.enable_depth_test(); rend_data_ctx.state.set_depth_func(GL_LEQUAL); @@ -2113,10 +2120,10 @@ static void draw_pass_reflect_full(render_data_context& rend_data_ctx, rndr::Ren } else { vec4 clear_color; - glGetFloatv(GL_COLOR_CLEAR_VALUE, (GLfloat*)&clear_color); - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClear(GL_COLOR_BUFFER_BIT); - glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + rend_data_ctx.state.get_clear_color(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + rend_data_ctx.state.clear_color(0.0f, 0.0f, 0.0f, 0.0f); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT); + rend_data_ctx.state.clear_color(clear_color.x, clear_color.y, clear_color.z, clear_color.w); } shader::unbind(rend_data_ctx.state); rend_data_ctx.state.bind_framebuffer(0); diff --git a/src/CRE/render_texture.cpp b/src/CRE/render_texture.cpp index a381f915..913e06b9 100644 --- a/src/CRE/render_texture.cpp +++ b/src/CRE/render_texture.cpp @@ -40,7 +40,7 @@ int32_t RenderTexture::Bind(p_gl_rend_state& p_gl_rend_st, int32_t index) { return -1; p_gl_rend_st.bind_framebuffer(fbos[index]); - if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + if (p_gl_rend_st.check_framebuffer_status(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) return -1; gl_get_error_print(); diff --git a/src/CRE/renderer/dof.cpp b/src/CRE/renderer/dof.cpp index ca96859f..8e501e64 100644 --- a/src/CRE/renderer/dof.cpp +++ b/src/CRE/renderer/dof.cpp @@ -316,7 +316,7 @@ namespace renderer { rend_data_ctx.state.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); if (GLAD_GL_VERSION_4_3) - glCopyImageSubData( + rend_data_ctx.state.copy_image_sub_data( buf_rt->GetColorTex(), GL_TEXTURE_2D, 0, 0, 0, 0, rt->GetColorTex(), GL_TEXTURE_2D, 0, 0, 0, 0, width, height, 1); else diff --git a/src/CRE/renderer/transparency.cpp b/src/CRE/renderer/transparency.cpp index 37c282cd..7e142f94 100644 --- a/src/CRE/renderer/transparency.cpp +++ b/src/CRE/renderer/transparency.cpp @@ -58,7 +58,7 @@ namespace renderer { (rctx_ptr->render_buffer.GetColorTex(), GL_TEXTURE_2D, 0, 0, 0, 0, rt->GetColorTex(), GL_TEXTURE_2D, 0, 0, 0, 0, fbo.width, fbo.height, 1); if (GLAD_GL_VERSION_4_3) - glCopyImageSubData( + rend_data_ctx.state.copy_image_sub_data( rctx_ptr->render_buffer.GetColorTex(), GL_TEXTURE_2D, 0, 0, 0, 0, rt->GetColorTex(), GL_TEXTURE_2D, 0, 0, 0, 0, fbo.width, fbo.height, 1); else @@ -69,7 +69,7 @@ namespace renderer { void Transparency::copy(render_data_context& rend_data_ctx, GLuint texture) { if (GLAD_GL_VERSION_4_3) - glCopyImageSubData(texture, GL_TEXTURE_2D, 0, 0, 0, 0, + rend_data_ctx.state.copy_image_sub_data(texture, GL_TEXTURE_2D, 0, 0, 0, 0, fbo.textures[0], GL_TEXTURE_2D, 0, 0, 0, 0, fbo.width, fbo.height, 1); rend_data_ctx.state.bind_framebuffer(fbo.buffer); diff --git a/src/CRE/shadow.cpp b/src/CRE/shadow.cpp index 0e1a5e9e..e94daead 100644 --- a/src/CRE/shadow.cpp +++ b/src/CRE/shadow.cpp @@ -59,8 +59,8 @@ void Shadow::clear_textures(p_gl_rend_state& p_gl_rend_st) { for (int32_t i = 1; i < 3; i++) for (int32_t j = 0; j < 4; j++) { curr_render_textures[i]->Bind(p_gl_rend_st, j); - glClearColor(1.0f, 1.0f, 1.0f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT); + p_gl_rend_st.clear_color(1.0f, 1.0f, 1.0f, 1.0f); + p_gl_rend_st.clear(GL_COLOR_BUFFER_BIT); } p_gl_rend_st.bind_framebuffer(0); } diff --git a/src/CRE/shared.cpp b/src/CRE/shared.cpp index c6af71e9..31131deb 100644 --- a/src/CRE/shared.cpp +++ b/src/CRE/shared.cpp @@ -11,7 +11,7 @@ void fbo_blit(p_gl_rend_state& p_gl_rend_st, GLuint src_fbo, GLuint dst_fbo, GLint dst_x, GLint dst_y, GLint dst_width, GLint dst_height, GLbitfield mask, GLenum filter) { p_gl_rend_st.bind_read_framebuffer(src_fbo); p_gl_rend_st.bind_draw_framebuffer(dst_fbo); - glBlitFramebuffer(src_x, src_y, src_x + src_width, src_y + src_height, + p_gl_rend_st.blit_framebuffer(src_x, src_y, src_x + src_width, src_y + src_height, dst_x, dst_y, dst_x + dst_width, dst_y + dst_height, mask, filter); } diff --git a/src/CRE/sprite.cpp b/src/CRE/sprite.cpp index a5049ea5..de2822b2 100644 --- a/src/CRE/sprite.cpp +++ b/src/CRE/sprite.cpp @@ -1940,7 +1940,8 @@ namespace spr { const int32_t height = y_max - y_min + 1; if (width * height > 0) { rend_data_ctx.state.active_texture(7); - glCopyTexSubImage2D(GL_TEXTURE_2D, 0, x_min, y_min, x_min, y_min, width, height); + rend_data_ctx.state.copy_tex_sub_image_2d(GL_TEXTURE_2D, + 0, x_min, y_min, x_min, y_min, width, height); } } diff --git a/src/CRE/static_var.cpp b/src/CRE/static_var.cpp index 58962efc..3d4277ef 100644 --- a/src/CRE/static_var.cpp +++ b/src/CRE/static_var.cpp @@ -18,7 +18,7 @@ int32_t sv_anisotropy = 1; bool sv_better_reflect = false; -bool sv_shared_storage_uniform_buffer = false; +bool sv_shared_storage_uniform_buffer = true; const vec3 sv_rgb_to_luma = { 0.2126f, 0.7152f, 0.0722f diff --git a/src/ReDIVA/app.cpp b/src/ReDIVA/app.cpp index 01fa9dfe..57cc2075 100644 --- a/src/ReDIVA/app.cpp +++ b/src/ReDIVA/app.cpp @@ -439,8 +439,6 @@ int32_t app_main(const app_init_struct& ais) { glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &sv_min_uniform_buffer_alignment); if (GLAD_GL_VERSION_4_3) glGetIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &sv_min_storage_buffer_alignment); - glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); - glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); } #endif @@ -768,7 +766,6 @@ static render_context* render_context_load() { gl_state.get(); render_data_context rend_data_ctx(GL_REND_STATE_PRE_3D); - rend_data_ctx.state.get(); data_struct* aft_data = &data_list[DATA_AFT]; aet_database* aft_aet_db = &aft_data->data_ft.aet_db; @@ -1557,12 +1554,13 @@ static void render_context_disp(render_context* rctx) { pre_rend_data_ctx.state.get(); pre_rend_data_ctx.state.set_depth_mask(GL_TRUE); pre_rend_data_ctx.state.set_stencil_mask(0xFF); - glClearBufferfv(GL_COLOR, 0, (float_t*)&color_clear); - glClearDepthf(depth_clear); + pre_rend_data_ctx.state.clear_buffer(GL_COLOR, 0, (float_t*)&color_clear); + pre_rend_data_ctx.state.clear_buffer(GL_DEPTH, 0, &depth_clear); pre_rend_data_ctx.state.set_stencil_mask(0x00); pre_rend_data_ctx.state.set_depth_mask(GL_FALSE); pre_rend_data_ctx.state.set_viewport(0, 0, internal_3d_res.x, internal_3d_res.y); + pre_rend_data_ctx.state.update(); rctx->disp(); @@ -1631,6 +1629,7 @@ static void render_context_disp(render_context* rctx) { #endif } #endif + post_rend_data_ctx.state.update(); if (draw_imgui) render_context_imgui(rctx);