project64/Source/Project64-video/Renderer/OGLESwrappers.cpp

441 lines
14 KiB
C++

/***************************************************************************
* *
* Project64-video - A Nintendo 64 gfx plugin. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2017 Project64. All rights reserved. *
* Copyright (C) 2003-2009 Sergey 'Gonetz' Lipski *
* Copyright (C) 2002 Dave2001 *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* version 2 of the License, or (at your option) any later version. *
* *
****************************************************************************/
#include <GLES2/gl2.h>
#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, "func: %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);
}
}