1
0
mirror of https://github.com/blawar/GLideN64.git synced 2024-07-04 10:03:36 +00:00

Remove unused shaders related files.

This commit is contained in:
Sergey Lipskiy 2017-01-08 20:31:38 +07:00
parent f650e5e54b
commit c39b639d7c
23 changed files with 0 additions and 4600 deletions

View File

@ -290,16 +290,6 @@
<ClCompile Include="..\..\src\GBI.cpp" />
<ClCompile Include="..\..\src\gDP.cpp" />
<ClCompile Include="..\..\src\GLideN64.cpp" />
<ClCompile Include="..\..\src\GLUniforms\UniformBlock.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug_mupenplus_uniformset|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\GLUniforms\UniformSet.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug_mupenplus_uniformset|Win32'">false</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_mupenplus|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug_mupenplus|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\Graphics\CombinerProgram.cpp" />
<ClCompile Include="..\..\src\Graphics\Context.cpp" />
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLFunctions.cpp" />
@ -343,7 +333,6 @@
</ClCompile>
<ClCompile Include="..\..\src\N64.cpp" />
<ClCompile Include="..\..\src\NoiseTexture.cpp" />
<ClCompile Include="..\..\src\OGL3X\GLSLCombiner_ogl3x.cpp" />
<ClCompile Include="..\..\src\OpenGL.cpp" />
<ClCompile Include="..\..\src\PaletteTexture.cpp" />
<ClCompile Include="..\..\src\Performance.cpp" />
@ -431,17 +420,6 @@
<ClInclude Include="..\..\src\gDP.h" />
<ClInclude Include="..\..\src\GLideN64.h" />
<ClInclude Include="..\..\src\GLideNHQ\Ext_TxFilter.h" />
<ClInclude Include="..\..\src\GLSLCombiner.h" />
<ClInclude Include="..\..\src\GLUniforms\UniformBlock.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug_mupenplus_uniformset|Win32'">true</ExcludedFromBuild>
</ClInclude>
<ClInclude Include="..\..\src\GLUniforms\UniformSet.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug_mupenplus|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug_mupenplus_uniformset|Win32'">false</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_mupenplus|Win32'">true</ExcludedFromBuild>
</ClInclude>
<ClInclude Include="..\..\src\Graphics\CombinerProgram.h" />
<ClInclude Include="..\..\src\Graphics\Context.h" />
<ClInclude Include="..\..\src\Graphics\ContextImpl.h" />
@ -476,7 +454,6 @@
</ClInclude>
<ClInclude Include="..\..\src\N64.h" />
<ClInclude Include="..\..\src\NoiseTexture.h" />
<ClInclude Include="..\..\src\OGL3X\Shaders_ogl3x.h" />
<ClInclude Include="..\..\src\OpenGL.h" />
<ClInclude Include="..\..\src\PaletteTexture.h" />
<ClInclude Include="..\..\src\Performance.h" />
@ -491,7 +468,6 @@
<ClInclude Include="..\..\src\Textures.h" />
<ClInclude Include="..\..\src\Turbo3D.h" />
<ClInclude Include="..\..\src\Types.h" />
<ClInclude Include="..\..\src\UniformCollection.h" />
<ClInclude Include="..\..\src\VI.h" />
<ClInclude Include="..\..\src\F3D.h" />
<ClInclude Include="..\..\src\F3DDKR.h" />

View File

@ -30,12 +30,6 @@
<Filter Include="Source Files\mupenplus">
<UniqueIdentifier>{b10a85f0-0fbb-4f8e-b6d8-78ee2a6394bf}</UniqueIdentifier>
</Filter>
<Filter Include="OGL3X">
<UniqueIdentifier>{b3016e90-1a88-4a28-9ca4-fbebf41e10ee}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\OGL3X">
<UniqueIdentifier>{32bbb389-ea50-4ac9-bb55-84e4f066fe94}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\BufferCopy">
<UniqueIdentifier>{e9bcfc4d-06e5-496a-a069-3d28e2fcd559}</UniqueIdentifier>
</Filter>
@ -48,12 +42,6 @@
<Filter Include="Source Files\DepthBufferRender">
<UniqueIdentifier>{ac6b6e3c-c470-4a66-ad6c-d4ad388ec793}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\GLUniforms">
<UniqueIdentifier>{b4b4d718-d4cf-4851-bd8f-fe0646df3d76}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\GLUniforms">
<UniqueIdentifier>{6207c101-59f4-44f2-9022-0b5d14645d92}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\common">
<UniqueIdentifier>{699714e2-bd52-4b7d-a5d5-4e514651293f}</UniqueIdentifier>
</Filter>
@ -212,9 +200,6 @@
<ClCompile Include="..\..\src\ShaderUtils.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\src\OGL3X\GLSLCombiner_ogl3x.cpp">
<Filter>Source Files\OGL3X</Filter>
</ClCompile>
<ClCompile Include="..\..\src\FrameBufferInfo.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@ -245,12 +230,6 @@
<ClCompile Include="..\..\src\FBOTextureFormats.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\src\GLUniforms\UniformSet.cpp">
<Filter>Source Files\GLUniforms</Filter>
</ClCompile>
<ClCompile Include="..\..\src\GLUniforms\UniformBlock.cpp">
<Filter>Source Files\GLUniforms</Filter>
</ClCompile>
<ClCompile Include="..\..\src\convert.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@ -469,18 +448,9 @@
<ClInclude Include="..\..\src\Keys.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\src\UniformCollection.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ShaderUtils.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\src\OGL3X\Shaders_ogl3x.h">
<Filter>OGL3X</Filter>
</ClInclude>
<ClInclude Include="..\..\src\GLSLCombiner.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\src\wst.h">
<Filter>Header Files</Filter>
</ClInclude>
@ -517,12 +487,6 @@
<ClInclude Include="..\..\src\FBOTextureFormats.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\src\GLUniforms\UniformSet.h">
<Filter>Header Files\GLUniforms</Filter>
</ClInclude>
<ClInclude Include="..\..\src\GLUniforms\UniformBlock.h">
<Filter>Header Files\GLUniforms</Filter>
</ClInclude>
<ClInclude Include="..\..\src\inc\glext.h">
<Filter>Header Files</Filter>
</ClInclude>

View File

@ -2,7 +2,6 @@
#include <FBOTextureFormats.h>
#include <FrameBufferInfo.h>
#include <GLSLCombiner.h>
#include <FrameBuffer.h>
#include <Combiner.h>
#include <Textures.h>

View File

@ -5,8 +5,6 @@
#include "OpenGL.h"
#include "Combiner.h"
#include "GLSLCombiner.h"
#include "UniformCollection.h"
#include "Debug.h"
#include "gDP.h"
#include "Config.h"

View File

@ -12,7 +12,6 @@
#include "VI.h"
#include "Textures.h"
#include "Combiner.h"
#include "GLSLCombiner.h"
#include "Types.h"
#include "Config.h"
#include "Debug.h"

View File

