// Project64 - A Nintendo 64 emulator // https://www.pj64-emu.com/ // Copyright(C) 2001-2021 Project64 // Copyright(C) 2003-2009 Sergey 'Gonetz' Lipski // Copyright(C) 2002 Dave2001 // GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html #include #include "glitchmain.h" #undef glActiveTexture #undef glBindTexture #undef glBlendEquation #undef glBlendEquationSeparate #undef glBlendFunc #undef glBlendFuncSeparate #undef glClearColor #undef glClearDepthf #undef glCullFace #undef glDepthFunc #undef glDepthMask #undef glDepthRangef #undef glDisable #undef glEnable #undef glFrontFace #undef glPolygonOffset #undef glScissor #undef glUseProgram #undef glViewport void vbo_draw(); GLenum GLCache::m_cached_texture; GLenum GLCache::m_cached_mode; GLenum GLCache::m_cached_modeRGB; GLenum GLCache::m_cached_modeAlpha; GLenum GLCache::m_cached_sfactor; GLenum GLCache::m_cached_dfactor; GLenum GLCache::m_cached_BlendFuncSeparate_srcRGB; GLenum GLCache::m_cached_BlendFuncSeparate_dstRGB; GLenum GLCache::m_cached_BlendFuncSeparate_srcAlpha; GLenum GLCache::m_cached_BlendFuncSeparate_dstAlpha; GLclampf GLCache::m_cached_depth; GLenum GLCache::m_cached_CullFace_mode; GLenum GLCache::m_cached_func; GLboolean GLCache::m_cached_DepthMask_flag; GLclampf GLCache::m_cached_zNear; GLclampf GLCache::m_cached_zFar; bool GLCache::m_cached_BLEND = false; bool GLCache::m_cached_CULL_FACE = false; bool GLCache::m_cached_DEPTH_TEST = false; bool GLCache::m_cached_DITHER = false; bool GLCache::m_cached_POLYGON_OFFSET_FILL = false; bool GLCache::m_cached_SAMPLE_ALPHA_TO_COVERAGE = false; bool GLCache::m_cached_SAMPLE_COVERAGE = false; bool GLCache::m_cached_SCISSOR_TEST = false; bool GLCache::m_cached_STENCIL_TEST = false; GLenum GLCache::m_cached_FrontFace_mode; GLfloat GLCache::m_cached_factor; GLfloat GLCache::m_cached_units; GLclampf GLCache::m_cached_red, GLCache::m_cached_green, GLCache::m_cached_blue, GLCache::m_cached_alpha; GLint GLCache::m_cached_x, GLCache::m_cached_y; GLsizei GLCache::m_cached_width, GLCache::m_cached_height; GLuint GLCache::m_cached_program; GLint GLCache::m_Viewport_cached_x = 0, GLCache::m_Viewport_cached_y = 0; GLsizei GLCache::m_Viewport_cached_width = 0, GLCache::m_Viewport_cached_height = 0; void GLCache::ResetCache(void) { m_cached_texture = 0; m_cached_mode = 0; m_cached_modeRGB = 0; m_cached_modeAlpha = 0; m_cached_sfactor = 0; m_cached_dfactor = 0; m_cached_BlendFuncSeparate_srcRGB = 0; m_cached_BlendFuncSeparate_dstRGB = 0; m_cached_BlendFuncSeparate_srcAlpha = 0; m_cached_BlendFuncSeparate_dstAlpha = 0; m_cached_depth = 0; m_cached_CullFace_mode = 0; m_cached_func = 0; m_cached_DepthMask_flag = 0; m_cached_zNear = 0; m_cached_zFar = 0; m_cached_BLEND = false; m_cached_CULL_FACE = false; m_cached_DEPTH_TEST = false; m_cached_DITHER = false; m_cached_POLYGON_OFFSET_FILL = false; m_cached_SAMPLE_ALPHA_TO_COVERAGE = false; m_cached_SAMPLE_COVERAGE = false; m_cached_SCISSOR_TEST = false; m_cached_STENCIL_TEST = false; m_cached_FrontFace_mode = 0; m_cached_factor = 0; m_cached_units = 0; m_cached_red = 0; m_cached_green = 0; m_cached_blue = 0; m_cached_alpha = 0; m_cached_x = 0; m_cached_y = 0; m_cached_width = 0; m_cached_height = 0; m_cached_program = 0; m_Viewport_cached_x = 0; m_Viewport_cached_y = 0; m_Viewport_cached_width = 0; m_Viewport_cached_height = 0; } void GLCache::glActiveTexture(GLenum texture) { if (texture != m_cached_texture) { WriteTrace(TraceOGLWrapper, TraceDebug, "Texture: %d", texture); vbo_draw(); ::glActiveTexture(texture); m_cached_texture = texture; } else { WriteTrace(TraceOGLWrapper, TraceDebug, "Ignored - texture: %d", texture); } } void GLCache::glBindTexture(GLenum target, GLuint texture) { WriteTrace(TraceOGLWrapper, TraceDebug, "Target: %d texture: %d", target, texture); vbo_draw(); ::glBindTexture(target, texture); } void GLCache::glBlendEquation(GLenum mode) { if (mode != m_cached_mode) { WriteTrace(TraceOGLWrapper, TraceDebug, "Mode: %d", mode); vbo_draw(); ::glBlendEquation(mode); m_cached_mode = mode; } else { WriteTrace(TraceOGLWrapper, TraceDebug, "Ignored - mode: %d", mode); } } void GLCache::glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) { if (modeRGB != m_cached_modeRGB || modeAlpha != m_cached_modeAlpha) { WriteTrace(TraceOGLWrapper, TraceDebug, "modeRGB: %d cached_modeAlpha: %d", modeRGB, m_cached_modeAlpha); vbo_draw(); ::glBlendEquationSeparate(modeRGB, modeAlpha); m_cached_modeRGB = modeRGB; m_cached_modeAlpha = modeAlpha; } else { WriteTrace(TraceOGLWrapper, TraceDebug, "Ignored - modeRGB: %d cached_modeAlpha: %d", modeRGB, m_cached_modeAlpha); } } void GLCache::glBlendFunc(GLenum sfactor, GLenum dfactor) { if (sfactor != m_cached_sfactor || dfactor != m_cached_dfactor) { WriteTrace(TraceOGLWrapper, TraceDebug, "sfactor: %d dfactor: %d", sfactor, dfactor); vbo_draw(); ::glBlendFunc(sfactor, dfactor); m_cached_sfactor = sfactor; m_cached_dfactor = dfactor; } else { WriteTrace(TraceOGLWrapper, TraceDebug, "Ignored - sfactor: %d dfactor: %d", sfactor, dfactor); } } void GLCache::glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) { if (srcRGB != m_cached_BlendFuncSeparate_srcRGB || dstRGB != m_cached_BlendFuncSeparate_dstRGB || srcAlpha != m_cached_BlendFuncSeparate_srcAlpha || dstAlpha != m_cached_BlendFuncSeparate_dstAlpha) { WriteTrace(TraceOGLWrapper, TraceDebug, "srcRGB: %d dstRGB: %d srcAlpha: %d dstAlpha: %d", srcRGB, dstRGB, srcAlpha, dstAlpha); vbo_draw(); ::glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha); m_cached_BlendFuncSeparate_srcRGB = srcRGB; m_cached_BlendFuncSeparate_dstRGB = dstRGB; m_cached_BlendFuncSeparate_srcAlpha = srcAlpha; m_cached_BlendFuncSeparate_dstAlpha = dstAlpha; } else { WriteTrace(TraceOGLWrapper, TraceDebug, "Ignored - srcRGB: %d dstRGB: %d srcAlpha: %d dstAlpha: %d", srcRGB, dstRGB, srcAlpha, dstAlpha); } } void GLCache::glClearDepthf(GLclampf depth) { if (depth != m_cached_depth) { WriteTrace(TraceOGLWrapper, TraceDebug, "Depth: %d", depth); vbo_draw(); ::glClearDepthf(depth); m_cached_depth = depth; } else { WriteTrace(TraceOGLWrapper, TraceDebug, "Ignored - depth: %d", depth); } } void GLCache::glCullFace(GLenum mode) { if (mode != m_cached_CullFace_mode) { WriteTrace(TraceOGLWrapper, TraceDebug, "Mode: %d", mode); vbo_draw(); ::glCullFace(mode); m_cached_CullFace_mode = mode; } else { WriteTrace(TraceOGLWrapper, TraceDebug, "Ignored - mode: %d", mode); } } void GLCache::glDepthFunc(GLenum func) { if (func != m_cached_func) { WriteTrace(TraceOGLWrapper, TraceDebug, "Function: %d", func); vbo_draw(); ::glDepthFunc(func); m_cached_func = func; } else { WriteTrace(TraceOGLWrapper, TraceDebug, "Ignored - func: %d", func); } } void GLCache::glDepthMask(GLboolean flag) { if (flag != m_cached_DepthMask_flag) { WriteTrace(TraceOGLWrapper, TraceDebug, "Flag: %d", (int)flag); vbo_draw(); ::glDepthMask(flag); m_cached_DepthMask_flag = flag; } else { WriteTrace(TraceOGLWrapper, TraceDebug, "Ignored - flag: %d", (int)flag); } } void GLCache::glDepthRangef(GLclampf zNear, GLclampf zFar) { if (zNear != m_cached_zNear || zFar != m_cached_zFar) { WriteTrace(TraceOGLWrapper, TraceDebug, "zNear: %d zFar: %d", zNear, zFar); vbo_draw(); ::glDepthRangef(zNear, zFar); m_cached_zNear = zNear; m_cached_zFar = zFar; } else { WriteTrace(TraceOGLWrapper, TraceDebug, "Ignored - zNear: %d zFar: %d", zNear, zFar); } } void GLCache::glEnableDisableItem(GLenum cap, bool enable, bool & cached_state, const char * StateName) { if (enable) { if (!cached_state) { WriteTrace(TraceOGLWrapper, TraceDebug, "glEnable(%s)", StateName); vbo_draw(); ::glEnable(cap); cached_state = true; } else { WriteTrace(TraceOGLWrapper, TraceDebug, "Ignored - glEnable(%s)", StateName); } } else { if (cached_state) { WriteTrace(TraceOGLWrapper, TraceDebug, "glDisable(%s)", StateName); vbo_draw(); ::glDisable(cap); cached_state = false; } else { WriteTrace(TraceOGLWrapper, TraceDebug, "Ignored - glEnable(%s)", StateName); } } } void GLCache::glEnableDisable(GLenum cap, bool enable) { if (cap == GL_BLEND) { GLCache::glEnableDisableItem(cap, enable, m_cached_BLEND, "GL_BLEND"); } else if (cap == GL_CULL_FACE) { GLCache::glEnableDisableItem(cap, enable, m_cached_CULL_FACE, "GL_CULL_FACE"); } else if (cap == GL_DEPTH_TEST) { GLCache::glEnableDisableItem(cap, enable, m_cached_DEPTH_TEST, "GL_DEPTH_TEST"); } else if (cap == GL_DITHER) { GLCache::glEnableDisableItem(cap, enable, m_cached_DITHER, "GL_DITHER"); } else if (cap == GL_POLYGON_OFFSET_FILL) { GLCache::glEnableDisableItem(cap, enable, m_cached_POLYGON_OFFSET_FILL, "GL_POLYGON_OFFSET_FILL"); } else if (cap == GL_SAMPLE_ALPHA_TO_COVERAGE) { GLCache::glEnableDisableItem(cap, enable, m_cached_SAMPLE_ALPHA_TO_COVERAGE, "GL_SAMPLE_ALPHA_TO_COVERAGE"); } else if (cap == GL_SAMPLE_COVERAGE) { GLCache::glEnableDisableItem(cap, enable, m_cached_SAMPLE_COVERAGE, "GL_SAMPLE_COVERAGE"); } else if (cap == GL_SCISSOR_TEST) { GLCache::glEnableDisableItem(cap, enable, m_cached_SCISSOR_TEST, "GL_SCISSOR_TEST"); } else if (cap == GL_STENCIL_TEST) { GLCache::glEnableDisableItem(cap, enable, m_cached_STENCIL_TEST, "GL_STENCIL_TEST"); } else { if (enable) { WriteTrace(TraceOGLWrapper, TraceDebug, "glEnable(%d)", cap); vbo_draw(); ::glEnable(cap); } else { WriteTrace(TraceOGLWrapper, TraceDebug, "glDisable(%d)", cap); vbo_draw(); ::glDisable(cap); } } } void GLCache::glFrontFace(GLenum mode) { if (mode != m_cached_FrontFace_mode) { WriteTrace(TraceOGLWrapper, TraceDebug, "Mode: %d", mode); vbo_draw(); ::glFrontFace(mode); m_cached_FrontFace_mode = mode; } else { WriteTrace(TraceOGLWrapper, TraceDebug, "Ignored - mode: %d", mode); } } void GLCache::glPolygonOffset(GLfloat factor, GLfloat units) { if (factor != m_cached_factor || units != m_cached_units) { vbo_draw(); WriteTrace(TraceOGLWrapper, TraceDebug, "Factor: %f units: %f", factor, units); ::glPolygonOffset(factor, units); m_cached_factor = factor; m_cached_units = units; } else { WriteTrace(TraceOGLWrapper, TraceDebug, "Ignored - factor: %f units: %f", factor, units); } } void GLCache::glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { if (red != m_cached_red || green != m_cached_green || blue != m_cached_blue || alpha != m_cached_alpha) { WriteTrace(TraceOGLWrapper, TraceDebug, "red: %f, green: %f, blue: %f, alpha: %f", red, green, blue, alpha); vbo_draw(); ::glClearColor(red, green, blue, alpha); m_cached_red = red; m_cached_green = green; m_cached_blue = blue; m_cached_alpha = alpha; } else { WriteTrace(TraceOGLWrapper, TraceDebug, "Ignored - red: %f, green: %f, blue: %f, alpha: %f", red, green, blue, alpha); } } void GLCache::glScissor(GLint x, GLint y, GLsizei width, GLsizei height) { if (x != m_cached_x || y != m_cached_y || width != m_cached_width || height != m_cached_height) { WriteTrace(TraceOGLWrapper, TraceDebug, "x: %d, y: %d, width: %d, height: %d", x, y, width, height); vbo_draw(); ::glScissor(x, y, width, height); m_cached_x = x; m_cached_y = y; m_cached_width = width; m_cached_height = height; } else { WriteTrace(TraceOGLWrapper, TraceDebug, "Ignored - x: %d, y: %d, width: %d, height: %d", x, y, width, height); } } void GLCache::glUseProgram(GLuint program) { if (program != m_cached_program) { WriteTrace(TraceOGLWrapper, TraceDebug, "Program: %d", program); vbo_draw(); ::glUseProgram(program); m_cached_program = program; } else { WriteTrace(TraceOGLWrapper, TraceDebug, "Ignored - program: %d", program); } } void GLCache::glViewport(GLint x, GLint y, GLsizei width, GLsizei height) { if (x != m_Viewport_cached_x || y != m_Viewport_cached_y || width != m_Viewport_cached_width || height != m_Viewport_cached_height) { WriteTrace(TraceOGLWrapper, TraceDebug, "x: %d, y: %d, width: %d, height: %d", x, y, width, height); vbo_draw(); ::glViewport(x, y, width, height); m_Viewport_cached_x = x; m_Viewport_cached_y = y; m_Viewport_cached_width = width; m_Viewport_cached_height = height; } else { WriteTrace(TraceOGLWrapper, TraceDebug, "Ignored x: %d, y: %d, width: %d, height: %d", x, y, width, height); } }