@ -11,7 +11,9 @@
namespace OpenGL {
namespace OpenGL {
OpenGLState OpenGLState : : cur_state ;
OpenGLState OpenGLState : : cur_state ;
bool OpenGLState : : s_rgb_used ;
bool OpenGLState : : s_rgb_used ;
OpenGLState : : OpenGLState ( ) {
OpenGLState : : OpenGLState ( ) {
// These all match default OpenGL values
// These all match default OpenGL values
geometry_shaders . enabled = false ;
geometry_shaders . enabled = false ;
@ -112,7 +114,6 @@ void OpenGLState::ApplyDefaultState() {
}
}
void OpenGLState : : ApplySRgb ( ) const {
void OpenGLState : : ApplySRgb ( ) const {
// sRGB
if ( framebuffer_srgb . enabled ! = cur_state . framebuffer_srgb . enabled ) {
if ( framebuffer_srgb . enabled ! = cur_state . framebuffer_srgb . enabled ) {
if ( framebuffer_srgb . enabled ) {
if ( framebuffer_srgb . enabled ) {
// Track if sRGB is used
// Track if sRGB is used
@ -125,23 +126,20 @@ void OpenGLState::ApplySRgb() const {
}
}
void OpenGLState : : ApplyCulling ( ) const {
void OpenGLState : : ApplyCulling ( ) const {
// Culling
if ( cull . enabled ! = cur_state . cull . enabled ) {
const bool cull_changed = cull . enabled ! = cur_state . cull . enabled ;
if ( cull_changed ) {
if ( cull . enabled ) {
if ( cull . enabled ) {
glEnable ( GL_CULL_FACE ) ;
glEnable ( GL_CULL_FACE ) ;
} else {
} else {
glDisable ( GL_CULL_FACE ) ;
glDisable ( GL_CULL_FACE ) ;
}
}
}
}
if ( cull . enabled ) {
if ( cull_changed | | cull . mode ! = cur_state . cull . mode ) {
glCullFace ( cull . mode ) ;
}
if ( cull_changed | | cull . front_face ! = cur_state . cull . front_face ) {
if ( cull . mode ! = cur_state . cull . mode ) {
glFrontFace ( cull . front_face ) ;
glCullFace ( cull . mode ) ;
}
}
if ( cull . front_face ! = cur_state . cull . front_face ) {
glFrontFace ( cull . front_face ) ;
}
}
}
}
@ -172,72 +170,63 @@ void OpenGLState::ApplyColorMask() const {
}
}
void OpenGLState : : ApplyDepth ( ) const {
void OpenGLState : : ApplyDepth ( ) const {
// Depth test
if ( depth . test_enabled ! = cur_state . depth . test_enabled ) {
const bool depth_test_changed = depth . test_enabled ! = cur_state . depth . test_enabled ;
if ( depth_test_changed ) {
if ( depth . test_enabled ) {
if ( depth . test_enabled ) {
glEnable ( GL_DEPTH_TEST ) ;
glEnable ( GL_DEPTH_TEST ) ;
} else {
} else {
glDisable ( GL_DEPTH_TEST ) ;
glDisable ( GL_DEPTH_TEST ) ;
}
}
}
}
if ( depth . test_enabled & &
( depth_test_changed | | depth . test_func ! = cur_state . depth . test_func ) ) {
if ( depth . test_func ! = cur_state . depth . test_func ) {
glDepthFunc ( depth . test_func ) ;
glDepthFunc ( depth . test_func ) ;
}
}
// Depth mask
if ( depth . write_mask ! = cur_state . depth . write_mask ) {
if ( depth . write_mask ! = cur_state . depth . write_mask ) {
glDepthMask ( depth . write_mask ) ;
glDepthMask ( depth . write_mask ) ;
}
}
}
}
void OpenGLState : : ApplyPrimitiveRestart ( ) const {
void OpenGLState : : ApplyPrimitiveRestart ( ) const {
const bool primitive_restart_changed =
if ( primitive_restart . enabled ! = cur_state . primitive_restart . enabled ) {
primitive_restart . enabled ! = cur_state . primitive_restart . enabled ;
if ( primitive_restart_changed ) {
if ( primitive_restart . enabled ) {
if ( primitive_restart . enabled ) {
glEnable ( GL_PRIMITIVE_RESTART ) ;
glEnable ( GL_PRIMITIVE_RESTART ) ;
} else {
} else {
glDisable ( GL_PRIMITIVE_RESTART ) ;
glDisable ( GL_PRIMITIVE_RESTART ) ;
}
}
}
}
if ( primitive_restart_changed | |
( primitive_restart . enabled & &
if ( primitive_restart . index ! = cur_state . primitive_restart . index ) {
primitive_restart . index ! = cur_state . primitive_restart . index ) ) {
glPrimitiveRestartIndex ( primitive_restart . index ) ;
glPrimitiveRestartIndex ( primitive_restart . index ) ;
}
}
}
}
void OpenGLState : : ApplyStencilTest ( ) const {
void OpenGLState : : ApplyStencilTest ( ) const {
const bool stencil_test_changed = stencil . test_enabled ! = cur_state . stencil . test_enabled ;
if ( stencil . test_enabled ! = cur_state . stencil . test_enabled ) {
if ( stencil_test_changed ) {
if ( stencil . test_enabled ) {
if ( stencil . test_enabled ) {
glEnable ( GL_STENCIL_TEST ) ;
glEnable ( GL_STENCIL_TEST ) ;
} else {
} else {
glDisable ( GL_STENCIL_TEST ) ;
glDisable ( GL_STENCIL_TEST ) ;
}
}
}
}
if ( stencil . test_enabled ) {
auto config_stencil = [ stencil_test_changed ] ( GLenum face , const auto & config ,
const auto ConfigStencil = [ ] ( GLenum face , const auto & config , const auto & prev_config ) {
const auto & prev_config ) {
if ( config . test_func ! = prev_config . test_func | | config . test_ref ! = prev_config . test_ref | |
if ( stencil_test_changed | | config . test_func ! = prev_config . test_func | |
config . test_mask ! = prev_config . test_mask ) {
config . test_ref ! = prev_config . test_ref | |
glStencilFuncSeparate ( face , config . test_func , config . test_ref , config . test_mask ) ;
config . test_mask ! = prev_config . test_mask ) {
}
glStencilFuncSeparate ( face , config . test_func , config . test_ref , config . test_mask ) ;
if ( config . action_depth_fail ! = prev_config . action_depth_fail | |
}
config . action_depth_pass ! = prev_config . action_depth_pass | |
if ( stencil_test_changed | | config . action_depth_fail ! = prev_config . action_depth_fail | |
config . action_stencil_fail ! = prev_config . action_stencil_fail ) {
config . action_depth_pass ! = prev_config . action_depth_pass | |
glStencilOpSeparate ( face , config . action_stencil_fail , config . action_depth_fail ,
config . action_stencil_fail ! = prev_config . action_stencil_fail ) {
config . action_depth_pass ) ;
glStencilOpSeparate ( face , config . action_stencil_fail , config . action_depth_fail ,
}
config . action_depth_pass ) ;
if ( config . write_mask ! = prev_config . write_mask ) {
}
glStencilMaskSeparate ( face , config . write_mask ) ;
if ( config . write_mask ! = prev_config . write_mask ) {
}
glStencilMaskSeparate ( face , config . write_mask ) ;
} ;
}
ConfigStencil ( GL_FRONT , stencil . front , cur_state . stencil . front ) ;
} ;
ConfigStencil ( GL_BACK , stencil . back , cur_state . stencil . back ) ;
config_stencil ( GL_FRONT , stencil . front , cur_state . stencil . front ) ;
config_stencil ( GL_BACK , stencil . back , cur_state . stencil . back ) ;
}
}
}
// Viewport does not affects glClearBuffer so emulate viewport using scissor test
// Viewport does not affects glClearBuffer so emulate viewport using scissor test
void OpenGLState : : EmulateViewportWithScissor ( ) {
void OpenGLState : : EmulateViewportWithScissor ( ) {
@ -278,19 +267,18 @@ void OpenGLState::ApplyViewport() const {
updated . depth_range_far ! = current . depth_range_far ) {
updated . depth_range_far ! = current . depth_range_far ) {
glDepthRangeIndexed ( i , updated . depth_range_near , updated . depth_range_far ) ;
glDepthRangeIndexed ( i , updated . depth_range_near , updated . depth_range_far ) ;
}
}
const bool scissor_changed = updated . scissor . enabled ! = current . scissor . enabled ;
if ( scissor_chang ed) {
if ( updated. scissor . enabled ! = current . scissor . enabl ed) {
if ( updated . scissor . enabled ) {
if ( updated . scissor . enabled ) {
glEnablei ( GL_SCISSOR_TEST , i ) ;
glEnablei ( GL_SCISSOR_TEST , i ) ;
} else {
} else {
glDisablei ( GL_SCISSOR_TEST , i ) ;
glDisablei ( GL_SCISSOR_TEST , i ) ;
}
}
}
}
if ( updated . scissor . enabled & &
( scissor_changed | | updated . scissor . x ! = current . scissor . x | |
if ( updated . scissor . x ! = current . scissor . x | | updated . scissor . y ! = current . scissor . y | |
updated . scissor . y ! = current . scissor . y | |
updated . scissor . width ! = current . scissor . width | |
updated . scissor . width ! = current . scissor . width | |
updated . scissor . height ! = current . scissor . height ) {
updated . scissor . height ! = current . scissor . height ) ) {
glScissorIndexed ( i , updated . scissor . x , updated . scissor . y , updated . scissor . width ,
glScissorIndexed ( i , updated . scissor . x , updated . scissor . y , updated . scissor . width ,
updated . scissor . height ) ;
updated . scissor . height ) ;
}
}
@ -302,22 +290,23 @@ void OpenGLState::ApplyViewport() const {
updated . height ! = current . height ) {
updated . height ! = current . height ) {
glViewport ( updated . x , updated . y , updated . width , updated . height ) ;
glViewport ( updated . x , updated . y , updated . width , updated . height ) ;
}
}
if ( updated . depth_range_near ! = current . depth_range_near | |
if ( updated . depth_range_near ! = current . depth_range_near | |
updated . depth_range_far ! = current . depth_range_far ) {
updated . depth_range_far ! = current . depth_range_far ) {
glDepthRange ( updated . depth_range_near , updated . depth_range_far ) ;
glDepthRange ( updated . depth_range_near , updated . depth_range_far ) ;
}
}
const bool scissor_changed = updated . scissor . enabled ! = current . scissor . enabled ;
if ( scissor_chang ed) {
if ( updated. scissor . enabled ! = current . scissor . enabl ed) {
if ( updated . scissor . enabled ) {
if ( updated . scissor . enabled ) {
glEnable ( GL_SCISSOR_TEST ) ;
glEnable ( GL_SCISSOR_TEST ) ;
} else {
} else {
glDisable ( GL_SCISSOR_TEST ) ;
glDisable ( GL_SCISSOR_TEST ) ;
}
}
}
}
if ( updated . scissor . enabled & & ( scissor_changed | | updated . scissor . x ! = current . scissor . x | |
updated . scissor . y ! = current . scissor . y | |
if ( updated . scissor . x ! = current . scissor . x | | updated . scissor . y ! = current . scissor . y | |
updated . scissor . width ! = current . scissor . width | |
updated . scissor . width ! = current . scissor . width | |
updated . scissor . height ! = current . scissor . height ) ) {
updated . scissor . height ! = current . scissor . height ) {
glScissor ( updated . scissor . x , updated . scissor . y , updated . scissor . width ,
glScissor ( updated . scissor . x , updated . scissor . y , updated . scissor . width ,
updated . scissor . height ) ;
updated . scissor . height ) ;
}
}
@ -327,8 +316,7 @@ void OpenGLState::ApplyViewport() const {
void OpenGLState : : ApplyGlobalBlending ( ) const {
void OpenGLState : : ApplyGlobalBlending ( ) const {
const Blend & current = cur_state . blend [ 0 ] ;
const Blend & current = cur_state . blend [ 0 ] ;
const Blend & updated = blend [ 0 ] ;
const Blend & updated = blend [ 0 ] ;
const bool blend_changed = updated . enabled ! = current . enabled ;
if ( updated . enabled ! = current . enabled ) {
if ( blend_changed ) {
if ( updated . enabled ) {
if ( updated . enabled ) {
glEnable ( GL_BLEND ) ;
glEnable ( GL_BLEND ) ;
} else {
} else {
@ -338,15 +326,14 @@ void OpenGLState::ApplyGlobalBlending() const {
if ( ! updated . enabled ) {
if ( ! updated . enabled ) {
return ;
return ;
}
}
if ( blend_changed | | updated. src_rgb_func ! = current . src_rgb_func | |
if ( updated. src_rgb_func ! = current . src_rgb_func | |
updated . dst_rgb_func ! = current . dst_rgb_func | | updated . src_a_func ! = current . src_a_func | |
updated . dst_rgb_func ! = current . dst_rgb_func | | updated . src_a_func ! = current . src_a_func | |
updated . dst_a_func ! = current . dst_a_func ) {
updated . dst_a_func ! = current . dst_a_func ) {
glBlendFuncSeparate ( updated . src_rgb_func , updated . dst_rgb_func , updated . src_a_func ,
glBlendFuncSeparate ( updated . src_rgb_func , updated . dst_rgb_func , updated . src_a_func ,
updated . dst_a_func ) ;
updated . dst_a_func ) ;
}
}
if ( blend_changed | | updated . rgb_equation ! = current . rgb_equation | |
if ( updated . rgb_equation ! = current . rgb_equation | | updated . a_equation ! = current . a_equation ) {
updated . a_equation ! = current . a_equation ) {
glBlendEquationSeparate ( updated . rgb_equation , updated . a_equation ) ;
glBlendEquationSeparate ( updated . rgb_equation , updated . a_equation ) ;
}
}
}
}
@ -354,26 +341,22 @@ void OpenGLState::ApplyGlobalBlending() const {
void OpenGLState : : ApplyTargetBlending ( std : : size_t target , bool force ) const {
void OpenGLState : : ApplyTargetBlending ( std : : size_t target , bool force ) const {
const Blend & updated = blend [ target ] ;
const Blend & updated = blend [ target ] ;
const Blend & current = cur_state . blend [ target ] ;
const Blend & current = cur_state . blend [ target ] ;
const bool blend_changed = updated . enabled ! = current . enabled | | force ;
if ( updated . enabled ! = current . enabled | | force ) {
if ( blend_changed ) {
if ( updated . enabled ) {
if ( updated . enabled ) {
glEnablei ( GL_BLEND , static_cast < GLuint > ( target ) ) ;
glEnablei ( GL_BLEND , static_cast < GLuint > ( target ) ) ;
} else {
} else {
glDisablei ( GL_BLEND , static_cast < GLuint > ( target ) ) ;
glDisablei ( GL_BLEND , static_cast < GLuint > ( target ) ) ;
}
}
}
}
if ( ! updated . enabled ) {
return ;
if ( updated . src_rgb_func ! = current . src_rgb_func | |
}
if ( blend_changed | | updated . src_rgb_func ! = current . src_rgb_func | |
updated . dst_rgb_func ! = current . dst_rgb_func | | updated . src_a_func ! = current . src_a_func | |
updated . dst_rgb_func ! = current . dst_rgb_func | | updated . src_a_func ! = current . src_a_func | |
updated . dst_a_func ! = current . dst_a_func ) {
updated . dst_a_func ! = current . dst_a_func ) {
glBlendFuncSeparatei ( static_cast < GLuint > ( target ) , updated . src_rgb_func ,
glBlendFuncSeparatei ( static_cast < GLuint > ( target ) , updated . src_rgb_func ,
updated . dst_rgb_func , updated . src_a_func , updated . dst_a_func ) ;
updated . dst_rgb_func , updated . src_a_func , updated . dst_a_func ) ;
}
}
if ( blend_changed | | updated . rgb_equation ! = current . rgb_equation | |
if ( updated . rgb_equation ! = current . rgb_equation | | updated . a_equation ! = current . a_equation ) {
updated . a_equation ! = current . a_equation ) {
glBlendEquationSeparatei ( static_cast < GLuint > ( target ) , updated . rgb_equation ,
glBlendEquationSeparatei ( static_cast < GLuint > ( target ) , updated . rgb_equation ,
updated . a_equation ) ;
updated . a_equation ) ;
}
}
@ -397,8 +380,7 @@ void OpenGLState::ApplyBlending() const {
}
}
void OpenGLState : : ApplyLogicOp ( ) const {
void OpenGLState : : ApplyLogicOp ( ) const {
const bool logic_op_changed = logic_op . enabled ! = cur_state . logic_op . enabled ;
if ( logic_op . enabled ! = cur_state . logic_op . enabled ) {
if ( logic_op_changed ) {
if ( logic_op . enabled ) {
if ( logic_op . enabled ) {
glEnable ( GL_COLOR_LOGIC_OP ) ;
glEnable ( GL_COLOR_LOGIC_OP ) ;
} else {
} else {
@ -406,14 +388,12 @@ void OpenGLState::ApplyLogicOp() const {
}
}
}
}
if ( logic_op . enabled & &
if ( logic_op . operation ! = cur_state . logic_op . operation ) {
( logic_op_changed | | logic_op . operation ! = cur_state . logic_op . operation ) ) {
glLogicOp ( logic_op . operation ) ;
glLogicOp ( logic_op . operation ) ;
}
}
}
}
void OpenGLState : : ApplyPolygonOffset ( ) const {
void OpenGLState : : ApplyPolygonOffset ( ) const {
const bool fill_enable_changed =
const bool fill_enable_changed =
polygon_offset . fill_enable ! = cur_state . polygon_offset . fill_enable ;
polygon_offset . fill_enable ! = cur_state . polygon_offset . fill_enable ;
const bool line_enable_changed =
const bool line_enable_changed =
@ -448,9 +428,7 @@ void OpenGLState::ApplyPolygonOffset() const {
}
}
}
}
if ( ( polygon_offset . fill_enable | | polygon_offset . line_enable | | polygon_offset . point_enable ) & &
if ( factor_changed | | units_changed | | clamp_changed ) {
( factor_changed | | units_changed | | clamp_changed ) ) {
if ( GLAD_GL_EXT_polygon_offset_clamp & & polygon_offset . clamp ! = 0 ) {
if ( GLAD_GL_EXT_polygon_offset_clamp & & polygon_offset . clamp ! = 0 ) {
glPolygonOffsetClamp ( polygon_offset . factor , polygon_offset . units , polygon_offset . clamp ) ;
glPolygonOffsetClamp ( polygon_offset . factor , polygon_offset . units , polygon_offset . clamp ) ;
} else {
} else {
@ -528,9 +506,9 @@ void OpenGLState::ApplyDepthClamp() const {
depth_clamp . near_plane = = cur_state . depth_clamp . near_plane ) {
depth_clamp . near_plane = = cur_state . depth_clamp . near_plane ) {
return ;
return ;
}
}
if ( depth_clamp . far_plane ! = depth_clamp . near_plane ) {
UNIMPLEMENTED_IF_MSG ( depth_clamp . far_plane ! = depth_clamp . near_plane ,
UNIMPLEMENTED_MSG ( " Unimplemented Depth Clamp Separation! " ) ;
" Unimplemented Depth Clamp Separation! " ) ;
}
if ( depth_clamp . far_plane | | depth_clamp . near_plane ) {
if ( depth_clamp . far_plane | | depth_clamp . near_plane ) {
glEnable ( GL_DEPTH_CLAMP ) ;
glEnable ( GL_DEPTH_CLAMP ) ;
} else {
} else {