@ -1,522 +0,0 @@
#include <assert.h>
#include <stdio.h>
#include <string>
#include <memory>
#include <N64.h>
#include <OpenGL.h>
#include <Config.h>
#include <GLSLCombiner.h>
#include <ShaderUtils.h>
#include <FrameBuffer.h>
#include <DepthBuffer.h>
#include <RSP.h>
#include <VI.h>
#include <Log.h>
#include <FBOTextureFormats.h>
#include "Shaders_gles2.h"
using namespace std;
static GLuint g_vertex_shader_object;
static GLuint g_vertex_shader_object_notex;
GLuint g_monochrome_image_program = 0;
static bool g_weakGLSL = false;
#define GL_RED16 GL_R16UI
static std::string strFragmentShader;
class NoiseTexture
{
public:
NoiseTexture() : m_pTexture(nullptr), m_pData(nullptr), m_DList(0) {}
void init();
void destroy();
void update();
private:
CachedTexture * m_pTexture;
std::unique_ptr<GLubyte[]> m_pData;
u32 m_DList;
} noiseTex;
void NoiseTexture::init()
{
if (config.generalEmulation.enableNoise == 0)
return;
m_pTexture = textureCache().addFrameBufferTexture();
m_pTexture->format = G_IM_FMT_RGBA;
m_pTexture->clampS = 1;
m_pTexture->clampT = 1;
m_pTexture->frameBufferTexture = CachedTexture::fbOneSample;
m_pTexture->maskS = 0;
m_pTexture->maskT = 0;
m_pTexture->mirrorS = 0;
m_pTexture->mirrorT = 0;
m_pTexture->realWidth = 640;
m_pTexture->realHeight = 580;
m_pTexture->textureBytes = m_pTexture->realWidth * m_pTexture->realHeight;
textureCache().addFrameBufferTextureSize(m_pTexture->textureBytes);
glBindTexture(GL_TEXTURE_2D, m_pTexture->glName);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, m_pTexture->realWidth, m_pTexture->realHeight, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, 0);
m_pData.reset(new GLubyte[640 * 580]);
}
void NoiseTexture::destroy()
{
if (m_pTexture != nullptr) {
textureCache().removeFrameBufferTexture(m_pTexture);
m_pTexture = nullptr;
}
}
void NoiseTexture::update()
{
if (m_DList == video().getBuffersSwapCount() || config.generalEmulation.enableNoise == 0)
return;
if (VI.width*VI.height == 0)
return;
for (u32 y = 0; y < VI.height; ++y) {
for (u32 x = 0; x < VI.width; ++x)
m_pData[x + y*VI.width] = rand() & 0xFF;
}
glActiveTexture(GL_TEXTURE0 + g_noiseTexIndex);
glBindTexture(GL_TEXTURE_2D, m_pTexture->glName);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, VI.width, VI.height, GL_LUMINANCE, GL_UNSIGNED_BYTE, m_pData.get());
m_DList = video().getBuffersSwapCount();
}
static
GLuint _createShader(GLenum _type, const char * _strShader)
{
GLuint shader_object = glCreateShader(_type);
glShaderSource(shader_object, 1, &_strShader, nullptr);
glCompileShader(shader_object);
assert(checkShaderCompileStatus(shader_object));
return shader_object;
}
void InitShaderCombiner()
{
if (strstr((const char*)glGetString(GL_VERSION), "OpenGL ES 2") != nullptr) {
const char * strRenderer = reinterpret_cast<const char*>(glGetString(GL_RENDERER));
if (strstr(strRenderer, "PowerVR") != nullptr || strstr(strRenderer, "Adreno") != nullptr) {
g_weakGLSL = true;
LOG(LOG_MINIMAL, "GPU with week GLSL detected: %s\n", strRenderer);
}
}
g_vertex_shader_object = _createShader(GL_VERTEX_SHADER, vertex_shader);
g_vertex_shader_object_notex = _createShader(GL_VERTEX_SHADER, vertex_shader_notex);
strFragmentShader.reserve(1024*5);
noiseTex.init();
g_monochrome_image_program = createShaderProgram(default_vertex_shader, zelda_monochrome_fragment_shader);
}
void DestroyShaderCombiner() {
strFragmentShader.clear();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDeleteShader(g_vertex_shader_object);
g_vertex_shader_object = 0;
glDeleteShader(g_vertex_shader_object_notex);
g_vertex_shader_object_notex = 0;
glDeleteProgram(g_monochrome_image_program);
g_monochrome_image_program = 0;
noiseTex.destroy();
}
ShaderCombiner::ShaderCombiner(Combiner & _color, Combiner & _alpha, const gDPCombine & _combine) : m_key(getCombinerKey(_combine.mux))
{
std::string strCombiner;
m_nInputs = compileCombiner(_combine, _color, _alpha, strCombiner);
if (usesTexture()) {
strFragmentShader.assign(fragment_shader_header_common_variables);
if (gDP.otherMode.cycleType == G_CYC_2CYCLE && config.generalEmulation.enableLegacyBlending == 0)
strFragmentShader.append(fragment_shader_header_common_variables_blend_mux_2cycle);
strFragmentShader.append(fragment_shader_header_common_functions);
} else {
strFragmentShader.assign(fragment_shader_header_common_variables_notex);
if (gDP.otherMode.cycleType == G_CYC_2CYCLE && config.generalEmulation.enableLegacyBlending == 0)
strFragmentShader.append(fragment_shader_header_common_variables_blend_mux_2cycle);
strFragmentShader.append(fragment_shader_header_common_functions_notex);
}
strFragmentShader.append(fragment_shader_header_main);
if (config.generalEmulation.enableLegacyBlending == 0)
strFragmentShader.append(fragment_shader_blend_mux);
const bool bUseLod = usesLOD();
if (bUseLod) {
strFragmentShader.append(" lowp vec4 readtex0, readtex1; \n");
strFragmentShader.append(" lowp float lod_frac = mipmap(readtex0, readtex1); \n");
} else {
if (usesTile(0)) {
strFragmentShader.append(" nCurrentTile = 0; \n");
strFragmentShader.append(" lowp vec4 readtex0 = readTex(uTex0, vTexCoord0, uFbMonochrome[0], uFbFixedAlpha[0]); \n");
}
if (usesTile(1)) {
strFragmentShader.append(" nCurrentTile = 1; \n");
strFragmentShader.append(" lowp vec4 readtex1 = readTex(uTex1, vTexCoord1, uFbMonochrome[1], uFbFixedAlpha[1]); \n");
}
}
const bool bUseHWLight = config.generalEmulation.enableHWLighting != 0 && GBI.isHWLSupported() && usesShadeColor();
if (bUseHWLight) {
strFragmentShader.append(" calc_light(vNumLights, vShadeColor.rgb, input_color); \n");
m_nInputs |= 1 << HW_LIGHT;
} else {
strFragmentShader.append(" input_color = vShadeColor.rgb;\n");
}
strFragmentShader.append(" vec_color = vec4(input_color, vShadeColor.a); \n");
strFragmentShader.append(strCombiner);
strFragmentShader.append(" gl_FragColor = fragColor; \n");
strFragmentShader.append(fragment_shader_end);
if (config.generalEmulation.enableNoise == 0)
strFragmentShader.append(fragment_shader_dummy_noise);
if (bUseHWLight)
strFragmentShader.append(fragment_shader_calc_light);
if (bUseLod) {
if (config.generalEmulation.enableLOD != 0)
strFragmentShader.append(fragment_shader_mipmap);
else
strFragmentShader.append(fragment_shader_fake_mipmap);
} else if (usesTexture()) {
if (config.texture.bilinearMode == BILINEAR_3POINT)
strFragmentShader.append(fragment_shader_readtex_3point);
else
strFragmentShader.append(fragment_shader_readtex);
}
if (config.generalEmulation.enableNoise != 0) {
strFragmentShader.append(fragment_shader_noise);
}
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
const GLchar * strShaderData = strFragmentShader.data();
glShaderSource(fragmentShader, 1, &strShaderData, nullptr);
glCompileShader(fragmentShader);
if (!checkShaderCompileStatus(fragmentShader))
logErrorShader(GL_FRAGMENT_SHADER, strFragmentShader);
m_program = glCreateProgram();
_locate_attributes();
if (usesTexture())
glAttachShader(m_program, g_vertex_shader_object);
else
glAttachShader(m_program, g_vertex_shader_object_notex);
glAttachShader(m_program, fragmentShader);
glLinkProgram(m_program);
assert(checkProgramLinkStatus(m_program));
glDeleteShader(fragmentShader);
_locateUniforms();
}
ShaderCombiner::~ShaderCombiner() {
glDeleteProgram(m_program);
m_program = 0;
}
#define LocateUniform(A) \
m_uniforms.A.loc = glGetUniformLocation(m_program, #A);
void ShaderCombiner::_locateUniforms() {
LocateUniform(uTex0);
LocateUniform(uTex1);
LocateUniform(uTexNoise);
LocateUniform(uTlutImage);
LocateUniform(uZlutImage);
LocateUniform(uDepthImage);
LocateUniform(uFogUsage);
LocateUniform(uScreenCoordsScale);
LocateUniform(uAlphaCompareMode);
LocateUniform(uCvgXAlpha);
LocateUniform(uAlphaCvgSel);
LocateUniform(uEnableLod);
LocateUniform(uEnableAlphaTest);
LocateUniform(uEnableDepth);
LocateUniform(uEnableDepthCompare)
LocateUniform(uEnableDepthUpdate);
LocateUniform(uDepthMode);
LocateUniform(uDepthSource);
LocateUniform(uFbMonochrome);
LocateUniform(uFbFixedAlpha);
LocateUniform(uMaxTile)
LocateUniform(uTextureDetail);
LocateUniform(uTexturePersp);
LocateUniform(uTextureFilterMode);
LocateUniform(uForceBlendCycle1);
LocateUniform(uForceBlendCycle2);
LocateUniform(uMinLod);
LocateUniform(uDeltaZ);
LocateUniform(uAlphaTestValue);
LocateUniform(uRenderState);
LocateUniform(uScreenScale);
LocateUniform(uFogScale);
LocateUniform(uBlendMux1);
LocateUniform(uBlendMux2);
}
void ShaderCombiner::_locate_attributes() const {
glBindAttribLocation(m_program, SC_POSITION, "aPosition");
glBindAttribLocation(m_program, SC_COLOR, "aColor");
glBindAttribLocation(m_program, SC_TEXCOORD0, "aTexCoord0");
glBindAttribLocation(m_program, SC_TEXCOORD1, "aTexCoord1");
glBindAttribLocation(m_program, SC_NUMLIGHTS, "aNumLights");
glBindAttribLocation(m_program, SC_MODIFY, "aModify");
}
void ShaderCombiner::update(bool _bForce) {
_bForce |= m_bNeedUpdate;
m_bNeedUpdate = false;
glUseProgram(m_program);
if (_bForce) {
m_uniforms.uTexNoise.set(g_noiseTexIndex, true);
if (usesTexture()) {
m_uniforms.uTex0.set(0, true);
m_uniforms.uTex1.set(1, true);
}
updateFrameBufferInfo(true);
updateRenderState(true);
}
updateFogMode(_bForce);
updateBlendMode(_bForce);
updateDitherMode(_bForce);
updateLOD(_bForce);
updateTextureInfo(_bForce);
updateAlphaTestInfo(_bForce);
updateDepthInfo(_bForce);
updateScreenCoordsScale(_bForce);
}
void ShaderCombiner::updateRenderState(bool _bForce)
{
m_uniforms.uRenderState.set(video().getRender().getRenderState(), _bForce);
}
void ShaderCombiner::updateScreenCoordsScale(bool _bForce)
{
FrameBuffer * pCurrentBuffer = frameBufferList().getCurrent();
const float scaleX = pCurrentBuffer != nullptr ? 1.0f / pCurrentBuffer->m_width : VI.rwidth;
const float scaleY = pCurrentBuffer != nullptr ? 1.0f / pCurrentBuffer->m_height : VI.rheight;
m_uniforms.uScreenCoordsScale.set(2.0f*scaleX, -2.0f*scaleY, _bForce);
}
void ShaderCombiner::updateFogMode(bool _bForce)
{
if (RSP.bLLE) {
m_uniforms.uFogUsage.set(0, _bForce);
return;
}
int nFogUsage = ((gSP.geometryMode & G_FOG) != 0) ? 1 : 0;
if (!GBI.isTextureGen())
// F-Zero ucode seems to always use fog mode when fog is used in blender.
nFogUsage |= (gDP.otherMode.c1_m1a == 3 || gDP.otherMode.c1_m2a == 3) ? 1 : 0;
m_uniforms.uFogUsage.set(nFogUsage, _bForce);
m_uniforms.uFogScale.set((float)gSP.fog.multiplier / 256.0f, (float)gSP.fog.offset / 256.0f, _bForce);
}
void ShaderCombiner::updateBlendMode(bool _bForce)
{
if (config.generalEmulation.enableLegacyBlending != 0)
return;
if (gDP.otherMode.cycleType <= G_CYC_2CYCLE) {
m_uniforms.uBlendMux1.set(gDP.otherMode.c1_m1a,
gDP.otherMode.c1_m1b,
gDP.otherMode.c1_m2a,
gDP.otherMode.c1_m2b,
_bForce);
}
int forceBlend1 = gDP.otherMode.cycleType == G_CYC_2CYCLE ? 1 : 0;
int forceBlend2 = 0;
if (gDP.otherMode.forceBlender != 0 && gDP.otherMode.cycleType <= G_CYC_2CYCLE) {
forceBlend1 = 1;
if (gDP.otherMode.cycleType == G_CYC_2CYCLE) {
forceBlend2 = 1;
m_uniforms.uBlendMux2.set(gDP.otherMode.c2_m1a,
gDP.otherMode.c2_m1b,
gDP.otherMode.c2_m2a,
gDP.otherMode.c2_m2b,
_bForce);
}
}
m_uniforms.uForceBlendCycle1.set(forceBlend1, _bForce);
m_uniforms.uForceBlendCycle2.set(forceBlend2, _bForce);
}
void ShaderCombiner::disableBlending()
{
if (config.generalEmulation.enableLegacyBlending != 0)
return;
m_uniforms.uForceBlendCycle1.set(0, false);
m_uniforms.uForceBlendCycle2.set(0, false);
}
void ShaderCombiner::updateDitherMode(bool _bForce)
{
if (gDP.otherMode.cycleType < G_CYC_COPY)
m_uniforms.uAlphaCompareMode.set(gDP.otherMode.alphaCompare, _bForce);
else
m_uniforms.uAlphaCompareMode.set(0, _bForce);
const int nDither = (gDP.otherMode.cycleType < G_CYC_COPY) && (gDP.otherMode.alphaCompare == G_AC_DITHER) ? 1 : 0;
if ((m_nInputs & (1 << NOISE)) + nDither != 0) {
if (config.frameBufferEmulation.nativeResFactor == 0)
m_uniforms.uScreenScale.set(video().getScaleX(), video().getScaleY(), _bForce);
else
m_uniforms.uScreenScale.set(float(config.frameBufferEmulation.nativeResFactor), float(config.frameBufferEmulation.nativeResFactor), _bForce);
noiseTex.update();
}
}
void ShaderCombiner::updateLOD(bool _bForce)
{
if (!usesLOD())
return;
m_uniforms.uMinLod.set(gDP.primColor.m, _bForce);
m_uniforms.uMaxTile.set(gSP.texture.level, _bForce);
if (config.generalEmulation.enableLOD != 0) {
const int uCalcLOD = (gDP.otherMode.textureLOD == G_TL_LOD) ? 1 : 0;
m_uniforms.uEnableLod.set(uCalcLOD, _bForce);
if (config.frameBufferEmulation.nativeResFactor == 0)
m_uniforms.uScreenScale.set(video().getScaleX(), video().getScaleY(), _bForce);
else
m_uniforms.uScreenScale.set(float(config.frameBufferEmulation.nativeResFactor), float(config.frameBufferEmulation.nativeResFactor), _bForce);
m_uniforms.uTextureDetail.set(gDP.otherMode.textureDetail, _bForce);
}
}
void ShaderCombiner::updateTextureInfo(bool _bForce) {
const u32 texturePersp = (RSP.bLLE || GBI.isTexturePersp()) ? gDP.otherMode.texturePersp : 1U;
m_uniforms.uTexturePersp.set(texturePersp, _bForce);
if (config.texture.bilinearMode == BILINEAR_3POINT)
m_uniforms.uTextureFilterMode.set(gDP.otherMode.textureFilter | (gSP.objRendermode&G_OBJRM_BILERP), _bForce);
}
void ShaderCombiner::updateFrameBufferInfo(bool _bForce) {
if (!usesTexture())
return;
int nFbMonochromeMode0 = 0, nFbMonochromeMode1 = 0;
int nFbFixedAlpha0 = 0, nFbFixedAlpha1 = 0;
int nMSTex0Enabled = 0, nMSTex1Enabled = 0;
TextureCache & cache = textureCache();
if (cache.current[0] != nullptr && cache.current[0]->frameBufferTexture != CachedTexture::fbNone) {
if (cache.current[0]->size == G_IM_SIZ_8b) {
nFbMonochromeMode0 = 1;
if (gDP.otherMode.imageRead == 0)
nFbFixedAlpha0 = 1;
} else if (gSP.textureTile[0]->size == G_IM_SIZ_16b && gSP.textureTile[0]->format == G_IM_FMT_IA)
nFbMonochromeMode0 = 2;
}
if (cache.current[1] != nullptr && cache.current[1]->frameBufferTexture != CachedTexture::fbNone) {
if (cache.current[1]->size == G_IM_SIZ_8b) {
nFbMonochromeMode1 = 1;
if (gDP.otherMode.imageRead == 0)
nFbFixedAlpha1 = 1;
} else if (gSP.textureTile[1]->size == G_IM_SIZ_16b && gSP.textureTile[1]->format == G_IM_FMT_IA)
nFbMonochromeMode1 = 2;
}
m_uniforms.uFbMonochrome.set(nFbMonochromeMode0, nFbMonochromeMode1, _bForce);
m_uniforms.uFbFixedAlpha.set(nFbFixedAlpha0, nFbFixedAlpha1, _bForce);
gDP.changed &= ~CHANGED_FB_TEXTURE;
}
void ShaderCombiner::updateDepthInfo(bool _bForce) {
if (config.frameBufferEmulation.N64DepthCompare == 0 || !video().getRender().isImageTexturesSupported())
return;
FrameBuffer * pBuffer = frameBufferList().getCurrent();
if (pBuffer == nullptr || pBuffer->m_pDepthBuffer == nullptr)
return;
const int nDepthEnabled = (gSP.geometryMode & G_ZBUFFER) > 0 ? 1 : 0;
m_uniforms.uEnableDepth.set(nDepthEnabled, _bForce);
if (nDepthEnabled == 0) {
m_uniforms.uEnableDepthCompare.set(0, _bForce);
m_uniforms.uEnableDepthUpdate.set(0, _bForce);
} else {
m_uniforms.uEnableDepthCompare.set(gDP.otherMode.depthCompare, _bForce);
m_uniforms.uEnableDepthUpdate.set(gDP.otherMode.depthUpdate, _bForce);
}
m_uniforms.uDepthMode.set(gDP.otherMode.depthMode, _bForce);
m_uniforms.uDepthSource.set(gDP.otherMode.depthSource, _bForce);
if (gDP.otherMode.depthSource == G_ZS_PRIM)
m_uniforms.uDeltaZ.set(gDP.primDepth.deltaZ, _bForce);
}
void ShaderCombiner::updateAlphaTestInfo(bool _bForce) {
if (gDP.otherMode.cycleType == G_CYC_FILL) {
m_uniforms.uEnableAlphaTest.set(0, _bForce);
} else if (gDP.otherMode.cycleType == G_CYC_COPY) {
if (gDP.otherMode.alphaCompare & G_AC_THRESHOLD) {
m_uniforms.uEnableAlphaTest.set(1, _bForce);
m_uniforms.uAlphaCvgSel.set(0, _bForce);
m_uniforms.uAlphaTestValue.set(0.5f, _bForce);
} else {
m_uniforms.uEnableAlphaTest.set(0, _bForce);
}
} else if ((gDP.otherMode.alphaCompare & G_AC_THRESHOLD) != 0) {
m_uniforms.uEnableAlphaTest.set(1, _bForce);
m_uniforms.uAlphaTestValue.set(gDP.blendColor.a, _bForce);
m_uniforms.uAlphaCvgSel.set(gDP.otherMode.alphaCvgSel, _bForce);
} else {
m_uniforms.uEnableAlphaTest.set(0, _bForce);
}
m_uniforms.uCvgXAlpha.set(gDP.otherMode.cvgXAlpha, _bForce);
}
void SetMonochromeCombiner() {
glUseProgram(g_monochrome_image_program);
static int texLoc = -1;
if (texLoc < 0) {
texLoc = glGetUniformLocation(g_monochrome_image_program, "uColorImage");
glUniform1i(texLoc, 0);
}
static int sizeLoc = -1;
if (sizeLoc < 0) {
glGetUniformLocation(g_monochrome_image_program, "uScreenSize");
glUniform2f(sizeLoc, (float)video().getWidth(), (float)video().getHeight());
}
gDP.changed |= CHANGED_COMBINE;
}
bool SetDepthTextureCombiner() {
// All I can do for GLES2 is just to clear depth buffer.
glDepthMask(TRUE);
glClear(GL_DEPTH_BUFFER_BIT);
return false;
}

View File

@ -1,589 +0,0 @@
#define SHADER_VERSION "#version 100 \n" \
"#extension GL_EXT_shader_texture_lod : enable \n" \
"#extension GL_OES_standard_derivatives : enable \n"
static const char* vertex_shader =
SHADER_VERSION
"#if (__VERSION__ > 120) \n"
"# define IN in \n"
"# define OUT out \n"
"#else \n"
"# define IN attribute \n"
"# define OUT varying \n"
"#endif // __VERSION \n"
"IN highp vec4 aPosition; \n"
"IN lowp vec4 aColor; \n"
"IN highp vec2 aTexCoord0; \n"
"IN highp vec2 aTexCoord1; \n"
"IN lowp float aNumLights; \n"
"IN highp vec4 aModify; \n"
" \n"
"uniform int uRenderState; \n"
"uniform int uTexturePersp; \n"
" \n"
"uniform lowp int uFogUsage; \n"
"uniform mediump vec2 uFogScale; \n"
"uniform mediump vec2 uScreenCoordsScale; \n"
" \n"
"uniform mediump vec2 uTexScale; \n"
"uniform mediump vec2 uTexOffset[2]; \n"
"uniform mediump vec2 uCacheScale[2]; \n"
"uniform mediump vec2 uCacheOffset[2]; \n"
"uniform mediump vec2 uCacheShiftScale[2]; \n"
"uniform lowp ivec2 uCacheFrameBuffer; \n"
"OUT lowp vec4 vShadeColor; \n"
"OUT mediump vec2 vTexCoord0; \n"
"OUT mediump vec2 vTexCoord1; \n"
"OUT mediump vec2 vLodTexCoord; \n"
"OUT lowp float vNumLights; \n"
"mediump vec2 calcTexCoord(in vec2 texCoord, in int idx) \n"
"{ \n"
" vec2 texCoordOut = texCoord*uCacheShiftScale[idx]; \n"
" texCoordOut -= uTexOffset[idx]; \n"
" if (uCacheFrameBuffer[idx] != 0) \n"
" texCoordOut.t = -texCoordOut.t; \n"
" return (uCacheOffset[idx] + texCoordOut)* uCacheScale[idx];\n"
"} \n"
" \n"
"void main() \n"
"{ \n"
" gl_Position = aPosition; \n"
" vShadeColor = aColor; \n"
" if (uRenderState < 3) { \n"
" vec2 texCoord = aTexCoord0; \n"
" texCoord *= uTexScale; \n"
" if (uTexturePersp == 0 && aModify[2] == 0.0) texCoord *= 0.5;\n"
" vTexCoord0 = calcTexCoord(texCoord, 0); \n"
" vTexCoord1 = calcTexCoord(texCoord, 1); \n"
" vLodTexCoord = texCoord; \n"
" vNumLights = aNumLights; \n"
" if (aModify != vec4(0.0)) { \n"
" if (aModify[0] != 0.0) { \n"
" gl_Position.xy = gl_Position.xy * uScreenCoordsScale + vec2(-1.0, 1.0); \n"
" gl_Position.xy *= gl_Position.w; \n"
" } \n"
" if (aModify[1] != 0.0) \n"
" gl_Position.z *= gl_Position.w; \n"
" if (aModify[3] != 0.0) \n"
" vNumLights = 0.0; \n"
" } \n"
" if (uFogUsage == 1) { \n"
" lowp float fp; \n"
" if (aPosition.z < -aPosition.w && aModify[1] == 0.0) \n"
" fp = -uFogScale.s + uFogScale.t; \n"
" else \n"
" fp = aPosition.z/aPosition.w*uFogScale.s + uFogScale.t;\n"
" vShadeColor.a = clamp(fp, 0.0, 1.0); \n"
" } \n"
" } else { \n"
" vTexCoord0 = aTexCoord0; \n"
" vTexCoord1 = aTexCoord1; \n"
" vNumLights = 0.0; \n"
" } \n"
"} \n"
;
static const char* vertex_shader_notex =
SHADER_VERSION
"#if (__VERSION__ > 120) \n"
"# define IN in \n"
"# define OUT out \n"
"#else \n"
"# define IN attribute \n"
"# define OUT varying \n"
"#endif // __VERSION \n"
"IN highp vec4 aPosition; \n"
"IN lowp vec4 aColor; \n"
"IN lowp float aNumLights; \n"
"IN highp vec4 aModify; \n"
" \n"
"uniform int uRenderState; \n"
" \n"
"uniform lowp int uFogUsage; \n"
"uniform mediump vec2 uFogScale; \n"
"uniform mediump vec2 uScreenCoordsScale;\n"
" \n"
"OUT lowp vec4 vShadeColor; \n"
"OUT lowp float vNumLights; \n"
" \n"
"void main() \n"
"{ \n"
" gl_Position = aPosition; \n"
" vShadeColor = aColor; \n"
" if (uRenderState < 3) { \n"
" vNumLights = aNumLights; \n"
" if (aModify != vec4(0.0)) { \n"
" if (aModify[0] != 0.0) { \n"
" gl_Position.xy = gl_Position.xy * uScreenCoordsScale + vec2(-1.0, 1.0); \n"
" gl_Position.xy *= gl_Position.w; \n"
" } \n"
" if (aModify[1] != 0.0) \n"
" gl_Position.z *= gl_Position.w; \n"
" if (aModify[3] != 0.0) \n"
" vNumLights = 0.0; \n"
" } \n"
" if (uFogUsage == 1) { \n"
" lowp float fp; \n"
" if (aPosition.z < -aPosition.w && aModify[1] == 0.0) \n"
" fp = -uFogScale.s + uFogScale.t; \n"
" else \n"
" fp = aPosition.z/aPosition.w*uFogScale.s + uFogScale.t;\n"
" vShadeColor.a = clamp(fp, 0.0, 1.0); \n"
" } \n"
" } else { \n"
" vNumLights = 0.0; \n"
" } \n"
"} \n"
;
static const char* fragment_shader_header_common_variables =
SHADER_VERSION
"#if (__VERSION__ > 120) \n"
"# define IN in \n"
"# define OUT out \n"
"#else \n"
"# define IN varying \n"
"# define OUT \n"
"#endif // __VERSION __ \n"
"uniform sampler2D uTex0; \n"
"uniform sampler2D uTex1; \n"
"uniform lowp vec4 uFogColor; \n"
"uniform lowp vec4 uCenterColor;\n"
"uniform lowp vec4 uScaleColor; \n"
"uniform lowp vec4 uBlendColor; \n"
"uniform lowp vec4 uEnvColor; \n"
"uniform lowp vec4 uPrimColor; \n"
"uniform lowp float uPrimLod; \n"
"uniform lowp float uK4; \n"
"uniform lowp float uK5; \n"
"uniform mediump vec2 uScreenScale; \n"
"uniform lowp int uAlphaCompareMode; \n"
"uniform lowp int uFogUsage; \n"
"uniform lowp ivec2 uFbMonochrome; \n"
"uniform lowp ivec2 uFbFixedAlpha;\n"
"uniform lowp int uEnableAlphaTest; \n"
"uniform lowp int uCvgXAlpha; \n"
"uniform lowp int uAlphaCvgSel; \n"
"uniform lowp float uAlphaTestValue;\n"
"uniform lowp ivec4 uBlendMux1; \n"
"uniform lowp int uForceBlendCycle1;\n"
"IN lowp vec4 vShadeColor; \n"
"IN mediump vec2 vTexCoord0;\n"
"IN mediump vec2 vTexCoord1;\n"
"IN mediump vec2 vLodTexCoord;\n"
"IN lowp float vNumLights; \n"
"OUT lowp vec4 fragColor; \n"
"lowp int nCurrentTile; \n"
;
static const char* fragment_shader_header_common_variables_notex =
SHADER_VERSION
"#if (__VERSION__ > 120) \n"
"# define IN in \n"
"# define OUT out \n"
"#else \n"
"# define IN varying \n"
"# define OUT \n"
"#endif // __VERSION __ \n"
"uniform lowp vec4 uFogColor; \n"
"uniform lowp vec4 uCenterColor;\n"
"uniform lowp vec4 uScaleColor; \n"
"uniform lowp vec4 uBlendColor; \n"
"uniform lowp vec4 uEnvColor; \n"
"uniform lowp vec4 uPrimColor; \n"
"uniform lowp float uPrimLod; \n"
"uniform lowp float uK4; \n"
"uniform lowp float uK5; \n"
"uniform mediump vec2 uScreenScale; \n"
"uniform lowp int uAlphaCompareMode; \n"
"uniform lowp int uFogUsage; \n"
"uniform lowp int uEnableAlphaTest; \n"
"uniform lowp int uCvgXAlpha; \n"
"uniform lowp int uAlphaCvgSel; \n"
"uniform lowp float uAlphaTestValue;\n"
"uniform lowp ivec4 uBlendMux1; \n"
"uniform lowp int uForceBlendCycle1;\n"
"IN lowp vec4 vShadeColor; \n"
"IN lowp float vNumLights; \n"
"OUT lowp vec4 fragColor; \n"
;
static const char* fragment_shader_header_common_variables_blend_mux_2cycle =
"uniform lowp ivec4 uBlendMux2; \n"
"uniform lowp int uForceBlendCycle2; \n"
;
static const char* fragment_shader_header_common_functions =
" \n"
"lowp float snoise(); \n"
"void calc_light(in lowp float fLights, in lowp vec3 input_color, out lowp vec3 output_color);\n"
"mediump float mipmap(out lowp vec4 readtex0, out lowp vec4 readtex1); \n"
"lowp vec4 readTex(in sampler2D tex, in mediump vec2 texCoord, in lowp int fbMonochrome, in lowp int fbFixedAlpha); \n"
#ifdef USE_TOONIFY
"void toonify(in mediump float intensity); \n"
#endif
;
static const char* fragment_shader_header_common_functions_notex =
" \n"
"lowp float snoise(); \n"
"void calc_light(in lowp float fLights, in lowp vec3 input_color, out lowp vec3 output_color);\n"
;
static const char* fragment_shader_calc_light =
"uniform mediump vec3 uLightDirection[8]; \n"
"uniform lowp vec3 uLightColor[8]; \n"
"void calc_light(in lowp float fLights, in lowp vec3 input_color, out lowp vec3 output_color) {\n"
" output_color = input_color; \n"
" lowp int nLights = int(floor(fLights + 0.5)); \n"
" if (nLights == 0) \n"
" return; \n"
" output_color = uLightColor[nLights]; \n"
" mediump float intensity; \n"
" for (int i = 0; i < nLights; i++) { \n"
" intensity = max(dot(input_color, uLightDirection[i]), 0.0);\n"
" output_color += intensity*uLightColor[i]; \n"
" }; \n"
" output_color = clamp(output_color, 0.0, 1.0); \n"
"} \n"
;
static const char* fragment_shader_header_main =
" \n"
"void main() \n"
"{ \n"
" lowp vec4 vec_color, combined_color; \n"
" lowp float alpha1, alpha2; \n"
" lowp vec3 color1, color2, input_color; \n"
;
static const char* fragment_shader_blend_mux =
" lowp mat4 muxPM = mat4(vec4(0.0), vec4(0.0), uBlendColor, uFogColor); \n"
" lowp vec4 muxA = vec4(0.0, uFogColor.a, vShadeColor.a, 0.0); \n"
" lowp vec4 muxB = vec4(0.0, 1.0, 1.0, 0.0); \n"
;
#ifdef USE_TOONIFY
static const char* fragment_shader_toonify =
" \n"
"void toonify(in mediump float intensity) { \n"
" if (intensity > 0.5) \n"
" return; \n"
" else if (intensity > 0.125) \n"
" fragColor = vec4(vec3(fragColor)*0.5, fragColor.a);\n"
" else \n"
" fragColor = vec4(vec3(fragColor)*0.2, fragColor.a);\n"
"} \n"
;
#endif
static const char* fragment_shader_end =
"} \n"
;
static const char* fragment_shader_mipmap =
"uniform lowp int uEnableLod; \n"
"uniform mediump float uMinLod; \n"
"uniform lowp int uMaxTile; \n"
"uniform lowp int uTextureDetail; \n"
" \n"
"mediump float mipmap(out lowp vec4 readtex0, out lowp vec4 readtex1) { \n"
" readtex0 = texture2D(uTex0, vTexCoord0); \n"
" readtex1 = texture2DLodEXT(uTex1, vTexCoord1, 0.0); \n"
" \n"
" mediump float fMaxTile = float(uMaxTile); \n"
#if 1
" mediump vec2 dx = abs(dFdx(vLodTexCoord)); \n"
" dx *= uScreenScale; \n"
" mediump float lod = max(dx.x, dx.y); \n"
#else
" mediump vec2 dx = dFdx(vLodTexCoord); \n"
" dx *= uScreenScale; \n"
" mediump vec2 dy = dFdy(vLodTexCoord); \n"
" dy *= uScreenScale; \n"
" mediump float lod = max(length(dx), length(dy)); \n"
#endif
" bool magnify = lod < 1.0; \n"
" mediump float lod_tile = magnify ? 0.0 : floor(log2(floor(lod))); \n"
" bool distant = lod > 128.0 || lod_tile >= fMaxTile; \n"
" mediump float lod_frac = fract(lod/pow(2.0, lod_tile)); \n"
" if (magnify) lod_frac = max(lod_frac, uMinLod); \n"
" if (uTextureDetail == 0) { \n"
" if (distant) lod_frac = 1.0; \n"
" else if (magnify) lod_frac = 0.0; \n"
" } \n"
" if (magnify && (uTextureDetail == 1 || uTextureDetail == 3)) \n"
" lod_frac = 1.0 - lod_frac; \n"
" if (uMaxTile == 0) { \n"
" if (uEnableLod != 0 && uTextureDetail < 2) \n"
" readtex1 = readtex0; \n"
" return lod_frac; \n"
" } \n"
" if (uEnableLod == 0) return lod_frac; \n"
" \n"
" lod_tile = min(lod_tile, fMaxTile); \n"
" lowp float lod_tile_m1 = max(0.0, lod_tile - 1.0); \n"
" lowp vec4 lodT = texture2DLodEXT(uTex1, vTexCoord1, lod_tile); \n"
" lowp vec4 lodT_m1 = texture2DLodEXT(uTex1, vTexCoord1, lod_tile_m1); \n"
" lowp vec4 lodT_p1 = texture2DLodEXT(uTex1, vTexCoord1, lod_tile + 1.0); \n"
" if (lod_tile < 1.0) { \n"
" if (magnify) { \n"
// !sharpen && !detail
" if (uTextureDetail == 0) readtex1 = readtex0; \n"
" } else { \n"
// detail
" if (uTextureDetail > 1) { \n"
" readtex0 = lodT; \n"
" readtex1 = lodT_p1; \n"
" } \n"
" } \n"
" } else { \n"
" if (uTextureDetail > 1) { \n"
" readtex0 = lodT; \n"
" readtex1 = lodT_p1; \n"
" } else { \n"
" readtex0 = lodT_m1; \n"
" readtex1 = lodT; \n"
" } \n"
" } \n"
" return lod_frac; \n"
"} \n"
;
static const char* fragment_shader_fake_mipmap =
"uniform lowp int uMaxTile; \n"
"uniform mediump float uMinLod; \n"
" \n"
"mediump float mipmap(out lowp vec4 readtex0, out lowp vec4 readtex1) { \n"
" readtex0 = texture2D(uTex0, vTexCoord0); \n"
" readtex1 = texture2D(uTex1, vTexCoord1); \n"
" if (uMaxTile == 0) return 1.0; \n"
" return uMinLod; \n"
"} \n"
;
static const char* fragment_shader_readtex =
"lowp vec4 readTex(in sampler2D tex, in mediump vec2 texCoord, in lowp int fbMonochrome, in lowp int fbFixedAlpha) \n"
"{ \n"
" lowp vec4 texColor = texture2D(tex, texCoord); \n"
" if (fbMonochrome == 1) texColor = vec4(texColor.r); \n"
" else if (fbMonochrome == 2) \n"
" texColor.rgb = vec3(dot(vec3(0.2126, 0.7152, 0.0722), texColor.rgb)); \n"
" if (fbFixedAlpha == 1) texColor.a = 0.825; \n"
" return texColor; \n"
"} \n"
;
static const char* fragment_shader_readtex_3point =
"uniform mediump vec2 uTextureSize[2]; \n"
"uniform lowp int uTextureFilterMode; \n"
// 3 point texture filtering.
// Original author: ArthurCarvalho
// GLSL implementation: twinaphex, mupen64plus-libretro project.
"#define TEX_OFFSET(off) texture2D(tex, texCoord - (off)/texSize) \n"
"lowp vec4 filter3point(in sampler2D tex, in mediump vec2 texCoord) \n"
"{ \n"
#ifndef VC
" mediump vec2 texSize = uTextureSize[nCurrentTile]; \n"
#else
" mediump vec2 texSize; \n"
" if (nCurrentTile == 0) \n"
" texSize = uTextureSize[0]; \n"
" else \n"
" texSize = uTextureSize[1]; \n"
#endif
" mediump vec2 offset = fract(texCoord*texSize - vec2(0.5)); \n"
" offset -= step(1.0, offset.x + offset.y); \n"
" lowp vec4 c0 = TEX_OFFSET(offset); \n"
" lowp vec4 c1 = TEX_OFFSET(vec2(offset.x - sign(offset.x), offset.y)); \n"
" lowp vec4 c2 = TEX_OFFSET(vec2(offset.x, offset.y - sign(offset.y))); \n"
" return c0 + abs(offset.x)*(c1-c0) + abs(offset.y)*(c2-c0); \n"
"} \n"
"lowp vec4 readTex(in sampler2D tex, in mediump vec2 texCoord, in lowp int fbMonochrome, in lowp int fbFixedAlpha) \n"
"{ \n"
" lowp vec4 texStandard = texture2D(tex, texCoord); \n"
" lowp vec4 tex3Point = filter3point(tex, texCoord); \n"
" lowp vec4 texColor = uTextureFilterMode == 0 ? texStandard : tex3Point; \n"
" if (fbMonochrome == 1) texColor = vec4(texColor.r); \n"
" else if (fbMonochrome == 2) \n"
" texColor.rgb = vec3(dot(vec3(0.2126, 0.7152, 0.0722), texColor.rgb)); \n"
" if (fbFixedAlpha == 1) texColor.a = 0.825; \n"
" return texColor; \n"
"} \n"
;
static const char* fragment_shader_noise =
"uniform sampler2D uTexNoise; \n"
"lowp float snoise() \n"
"{ \n"
" mediump vec2 texSize = vec2(640.0, 580.0); \n"
" mediump vec2 coord = gl_FragCoord.xy/uScreenScale/texSize; \n"
" return texture2D(uTexNoise, coord).r; \n"
"} \n"
;
static const char* fragment_shader_dummy_noise =
" \n"
"lowp float snoise() \n"
"{ \n"
" return 1.0; \n"
"} \n"
;
static const char* default_vertex_shader =
SHADER_VERSION
"#if (__VERSION__ > 120) \n"
"# define IN in \n"
"#else \n"
"# define IN attribute \n"
"#endif // __VERSION \n"
"IN highp vec4 aPosition; \n"
"void main() \n"
"{ \n"
" gl_Position = aPosition; \n"
"} \n"
;
static const char* zelda_monochrome_fragment_shader =
SHADER_VERSION
"uniform sampler2D uColorImage; \n"
"uniform mediump vec2 uScreenSize; \n"
"void main() \n"
"{ \n"
" mediump vec2 coord = gl_FragCoord.xy/uScreenSize; \n"
" lowp vec4 tex = texture2D(uColorImage, coord); \n"
" lowp float c = dot(vec4(0.2126, 0.7152, 0.0722, 0.0), tex); \n"
" gl_FragColor = vec4(c, c, c, 1.0); \n"
"} \n"
;
const char * strTexrectDrawerVertexShader =
SHADER_VERSION
"#if (__VERSION__ > 120) \n"
"# define IN in \n"
"# define OUT out \n"
"#else \n"
"# define IN attribute \n"
"# define OUT varying \n"
"#endif // __VERSION \n"
"IN highp vec4 aPosition; \n"
"IN highp vec2 aTexCoord0; \n"
"OUT mediump vec2 vTexCoord0; \n"
"void main() \n"
"{ \n"
" gl_Position = aPosition; \n"
" vTexCoord0 = aTexCoord0; \n"
"} \n"
;
const char * strTexrectDrawerTex3PointFilter =
SHADER_VERSION
"#if (__VERSION__ > 120) \n"
"# define IN in \n"
"# define OUT out \n"
"#else \n"
"# define IN varying \n"
"# define OUT \n"
"#endif // __VERSION __ \n"
"uniform mediump vec4 uTextureBounds; \n"
"uniform mediump vec2 uTextureSize; \n"
// 3 point texture filtering.
// Original author: ArthurCarvalho
// GLSL implementation: twinaphex, mupen64plus-libretro project.
"#define TEX_OFFSET(off) texture2D(tex, texCoord - (off)/texSize) \n"
"lowp vec4 texFilter(in sampler2D tex, in mediump vec2 texCoord) \n"
"{ \n"
" mediump vec2 texSize = uTextureSize; \n"
" mediump vec2 texelSize = vec2(1.0) / texSize; \n"
" lowp vec4 c = texture2D(tex, texCoord); \n"
" if (abs(texCoord.s - uTextureBounds[0]) < texelSize.x || abs(texCoord.s - uTextureBounds[2]) < texelSize.x) return c; \n"
" if (abs(texCoord.t - uTextureBounds[1]) < texelSize.y || abs(texCoord.t - uTextureBounds[3]) < texelSize.y) return c; \n"
" \n"
" mediump vec2 offset = fract(texCoord*texSize - vec2(0.5)); \n"
" offset -= step(1.0, offset.x + offset.y); \n"
" lowp vec4 zero = vec4(0.0); \n"
" lowp vec4 c0 = TEX_OFFSET(offset); \n"
" lowp vec4 c1 = TEX_OFFSET(vec2(offset.x - sign(offset.x), offset.y)); \n"
" lowp vec4 c2 = TEX_OFFSET(vec2(offset.x, offset.y - sign(offset.y))); \n"
" return c0 + abs(offset.x)*(c1-c0) + abs(offset.y)*(c2-c0); \n"
"} \n"
" \n"
;
const char * strTexrectDrawerTexBilinearFilter =
SHADER_VERSION
"#if (__VERSION__ > 120) \n"
"# define IN in \n"
"# define OUT out \n"
"#else \n"
"# define IN varying \n"
"# define OUT \n"
"#endif // __VERSION __ \n"
"uniform mediump vec4 uTextureBounds; \n"
"uniform mediump vec2 uTextureSize; \n"
"#define TEX_OFFSET(off) texture2D(tex, texCoord - (off)/texSize) \n"
"lowp vec4 texFilter(in sampler2D tex, in mediump vec2 texCoord) \n"
"{ \n"
" mediump vec2 texSize = uTextureSize; \n"
" mediump vec2 texelSize = vec2(1.0) / texSize; \n"
" lowp vec4 c = texture2D(tex, texCoord); \n"
" if (abs(texCoord.s - uTextureBounds[0]) < texelSize.x || abs(texCoord.s - uTextureBounds[2]) < texelSize.x) return c; \n"
" if (abs(texCoord.t - uTextureBounds[1]) < texelSize.y || abs(texCoord.t - uTextureBounds[3]) < texelSize.y) return c; \n"
" \n"
" mediump vec2 offset = fract(texCoord*texSize - vec2(0.5)); \n"
" offset -= step(1.0, offset.x + offset.y); \n"
" lowp vec4 zero = vec4(0.0); \n"
" \n"
" lowp vec4 p0q0 = TEX_OFFSET(offset); \n"
" lowp vec4 p1q0 = TEX_OFFSET(vec2(offset.x - sign(offset.x), offset.y)); \n"
" \n"
" lowp vec4 p0q1 = TEX_OFFSET(vec2(offset.x, offset.y - sign(offset.y))); \n"
" lowp vec4 p1q1 = TEX_OFFSET(vec2(offset.x - sign(offset.x), offset.y - sign(offset.y))); \n"
" \n"
" mediump vec2 interpolationFactor = abs(offset); \n"
" lowp vec4 pInterp_q0 = mix( p0q0, p1q0, interpolationFactor.x ); // Interpolates top row in X direction. \n"
" lowp vec4 pInterp_q1 = mix( p0q1, p1q1, interpolationFactor.x ); // Interpolates bottom row in X direction. \n"
" return mix( pInterp_q0, pInterp_q1, interpolationFactor.y ); // Interpolate in Y direction. \n"
"} \n"
;
const char * strTexrectDrawerFragmentShaderTex =
"uniform sampler2D uTex0; \n"
"uniform lowp int uEnableAlphaTest; \n"
"lowp vec4 uTestColor = vec4(4.0/255.0, 2.0/255.0, 1.0/255.0, 0.0); \n"
"IN mediump vec2 vTexCoord0; \n"
"OUT lowp vec4 fragColor; \n"
"void main() \n"
"{ \n"
" fragColor = texFilter(uTex0, vTexCoord0); \n"
" if (fragColor == uTestColor) discard; \n"
" if (uEnableAlphaTest != 0 && !(fragColor.a > 0.0)) discard; \n"
" gl_FragColor = fragColor; \n"
"} \n"
;
const char * strTexrectDrawerFragmentShaderClean =
SHADER_VERSION
"lowp vec4 uTestColor = vec4(4.0/255.0, 2.0/255.0, 1.0/255.0, 0.0); \n"
"void main() \n"
"{ \n"
" gl_FragColor = uTestColor; \n"
"} \n"
;
const char* strTextureCopyShader =
SHADER_VERSION
"#if (__VERSION__ > 120) \n"
"# define IN in \n"
"#else \n"
"# define IN varying \n"
"#endif // __VERSION __ \n"
"IN mediump vec2 vTexCoord0; \n"
"uniform sampler2D uTex0; \n"
" \n"
"void main() \n"
"{ \n"
" gl_FragColor = texture2D(uTex0, vTexCoord0); \n"
"} \n"
;

View File

@ -1,163 +0,0 @@
#ifndef GLSL_COMBINER_H
#define GLSL_COMBINER_H
#include <vector>
#include <iostream>
#include "gDP.h"
#include "Combiner.h"
class ShaderCombiner {
public:
ShaderCombiner();
ShaderCombiner(Combiner & _color, Combiner & _alpha, const gDPCombine & _combine);
~ShaderCombiner();
void update(bool _bForce);
void updateFogMode(bool _bForce = false);
void updateDitherMode(bool _bForce = false);
void updateLOD(bool _bForce = false);
void updateFrameBufferInfo(bool _bForce = false);
void updateDepthInfo(bool _bForce = false);
void updateAlphaTestInfo(bool _bForce = false);
void updateTextureInfo(bool _bForce = false);
void updateRenderState(bool _bForce = false);
void updateRenderTarget(bool _bForce = false);
void updateScreenCoordsScale(bool _bForce = false);
void updateBlendMode(bool _bForce = false);
void disableBlending();
CombinerKey getKey() const { return m_key; }
bool usesTile(u32 _t) const {
if (_t == 0)
return (m_nInputs & ((1<<TEXEL0)|(1<<TEXEL0_ALPHA))) != 0;
return (m_nInputs & ((1 << TEXEL1) | (1 << TEXEL1_ALPHA))) != 0;
}
bool usesTexture() const { return (m_nInputs & ((1 << TEXEL1)|(1 << TEXEL1_ALPHA)|(1 << TEXEL0)|(1 << TEXEL0_ALPHA))) != 0; }
bool usesLOD() const { return (m_nInputs & (1 << LOD_FRACTION)) != 0; }
bool usesShade() const { return (m_nInputs & ((1 << SHADE) | (1 << SHADE_ALPHA))) != 0; }
bool usesShadeColor() const { return (m_nInputs & (1 << SHADE)) != 0; }
bool usesHwLighting() const { return (m_nInputs & (1 << HW_LIGHT)) != 0; }
friend std::ostream & operator<< (std::ostream & _os, const ShaderCombiner & _combiner);
friend std::istream & operator>> (std::istream & _os, ShaderCombiner & _combiner);
static void getShaderCombinerOptionsSet(std::vector<u32> & _vecOptions);
private:
friend class UniformBlock;
friend class UniformSet;
struct iUniform {
GLint loc = -1;
int val = -999;
void set(int _val, bool _force) {
if (loc >= 0 && (_force || val != _val)) {
val = _val;
glUniform1i(loc, _val);
}
}
};
struct fUniform {
GLint loc = -1;
float val = -9999.9f;
void set(float _val, bool _force) {
if (loc >= 0 && (_force || val != _val)) {
val = _val;
glUniform1f(loc, _val);
}
}
};
struct fv2Uniform {
GLint loc = -1;
float val1 = -9999.9f, val2 = -9999.9f;
void set(float _val1, float _val2, bool _force) {
if (loc >= 0 && (_force || val1 != _val1 || val2 != _val2)) {
val1 = _val1;
val2 = _val2;
glUniform2f(loc, _val1, _val2);
}
}
};
struct iv2Uniform {
GLint loc = -1;
int val1 = -999, val2 = -999;
void set(int _val1, int _val2, bool _force) {
if (loc >= 0 && (_force || val1 != _val1 || val2 != _val2)) {
val1 = _val1;
val2 = _val2;
glUniform2i(loc, _val1, _val2);
}
}
};
struct i4Uniform {
GLint loc = -1;
int val0 = -999, val1 = -999, val2 = -999, val3 = -999;
void set(int _val0, int _val1, int _val2, int _val3, bool _force) {
if (loc < 0)
return;
if (_force || _val0 != val0 || _val1 != val1 || _val2 != val2 || _val3 != val3) {
val0 = _val0;
val1 = _val1;
val2 = _val2;
val3 = _val3;
glUniform4i(loc, val0, val1, val2, val3);
}
}
};
struct UniformLocation
{
iUniform uTex0, uTex1, uMSTex0, uMSTex1, uDepthTex,
uTexNoise, uTlutImage, uZlutImage, uDepthImage,
uFogUsage, uEnableLod, uEnableAlphaTest,
uEnableDepth, uEnableDepthCompare, uEnableDepthUpdate,
uDepthMode, uDepthSource, uRenderState,
uMaxTile, uTextureDetail, uTexturePersp, uTextureFilterMode, uMSAASamples,
uAlphaCompareMode, uAlphaDitherMode, uColorDitherMode,
uCvgXAlpha, uAlphaCvgSel, uRenderTarget,
uForceBlendCycle1, uForceBlendCycle2;
fUniform uMinLod, uDeltaZ, uAlphaTestValue, uMSAAScale;
fv2Uniform uScreenScale, uDepthScale, uFogScale, uScreenCoordsScale;
iv2Uniform uMSTexEnabled, uFbMonochrome, uFbFixedAlpha;
i4Uniform uBlendMux1, uBlendMux2;
};
#ifdef OS_MAC_OS_X
#define glUniform1i glUniform1iARB
#define glUniform1f glUniform1fARB
#define glUniform2f glUniform2fARB
#define glUniform2i glUniform2iARB
#define glUniform3fv glUniform3fvARB
#define glUniform4fv glUniform4fvARB
#endif
void _locate_attributes() const;
void _locateUniforms();
CombinerKey m_key;
UniformLocation m_uniforms;
GLuint m_program;
int m_nInputs;
bool m_bNeedUpdate;
};
void InitShaderCombiner();
void DestroyShaderCombiner();
#ifdef GL_IMAGE_TEXTURES_SUPPORT
//void SetDepthFogCombiner();
//void SetMonochromeCombiner();
#endif // GL_IMAGE_TEXTURES_SUPPORT
//#define USE_TOONIFY
#endif //GLSL_COMBINER_H

View File

@ -1,260 +0,0 @@
#include "UniformBlock.h"
#include "../Config.h"
#include "../Textures.h"
static
const char * strTextureUniforms[UniformBlock::tuTotal] = {
"uTexScale",
"uTexOffset",
"uCacheScale",
"uCacheOffset",
"uCacheShiftScale",
"uCacheFrameBuffer"
};
static
const char * strColorUniforms[UniformBlock::cuTotal] = {
"uFogColor",
"uCenterColor",
"uScaleColor",
"uBlendColor",
"uEnvColor",
"uPrimColor",
"uPrimLod",
"uK4",
"uK5"
};
static
const char * strLightUniforms[UniformBlock::luTotal] = {
"uLightDirection",
"uLightColor"
};
UniformBlock::UniformBlock() : m_currentBuffer(0)
{
}
UniformBlock::~UniformBlock()
{
}
void UniformBlock::_initTextureBuffer(GLuint _program)
{
const GLint blockSize = m_textureBlock.initBuffer(_program, "TextureBlock", strTextureUniforms);
if (blockSize == 0)
return;
m_textureBlockData.resize(blockSize);
GLbyte * pData = m_textureBlockData.data();
memset(pData, 0, blockSize);
glBindBuffer(GL_UNIFORM_BUFFER, m_textureBlock.m_buffer);
glBufferData(GL_UNIFORM_BUFFER, blockSize, 0, GL_DYNAMIC_DRAW);
glBindBufferBase(GL_UNIFORM_BUFFER, m_textureBlock.m_blockBindingPoint, m_textureBlock.m_buffer);
updateTextureParameters();
}
void UniformBlock::_initColorsBuffer(GLuint _program)
{
const GLint blockSize = m_colorsBlock.initBuffer(_program, "ColorsBlock", strColorUniforms);
if (blockSize == 0)
return;
m_colorsBlockData.resize(blockSize);
GLbyte * pData = m_colorsBlockData.data();
memset(pData, 0, blockSize);
memcpy(pData + m_colorsBlock.m_offsets[cuFogColor], &gDP.fogColor.r, sizeof(f32)* 4);
memcpy(pData + m_colorsBlock.m_offsets[cuCenterColor], &gDP.key.center.r, sizeof(f32)* 4);
memcpy(pData + m_colorsBlock.m_offsets[cuScaleColor], &gDP.key.scale.r, sizeof(f32)* 4);
memcpy(pData + m_colorsBlock.m_offsets[cuEnvColor], &gDP.envColor.r, sizeof(f32)* 4);
memcpy(pData + m_colorsBlock.m_offsets[cuPrimColor], &gDP.primColor.r, sizeof(f32)* 4);
*(f32*)(pData + m_colorsBlock.m_offsets[cuPrimLod]) = gDP.primColor.l;
*(f32*)(pData + m_colorsBlock.m_offsets[cuK4]) = gDP.convert.k4*0.0039215689f;
*(f32*)(pData + m_colorsBlock.m_offsets[cuK5]) = gDP.convert.k5*0.0039215689f;
glBindBuffer(GL_UNIFORM_BUFFER, m_colorsBlock.m_buffer);
glBufferData(GL_UNIFORM_BUFFER, blockSize, pData, GL_DYNAMIC_DRAW);
glBindBufferBase(GL_UNIFORM_BUFFER, m_colorsBlock.m_blockBindingPoint, m_colorsBlock.m_buffer);
m_currentBuffer = m_colorsBlock.m_buffer;
}
void UniformBlock::_initLightBuffer(GLuint _program)
{
const GLint blockSize = m_lightBlock.initBuffer(_program, "LightBlock", strLightUniforms);
if (blockSize == 0)
return;
m_lightBlockData.resize(blockSize);
GLbyte * pData = m_lightBlockData.data();
memset(pData, 0, blockSize);
glBindBuffer(GL_UNIFORM_BUFFER, m_lightBlock.m_buffer);
glBufferData(GL_UNIFORM_BUFFER, blockSize, 0, GL_DYNAMIC_DRAW);
glBindBufferBase(GL_UNIFORM_BUFFER, m_lightBlock.m_blockBindingPoint, m_lightBlock.m_buffer);
updateLightParameters();
}
bool UniformBlock::_isDataChanged(void * _pBuffer, const void * _pData, u32 _dataSize)
{
u32 * pSrc = (u32*)_pData;
u32 * pDst = (u32*)_pBuffer;
u32 cnt = _dataSize / 4;
for (u32 i = 0; i < cnt; ++i) {
if (pSrc[i] != pDst[i]) {
memcpy(_pBuffer, _pData, _dataSize);
return true;
}
}
return false;
}
void UniformBlock::bindWithShaderCombiner(ShaderCombiner * _pCombiner)
{
const GLuint program = _pCombiner->m_program;
if (_pCombiner->usesTexture()) {
if (m_textureBlock.m_buffer == 0)
_initTextureBuffer(program);
else {
const GLint blockIndex = glGetUniformBlockIndex(program, "TextureBlock");
if (blockIndex != GL_INVALID_INDEX)
glUniformBlockBinding(program, blockIndex, m_textureBlock.m_blockBindingPoint);
}
}
if (m_colorsBlock.m_buffer == 0)
_initColorsBuffer(program);
else {
const GLint blockIndex = glGetUniformBlockIndex(program, "ColorsBlock");
if (blockIndex != GL_INVALID_INDEX)
glUniformBlockBinding(program, blockIndex, m_colorsBlock.m_blockBindingPoint);
}
if (_pCombiner->usesHwLighting()) {
if (m_lightBlock.m_buffer == 0)
_initLightBuffer(program);
else {
const GLint blockIndex = glGetUniformBlockIndex(program, "LightBlock");
if (blockIndex != GL_INVALID_INDEX)
glUniformBlockBinding(program, blockIndex, m_lightBlock.m_blockBindingPoint);
}
}
}
void UniformBlock::setColorData(ColorUniforms _index, u32 _dataSize, const void * _data)
{
if (m_colorsBlock.m_buffer == 0)
return;
if (!_isDataChanged(m_colorsBlockData.data() + m_colorsBlock.m_offsets[_index], _data, _dataSize))
return;
if (m_currentBuffer != m_colorsBlock.m_buffer) {
m_currentBuffer = m_colorsBlock.m_buffer;
glBindBuffer(GL_UNIFORM_BUFFER, m_colorsBlock.m_buffer);
}
glBufferSubData(GL_UNIFORM_BUFFER, m_colorsBlock.m_offsets[_index], _dataSize, _data);
}
void UniformBlock::updateTextureParameters()
{
if (m_textureBlock.m_buffer == 0)
return;
std::vector<GLbyte> temp(m_textureBlockData.size(), 0);
GLbyte * pData = temp.data();
f32 texScale[4] = { gSP.texture.scales, gSP.texture.scalet, 0, 0 };
memcpy(pData + m_textureBlock.m_offsets[tuTexScale], texScale, m_textureBlock.m_offsets[tuTexOffset] - m_textureBlock.m_offsets[tuTexScale]);
f32 texOffset[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
if (gSP.textureTile[0] != nullptr) {
if (gSP.textureTile[0]->textureMode != TEXTUREMODE_BGIMAGE && gSP.textureTile[0]->textureMode != TEXTUREMODE_FRAMEBUFFER_BG) {
texOffset[0] = gSP.textureTile[0]->fuls;
texOffset[1] = gSP.textureTile[0]->fult;
FrameBuffer * pBuffer = gSP.textureTile[0]->frameBuffer;
if (pBuffer != nullptr) {
if (gSP.textureTile[0]->masks > 0 && gSP.textureTile[0]->clamps == 0)
texOffset[0] = float(gSP.textureTile[0]->uls % (1 << gSP.textureTile[0]->masks));
if (gSP.textureTile[0]->maskt > 0 && gSP.textureTile[0]->clampt == 0)
texOffset[1] = float(gSP.textureTile[0]->ult % (1 << gSP.textureTile[0]->maskt));
}
}
}
if (gSP.textureTile[1] != 0) {
texOffset[4] = gSP.textureTile[1]->fuls;
texOffset[5] = gSP.textureTile[1]->fult;
FrameBuffer * pBuffer = gSP.textureTile[1]->frameBuffer;
if (pBuffer != nullptr) {
if (gSP.textureTile[1]->masks > 0 && gSP.textureTile[1]->clamps == 0)
texOffset[4] = float(gSP.textureTile[1]->uls % (1 << gSP.textureTile[1]->masks));
if (gSP.textureTile[1]->maskt > 0 && gSP.textureTile[1]->clampt == 0)
texOffset[5] = float(gSP.textureTile[1]->ult % (1 << gSP.textureTile[1]->maskt));
}
}
memcpy(pData + m_textureBlock.m_offsets[tuTexOffset], texOffset, m_textureBlock.m_offsets[tuCacheScale] - m_textureBlock.m_offsets[tuTexOffset]);
f32 texCacheScale[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
f32 texCacheOffset[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
f32 texCacheShiftScale[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
GLint texCacheFrameBuffer[4] = { 0, 0, 0, 0 };
TextureCache & cache = textureCache();
if (cache.current[0]) {
texCacheScale[0] = cache.current[0]->scaleS;
texCacheScale[1] = cache.current[0]->scaleT;
texCacheOffset[0] = cache.current[0]->offsetS;
texCacheOffset[1] = cache.current[0]->offsetT;
f32 shiftScaleS = 1.0f;
f32 shiftScaleT = 1.0f;
getTextureShiftScale(0, cache, shiftScaleS, shiftScaleT);
texCacheShiftScale[0] = shiftScaleS;
texCacheShiftScale[1] = shiftScaleT;
texCacheFrameBuffer[0] = cache.current[0]->frameBufferTexture;
}
if (cache.current[1]) {
texCacheScale[4] = cache.current[1]->scaleS;
texCacheScale[5] = cache.current[1]->scaleT;
texCacheOffset[4] = cache.current[1]->offsetS;
texCacheOffset[5] = cache.current[1]->offsetT;
f32 shiftScaleS = 1.0f;
f32 shiftScaleT = 1.0f;
getTextureShiftScale(1, cache, shiftScaleS, shiftScaleT);
texCacheShiftScale[4] = shiftScaleS;
texCacheShiftScale[5] = shiftScaleT;
texCacheFrameBuffer[1] = cache.current[1]->frameBufferTexture;
}
memcpy(pData + m_textureBlock.m_offsets[tuCacheScale], texCacheScale, m_textureBlock.m_offsets[tuCacheOffset] - m_textureBlock.m_offsets[tuCacheScale]);
memcpy(pData + m_textureBlock.m_offsets[tuCacheOffset], texCacheOffset, m_textureBlock.m_offsets[tuCacheShiftScale] - m_textureBlock.m_offsets[tuCacheOffset]);
memcpy(pData + m_textureBlock.m_offsets[tuCacheShiftScale], texCacheShiftScale, m_textureBlock.m_offsets[tuCacheFrameBuffer] - m_textureBlock.m_offsets[tuCacheShiftScale]);
memcpy(pData + m_textureBlock.m_offsets[tuCacheFrameBuffer], texCacheFrameBuffer, m_textureBlockData.size() - m_textureBlock.m_offsets[tuCacheFrameBuffer]);
if (m_currentBuffer != m_textureBlock.m_buffer) {
m_currentBuffer = m_textureBlock.m_buffer;
glBindBuffer(GL_UNIFORM_BUFFER, m_textureBlock.m_buffer);
}
if(temp != m_textureBlockData) {
m_textureBlockData = temp;
glBufferSubData(GL_UNIFORM_BUFFER, m_textureBlock.m_offsets[tuTexScale], m_textureBlockData.size(), pData);
}
}
void UniformBlock::updateLightParameters()
{
if (m_lightBlock.m_buffer == 0)
return;
GLbyte * pData = m_lightBlockData.data();
const u32 arraySize = m_lightBlock.m_offsets[luLightColor] / 8;
for (s32 i = 0; i <= gSP.numLights; ++i) {
memcpy(pData + m_lightBlock.m_offsets[luLightDirection] + arraySize*i, &gSP.lights[i].ix, arraySize);
memcpy(pData + m_lightBlock.m_offsets[luLightColor] + arraySize*i, &gSP.lights[i].r, arraySize);
}
if (m_currentBuffer != m_lightBlock.m_buffer) {
m_currentBuffer = m_lightBlock.m_buffer;
glBindBuffer(GL_UNIFORM_BUFFER, m_lightBlock.m_buffer);
}
glBufferSubData(GL_UNIFORM_BUFFER, m_lightBlock.m_offsets[luLightDirection], m_lightBlockData.size(), pData);
}
UniformCollection * createUniformCollection()
{
return new UniformBlock();
}

View File

@ -1,76 +0,0 @@
#ifndef UNIFORM_BLOCK_H
#define UNIFORM_BLOCK_H
#include "../UniformCollection.h"
class UniformBlock : public UniformCollection
{
public:
UniformBlock();
~UniformBlock();
virtual void bindWithShaderCombiner(ShaderCombiner * _pCombiner);
virtual void setColorData(ColorUniforms _index, u32 _dataSize, const void * _data);
virtual void updateTextureParameters();
virtual void updateLightParameters();
virtual void updateUniforms(ShaderCombiner * /*_pCombiner*/, OGLRender::RENDER_STATE /*_renderState*/) {}
private:
void _initTextureBuffer(GLuint _program);
void _initColorsBuffer(GLuint _program);
void _initLightBuffer(GLuint _program);
bool _isDataChanged(void * _pBuffer, const void * _pData, u32 _dataSize);
template <u32 _numUniforms, u32 _bindingPoint>
struct UniformBlockData
{
UniformBlockData() : m_buffer(0), m_blockBindingPoint(_bindingPoint)
{
memset(m_indices, 0, sizeof(m_indices));
memset(m_offsets, 0, sizeof(m_offsets));
}
~UniformBlockData()
{
if (m_buffer != 0) {
glDeleteBuffers(1, &m_buffer);
m_buffer = 0;
}
}
GLint initBuffer(GLuint _program, const char * _strBlockName, const char ** _strUniformNames)
{
GLuint blockIndex = glGetUniformBlockIndex(_program, _strBlockName);
if (blockIndex == GL_INVALID_INDEX)
return 0;
GLint blockSize, numUniforms;
glGetActiveUniformBlockiv(_program, blockIndex, GL_UNIFORM_BLOCK_DATA_SIZE, &blockSize);
glGetActiveUniformBlockiv(_program, blockIndex, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &numUniforms);
glGetUniformIndices(_program, numUniforms, _strUniformNames, m_indices);
glGetActiveUniformsiv(_program, numUniforms, m_indices, GL_UNIFORM_OFFSET, m_offsets);
glUniformBlockBinding(_program, blockIndex, m_blockBindingPoint);
glGenBuffers(1, &m_buffer);
return blockSize;
}
GLuint m_buffer;
GLuint m_blockBindingPoint;
GLuint m_indices[_numUniforms];
GLint m_offsets[_numUniforms];
};
GLuint m_currentBuffer;
UniformBlockData<tuTotal, 1> m_textureBlock;
UniformBlockData<cuTotal, 2> m_colorsBlock;
UniformBlockData<luTotal, 3> m_lightBlock;
std::vector<GLbyte> m_textureBlockData;
std::vector<GLbyte> m_colorsBlockData;
std::vector<GLbyte> m_lightBlockData;
};
#endif // UNIFORM_BLOCK_H

View File

@ -1,149 +0,0 @@
#include "UniformSet.h"
#include "../Config.h"
#include "../Textures.h"
#define LocateUniform2(A) \
location.A.loc = glGetUniformLocation(program, #A);
void UniformSet::bindWithShaderCombiner(ShaderCombiner * _pCombiner)
{
const CombinerKey key = _pCombiner->getKey();
const GLuint program = _pCombiner->m_program;
m_uniforms.emplace(key, program);
UniformSetLocation & location = m_uniforms.at(key);
// Texture parameters
if (_pCombiner->usesTexture()) {
LocateUniform2(uTexScale);
LocateUniform2(uTexOffset[0]);
LocateUniform2(uTexOffset[1]);
LocateUniform2(uCacheScale[0]);
LocateUniform2(uCacheScale[1]);
LocateUniform2(uCacheOffset[0]);
LocateUniform2(uCacheOffset[1]);
LocateUniform2(uCacheShiftScale[0]);
LocateUniform2(uCacheShiftScale[1]);
LocateUniform2(uCacheFrameBuffer);
LocateUniform2(uTextureSize[0]);
LocateUniform2(uTextureSize[1]);
_updateTextureUniforms(location, _pCombiner->usesTile(0), _pCombiner->usesTile(1), true);
}
// Colors
LocateUniform2(uFogColor);
LocateUniform2(uCenterColor);
LocateUniform2(uScaleColor);
LocateUniform2(uBlendColor);
LocateUniform2(uEnvColor);
LocateUniform2(uPrimColor);
LocateUniform2(uPrimLod);
LocateUniform2(uK4);
LocateUniform2(uK5);
_updateColorUniforms(location, true);
// Lights
if (_pCombiner->usesHwLighting()) {
// locate lights uniforms
char buf[32];
for (s32 i = 0; i < 8; ++i) {
sprintf(buf, "uLightDirection[%d]", i);
location.uLightDirection[i].loc = glGetUniformLocation(program, buf);
sprintf(buf, "uLightColor[%d]", i);
location.uLightColor[i].loc = glGetUniformLocation(program, buf);
}
_updateLightUniforms(location, true);
}
}
void UniformSet::_updateColorUniforms(UniformSetLocation & _location, bool _bForce)
{
_location.uFogColor.set(&gDP.fogColor.r, _bForce);
_location.uCenterColor.set(&gDP.key.center.r, _bForce);
_location.uScaleColor.set(&gDP.key.scale.r, _bForce);
_location.uBlendColor.set(&gDP.blendColor.r, _bForce);
_location.uEnvColor.set(&gDP.envColor.r, _bForce);
_location.uPrimColor.set(&gDP.primColor.r, _bForce);
_location.uPrimLod.set(gDP.primColor.l, _bForce);
_location.uK4.set(gDP.convert.k4*0.0039215689f, _bForce);
_location.uK5.set(gDP.convert.k5*0.0039215689f, _bForce);
}
void UniformSet::_updateTextureUniforms(UniformSetLocation & _location, bool _bUsesT0, bool _bUsesT1, bool _bForce)
{
int nFB[2] = { 0, 0 };
const bool bUsesTile[2] = { _bUsesT0, _bUsesT1 };
TextureCache & cache = textureCache();
for (u32 t = 0; t < 2; ++t) {
if (!bUsesTile[t])
continue;
if (gSP.textureTile[t] != NULL) {
if (gSP.textureTile[t]->textureMode == TEXTUREMODE_BGIMAGE || gSP.textureTile[t]->textureMode == TEXTUREMODE_FRAMEBUFFER_BG)
_location.uTexOffset[t].set(0.0f, 0.0f, _bForce);
else {
float fuls = gSP.textureTile[t]->fuls;
float fult = gSP.textureTile[t]->fult;
FrameBuffer * pBuffer = gSP.textureTile[t]->frameBuffer;
if (pBuffer != NULL) {
if (gSP.textureTile[t]->masks > 0 && gSP.textureTile[t]->clamps == 0)
fuls = float(gSP.textureTile[t]->uls % (1 << gSP.textureTile[t]->masks));
if (gSP.textureTile[t]->maskt > 0 && gSP.textureTile[t]->clampt == 0)
fult = float(gSP.textureTile[t]->ult % (1 << gSP.textureTile[t]->maskt));
}
_location.uTexOffset[t].set(fuls, fult, _bForce);
}
}
if (cache.current[t] != NULL) {
f32 shiftScaleS = 1.0f;
f32 shiftScaleT = 1.0f;
getTextureShiftScale(t, cache, shiftScaleS, shiftScaleT);
_location.uCacheShiftScale[t].set(shiftScaleS, shiftScaleT, _bForce);
_location.uCacheScale[t].set(cache.current[t]->scaleS, cache.current[t]->scaleT, _bForce);
_location.uCacheOffset[t].set(cache.current[t]->offsetS, cache.current[t]->offsetT, _bForce);
nFB[t] = cache.current[t]->frameBufferTexture;
}
}
_location.uCacheFrameBuffer.set(nFB[0], nFB[1], _bForce);
_location.uTexScale.set(gSP.texture.scales, gSP.texture.scalet, _bForce);
}
void UniformSet::_updateTextureSize(UniformSetLocation & _location, bool _bUsesT0, bool _bUsesT1, bool _bForce)
{
TextureCache & cache = textureCache();
if (_bUsesT0 && cache.current[0] != NULL)
_location.uTextureSize[0].set((float)cache.current[0]->realWidth, (float)cache.current[0]->realHeight, _bForce);
if (_bUsesT1 && cache.current[1] != NULL)
_location.uTextureSize[1].set((float)cache.current[1]->realWidth, (float)cache.current[1]->realHeight, _bForce);
}
void UniformSet::_updateLightUniforms(UniformSetLocation & _location, bool _bForce)
{
for (s32 i = 0; i <= gSP.numLights; ++i) {
_location.uLightDirection[i].set(&gSP.lights[i].ix, _bForce);
_location.uLightColor[i].set(&gSP.lights[i].r, _bForce);
}
}
void UniformSet::updateUniforms(ShaderCombiner * _pCombiner, OGLRender::RENDER_STATE _renderState)
{
UniformSetLocation & location = m_uniforms.at(_pCombiner->getKey());
_updateColorUniforms(location, false);
if ((_renderState == OGLRender::rsTriangle || _renderState == OGLRender::rsLine) && _pCombiner->usesTexture())
_updateTextureUniforms(location, _pCombiner->usesTile(0), _pCombiner->usesTile(1), false);
if (_pCombiner->usesTexture())
_updateTextureSize(location, _pCombiner->usesTile(0), _pCombiner->usesTile(1), false);
if (config.generalEmulation.enableHWLighting != 0 && GBI.isHWLSupported() && _pCombiner->usesShadeColor())
_updateLightUniforms(location, false);
}
UniformCollection * createUniformCollection()
{
return new UniformSet();
}

View File

@ -1,71 +0,0 @@
#ifndef UNIFORM_SET_H
#define UNIFORM_SET_H
#include "../UniformCollection.h"
class UniformSet : public UniformCollection
{
public:
UniformSet() {}
~UniformSet() {}
virtual void bindWithShaderCombiner(ShaderCombiner * _pCombiner);
virtual void setColorData(ColorUniforms _index, u32 _dataSize, const void * _data) {}
virtual void updateTextureParameters() {}
virtual void updateLightParameters() {}
virtual void updateUniforms(ShaderCombiner * _pCombiner, OGLRender::RENDER_STATE _renderState);
private:
struct fv3Uniform {
GLint loc = -1;
float val[3];
void set(float * _pVal, bool _force) {
const size_t szData = sizeof(float)* 3;
if (loc >= 0 && (_force || memcmp(val, _pVal, szData) != 0)) {
memcpy(val, _pVal, szData);
glUniform3fv(loc, 1, _pVal);
}
}
};
struct fv4Uniform {
GLint loc = -1;
float val[4];
void set(float * _pVal, bool _force) {
const size_t szData = sizeof(float)* 4;
if (loc >= 0 && (_force || memcmp(val, _pVal, szData) != 0)) {
memcpy(val, _pVal, szData);
glUniform4fv(loc, 1, _pVal);
}
}
};
struct UniformSetLocation
{
UniformSetLocation(GLuint _program) : m_program(_program) {}
GLuint m_program;
// Texture parameters
ShaderCombiner::fv2Uniform uTexScale, uTexOffset[2], uCacheScale[2], uCacheOffset[2], uCacheShiftScale[2], uTextureSize[2];
ShaderCombiner::iv2Uniform uCacheFrameBuffer;
// Colors
fv4Uniform uFogColor, uCenterColor, uScaleColor, uBlendColor, uEnvColor, uPrimColor;
ShaderCombiner::fUniform uPrimLod, uK4, uK5;
// Lights
fv3Uniform uLightDirection[8], uLightColor[8];
};
void _updateColorUniforms(UniformSetLocation & _location, bool _bForce);
void _updateTextureUniforms(UniformSetLocation & _location, bool _bUsesT0, bool _bUsesT1, bool _bForce);
void _updateTextureSize(UniformSetLocation & _location, bool _bUsesT0, bool _bUsesT1, bool _bForce);
void _updateLightUniforms(UniformSetLocation & _location, bool _bForce);
typedef std::map<CombinerKey, UniformSetLocation> Uniforms;
Uniforms m_uniforms;
};
#endif // UNIFORM_SET_H

File diff suppressed because it is too large Load Diff

View File

@ -1,859 +0,0 @@
#if defined(GLES3_1)
#define MAIN_SHADER_VERSION "#version 310 es \n"
#define AUXILIARY_SHADER_VERSION "\n"
#elif defined(GLES3)
#define MAIN_SHADER_VERSION "#version 300 es \n"
#define AUXILIARY_SHADER_VERSION "\n"
#else
#define MAIN_SHADER_VERSION "#version 330 core \n"
#define AUXILIARY_SHADER_VERSION "#version 330 core \n"
#endif
static const char* vertex_shader =
MAIN_SHADER_VERSION
"in highp vec4 aPosition; \n"
"in lowp vec4 aColor; \n"
"in highp vec2 aTexCoord; \n"
"in lowp float aNumLights; \n"
"in highp vec4 aModify; \n"
" \n"
"uniform int uTexturePersp; \n"
" \n"
"uniform lowp int uFogUsage; \n"
"uniform mediump vec2 uFogScale; \n"
"uniform mediump vec2 uScreenCoordsScale; \n"
" \n"
#ifdef GL_USE_UNIFORMBLOCK
"layout (std140) uniform TextureBlock { \n"
" mediump vec2 uTexScale; \n"
" mediump vec2 uTexOffset[2]; \n"
" mediump vec2 uCacheScale[2]; \n"
" mediump vec2 uCacheOffset[2]; \n"
" mediump vec2 uCacheShiftScale[2]; \n"
" lowp ivec2 uCacheFrameBuffer; \n"
"}; \n"
#else
"uniform mediump vec2 uTexScale; \n"
"uniform mediump vec2 uTexOffset[2]; \n"
"uniform mediump vec2 uCacheScale[2]; \n"
"uniform mediump vec2 uCacheOffset[2]; \n"
"uniform mediump vec2 uCacheShiftScale[2]; \n"
"uniform lowp ivec2 uCacheFrameBuffer; \n"
#endif // GL_USE_UNIFORMBLOCK
"out lowp vec4 vShadeColor; \n"
"out mediump vec2 vTexCoord0; \n"
"out mediump vec2 vTexCoord1; \n"
"out mediump vec2 vLodTexCoord; \n"
"out lowp float vNumLights; \n"
"mediump vec2 calcTexCoord(in vec2 texCoord, in int idx) \n"
"{ \n"
" vec2 texCoordOut = texCoord*uCacheShiftScale[idx]; \n"
" texCoordOut -= uTexOffset[idx]; \n"
" if (uCacheFrameBuffer[idx] != 0) \n"
" texCoordOut.t = -texCoordOut.t; \n"
" return (uCacheOffset[idx] + texCoordOut)* uCacheScale[idx];\n"
"} \n"
" \n"
"void main() \n"
"{ \n"
" gl_Position = aPosition; \n"
" vShadeColor = aColor; \n"
" vec2 texCoord = aTexCoord; \n"
" texCoord *= uTexScale; \n"
" if (uTexturePersp == 0 && aModify[2] == 0.0) texCoord *= 0.5;\n"
" vTexCoord0 = calcTexCoord(texCoord, 0); \n"
" vTexCoord1 = calcTexCoord(texCoord, 1); \n"
" vLodTexCoord = texCoord; \n"
" vNumLights = aNumLights; \n"
" if (aModify != vec4(0.0)) { \n"
" if ((aModify[0]) != 0.0) { \n"
" gl_Position.xy = gl_Position.xy * uScreenCoordsScale + vec2(-1.0, 1.0); \n"
" gl_Position.xy *= gl_Position.w; \n"
" } \n"
" if ((aModify[1]) != 0.0) \n"
" gl_Position.z *= gl_Position.w; \n"
" if ((aModify[3]) != 0.0) \n"
" vNumLights = 0.0; \n"
" } \n"
" if (uFogUsage == 1) { \n"
" lowp float fp; \n"
" if (aPosition.z < -aPosition.w && aModify[1] == 0.0) \n"
" fp = -uFogScale.s + uFogScale.t; \n"
" else \n"
" fp = aPosition.z/aPosition.w*uFogScale.s + uFogScale.t; \n"
" vShadeColor.a = clamp(fp, 0.0, 1.0); \n"
" } \n"
#ifndef GLESX
" gl_ClipDistance[0] = gl_Position.w - gl_Position.z; \n"
#endif
"} \n"
;
static const char* vertex_shader_notex =
MAIN_SHADER_VERSION
"in highp vec4 aPosition; \n"
"in lowp vec4 aColor; \n"
"in lowp float aNumLights; \n"
"in highp vec4 aModify; \n"
" \n"
"uniform lowp int uFogUsage; \n"
"uniform mediump vec2 uFogScale; \n"
"uniform mediump vec2 uScreenCoordsScale;\n"
" \n"
"out lowp vec4 vShadeColor; \n"
"out lowp float vNumLights; \n"
" \n"
"void main() \n"
"{ \n"
" gl_Position = aPosition; \n"
" vShadeColor = aColor; \n"
" vNumLights = aNumLights; \n"
" if (aModify != vec4(0.0)) { \n"
" if ((aModify[0]) != 0.0) { \n"
" gl_Position.xy = gl_Position.xy * uScreenCoordsScale + vec2(-1.0, 1.0); \n"
" gl_Position.xy *= gl_Position.w; \n"
" } \n"
" if ((aModify[1]) != 0.0) \n"
" gl_Position.z *= gl_Position.w; \n"
" if ((aModify[3]) != 0.0) \n"
" vNumLights = 0.0; \n"
" } \n"
" if (uFogUsage == 1) { \n"
" lowp float fp; \n"
" if (aPosition.z < -aPosition.w && aModify[1] == 0.0) \n"
" fp = -uFogScale.s + uFogScale.t; \n"
" else \n"
" fp = aPosition.z/aPosition.w*uFogScale.s + uFogScale.t; \n"
" vShadeColor.a = clamp(fp, 0.0, 1.0); \n"
" } \n"
#ifndef GLESX
" gl_ClipDistance[0] = gl_Position.w - gl_Position.z; \n"
#endif
"} \n"
;
static const char* vertex_shader_texrect =
MAIN_SHADER_VERSION
"in highp vec4 aRectPosition; \n"
"in lowp vec4 aRectColor; \n"
"in highp vec2 aTexCoord0; \n"
"in highp vec2 aTexCoord1; \n"
" \n"
"out lowp vec4 vShadeColor; \n"
"out mediump vec2 vTexCoord0; \n"
"out mediump vec2 vTexCoord1; \n"
"void main() \n"
"{ \n"
" gl_Position = aRectPosition; \n"
" vShadeColor = aRectColor; \n"
" vTexCoord0 = aTexCoord0; \n"
" vTexCoord1 = aTexCoord1; \n"
#ifndef GLESX
" gl_ClipDistance[0] = gl_Position.w - gl_Position.z; \n"
#endif
"} \n"
;
static const char* vertex_shader_rect =
MAIN_SHADER_VERSION
"in highp vec4 aRectPosition; \n"
"in lowp vec4 aRectColor; \n"
" \n"
"out lowp vec4 vShadeColor; \n"
"void main() \n"
"{ \n"
" gl_Position = aRectPosition; \n"
" vShadeColor = aRectColor; \n"
#ifndef GLESX
" gl_ClipDistance[0] = gl_Position.w - gl_Position.z; \n"
#endif
"} \n"
;
static const char* fragment_shader_header_common_variables =
MAIN_SHADER_VERSION
"uniform sampler2D uTex0; \n"
"uniform sampler2D uTex1; \n"
"uniform sampler2D uDepthTex; \n"
#ifdef GL_USE_UNIFORMBLOCK
"layout (std140) uniform ColorsBlock {\n"
" lowp vec4 uFogColor; \n"
" lowp vec4 uCenterColor; \n"
" lowp vec4 uScaleColor; \n"
" lowp vec4 uBlendColor; \n"
" lowp vec4 uEnvColor; \n"
" lowp vec4 uPrimColor; \n"
" lowp float uPrimLod; \n"
" lowp float uK4; \n"
" lowp float uK5; \n"
"}; \n"
#else
"uniform lowp vec4 uFogColor; \n"
"uniform lowp vec4 uCenterColor;\n"
"uniform lowp vec4 uScaleColor; \n"
"uniform lowp vec4 uBlendColor; \n"
"uniform lowp vec4 uEnvColor; \n"
"uniform lowp vec4 uPrimColor; \n"
"uniform lowp float uPrimLod; \n"
"uniform lowp float uK4; \n"
"uniform lowp float uK5; \n"
#endif // GL_USE_UNIFORMBLOCK
#ifdef GLESX
"uniform mediump vec2 uScreenScale; \n"
#endif
"uniform lowp int uAlphaCompareMode;\n"
"uniform lowp int uAlphaDitherMode; \n"
"uniform lowp int uColorDitherMode; \n"
"uniform lowp int uFogUsage; \n"
"uniform lowp ivec2 uFbMonochrome; \n"
"uniform lowp ivec2 uFbFixedAlpha; \n"
"uniform lowp int uEnableAlphaTest; \n"
"uniform lowp int uCvgXAlpha; \n"
"uniform lowp int uAlphaCvgSel; \n"
"uniform lowp int uRenderTarget; \n"
"uniform lowp float uAlphaTestValue;\n"
"uniform mediump vec2 uDepthScale; \n"
"uniform lowp ivec4 uBlendMux1; \n"
"uniform lowp int uForceBlendCycle1;\n"
"in lowp vec4 vShadeColor; \n"
"in mediump vec2 vTexCoord0; \n"
"in mediump vec2 vTexCoord1; \n"
"in mediump vec2 vLodTexCoord; \n"
"in lowp float vNumLights; \n"
"out lowp vec4 fragColor; \n"
;
#ifdef GL_MULTISAMPLING_SUPPORT
static const char* fragment_shader_header_common_variables_ms_enabled =
"uniform lowp ivec2 uMSTexEnabled; \n";
static const char* fragment_shader_header_common_variables_ms_tex0 =
"uniform lowp sampler2DMS uMSTex0; \n";
static const char* fragment_shader_header_common_variables_ms_tex1 =
"uniform lowp sampler2DMS uMSTex1; \n";
#endif
static const char* fragment_shader_header_common_variables_notex =
MAIN_SHADER_VERSION
"uniform sampler2D uDepthTex; \n"
#ifdef GL_USE_UNIFORMBLOCK
"layout (std140) uniform ColorsBlock {\n"
" lowp vec4 uFogColor; \n"
" lowp vec4 uCenterColor; \n"
" lowp vec4 uScaleColor; \n"
" lowp vec4 uBlendColor; \n"
" lowp vec4 uEnvColor; \n"
" lowp vec4 uPrimColor; \n"
" lowp float uPrimLod; \n"
" lowp float uK4; \n"
" lowp float uK5; \n"
"}; \n"
#else
"uniform lowp vec4 uFogColor; \n"
"uniform lowp vec4 uCenterColor;\n"
"uniform lowp vec4 uScaleColor; \n"
"uniform lowp vec4 uBlendColor; \n"
"uniform lowp vec4 uEnvColor; \n"
"uniform lowp vec4 uPrimColor; \n"
"uniform lowp float uPrimLod; \n"
"uniform lowp float uK4; \n"
"uniform lowp float uK5; \n"
#endif // GL_USE_UNIFORMBLOCK
#ifdef GLESX
"uniform mediump vec2 uScreenScale; \n"
#endif
"uniform lowp int uAlphaCompareMode;\n"
"uniform lowp int uAlphaDitherMode; \n"
"uniform lowp int uColorDitherMode; \n"
"uniform lowp int uFogUsage; \n"
"uniform lowp int uEnableAlphaTest; \n"
"uniform lowp int uCvgXAlpha; \n"
"uniform lowp int uAlphaCvgSel; \n"
"uniform lowp int uRenderTarget; \n"
"uniform lowp float uAlphaTestValue;\n"
"uniform mediump vec2 uDepthScale; \n"
"uniform lowp ivec4 uBlendMux1; \n"
"uniform lowp int uForceBlendCycle1;\n"
"in lowp vec4 vShadeColor; \n"
"in lowp float vNumLights; \n"
"out lowp vec4 fragColor; \n"
;
static const char* fragment_shader_header_common_variables_blend_mux_2cycle =
"uniform lowp ivec4 uBlendMux2; \n"
"uniform lowp int uForceBlendCycle2; \n"
;
static const char* fragment_shader_header_noise =
"lowp float snoise();\n";
static const char* fragment_shader_header_write_depth =
"void writeDepth();\n";
static const char* fragment_shader_header_calc_light =
"void calc_light(in lowp float fLights, in lowp vec3 input_color, out lowp vec3 output_color);\n";
static const char* fragment_shader_header_mipmap =
"mediump float mipmap(out lowp vec4 readtex0, out lowp vec4 readtex1);\n";
#ifdef GL_MULTISAMPLING_SUPPORT
static const char* fragment_shader_header_readTexMS =
"lowp vec4 readTexMS(in lowp sampler2DMS mstex, in mediump vec2 texCoord, in lowp int fbMonochrome, in lowp int fbFixedAlpha);\n";
#endif // GL_MULTISAMPLING_SUPPORT
#ifdef GL_IMAGE_TEXTURES_SUPPORT
static const char* fragment_shader_header_depth_compare =
"bool depth_compare();\n"
"bool depth_render(highp float Z);\n";
#endif // GL_IMAGE_TEXTURES_SUPPORT
static const char* fragment_shader_header_noise_dither =
"void colorNoiseDither(in lowp float _noise, inout lowp vec3 _color);\n"
"void alphaNoiseDither(in lowp float _noise, inout lowp float _alpha);\n";
#ifdef USE_TOONIFY
static const char* fragment_shader_header_alpha_noise_toonify =
"void toonify(in mediump float intensity);\n"
#endif
static const char* fragment_shader_calc_light =
AUXILIARY_SHADER_VERSION
#ifdef GL_USE_UNIFORMBLOCK
"layout (std140) uniform LightBlock { \n"
" mediump vec3 uLightDirection[8]; \n"
" lowp vec3 uLightColor[8]; \n"
"}; \n"
#else
"uniform mediump vec3 uLightDirection[8]; \n"
"uniform lowp vec3 uLightColor[8]; \n"
#endif // GL_USE_UNIFORMBLOCK
"void calc_light(in lowp float fLights, in lowp vec3 input_color, out lowp vec3 output_color) {\n"
" output_color = input_color; \n"
" lowp int nLights = int(floor(fLights + 0.5)); \n"
" if (nLights == 0) \n"
" return; \n"
" output_color = uLightColor[nLights]; \n"
" mediump float intensity; \n"
" for (int i = 0; i < nLights; i++) { \n"
" intensity = max(dot(input_color, uLightDirection[i]), 0.0);\n"
" output_color += intensity*uLightColor[i]; \n"
" }; \n"
" output_color = clamp(output_color, 0.0, 1.0); \n"
"} \n"
;
static const char* fragment_shader_header_main =
" \n"
"void main() \n"
"{ \n"
" writeDepth(); \n"
" lowp vec4 vec_color, combined_color; \n"
" lowp float alpha1, alpha2; \n"
" lowp vec3 color1, color2, input_color; \n"
;
static const char* fragment_shader_blend_mux =
" lowp mat4 muxPM = mat4(vec4(0.0), vec4(0.0), uBlendColor, uFogColor); \n"
" lowp vec4 muxA = vec4(0.0, uFogColor.a, vShadeColor.a, 0.0); \n"
" lowp vec4 muxB = vec4(0.0, 1.0, 1.0, 0.0); \n"
;
static const char* fragment_shader_dither =
AUXILIARY_SHADER_VERSION
"void colorNoiseDither(in lowp float _noise, inout lowp vec3 _color) \n"
"{ \n"
" mediump vec3 tmpColor = _color*255.0; \n"
" mediump ivec3 iColor = ivec3(tmpColor); \n"
//" iColor &= 248; \n" // does not work with HW lighting enabled (why?!)
" iColor |= ivec3(tmpColor*_noise)&7; \n"
" _color = vec3(iColor)/255.0; \n"
"} \n"
"void alphaNoiseDither(in lowp float _noise, inout lowp float _alpha) \n"
"{ \n"
" mediump float tmpAlpha = _alpha*255.0; \n"
" mediump int iAlpha = int(tmpAlpha); \n"
//" iAlpha &= 248; \n" // causes issue #518. need further investigation
" iAlpha |= int(tmpAlpha*_noise)&7; \n"
" _alpha = float(iAlpha)/255.0; \n"
"} \n"
;
#ifdef USE_TOONIFY
static const char* fragment_shader_toonify =
" \n"
"void toonify(in mediump float intensity) { \n"
" if (intensity > 0.5) \n"
" return; \n"
" else if (intensity > 0.125) \n"
" fragColor = vec4(vec3(fragColor)*0.5, fragColor.a);\n"
" else \n"
" fragColor = vec4(vec3(fragColor)*0.2, fragColor.a);\n"
"} \n"
;
#endif
static const char* fragment_shader_end =
"} \n"
;
static const char* fragment_shader_mipmap =
#ifndef GLESX
AUXILIARY_SHADER_VERSION
"in mediump vec2 vTexCoord0; \n"
"in mediump vec2 vTexCoord1; \n"
"in mediump vec2 vLodTexCoord; \n"
"uniform sampler2D uTex0; \n"
"uniform sampler2D uTex1; \n"
"uniform mediump vec2 uScreenScale; \n"
#endif
"uniform lowp int uEnableLod; \n"
"uniform mediump float uMinLod; \n"
"uniform lowp int uMaxTile; \n"
"uniform lowp int uTextureDetail; \n"
" \n"
"mediump float mipmap(out lowp vec4 readtex0, out lowp vec4 readtex1) { \n"
" readtex0 = texture(uTex0, vTexCoord0); \n"
" readtex1 = textureLod(uTex1, vTexCoord1, 0.0); \n"
" \n"
" mediump float fMaxTile = float(uMaxTile); \n"
#if 1
" mediump vec2 dx = abs(dFdx(vLodTexCoord)); \n"
" dx *= uScreenScale; \n"
" mediump float lod = max(dx.x, dx.y); \n"
#else
" mediump vec2 dx = dFdx(vLodTexCoord); \n"
" dx *= uScreenScale; \n"
" mediump vec2 dy = dFdy(vLodTexCoord); \n"
" dy *= uScreenScale; \n"
" mediump float lod = max(length(dx), length(dy)); \n"
#endif
" bool magnify = lod < 1.0; \n"
" mediump float lod_tile = magnify ? 0.0 : floor(log2(floor(lod))); \n"
" bool distant = lod > 128.0 || lod_tile >= fMaxTile; \n"
" mediump float lod_frac = fract(lod/pow(2.0, lod_tile)); \n"
" if (magnify) lod_frac = max(lod_frac, uMinLod); \n"
" if (uTextureDetail == 0) { \n"
" if (distant) lod_frac = 1.0; \n"
" else if (magnify) lod_frac = 0.0; \n"
" } \n"
" if (magnify && ((uTextureDetail & 1) != 0)) \n"
" lod_frac = 1.0 - lod_frac; \n"
" if (uMaxTile == 0) { \n"
" if (uEnableLod != 0 && (uTextureDetail & 2) == 0) \n"
" readtex1 = readtex0; \n"
" return lod_frac; \n"
" } \n"
" if (uEnableLod == 0) return lod_frac; \n"
" \n"
" lod_tile = min(lod_tile, fMaxTile); \n"
" lowp float lod_tile_m1 = max(0.0, lod_tile - 1.0); \n"
" lowp vec4 lodT = textureLod(uTex1, vTexCoord1, lod_tile); \n"
" lowp vec4 lodT_m1 = textureLod(uTex1, vTexCoord1, lod_tile_m1); \n"
" lowp vec4 lodT_p1 = textureLod(uTex1, vTexCoord1, lod_tile + 1.0); \n"
" if (lod_tile < 1.0) { \n"
" if (magnify) { \n"
// !sharpen && !detail
" if (uTextureDetail == 0) readtex1 = readtex0; \n"
" } else { \n"
// detail
" if ((uTextureDetail & 2) != 0 ) { \n"
" readtex0 = lodT; \n"
" readtex1 = lodT_p1; \n"
" } \n"
" } \n"
" } else { \n"
" if ((uTextureDetail & 2) != 0 ) { \n"
" readtex0 = lodT; \n"
" readtex1 = lodT_p1; \n"
" } else { \n"
" readtex0 = lodT_m1; \n"
" readtex1 = lodT; \n"
" } \n"
" } \n"
" return lod_frac; \n"
"} \n"
;
static const char* fragment_shader_fake_mipmap =
"uniform lowp int uMaxTile; \n"
"uniform mediump float uMinLod; \n"
" \n"
"mediump float mipmap(out lowp vec4 readtex0, out lowp vec4 readtex1) { \n"
" readtex0 = texture(uTex0, vTexCoord0); \n"
" readtex1 = texture(uTex1, vTexCoord1); \n"
" if (uMaxTile == 0) return 1.0; \n"
" return uMinLod; \n"
"} \n"
;
static const char* fragment_shader_readtex =
"#define READ_TEX(name, tex, texCoord, fbMonochrome, fbFixedAlpha) \\\n"
" { \\\n"
" name = texture(tex, texCoord); \\\n"
" if (fbMonochrome == 1) name = vec4(name.r); \\\n"
" else if (fbMonochrome == 2) \\\n"
" name.rgb = vec3(dot(vec3(0.2126, 0.7152, 0.0722), name.rgb)); \\\n"
" if (fbFixedAlpha == 1) name.a = 0.825; \\\n"
" } \n"
;
static const char* fragment_shader_readtex_3point =
"uniform lowp int uTextureFilterMode; \n"
// 3 point texture filtering.
// Original author: ArthurCarvalho
// GLSL implementation: twinaphex, mupen64plus-libretro project.
"#define TEX_OFFSET(tex, texCoord, off) texture(tex, texCoord - (off)/texSize) \n"
"#define FILTER_3POINT(tex, texCoord) \\\n"
" mediump vec2 texSize = vec2(textureSize(tex,0)); \\\n"
" mediump vec2 offset = fract(texCoord*texSize - vec2(0.5)); \\\n"
" offset -= step(1.0, offset.x + offset.y); \\\n"
" lowp vec4 c0 = TEX_OFFSET(tex, texCoord, offset); \\\n"
" lowp vec4 c1 = TEX_OFFSET(tex, texCoord, vec2(offset.x - sign(offset.x), offset.y)); \\\n"
" lowp vec4 c2 = TEX_OFFSET(tex, texCoord, vec2(offset.x, offset.y - sign(offset.y))); \\\n"
" lowp vec4 tex3Point = c0 + abs(offset.x)*(c1-c0) + abs(offset.y)*(c2-c0); \n"
"#define READ_TEX(name, tex, texCoord, fbMonochrome, fbFixedAlpha) \\\n"
" { \\\n"
" lowp vec4 texStandard = texture(tex, texCoord); \\\n"
" FILTER_3POINT(tex, texCoord); \\\n"
" name = uTextureFilterMode == 0 ? texStandard : tex3Point; \\\n"
" if (fbMonochrome == 1) name = vec4(name.r); \\\n"
" else if (fbMonochrome == 2) \\\n"
" name.rgb = vec3(dot(vec3(0.2126, 0.7152, 0.0722), name.rgb)); \\\n"
" if (fbFixedAlpha == 1) name.a = 0.825; \\\n"
" } \n"
;
#ifdef GL_MULTISAMPLING_SUPPORT
static const char* fragment_shader_readtex_ms =
AUXILIARY_SHADER_VERSION
"uniform lowp int uMSAASamples; \n"
"uniform lowp float uMSAAScale; \n"
"lowp vec4 sampleMS(in lowp sampler2DMS mstex, in mediump ivec2 ipos) \n"
"{ \n"
" lowp vec4 texel = vec4(0.0); \n"
" for (int i = 0; i < uMSAASamples; ++i) \n"
" texel += texelFetch(mstex, ipos, i); \n"
" return texel * uMSAAScale; \n"
"} \n"
" \n"
"lowp vec4 readTexMS(in lowp sampler2DMS mstex, in mediump vec2 texCoord, in lowp int fbMonochrome, in lowp int fbFixedAlpha) \n"
"{ \n"
" mediump vec2 msTexSize = vec2(textureSize(mstex)); \n"
" mediump ivec2 itexCoord = ivec2(msTexSize * texCoord); \n"
" lowp vec4 texColor = sampleMS(mstex, itexCoord); \n"
" if (fbMonochrome == 1) texColor = vec4(texColor.r); \n"
" else if (fbMonochrome == 2) \n"
" texColor.rgb = vec3(dot(vec3(0.2126, 0.7152, 0.0722), texColor.rgb)); \n"
" if (fbFixedAlpha == 1) texColor.a = 0.825; \n"
" return texColor; \n"
"} \n"
;
#endif // GL_MULTISAMPLING_SUPPORT
static const char* fragment_shader_noise =
AUXILIARY_SHADER_VERSION
#ifndef GLESX
"uniform mediump vec2 uScreenScale; \n"
#endif
"uniform sampler2D uTexNoise; \n"
"lowp float snoise() \n"
"{ \n"
" ivec2 coord = ivec2(gl_FragCoord.xy/uScreenScale); \n"
" return texelFetch(uTexNoise, coord, 0).r; \n"
"} \n"
;
static const char* fragment_shader_dummy_noise =
" \n"
"lowp float snoise() \n"
"{ \n"
" return 1.0; \n"
"} \n"
;
static const char* fragment_shader_depth =
AUXILIARY_SHADER_VERSION
#ifndef GLESX
"uniform mediump vec2 uDepthScale; \n"
#endif
"void writeDepth() \n"
"{ \n"
" gl_FragDepth = clamp((gl_FragCoord.z * 2.0 - 1.0) * uDepthScale.s + uDepthScale.t, 0.0, 1.0); \n"
"} \n"
;
static const char* fragment_shader_dummy_depth =
"void writeDepth() \n"
"{ \n"
"} \n"
;
#ifdef GL_IMAGE_TEXTURES_SUPPORT
static const char* depth_compare_shader_float =
#ifndef GLESX
"#version 430 \n"
"layout(binding = 2, rg32f) uniform coherent image2D uDepthImage;\n"
#else
"layout(binding = 2, rgba32f) highp uniform coherent image2D uDepthImage;\n"
#endif
//"uniform int uEnableDepth; \n"
"uniform lowp int uDepthMode; \n"
"uniform lowp int uDepthSource; \n"
"uniform lowp int uEnableDepthCompare; \n"
"uniform lowp int uEnableDepthUpdate; \n"
"uniform mediump float uDeltaZ; \n"
"bool depth_compare() \n"
"{ \n"
//" if (uEnableDepth == 0) return true; \n"
" ivec2 coord = ivec2(gl_FragCoord.xy); \n"
" highp vec4 depth = imageLoad(uDepthImage,coord); \n"
" highp float bufZ = depth.r; \n"
" highp float curZ = gl_FragDepth; \n"
" highp float dz, dzMin; \n"
" if (uDepthSource == 1) { \n"
" dzMin = dz = uDeltaZ; \n"
" } else { \n"
" dz = 4.0*fwidth(gl_FragDepth); \n"
" dzMin = min(dz, depth.g); \n"
" } \n"
" bool bInfront = curZ < bufZ; \n"
" bool bFarther = (curZ + dzMin) >= bufZ; \n"
" bool bNearer = (curZ - dzMin) <= bufZ; \n"
" bool bMax = bufZ == 1.0; \n"
" bool bRes; \n"
" switch (uDepthMode) { \n"
" case 1: \n"
" bRes = bMax || bNearer; \n"
" break; \n"
" case 0: \n"
" case 2: \n"
" bRes = bMax || bInfront; \n"
" break; \n"
" case 3: \n"
" bRes = bFarther && bNearer && !bMax; \n"
" break; \n"
" default: \n"
" bRes = bInfront; \n"
" break; \n"
" } \n"
" if (uEnableDepthUpdate != 0 && bRes) { \n"
" highp vec4 depth_out = vec4(gl_FragDepth, dz, 1.0, 1.0); \n"
" imageStore(uDepthImage,coord, depth_out); \n"
" } \n"
" memoryBarrierImage(); \n"
" if (uEnableDepthCompare != 0) \n"
" return bRes; \n"
" return true; \n"
"} \n"
;
static const char* depth_render_shader =
#ifndef GLESX
"#version 430 \n"
"layout(binding = 2, rg32f) uniform coherent image2D uDepthImage;\n"
#else
"layout(binding = 2, rgba32f) highp uniform coherent image2D uDepthImage;\n"
#endif
"uniform lowp int uEnableDepthCompare; \n"
"bool depth_render(highp float Z) \n"
"{ \n"
" ivec2 coord = ivec2(gl_FragCoord.xy); \n"
" if (uEnableDepthCompare != 0) { \n"
" highp vec4 depth = imageLoad(uDepthImage,coord); \n"
" highp float bufZ = depth.r; \n"
" highp float curZ = gl_FragDepth; \n"
" if (curZ >= bufZ) return false; \n"
" } \n"
" highp vec4 depth_out = vec4(Z, 0.0, 1.0, 1.0); \n"
" imageStore(uDepthImage,coord, depth_out); \n"
" memoryBarrierImage(); \n"
" return true; \n"
"} \n"
;
static const char* shadow_map_fragment_shader_float =
#ifndef GLESX
"#version 420 core \n"
"layout(binding = 0, r16ui) uniform readonly uimage2D uZlutImage;\n"
"layout(binding = 1, r16ui) uniform readonly uimage2D uTlutImage;\n"
#else
MAIN_SHADER_VERSION
"layout(binding = 0, r32ui) highp uniform readonly uimage2D uZlutImage;\n"
"layout(binding = 1, r32ui) highp uniform readonly uimage2D uTlutImage;\n"
#endif
"layout(binding = 0) uniform sampler2D uDepthImage; \n"
"uniform lowp vec4 uFogColor; \n"
"out lowp vec4 fragColor; \n"
"lowp float get_alpha() \n"
"{ \n"
" mediump ivec2 coord = ivec2(gl_FragCoord.xy); \n"
" highp float bufZ = texelFetch(uDepthImage,coord, 0).r; \n"
" highp int iZ = bufZ > 0.999 ? 262143 : int(floor(bufZ * 262143.0));\n"
" mediump int y0 = clamp(iZ/512, 0, 511); \n"
" mediump int x0 = iZ - 512*y0; \n"
" highp uint iN64z = imageLoad(uZlutImage,ivec2(x0,y0)).r; \n"
" highp float n64z = clamp(float(iN64z)/65532.0, 0.0, 1.0);\n"
" highp int index = min(255, int(n64z*255.0)); \n"
" highp uint iAlpha = imageLoad(uTlutImage,ivec2(index,0)).r;\n"
" return float(iAlpha>>8)/255.0; \n"
"} \n"
"void main() \n"
"{ \n"
" fragColor = vec4(uFogColor.rgb, get_alpha()); \n"
"} \n"
;
#endif // GL_IMAGE_TEXTURES_SUPPORT
static const char* vertex_shader_rect_nocolor =
MAIN_SHADER_VERSION
"in highp vec4 aRectPosition; \n"
"void main() \n"
"{ \n"
" gl_Position = aRectPosition; \n"
"} \n"
;
#if 0 // Do palette based monochrome image. Exactly as N64 does
static const char* zelda_monochrome_fragment_shader =
"#version 420 core \n"
"layout(binding = 0) uniform sampler2D uColorImage; \n"
"layout(binding = 1, r16ui) uniform readonly uimage2D uTlutImage;\n"
"out lowp vec4 fragColor; \n"
"lowp float get_color() \n"
"{ \n"
" ivec2 coord = ivec2(gl_FragCoord.xy); \n"
" vec4 color = 31.0*texelFetch(uColorImage, coord, 0); \n"
" int r = int(color.r); int g = int(color.g); int b = int(color.b);\n"
//" int a = 0; if ((color.r + color.g + color.b) > 0) a = 32768;\n"
//" int color16 = 32768 + r*1024 + g*32 + b; \n"
" int color16 = r*1024 + g*32 + b; \n"
" int index = min(255, color16/256); \n"
" uint iAlpha = imageLoad(uTlutImage,ivec2(index,0)).r; \n"
" memoryBarrier(); \n"
" return clamp(float((iAlpha&255) + index)/255.0, 0.0, 1.0); \n"
"} \n"
"void main() \n"
"{ \n"
" fragColor = vec4(vec3(get_color()), 1.0); \n"
"} \n"
;
#else // Cheat it
static const char* zelda_monochrome_fragment_shader =
MAIN_SHADER_VERSION
"uniform sampler2D uColorImage; \n"
"out lowp vec4 fragColor; \n"
"void main() \n"
"{ \n"
" mediump ivec2 coord = ivec2(gl_FragCoord.xy); \n"
" lowp vec4 tex = texelFetch(uColorImage, coord, 0); \n"
//" lowp float c = (tex.r + tex.g + tex.b) / 3.0f; \n"
" lowp float c = dot(vec4(0.2126, 0.7152, 0.0722, 0.0), tex);\n"
" fragColor = vec4(c, c, c, 1.0); \n"
"} \n"
;
#endif
const char * strTexrectDrawerVertexShader =
MAIN_SHADER_VERSION
"in highp vec4 aRectPosition; \n"
"in highp vec2 aTexCoord0; \n"
"out mediump vec2 vTexCoord0; \n"
"void main() \n"
"{ \n"
" gl_Position = aRectPosition; \n"
" vTexCoord0 = aTexCoord0; \n"
"} \n"
;
const char * strTexrectDrawerTex3PointFilter =
MAIN_SHADER_VERSION
"uniform mediump vec4 uTextureBounds; \n"
// 3 point texture filtering.
// Original author: ArthurCarvalho
// GLSL implementation: twinaphex, mupen64plus-libretro project.
"#define TEX_OFFSET(off, tex, texCoord, texSize) texture(tex, texCoord - (off)/texSize) \n"
"#define TEX_FILTER(name, tex, texCoord) \\\n"
"{ \\\n"
" mediump vec2 texSize = vec2(textureSize(tex,0)); \\\n"
" mediump vec2 texelSize = vec2(1.0) / texSize; \\\n"
" lowp vec4 c = texture(tex, texCoord); \\\n"
" if (abs(texCoord.s - uTextureBounds[0]) < texelSize.x || abs(texCoord.s - uTextureBounds[2]) < texelSize.x){ \\\n"
" name = c; \\\n"
" } else if (abs(texCoord.t - uTextureBounds[1]) < texelSize.y || abs(texCoord.t - uTextureBounds[3]) < texelSize.y){ \\\n"
" name = c; \\\n"
" } else { \\\n"
" mediump vec2 offset = fract(texCoord*texSize - vec2(0.5)); \\\n"
" offset -= step(1.0, offset.x + offset.y); \\\n"
" lowp vec4 zero = vec4(0.0); \\\n"
" lowp vec4 c0 = TEX_OFFSET(offset, tex, texCoord, texSize); \\\n"
" lowp vec4 c1 = TEX_OFFSET(vec2(offset.x - sign(offset.x), offset.y), tex, texCoord, texSize); \\\n"
" lowp vec4 c2 = TEX_OFFSET(vec2(offset.x, offset.y - sign(offset.y)), tex, texCoord, texSize); \\\n"
" name = c0 + abs(offset.x)*(c1-c0) + abs(offset.y)*(c2-c0); \\\n"
" } \\\n"
"} \\\n"
" \n"
;
const char * strTexrectDrawerTexBilinearFilter =
MAIN_SHADER_VERSION
"uniform mediump vec4 uTextureBounds; \n"
"#define TEX_OFFSET(off, tex, texCoord, texSize) texture(tex, texCoord - (off)/texSize) \n"
"#define TEX_FILTER(name, tex, texCoord) \\\n"
"{ \\\n"
" mediump vec2 texSize = vec2(textureSize(tex,0)); \\\n"
" mediump vec2 texelSize = vec2(1.0) / texSize; \\\n"
" lowp vec4 c = texture(tex, texCoord); \\\n"
" if (abs(texCoord.s - uTextureBounds[0]) < texelSize.x || abs(texCoord.s - uTextureBounds[2]) < texelSize.x){ \\\n"
" name = c; \\\n"
" } else if (abs(texCoord.t - uTextureBounds[1]) < texelSize.y || abs(texCoord.t - uTextureBounds[3]) < texelSize.y){ \\\n"
" name = c; \\\n"
" } else { \\\n"
" mediump vec2 offset = fract(texCoord*texSize - vec2(0.5)); \\\n"
" offset -= step(1.0, offset.x + offset.y); \\\n"
" lowp vec4 zero = vec4(0.0); \\\n"
" \\\n"
" lowp vec4 p0q0 = TEX_OFFSET(offset, tex, texCoord, texSize); \\\n"
" lowp vec4 p1q0 = TEX_OFFSET(vec2(offset.x - sign(offset.x), offset.y), tex, texCoord, texSize); \\\n"
" \\\n"
" lowp vec4 p0q1 = TEX_OFFSET(vec2(offset.x, offset.y - sign(offset.y)), tex, texCoord, texSize); \\\n"
" lowp vec4 p1q1 = TEX_OFFSET(vec2(offset.x - sign(offset.x), offset.y - sign(offset.y)), tex, texCoord, texSize); \\\n"
" \\\n"
" mediump vec2 interpolationFactor = abs(offset); \\\n"
" lowp vec4 pInterp_q0 = mix( p0q0, p1q0, interpolationFactor.x ); \\\n" // Interpolates top row in X direction.
" lowp vec4 pInterp_q1 = mix( p0q1, p1q1, interpolationFactor.x ); \\\n" // Interpolates bottom row in X direction.
" name = mix( pInterp_q0, pInterp_q1, interpolationFactor.y ); \\\n" // Interpolate in Y direction.
" } \\\n"
"} \\\n"
" \n"
;
const char * strTexrectDrawerFragmentShaderTex =
"uniform sampler2D uTex0; \n"
"uniform lowp int uEnableAlphaTest; \n"
"lowp vec4 uTestColor = vec4(4.0/255.0, 2.0/255.0, 1.0/255.0, 0.0); \n"
"in mediump vec2 vTexCoord0; \n"
"out lowp vec4 fragColor; \n"
"void main() \n"
"{ \n"
" TEX_FILTER(fragColor, uTex0, vTexCoord0); \n"
" if (fragColor == uTestColor) discard; \n"
" if (uEnableAlphaTest == 1 && !(fragColor.a > 0.0)) discard; \n"
"} \n"
;
const char * strTexrectDrawerFragmentShaderClean =
MAIN_SHADER_VERSION
"lowp vec4 uTestColor = vec4(4.0/255.0, 2.0/255.0, 1.0/255.0, 0.0); \n"
"out lowp vec4 fragColor; \n"
"void main() \n"
"{ \n"
" fragColor = uTestColor; \n"
"} \n"
;
const char* strTextureCopyShader =
MAIN_SHADER_VERSION
"in mediump vec2 vTexCoord0; \n"
"uniform sampler2D uTex0; \n"
"out lowp vec4 fragColor; \n"
" \n"
"void main() \n"
"{ \n"
" fragColor = texture(uTex0, vTexCoord0); \n"
"} \n"
;

View File

@ -13,7 +13,6 @@
#include "gDP.h"
#include "Textures.h"
#include "Combiner.h"
#include "GLSLCombiner.h"
#include "FrameBuffer.h"
#include "DepthBuffer.h"
#include "FrameBufferInfo.h"

View File

@ -4,7 +4,6 @@
#include "gSP.h"
#include "PostProcessor.h"
#include "FrameBuffer.h"
#include "GLSLCombiner.h"
#include "ShaderUtils.h"
#include "Config.h"

View File

@ -86,369 +86,3 @@ GLuint createRectShaderProgram(const char * _strVertex, const char * _strFragmen
assert(checkProgramLinkStatus(program));
return program;
}
#ifndef VC
static
const char* fragment_shader_blender1 =
" if (uForceBlendCycle1 != 0) { \n"
" muxPM[0] = clampedColor; \n"
" muxA[0] = clampedColor.a; \n"
" muxB[0] = 1.0 - muxA[uBlendMux1[1]]; \n"
" lowp vec4 blend1 = (muxPM[uBlendMux1[0]] * muxA[uBlendMux1[1]]) + (muxPM[uBlendMux1[2]] * muxB[uBlendMux1[3]]); \n"
" clampedColor.rgb = clamp(blend1.rgb, 0.0, 1.0); \n"
" } \n"
;
static
const char* fragment_shader_blender2 =
" if (uForceBlendCycle2 != 0) { \n"
" muxPM[0] = clampedColor; \n"
" muxA[0] = clampedColor.a; \n"
" muxB[0] = 1.0 - muxA[uBlendMux2[1]]; \n"
" lowp vec4 blend2 = muxPM[uBlendMux2[0]] * muxA[uBlendMux2[1]] + muxPM[uBlendMux2[2]] * muxB[uBlendMux2[3]]; \n"
" clampedColor.rgb = clamp(blend2.rgb, 0.0, 1.0); \n"
" } \n"
;
#endif
/*
// N64 color wrap and clamp on floats
// See https://github.com/gonetz/GLideN64/issues/661 for reference
if (c < -1.0) return c + 2.0;
if (c < -0.5) return 1;
if (c < 0.0) return 0;
if (c > 2.0) return c - 2.0;
if (c > 1.5) return 0;
if (c > 1.0) return 1;
return c;
*/
const char* fragment_shader_clamp =
" lowp vec4 wrappedColor = cmbRes + 2.0 * step(cmbRes, vec4(-0.51)) - 2.0*step(vec4(1.51), cmbRes); \n"
" lowp vec4 clampedColor = clamp(wrappedColor, 0.0, 1.0); \n"
;
/*
N64 sign-extension for C component of combiner
if (c > 1.0)
return c - 2.0;
return c;
*/
const char* fragment_shader_sign_extend_color_c =
" color1 = color1 - 2.0*(vec3(1.0) - step(color1, vec3(1.0))); \n"
;
const char* fragment_shader_sign_extend_alpha_c =
" alpha1 = alpha1 - 2.0*(1.0 - step(alpha1, 1.0)); \n"
;
/*
N64 sign-extension for ABD components of combiner
if (c > 1.5)
return c - 2.0;
if (c < -0.5)
return c + 2.0;
return c;
*/
const char* fragment_shader_sign_extend_color_abd =
" color1 = color1 + 2.0*step(color1, vec3(-0.51)) - 2.0*step(vec3(1.51), color1); \n"
;
const char* fragment_shader_sign_extend_alpha_abd =
" alpha1 = alpha1 + 2.0*step(alpha1, -0.51) - 2.0*step(1.51, alpha1); \n"
;
static
const char *ColorInput[] = {
"combined_color.rgb",
"readtex0.rgb",
"readtex1.rgb",
"uPrimColor.rgb",
"vec_color.rgb",
"uEnvColor.rgb",
"uCenterColor.rgb",
"uScaleColor.rgb",
"combined_color.a",
"vec3(readtex0.a)",
"vec3(readtex1.a)",
"vec3(uPrimColor.a)",
"vec3(vec_color.a)",
"vec3(uEnvColor.a)",
"vec3(lod_frac)",
"vec3(uPrimLod)",
"vec3(0.5 + 0.5*snoise())",
"vec3(uK4)",
"vec3(uK5)",
"vec3(1.0)",
"vec3(0.0)"
};
static
const char *AlphaInput[] = {
"combined_color.a",
"readtex0.a",
"readtex1.a",
"uPrimColor.a",
"vec_color.a",
"uEnvColor.a",
"uCenterColor.a",
"uScaleColor.a",
"combined_color.a",
"readtex0.a",
"readtex1.a",
"uPrimColor.a",
"vec_color.a",
"uEnvColor.a",
"lod_frac",
"uPrimLod",
"0.5 + 0.5*snoise()",
"uK4",
"uK5",
"1.0",
"0.0"
};
inline
int correctFirstStageParam(int _param)
{
switch (_param) {
case TEXEL1:
return TEXEL0;
case TEXEL1_ALPHA:
return TEXEL0_ALPHA;
}
return _param;
}
static
void _correctFirstStageParams(CombinerStage & _stage)
{
for (int i = 0; i < _stage.numOps; ++i) {
_stage.op[i].param1 = correctFirstStageParam(_stage.op[i].param1);
_stage.op[i].param2 = correctFirstStageParam(_stage.op[i].param2);
_stage.op[i].param3 = correctFirstStageParam(_stage.op[i].param3);
}
}
inline
int correctSecondStageParam(int _param)
{
switch (_param) {
case TEXEL0:
return TEXEL1;
case TEXEL1:
return TEXEL0;
case TEXEL0_ALPHA:
return TEXEL1_ALPHA;
case TEXEL1_ALPHA:
return TEXEL0_ALPHA;
}
return _param;
}
static
bool needClampColor() {
return gDP.otherMode.cycleType <= G_CYC_2CYCLE;
}
static
bool combinedColorC(const gDPCombine & _combine) {
if (gDP.otherMode.cycleType != G_CYC_2CYCLE)
return false;
return _combine.mRGB1 == G_CCMUX_COMBINED;
}
static
bool combinedAlphaC(const gDPCombine & _combine) {
if (gDP.otherMode.cycleType != G_CYC_2CYCLE)
return false;
return _combine.mA1 == G_ACMUX_COMBINED;
}
static
bool combinedColorABD(const gDPCombine & _combine) {
if (gDP.otherMode.cycleType != G_CYC_2CYCLE)
return false;
if (_combine.aRGB1 == G_CCMUX_COMBINED)
return true;
if (_combine.saRGB1 == G_CCMUX_COMBINED || _combine.sbRGB1 == G_CCMUX_COMBINED)
return _combine.mRGB1 != G_CCMUX_0;
return false;
}
static
bool combinedAlphaABD(const gDPCombine & _combine) {
if (gDP.otherMode.cycleType != G_CYC_2CYCLE)
return false;
if (_combine.aA1 == G_ACMUX_COMBINED)
return true;
if (_combine.saA1 == G_ACMUX_COMBINED || _combine.sbA1 == G_ACMUX_COMBINED)
return _combine.mA1 != G_ACMUX_0;
return false;
}
static
void _correctSecondStageParams(CombinerStage & _stage) {
for (int i = 0; i < _stage.numOps; ++i) {
_stage.op[i].param1 = correctSecondStageParam(_stage.op[i].param1);
_stage.op[i].param2 = correctSecondStageParam(_stage.op[i].param2);
_stage.op[i].param3 = correctSecondStageParam(_stage.op[i].param3);
}
}
static
int _compileCombiner(const CombinerStage & _stage, const char** _Input, std::string & _strShader) {
char buf[128];
bool bBracketOpen = false;
int nRes = 0;
for (int i = 0; i < _stage.numOps; ++i) {
switch (_stage.op[i].op) {
case LOAD:
sprintf(buf, "(%s ", _Input[_stage.op[i].param1]);
_strShader += buf;
bBracketOpen = true;
nRes |= 1 << _stage.op[i].param1;
break;
case SUB:
if (bBracketOpen) {
sprintf(buf, "- %s)", _Input[_stage.op[i].param1]);
bBracketOpen = false;
}
else
sprintf(buf, "- %s", _Input[_stage.op[i].param1]);
_strShader += buf;
nRes |= 1 << _stage.op[i].param1;
break;
case ADD:
if (bBracketOpen) {
sprintf(buf, "+ %s)", _Input[_stage.op[i].param1]);
bBracketOpen = false;
}
else
sprintf(buf, "+ %s", _Input[_stage.op[i].param1]);
_strShader += buf;
nRes |= 1 << _stage.op[i].param1;
break;
case MUL:
if (bBracketOpen) {
sprintf(buf, ")*%s", _Input[_stage.op[i].param1]);
bBracketOpen = false;
}
else
sprintf(buf, "*%s", _Input[_stage.op[i].param1]);
_strShader += buf;
nRes |= 1 << _stage.op[i].param1;
break;
case INTER:
sprintf(buf, "mix(%s, %s, %s)", _Input[_stage.op[0].param2], _Input[_stage.op[0].param1], _Input[_stage.op[0].param3]);
_strShader += buf;
nRes |= 1 << _stage.op[i].param1;
nRes |= 1 << _stage.op[i].param2;
nRes |= 1 << _stage.op[i].param3;
break;
// default:
// assert(false);
}
}
if (bBracketOpen)
_strShader.append(")");
_strShader.append("; \n");
return nRes;
}
int compileCombiner(const gDPCombine & _combine, Combiner & _color, Combiner & _alpha, std::string & _strShader)
{
if (gDP.otherMode.cycleType != G_CYC_2CYCLE) {
_correctFirstStageParams(_alpha.stage[0]);
_correctFirstStageParams(_color.stage[0]);
}
_strShader.append(" alpha1 = ");
int nInputs = _compileCombiner(_alpha.stage[0], AlphaInput, _strShader);
// Simulate N64 color sign-extend.
if (combinedAlphaC(_combine))
_strShader.append(fragment_shader_sign_extend_alpha_c);
else if (combinedAlphaABD(_combine))
_strShader.append(fragment_shader_sign_extend_alpha_abd);
_strShader.append(
" if (uEnableAlphaTest != 0) { \n"
" lowp float alphaTestValue = (uAlphaCompareMode == 3) ? snoise() : uAlphaTestValue; \n"
" lowp float alphaValue; \n"
" if ((uAlphaCvgSel != 0) && (uCvgXAlpha == 0)) { \n"
" alphaValue = 0.125; \n"
" } else { \n"
" alphaValue = clamp(alpha1, 0.0, 1.0); \n"
" } \n"
" if (alphaValue < alphaTestValue) discard; \n"
" } \n"
);
_strShader.append(" color1 = ");
nInputs |= _compileCombiner(_color.stage[0], ColorInput, _strShader);
// Simulate N64 color sign-extend.
if (combinedColorC(_combine))
_strShader.append(fragment_shader_sign_extend_color_c);
else if (combinedColorABD(_combine))
_strShader.append(fragment_shader_sign_extend_color_abd);
_strShader.append(" combined_color = vec4(color1, alpha1); \n");
if (_alpha.numStages == 2) {
_strShader.append(" alpha2 = ");
_correctSecondStageParams(_alpha.stage[1]);
nInputs |= _compileCombiner(_alpha.stage[1], AlphaInput, _strShader);
}
else
_strShader.append(" alpha2 = alpha1; \n");
_strShader.append(" if (uCvgXAlpha != 0 && alpha2 < 0.125) discard; \n");
if (_color.numStages == 2) {
_strShader.append(" color2 = ");
_correctSecondStageParams(_color.stage[1]);
nInputs |= _compileCombiner(_color.stage[1], ColorInput, _strShader);
}
else
_strShader.append(" color2 = color1; \n");
_strShader.append(" lowp vec4 cmbRes = vec4(color2, alpha2);\n");
// Simulate N64 color clamp.
if (needClampColor())
_strShader.append(fragment_shader_clamp);
else
_strShader.append(" lowp vec4 clampedColor = clamp(cmbRes, 0.0, 1.0);\n");
#ifndef GLES2
if (config.generalEmulation.enableNoise != 0) {
_strShader.append(
" if (uColorDitherMode == 2) colorNoiseDither(snoise(), clampedColor.rgb); \n"
" if (uAlphaDitherMode == 2) alphaNoiseDither(snoise(), clampedColor.a); \n"
);
}
#endif
if (config.generalEmulation.enableLegacyBlending == 0) {
if (gDP.otherMode.cycleType <= G_CYC_2CYCLE)
_strShader.append(fragment_shader_blender1);
if (gDP.otherMode.cycleType == G_CYC_2CYCLE)
_strShader.append(fragment_shader_blender2);
_strShader.append(
" fragColor = clampedColor; \n"
);
} else {
_strShader.append(
" fragColor = clampedColor; \n"
" if (uFogUsage == 1) \n"
" fragColor.rgb = mix(fragColor.rgb, uFogColor.rgb, vShadeColor.a); \n"
);
}
return nInputs;
}

View File

@ -8,6 +8,5 @@ GLuint createRectShaderProgram(const char * _strVertex, const char * _strFragmen
bool checkShaderCompileStatus(GLuint obj);
bool checkProgramLinkStatus(GLuint obj);
void logErrorShader(GLenum _shaderType, const std::string & _strShader);
int compileCombiner(const gDPCombine & _combine, Combiner & _color, Combiner & _alpha, std::string & _strShader);
#endif // SHADER_UTILS_H

View File

@ -18,7 +18,6 @@
#include "TextDrawer.h"
#include "RSP.h"
#include "Config.h"
#include "GLSLCombiner.h"
#include "ShaderUtils.h"
#include <FBOTextureFormats.h>
#include "Log.h"

View File

@ -5,7 +5,6 @@
#include <chrono> // std::chrono::seconds
#include "OpenGL.h"
#include "Textures.h"
#include "GLSLCombiner.h"
#include "GBI.h"
#include "RSP.h"
#include "gDP.h"

View File

@ -1,48 +0,0 @@
#ifndef UNIFORM_COLLECTION_H
#define UNIFORM_COLLECTION_H
#include "GLSLCombiner.h"
class UniformCollection {
public:
enum TextureUniforms {
tuTexScale,
tuTexOffset,
tuCacheScale,
tuCacheOffset,
tuCacheShiftScale,
tuCacheFrameBuffer,
tuTotal
};
enum ColorUniforms {
cuFogColor,
cuCenterColor,
cuScaleColor,
cuBlendColor,
cuEnvColor,
cuPrimColor,
cuPrimLod,
cuK4,
cuK5,
cuTotal
};
enum LightUniforms {
luLightDirection,
luLightColor,
luTotal
};
virtual ~UniformCollection() {}
virtual void bindWithShaderCombiner(ShaderCombiner * _pCombiner) = 0;
virtual void setColorData(ColorUniforms _index, u32 _dataSize, const void * _data) = 0;
virtual void updateTextureParameters() = 0;
virtual void updateLightParameters() = 0;
virtual void updateUniforms(ShaderCombiner * _pCombiner, OGLRender::RENDER_STATE _renderState) = 0;
};
UniformCollection * createUniformCollection();
#endif // UNIFORM_COLLECTION_H

View File

@ -1,45 +0,0 @@
#include "OpenGL.h"
#ifdef GLSTATE_H
void GLState::reset()
{
cached_ActiveTexture_texture = 0;
cached_BlendFunc_sfactor = 0;
cached_BlendFunc_dfactor = 0;
cached_ReadBufferMode = 0;
cached_glPixelStorei_target = 0;
cached_glPixelStorei_param = 0;
cached_ClearColor_red = 0;
cached_ClearColor_green = 0;
cached_ClearColor_blue = 0;
cached_ClearColor_alpha = 0;
cached_CullFace_mode = 0;
cached_DepthFunc_func = 0;
cached_DepthMask_flag = 0;
cached_BLEND = false;
cached_CULL_FACE = false;
cached_DEPTH_TEST = false;
cached_DEPTH_CLAMP = false;
cached_CLIP_DISTANCE0 = false;
cached_DITHER = false;
cached_POLYGON_OFFSET_FILL = false;
cached_SAMPLE_ALPHA_TO_COVERAGE = false;
cached_SAMPLE_COVERAGE = false;
cached_SCISSOR_TEST = false;
cached_PolygonOffset_factor = 0;
cached_PolygonOffset_units = 0;
cached_Scissor_x = 0;
cached_Scissor_y = 0;
cached_Scissor_width = 0;
cached_Scissor_height = 0;
cached_UseProgram_program = -1;
cached_Viewport_x = 0;
cached_Viewport_y = 0;
cached_Viewport_width = 0;
cached_Viewport_height = 0;
}
GLState glState;
#endif // GLSTATE_H

View File

@ -1,327 +0,0 @@
#ifndef GLSTATE_H
#define GLSTATE_H
#ifdef __cplusplus
extern "C" {
#endif
struct GLState {
GLState() { reset(); }
void reset();
GLenum cached_ActiveTexture_texture;
GLenum cached_BlendFunc_sfactor;
GLenum cached_BlendFunc_dfactor;
GLenum cached_ReadBufferMode;
GLenum cached_glPixelStorei_target;
GLint cached_glPixelStorei_param;
GLclampf cached_ClearColor_red;
GLclampf cached_ClearColor_green;
GLclampf cached_ClearColor_blue;
GLclampf cached_ClearColor_alpha;
GLenum cached_DepthFunc_func;
GLboolean cached_DepthMask_flag;
bool cached_BLEND;
bool cached_CULL_FACE;
bool cached_DEPTH_TEST;
bool cached_DEPTH_CLAMP;
bool cached_CLIP_DISTANCE0;
bool cached_DITHER;
bool cached_POLYGON_OFFSET_FILL;
bool cached_SAMPLE_ALPHA_TO_COVERAGE;
bool cached_SAMPLE_COVERAGE;
bool cached_SCISSOR_TEST;
GLenum cached_FrontFace_mode;
GLenum cached_CullFace_mode;
GLfloat cached_PolygonOffset_factor;
GLfloat cached_PolygonOffset_units;
GLint cached_Scissor_x;
GLint cached_Scissor_y;
GLsizei cached_Scissor_width;
GLsizei cached_Scissor_height;
GLuint cached_UseProgram_program;
GLint cached_Viewport_x;
GLint cached_Viewport_y;
GLsizei cached_Viewport_width;
GLsizei cached_Viewport_height;
};
extern GLState glState;
void inline cache_glActiveTexture (GLenum texture)
{
if (texture != glState.cached_ActiveTexture_texture) {
glActiveTexture(texture);
glState.cached_ActiveTexture_texture = texture;
}
}
#define glActiveTexture(texture) cache_glActiveTexture(texture)
void inline cache_glBlendFunc (GLenum sfactor, GLenum dfactor)
{
if (sfactor != glState.cached_BlendFunc_sfactor || dfactor != glState.cached_BlendFunc_dfactor) {
glBlendFunc(sfactor, dfactor);
glState.cached_BlendFunc_sfactor = sfactor;
glState.cached_BlendFunc_dfactor = dfactor;
}
}
#define glBlendFunc(sfactor, dfactor) cache_glBlendFunc(sfactor, dfactor)
void inline cache_glReadBuffer(GLenum mode)
{
if (mode != glState.cached_ReadBufferMode)
glState.cached_ReadBufferMode = mode;
}
#define glReadBuffer(mode) cache_glReadBuffer(mode)
void inline cache_glPixelStorei(GLenum target, GLint param)
{
if (target != glState.cached_glPixelStorei_target || param != glState.cached_glPixelStorei_param) {
glPixelStorei(target, param);
glState.cached_glPixelStorei_target = target;
glState.cached_glPixelStorei_param = param;
}
}
#define glPixelStorei(target, param) cache_glPixelStorei(target, param)
void inline cache_glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
{
if (red != glState.cached_ClearColor_red || green != glState.cached_ClearColor_green || blue != glState.cached_ClearColor_blue || alpha != glState.cached_ClearColor_alpha) {
glClearColor(red, green, blue, alpha);
glState.cached_ClearColor_red = red;
glState.cached_ClearColor_green = green;
glState.cached_ClearColor_blue = blue;
glState.cached_ClearColor_alpha = alpha;
}
}
#define glClearColor(red, green, blue, alpha) cache_glClearColor(red, green, blue, alpha)
void inline cache_glCullFace (GLenum mode)
{
if (mode != glState.cached_CullFace_mode) {
glCullFace(mode);
glState.cached_CullFace_mode = mode;
}
}
#define glCullFace(mode) cache_glCullFace(mode)
void inline cache_glDepthFunc (GLenum func)
{
if (func != glState.cached_DepthFunc_func) {
glDepthFunc(func);
glState.cached_DepthFunc_func = func;
}
}
#define glDepthFunc(func) cache_glDepthFunc(func)
void inline cache_glDepthMask (GLboolean flag)
{
if (flag != glState.cached_DepthMask_flag) {
glDepthMask(flag);
glState.cached_DepthMask_flag = flag;
}
}
#define glDepthMask(flag) cache_glDepthMask(flag)
void inline cache_glDisable (GLenum cap)
{
switch (cap) {
case GL_BLEND:
if (glState.cached_BLEND) {
glDisable(GL_BLEND);
glState.cached_BLEND = false;
}
break;
case GL_CULL_FACE:
if (glState.cached_CULL_FACE) {
glDisable(GL_CULL_FACE);
glState.cached_CULL_FACE = false;
}
break;
case GL_DEPTH_TEST:
if (glState.cached_DEPTH_TEST) {
glDisable(GL_DEPTH_TEST);
glState.cached_DEPTH_TEST = false;
}
break;
#ifndef GLESX
case GL_DEPTH_CLAMP:
if (glState.cached_DEPTH_CLAMP) {
glDisable(GL_DEPTH_CLAMP);
glState.cached_DEPTH_CLAMP = false;
}
break;
case GL_CLIP_DISTANCE0:
if (glState.cached_CLIP_DISTANCE0) {
glDisable(GL_CLIP_DISTANCE0);
glState.cached_CLIP_DISTANCE0 = false;
}
break;
#endif
case GL_DITHER:
if (glState.cached_DITHER) {
glDisable(GL_DITHER);
glState.cached_DITHER = false;
}
break;
case GL_POLYGON_OFFSET_FILL:
if (glState.cached_POLYGON_OFFSET_FILL) {
glDisable(GL_POLYGON_OFFSET_FILL);
glState.cached_POLYGON_OFFSET_FILL = false;
}
break;
case GL_SAMPLE_ALPHA_TO_COVERAGE:
if (glState.cached_SAMPLE_ALPHA_TO_COVERAGE) {
glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
glState.cached_SAMPLE_ALPHA_TO_COVERAGE = false;
}
break;
case GL_SAMPLE_COVERAGE:
if (glState.cached_SAMPLE_COVERAGE) {
glDisable(GL_SAMPLE_COVERAGE);
glState.cached_SAMPLE_COVERAGE = false;
}
break;
case GL_SCISSOR_TEST:
if (glState.cached_SCISSOR_TEST) {
glDisable(GL_SCISSOR_TEST);
glState.cached_SCISSOR_TEST = false;
}
break;
default:
glDisable(cap);
break;
}
}
#define glDisable(cap) cache_glDisable(cap)
void inline cache_glEnable(GLenum cap)
{
switch (cap) {
case GL_BLEND:
if (!glState.cached_BLEND) {
glEnable(GL_BLEND);
glState.cached_BLEND = true;
}
break;
case GL_CULL_FACE:
if (!glState.cached_CULL_FACE) {
glEnable(GL_CULL_FACE);
glState.cached_CULL_FACE = true;
}
break;
case GL_DEPTH_TEST:
if (!glState.cached_DEPTH_TEST) {
glEnable(GL_DEPTH_TEST);
glState.cached_DEPTH_TEST = true;
}
break;
#ifndef GLESX
case GL_DEPTH_CLAMP:
if (!glState.cached_DEPTH_CLAMP) {
glEnable(GL_DEPTH_CLAMP);
glState.cached_DEPTH_CLAMP = true;
}
break;
case GL_CLIP_DISTANCE0:
if (!glState.cached_CLIP_DISTANCE0) {
glEnable(GL_CLIP_DISTANCE0);
glState.cached_CLIP_DISTANCE0 = true;
}
break;
#endif
case GL_DITHER:
if (!glState.cached_DITHER) {
glEnable(GL_DITHER);
glState.cached_DITHER = true;
}
break;
case GL_POLYGON_OFFSET_FILL:
if (!glState.cached_POLYGON_OFFSET_FILL) {
glEnable(GL_POLYGON_OFFSET_FILL);
glState.cached_POLYGON_OFFSET_FILL = true;
}
break;
case GL_SAMPLE_ALPHA_TO_COVERAGE:
if (!glState.cached_SAMPLE_ALPHA_TO_COVERAGE) {
glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
glState.cached_SAMPLE_ALPHA_TO_COVERAGE = true;
}
break;
case GL_SAMPLE_COVERAGE:
if (!glState.cached_SAMPLE_COVERAGE) {
glEnable(GL_SAMPLE_COVERAGE);
glState.cached_SAMPLE_COVERAGE = true;
}
break;
case GL_SCISSOR_TEST:
if (!glState.cached_SCISSOR_TEST) {
glEnable(GL_SCISSOR_TEST);
glState.cached_SCISSOR_TEST = true;
}
break;
default:
glEnable(cap);
break;
}
}
#define glEnable(cap) cache_glEnable(cap)
void inline cache_glPolygonOffset (GLfloat factor, GLfloat units)
{
if (factor != glState.cached_PolygonOffset_factor || units != glState.cached_PolygonOffset_units) {
glPolygonOffset(factor, units);
glState.cached_PolygonOffset_factor = factor;
glState.cached_PolygonOffset_units = units;
}
}
#define glPolygonOffset(factor, units) cache_glPolygonOffset(factor, units)
void inline cache_glScissor (GLint x, GLint y, GLsizei width, GLsizei height)
{
if (x != glState.cached_Scissor_x || y != glState.cached_Scissor_y || width != glState.cached_Scissor_width || height != glState.cached_Scissor_height) {
glScissor(x, y, width, height);
glState.cached_Scissor_x = x;
glState.cached_Scissor_y = y;
glState.cached_Scissor_width = width;
glState.cached_Scissor_height = height;
}
}
#define glScissor(x, y, width, height) cache_glScissor(x, y, width, height)
void inline cache_glUseProgram (GLuint program)
{
if (program != glState.cached_UseProgram_program) {
glUseProgram(program);
glState.cached_UseProgram_program = program;
}
}
#define glUseProgram(program) cache_glUseProgram(program)
void inline cache_glViewport (GLint x, GLint y, GLsizei width, GLsizei height)
{
if (x != glState.cached_Viewport_x || y != glState.cached_Viewport_y || width != glState.cached_Viewport_width || height != glState.cached_Viewport_height) {
glViewport(x, y, width, height);
glState.cached_Viewport_x = x;
glState.cached_Viewport_y = y;
glState.cached_Viewport_width = width;
glState.cached_Viewport_height = height;
}
}
#define glViewport(x, y, width, height) cache_glViewport(x, y, width, height)
#ifdef __cplusplus
}
#endif
#endif //GLSTATE_H