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:
parent
f650e5e54b
commit
c39b639d7c
|
@ -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" />
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
#include <FBOTextureFormats.h>
|
||||
#include <FrameBufferInfo.h>
|
||||
#include <GLSLCombiner.h>
|
||||
#include <FrameBuffer.h>
|
||||
#include <Combiner.h>
|
||||
#include <Textures.h>
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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"
|
||||
;
|
|
@ -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
|
|
@ -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();
|
||||
}
|
|
@ -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
|
|
@ -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();
|
||||
}
|
|
@ -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
|
@ -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"
|
||||
;
|
|
@ -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"
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
#include "gSP.h"
|
||||
#include "PostProcessor.h"
|
||||
#include "FrameBuffer.h"
|
||||
#include "GLSLCombiner.h"
|
||||
#include "ShaderUtils.h"
|
||||
#include "Config.h"
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
|
@ -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
|
327
src/glState.h
327
src/glState.h
|
@ -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
|
Loading…
Reference in New Issue
Block a user