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

Code refactor:

Move CompileCombiner to ShadersUtils.
Remove GLES2 specific code.
This commit is contained in:
Sergey Lipskiy 2015-05-21 00:11:30 +06:00
parent 9fd4d55b44
commit aad80168d3
4 changed files with 278 additions and 416 deletions

View File

@ -2,18 +2,18 @@
#include <stdio.h>
#include <string>
#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 "../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 "Shaders.h"
#include "Shaders_ogl3x.h"
using namespace std;
@ -52,11 +52,7 @@ public:
private:
CachedTexture * m_pTexture;
#ifndef GLES2
GLuint m_PBO;
#else
GLubyte* m_PBO;
#endif
u32 m_DList;
} noiseTex;
@ -76,19 +72,13 @@ void NoiseTexture::init()
m_pTexture->textureBytes = m_pTexture->realWidth * m_pTexture->realHeight;
textureCache().addFrameBufferTextureSize(m_pTexture->textureBytes);
glBindTexture(GL_TEXTURE_2D, m_pTexture->glName);
#ifdef GLES2
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, m_pTexture->realWidth, m_pTexture->realHeight, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
#else
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, m_pTexture->realWidth, m_pTexture->realHeight, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
#endif
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);
// Generate Pixel Buffer Object. Initialize it later
#ifndef GLES2
glGenBuffers(1, &m_PBO);
#endif
}
void NoiseTexture::destroy()
@ -97,10 +87,8 @@ void NoiseTexture::destroy()
textureCache().removeFrameBufferTexture(m_pTexture);
m_pTexture = NULL;
}
#ifndef GLES2
glDeleteBuffers(1, &m_PBO);
m_PBO = 0;
#endif
}
void NoiseTexture::update()
@ -110,34 +98,22 @@ void NoiseTexture::update()
const u32 dataSize = VI.width*VI.height;
if (dataSize == 0)
return;
#ifndef GLES2
PBOBinder binder(GL_PIXEL_UNPACK_BUFFER, m_PBO);
glBufferData(GL_PIXEL_UNPACK_BUFFER, dataSize, NULL, GL_DYNAMIC_DRAW);
isGLError();
GLubyte* ptr = (GLubyte*)glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, dataSize, GL_MAP_WRITE_BIT);
isGLError();
#else
m_PBO = (GLubyte*)malloc(dataSize);
GLubyte* ptr = m_PBO;
PBOBinder binder(m_PBO);
#endif // GLES2
if (ptr == NULL)
return;
for (u32 y = 0; y < VI.height; ++y) {
for (u32 x = 0; x < VI.width; ++x)
ptr[x + y*VI.width] = rand()&0xFF;
}
#ifndef GLES2
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); // release the mapped buffer
#endif
glActiveTexture(GL_TEXTURE0 + g_noiseTexIndex);
glBindTexture(GL_TEXTURE_2D, m_pTexture->glName);
#ifndef GLES2
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, VI.width, VI.height, GL_RED, GL_UNSIGNED_BYTE, 0);
#else
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, VI.width, VI.height, GL_LUMINANCE, GL_UNSIGNED_BYTE, m_PBO);
#endif
m_DList = RSP.DList;
}
@ -283,185 +259,10 @@ void DestroyShaderCombiner() {
#endif // GL_IMAGE_TEXTURES_SUPPORT
}
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)"
};
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
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, char * _strCombiner) {
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]);
strcat(_strCombiner, 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]);
strcat(_strCombiner, 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]);
strcat(_strCombiner, 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]);
strcat(_strCombiner, 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]);
strcat(_strCombiner, 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)
strcat(_strCombiner, ")");
strcat(_strCombiner, "; \n");
return nRes;
}
ShaderCombiner::ShaderCombiner(Combiner & _color, Combiner & _alpha, const gDPCombine & _combine) : m_combine(_combine)
{
if (gDP.otherMode.cycleType == G_CYC_1CYCLE) {
CorrectFirstStageParams(_alpha.stage[0]);
CorrectFirstStageParams(_color.stage[0]);
}
char strCombiner[1024];
strcpy(strCombiner, " alpha1 = ");
m_nInputs = CompileCombiner(_alpha.stage[0], AlphaInput, strCombiner);
strcat(strCombiner, " color1 = ");
m_nInputs |= CompileCombiner(_color.stage[0], ColorInput, strCombiner);
strcat(strCombiner, fragment_shader_blender);
strcat(strCombiner, " combined_color = vec4(color1, alpha1); \n");
if (_alpha.numStages == 2) {
strcat(strCombiner, " alpha2 = ");
CorrectSecondStageParams(_alpha.stage[1]);
m_nInputs |= CompileCombiner(_alpha.stage[1], AlphaInput, strCombiner);
} else
strcat(strCombiner, " alpha2 = alpha1; \n");
if (_color.numStages == 2) {
strcat(strCombiner, " color2 = ");
CorrectSecondStageParams(_color.stage[1]);
m_nInputs |= CompileCombiner(_color.stage[1], ColorInput, strCombiner);
} else
strcat(strCombiner, " color2 = color1; \n");
m_nInputs = compileCombiner(_color, _alpha, strCombiner);
if (usesTexture()) {
strFragmentShader.assign(fragment_shader_header_common_variables);
@ -495,18 +296,10 @@ ShaderCombiner::ShaderCombiner(Combiner & _color, Combiner & _alpha, const gDPCo
strFragmentShader.append(" lowp vec4 readtex1 = readTex(uTex1, vTexCoord1, uFb8Bit[1] != 0, uFbFixedAlpha[1] != 0); \n");
}
#else
if (usesTile(0)) {
#ifdef GLES2
strFragmentShader.append(" nCurrentTile = 0; \n");
#endif
if (usesTile(0))
strFragmentShader.append(" lowp vec4 readtex0 = readTex(uTex0, vTexCoord0, uFb8Bit[0] != 0, uFbFixedAlpha[0] != 0); \n");
}
if (usesTile(1)) {
#ifdef GLES2
strFragmentShader.append(" nCurrentTile = 1; \n");
#endif
if (usesTile(1))
strFragmentShader.append(" lowp vec4 readtex1 = readTex(uTex1, vTexCoord1, uFb8Bit[1] != 0, uFbFixedAlpha[1] != 0); \n");
}
#endif // GL_MULTISAMPLING_SUPPORT
}
const bool bUseHWLight = config.generalEmulation.enableHWLighting != 0 && GBI.isHWLSupported() && usesShadeColor();
@ -524,16 +317,13 @@ ShaderCombiner::ShaderCombiner(Combiner & _color, Combiner & _alpha, const gDPCo
" } \n"
);
#ifndef GLES2
if (config.generalEmulation.enableNoise != 0) {
strFragmentShader.append(
" if (uColorDitherMode == 2) colorNoiseDither(snoise(), color2); \n"
" if (uAlphaDitherMode == 2) alphaNoiseDither(snoise(), alpha2); \n"
);
}
#endif
#ifndef PowerVR_SGX_540
strFragmentShader.append(
" lowp int fogUsage = uFogUsage; \n"
" if (fogUsage >= 256) fogUsage -= 256; \n"
@ -542,9 +332,6 @@ ShaderCombiner::ShaderCombiner(Combiner & _color, Combiner & _alpha, const gDPCo
" else if (fogUsage == 4) fragColor = vec4(color2, uFogColor.a*alpha2); \n"
" else fragColor = vec4(color2, alpha2); \n"
);
#else
strFragmentShader.append(" fragColor = vec4(color2, alpha2); \n");
#endif
if (video().getRender().isImageTexturesSupported() && config.frameBufferEmulation.N64DepthCompare != 0)
strFragmentShader.append(" if (!depth_compare()) discard; \n");
@ -557,9 +344,6 @@ ShaderCombiner::ShaderCombiner(Combiner & _color, Combiner & _alpha, const gDPCo
" fragColor.rgb = mix(fragColor.rgb, uFogColor.rgb, vFogFragCoord); \n"
" if (uGammaCorrectionEnabled != 0) \n"
" fragColor.rgb = sqrt(fragColor.rgb); \n"
#ifdef GLES2
" gl_FragColor = fragColor; \n"
#endif
);
strFragmentShader.append(fragment_shader_end);
@ -584,9 +368,7 @@ ShaderCombiner::ShaderCombiner(Combiner & _color, Combiner & _alpha, const gDPCo
#endif
if (config.generalEmulation.enableNoise != 0) {
strFragmentShader.append(fragment_shader_noise);
#ifndef GLES2
strFragmentShader.append(fragment_shader_dither);
#endif
}
#endif
@ -961,6 +743,11 @@ void SetDepthFogCombiner()
#endif // GL_IMAGE_TEXTURES_SUPPORT
void SetMonochromeCombiner() {
static int texLoc = -1;
if (texLoc < 0) {
texLoc = glGetUniformLocation(g_monochrome_image_program, "uColorImage");
glUniform1i(texLoc, 0);
}
glUseProgram(g_monochrome_image_program);
gDP.changed |= CHANGED_COMBINE;
}

View File

@ -1,25 +1,21 @@
#ifdef GLES2
#define SHADER_VERSION "#version 100 \n"
#if defined(GLES3_1)
#define MAIN_SHADER_VERSION "#version 330 core \n"
#define AUXILIARY_SHADER_VERSION "\n"
#elif defined(GLES3)
#define SHADER_VERSION "#version 300 es \n"
#define MAIN_SHADER_VERSION "#version 300 es \n"
#define AUXILIARY_SHADER_VERSION "\n"
#else
#define SHADER_VERSION "#version 330 core \n"
#define MAIN_SHADER_VERSION "#version 330 core \n"
#define AUXILIARY_SHADER_VERSION "#version 330 core \n"
#endif
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"
MAIN_SHADER_VERSION
"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"
" \n"
"uniform int uRenderState; \n"
"uniform int uTexturePersp; \n"
@ -29,7 +25,6 @@ SHADER_VERSION
"uniform lowp float uFogAlpha; \n"
"uniform mediump vec2 uFogScale; \n"
" \n"
#ifdef GL_UNIFORMBLOCK_SUPPORT
"layout (std140) uniform TextureBlock { \n"
" mediump vec2 uTexScale; \n"
" mediump vec2 uTexMask[2]; \n"
@ -39,21 +34,12 @@ SHADER_VERSION
" mediump vec2 uCacheShiftScale[2]; \n"
" lowp ivec2 uCacheFrameBuffer; \n"
"}; \n"
#else
"uniform mediump vec2 uTexScale; \n"
"uniform mediump vec2 uTexMask[2]; \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_UNIFORMBLOCK_SUPPORT
"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"
"OUT mediump float vFogFragCoord; \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"
"out mediump float vFogFragCoord; \n"
"mediump vec2 calcTexCoord(in vec2 texCoord, in int idx) \n"
"{ \n"
@ -112,17 +98,10 @@ SHADER_VERSION
;
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"
MAIN_SHADER_VERSION
"in highp vec4 aPosition; \n"
"in lowp vec4 aColor; \n"
"in lowp float aNumLights; \n"
" \n"
"uniform int uRenderState; \n"
" \n"
@ -131,9 +110,9 @@ SHADER_VERSION
"uniform lowp float uFogAlpha; \n"
"uniform mediump vec2 uFogScale; \n"
" \n"
"OUT lowp vec4 vShadeColor; \n"
"OUT lowp float vNumLights; \n"
"OUT mediump float vFogFragCoord; \n"
"out lowp vec4 vShadeColor; \n"
"out lowp float vNumLights; \n"
"out mediump float vFogFragCoord; \n"
" \n"
"void main() \n"
"{ \n"
@ -170,14 +149,7 @@ SHADER_VERSION
;
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"
MAIN_SHADER_VERSION
"uniform sampler2D uTex0; \n"
"uniform sampler2D uTex1; \n"
#ifdef GL_MULTISAMPLING_SUPPORT
@ -185,7 +157,6 @@ SHADER_VERSION
"uniform sampler2DMS uMSTex1; \n"
"uniform lowp ivec2 uMSTexEnabled; \n"
#endif
#ifdef GL_UNIFORMBLOCK_SUPPORT
"layout (std140) uniform ColorsBlock {\n"
" lowp vec4 uFogColor; \n"
" lowp vec4 uCenterColor; \n"
@ -197,17 +168,6 @@ SHADER_VERSION
" 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_UNIFORMBLOCK_SUPPORT
#ifdef GLESX
"uniform mediump vec2 uScreenScale; \n"
#endif
@ -222,29 +182,18 @@ SHADER_VERSION
"uniform lowp int uEnableAlphaTest; \n"
"uniform lowp float uAlphaTestValue;\n"
"uniform mediump vec2 uDepthScale; \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"
"IN mediump float vFogFragCoord;\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"
"in mediump float vFogFragCoord;\n"
"lowp vec3 input_color; \n"
"OUT lowp vec4 fragColor; \n"
#ifdef GLES2
"lowp int nCurrentTile; \n"
#endif
"out lowp vec4 fragColor; \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"
#ifdef GL_UNIFORMBLOCK_SUPPORT
MAIN_SHADER_VERSION
"layout (std140) uniform ColorsBlock {\n"
" lowp vec4 uFogColor; \n"
" lowp vec4 uCenterColor; \n"
@ -256,17 +205,6 @@ SHADER_VERSION
" 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_UNIFORMBLOCK_SUPPORT
#ifdef GLESX
"uniform mediump vec2 uScreenScale; \n"
#endif
@ -279,11 +217,11 @@ SHADER_VERSION
"uniform lowp int uEnableAlphaTest; \n"
"uniform lowp float uAlphaTestValue;\n"
"uniform mediump vec2 uDepthScale; \n"
"IN lowp vec4 vShadeColor; \n"
"IN lowp float vNumLights; \n"
"IN mediump float vFogFragCoord;\n"
"in lowp vec4 vShadeColor; \n"
"in lowp float vNumLights; \n"
"in mediump float vFogFragCoord;\n"
"lowp vec3 input_color; \n"
"OUT lowp vec4 fragColor; \n"
"out lowp vec4 fragColor; \n"
;
static const char* fragment_shader_header_common_functions =
@ -295,11 +233,9 @@ static const char* fragment_shader_header_common_functions =
#ifdef GL_MULTISAMPLING_SUPPORT
"lowp vec4 readTexMS(in sampler2DMS mstex, in mediump vec2 texCoord, in bool fb8bit, in bool fbFixedAlpha); \n"
#endif // GL_MULTISAMPLING_SUPPORT
#ifndef GLES2
"bool depth_compare(); \n"
"void colorNoiseDither(in lowp float _noise, inout lowp vec3 _color); \n"
"void alphaNoiseDither(in lowp float _noise, inout lowp float _alpha);\n"
#endif // GLES2
#ifdef USE_TOONIFY
"void toonify(in mediump float intensity); \n"
#endif
@ -309,26 +245,17 @@ 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"
#ifndef GLES2
"bool depth_compare(); \n"
"void colorNoiseDither(in lowp float _noise, inout lowp vec3 _color); \n"
"void alphaNoiseDither(in lowp float _noise, inout lowp float _alpha);\n"
#endif
;
static const char* fragment_shader_calc_light =
#ifndef GLESX
SHADER_VERSION
#endif
#ifdef GL_UNIFORMBLOCK_SUPPORT
AUXILIARY_SHADER_VERSION
"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_UNIFORMBLOCK_SUPPORT
"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"
@ -357,11 +284,8 @@ static const char* fragment_shader_header_main =
" lowp vec3 color1, color2; \n"
;
#ifndef GLES2
static const char* fragment_shader_dither =
#ifndef GLESX
SHADER_VERSION
#endif
AUXILIARY_SHADER_VERSION
"void colorNoiseDither(in lowp float _noise, inout lowp vec3 _color) \n"
"{ \n"
" mediump vec3 tmpColor = _color*255.0; \n"
@ -378,7 +302,6 @@ SHADER_VERSION
" _alpha = float(iAlpha)/255.0; \n"
"} \n"
;
#endif //GLES2
#ifdef USE_TOONIFY
static const char* fragment_shader_toonify =
@ -394,40 +317,13 @@ static const char* fragment_shader_toonify =
;
#endif
#if 0
static const char* fragment_shader_blender =
" switch (uSpecialBlendMode) { \n"
" case 1: \n"
// Mace
" color1 = color1 * alpha1 + uBlendColor.rgb * (1.0 - alpha1); \n"
" break; \n"
// Donald Duck
" case 2: \n"
" color1 = uFogColor.rgb*uFogColor.a + color1*(1.0-alpha1);\n"
" break; \n"
" } \n"
;
#else
static const char* fragment_shader_blender =
// Mace
" if (uSpecialBlendMode == 1) \n"
" color1 = color1 * alpha1 + uBlendColor.rgb * (1.0 - alpha1); \n"
// Bomberman2
" else if (uSpecialBlendMode == 2) \n"
" color1 = uBlendColor.rgb * uFogColor.a + color1 * (1.0 - uFogColor.a); \n"
// Conker BFD
" else if (uSpecialBlendMode == 3) \n"
" color1 = color1 * uFogColor.a + uFogColor.rgb * (1.0 - uFogColor.a); \n"
;
#endif
static const char* fragment_shader_end =
"} \n"
;
static const char* fragment_shader_mipmap =
#ifndef GLESX
SHADER_VERSION
AUXILIARY_SHADER_VERSION
"in mediump vec2 vTexCoord0; \n"
"in mediump vec2 vTexCoord1; \n"
"in mediump vec2 vLodTexCoord; \n"
@ -438,9 +334,6 @@ SHADER_VERSION
"#ifdef GL_OES_standard_derivatives \n"
" #extension GL_OES_standard_derivatives : enable \n"
"#endif \n"
"#if (__VERSION__ < 120) \n"
"#define texture texture2D \n"
"#endif // __VERSION \n"
#endif
"uniform lowp float uPrimitiveLod; \n"
"uniform lowp int uEnableLod; \n"
@ -457,7 +350,6 @@ SHADER_VERSION
" readtex1 = readtex0; \n"
" return uMinLod; \n"
" } \n"
#ifndef GLES2
" mediump vec2 dx = dFdx(vLodTexCoord); \n"
" dx *= uScreenScale; \n"
" mediump vec2 dy = dFdy(vLodTexCoord); \n"
@ -503,24 +395,11 @@ SHADER_VERSION
" } \n"
" } \n"
" return lod_frac; \n"
#else
" return uPrimitiveLod; \n"
#endif // GLES2
"} \n"
;
static const char* fragment_shader_readtex =
#ifndef GLESX
SHADER_VERSION
#endif
#ifdef GLES2
"#define texture texture2D \n"
"uniform mediump ivec2 uTextureSize[2]; \n"
"mediump ivec2 textureSize(in sampler2D tex, in lowp int level) { \n"
" if (nCurrentTile == 0) return uTextureSize[0]; \n"
" return uTextureSize[1]; \n"
"} \n"
#endif
AUXILIARY_SHADER_VERSION
"uniform lowp int uTextureFilterMode; \n"
// 3 point texture filtering.
// Original author: ArthurCarvalho
@ -569,21 +448,15 @@ SHADER_VERSION
;
static const char* fragment_shader_noise =
AUXILIARY_SHADER_VERSION
#ifndef GLESX
SHADER_VERSION
"uniform mediump vec2 uScreenScale; \n"
#endif
"uniform sampler2D uTexNoise; \n"
"lowp float snoise() \n"
"{ \n"
#ifndef GLES2
" ivec2 coord = ivec2(gl_FragCoord.xy/uScreenScale); \n"
" return texelFetch(uTexNoise, coord, 0).r; \n"
#else
" mediump vec2 texSize = vec2(640.0, 580.0); \n"
" mediump vec2 coord = gl_FragCoord.xy/uScreenScale/texSize; \n"
" return texture2D(uTexNoise, coord).r; \n"
#endif
"} \n"
;
@ -656,15 +529,6 @@ static const char* depth_compare_shader_float =
"} \n"
;
static const char* default_vertex_shader =
"#version 420 core \n"
"in highp vec4 aPosition; \n"
"void main() \n"
"{ \n"
" gl_Position = aPosition; \n"
"} \n"
;
static const char* shadow_map_fragment_shader_float =
"#version 420 core \n"
"layout(binding = 0) uniform sampler2D uDepthImage; \n"
@ -692,7 +556,15 @@ static const char* shadow_map_fragment_shader_float =
;
#endif // GL_IMAGE_TEXTURES_SUPPORT
#ifdef GL_IMAGE_TEXTURES_SUPPORT
static const char* default_vertex_shader =
MAIN_SHADER_VERSION
"in highp vec4 aPosition; \n"
"void main() \n"
"{ \n"
" gl_Position = aPosition; \n"
"} \n"
;
#if 0 // Do palette based monochrome image. Exactly as N64 does
static const char* zelda_monochrome_fragment_shader =
"#version 420 core \n"
@ -719,8 +591,8 @@ static const char* zelda_monochrome_fragment_shader =
;
#else // Cheat it
static const char* zelda_monochrome_fragment_shader =
"#version 420 core \n"
"layout(binding = 0) uniform sampler2D uColorImage; \n"
MAIN_SHADER_VERSION
"uniform sampler2D uColorImage; \n"
"out lowp vec4 fragColor; \n"
"void main() \n"
"{ \n"
@ -732,4 +604,3 @@ static const char* zelda_monochrome_fragment_shader =
"} \n"
;
#endif
#endif // GL_IMAGE_TEXTURES_SUPPORT

View File

@ -1,4 +1,5 @@
#include <assert.h>
#include <stdio.h>
#include "ShaderUtils.h"
#include "Log.h"
@ -54,3 +55,204 @@ GLuint createShaderProgram(const char * _strVertex, const char * _strFragment)
assert(checkProgramLinkStatus(program));
return program;
}
static
const char* fragment_shader_blender =
// Mace
" if (uSpecialBlendMode == 1) \n"
" color1 = color1 * alpha1 + uBlendColor.rgb * (1.0 - alpha1); \n"
// Bomberman2
" else if (uSpecialBlendMode == 2) \n"
" color1 = uBlendColor.rgb * uFogColor.a + color1 * (1.0 - uFogColor.a); \n"
// Conker BFD
" else if (uSpecialBlendMode == 3) \n"
" color1 = color1 * uFogColor.a + uFogColor.rgb * (1.0 - uFogColor.a); \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
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, char * _strCombiner) {
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]);
strcat(_strCombiner, 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]);
strcat(_strCombiner, 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]);
strcat(_strCombiner, 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]);
strcat(_strCombiner, 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]);
strcat(_strCombiner, 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)
strcat(_strCombiner, ")");
strcat(_strCombiner, "; \n");
return nRes;
}
int compileCombiner(Combiner & _color, Combiner & _alpha, char * _strShader)
{
if (gDP.otherMode.cycleType == G_CYC_1CYCLE) {
_correctFirstStageParams(_alpha.stage[0]);
_correctFirstStageParams(_color.stage[0]);
}
strcpy(_strShader, " alpha1 = ");
int nInputs = _compileCombiner(_alpha.stage[0], AlphaInput, _strShader);
strcat(_strShader, " color1 = ");
nInputs |= _compileCombiner(_color.stage[0], ColorInput, _strShader);
strcat(_strShader, fragment_shader_blender);
strcat(_strShader, " combined_color = vec4(color1, alpha1); \n");
if (_alpha.numStages == 2) {
strcat(_strShader, " alpha2 = ");
_correctSecondStageParams(_alpha.stage[1]);
nInputs |= _compileCombiner(_alpha.stage[1], AlphaInput, _strShader);
}
else
strcat(_strShader, " alpha2 = alpha1; \n");
if (_color.numStages == 2) {
strcat(_strShader, " color2 = ");
_correctSecondStageParams(_color.stage[1]);
nInputs |= _compileCombiner(_color.stage[1], ColorInput, _strShader);
}
else
strcat(_strShader, " color2 = color1; \n");
return nInputs;
}

View File

@ -2,9 +2,11 @@
#define SHADER_UTILS_H
#include "OpenGL.h"
#include "Combiner.h"
GLuint createShaderProgram(const char * _strVertex, const char * _strFragment);
bool checkShaderCompileStatus(GLuint obj);
bool checkProgramLinkStatus(GLuint obj);
int compileCombiner(Combiner & _color, Combiner & _alpha, char * _strShader);
#endif // SHADER_UTILS_H