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

CombinerProgramUniformFactory

This commit is contained in:
Sergey Lipskiy 2017-01-05 18:05:47 +07:00
parent 659bd807f5
commit bda5d81f82
15 changed files with 1361 additions and 204 deletions

View File

@ -302,8 +302,11 @@
</ClCompile>
<ClCompile Include="..\..\src\Graphics\Context.cpp" />
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLFunctions.cpp" />
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerInputs.cpp" />
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramBuilder.cpp" />
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramImpl.cpp" />
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramUniformFactory.cpp" />
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_NoiseTexture.cpp" />
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_Utils.cpp" />
<ClCompile Include="..\..\src\Graphics\OpenGLContext\opengl_Attributes.cpp" />
<ClCompile Include="..\..\src\Graphics\OpenGLContext\opengl_BufferManipulationObjectFactory.cpp" />
@ -439,8 +442,11 @@
<ClInclude Include="..\..\src\Graphics\ContextImpl.h" />
<ClInclude Include="..\..\src\Graphics\ObjectHandle.h" />
<ClInclude Include="..\..\src\Graphics\OpenGLContext\GLFunctions.h" />
<ClInclude Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerInputs.h" />
<ClInclude Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramBuilder.h" />
<ClInclude Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramImpl.h" />
<ClInclude Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramUniformFactory.h" />
<ClInclude Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_NoiseTexture.h" />
<ClInclude Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_Utils.h" />
<ClInclude Include="..\..\src\Graphics\OpenGLContext\opengl_Attributes.h" />
<ClInclude Include="..\..\src\Graphics\OpenGLContext\opengl_BufferManipulationObjectFactory.h" />

View File

@ -320,6 +320,15 @@
<ClCompile Include="..\..\src\Graphics\OpenGLContext\opengl_GLInfo.cpp">
<Filter>Source Files\Graphics\OpenGL</Filter>
</ClCompile>
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramUniformFactory.cpp">
<Filter>Source Files\Graphics\OpenGL\GLSL</Filter>
</ClCompile>
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerInputs.cpp">
<Filter>Source Files\Graphics\OpenGL\GLSL</Filter>
</ClCompile>
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_NoiseTexture.cpp">
<Filter>Source Files\Graphics\OpenGL\GLSL</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\src\3DMath.h">
@ -583,5 +592,14 @@
<ClInclude Include="..\..\src\Graphics\OpenGLContext\opengl_GLInfo.h">
<Filter>Header Files\Graphics\OpenGL</Filter>
</ClInclude>
<ClInclude Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramUniformFactory.h">
<Filter>Header Files\Graphics\OpenGL\GLSL</Filter>
</ClInclude>
<ClInclude Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_NoiseTexture.h">
<Filter>Header Files\Graphics\OpenGL\GLSL</Filter>
</ClInclude>
<ClInclude Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerInputs.h">
<Filter>Header Files\Graphics\OpenGL\GLSL</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -10,6 +10,17 @@ namespace graphics {
virtual void activate() = 0;
virtual void update(bool _force) = 0;
virtual CombinerKey getKey() const = 0;
virtual bool usesTexture() const = 0;
virtual bool usesTile(u32 _t) const = 0;
virtual bool usesShade() const = 0;
virtual bool usesLOD() const = 0;
// TODO implement
void disableBlending() {}
void updateFrameBufferInfo(bool _bForce = false) {}
friend std::ostream & operator<< (std::ostream & _os, const CombinerProgram & _combiner);
friend std::istream & operator>> (std::istream & _os, CombinerProgram & _combiner);
};
}

View File

@ -0,0 +1,46 @@
#include <Combiner.h>
#include "glsl_CombinerInputs.h"
using namespace glsl;
bool CombinerInputs::usesTile(u32 _t) const
{
if (_t == 0)
return (m_inputs & ((1 << TEXEL0) | (1 << TEXEL0_ALPHA))) != 0;
return (m_inputs & ((1 << TEXEL1) | (1 << TEXEL1_ALPHA))) != 0;
}
bool CombinerInputs::usesTexture() const
{
return (m_inputs & ((1 << TEXEL1) | (1 << TEXEL1_ALPHA) | (1 << TEXEL0) | (1 << TEXEL0_ALPHA))) != 0;
}
bool CombinerInputs::usesLOD() const
{
return (m_inputs & (1 << LOD_FRACTION)) != 0;
}
bool CombinerInputs::usesNoise() const
{
return (m_inputs & (1 << NOISE)) != 0;
}
bool CombinerInputs::usesShade() const
{
return (m_inputs & ((1 << SHADE) | (1 << SHADE_ALPHA))) != 0;
}
bool CombinerInputs::usesShadeColor() const
{
return (m_inputs & (1 << SHADE)) != 0;
}
bool CombinerInputs::usesHwLighting() const
{
return (m_inputs & (1 << HW_LIGHT)) != 0;
}
void CombinerInputs::addInput(int _input)
{
m_inputs |= 1 << _input;
}

View File

@ -0,0 +1,31 @@
#pragma once
#include <Types.h>
namespace glsl {
class CombinerInputs
{
public:
explicit CombinerInputs(int _inputs) : m_inputs(_inputs) {}
bool usesTile(u32 _t) const;
bool usesTexture() const;
bool usesLOD() const;
bool usesNoise() const;
bool usesShade() const;
bool usesShadeColor() const;
bool usesHwLighting() const;
void addInput(int _input);
private:
int m_inputs;
};
}

View File

@ -2,8 +2,11 @@
#include <Log.h>
#include <Config.h>
#include "glsl_Utils.h"
#include "glsl_NoiseTexture.h"
#include "glsl_CombinerInputs.h"
#include "glsl_CombinerProgramImpl.h"
#include "glsl_CombinerProgramBuilder.h"
#include "glsl_CombinerProgramUniformFactory.h"
using namespace glsl;
@ -178,9 +181,9 @@ int _compileCombiner(const CombinerStage & _stage, const char** _Input, std::str
class VertexShaderHeader : public ShaderPart
{
public:
VertexShaderHeader(const opengl::GLInfo & _version)
VertexShaderHeader(const opengl::GLInfo & _glinfo)
{
if (_version.isGLES2) {
if (_glinfo.isGLES2) {
m_part = "#version 100 \n";
m_part +=
"#if (__VERSION__ > 120) \n"
@ -192,15 +195,15 @@ public:
"#endif // __VERSION \n"
;
}
else if (_version.isGLESX) {
else if (_glinfo.isGLESX) {
std::stringstream ss;
ss << "#version " << _version.majorVersion << _version.minorVersion << "0 es " << std::endl;
ss << "#version " << _glinfo.majorVersion << _glinfo.minorVersion << "0 es " << std::endl;
ss << "# define IN in" << std::endl << "# define OUT out" << std::endl;
m_part = ss.str();
}
else {
std::stringstream ss;
ss << "#version " << _version.majorVersion << _version.minorVersion << "0 core " << std::endl;
ss << "#version " << _glinfo.majorVersion << _glinfo.minorVersion << "0 core " << std::endl;
ss << "# define IN in" << std::endl << "# define OUT out" << std::endl;
m_part = ss.str();
}
@ -210,7 +213,7 @@ public:
class VertexShaderTexturedTriangle : public ShaderPart
{
public:
VertexShaderTexturedTriangle(const opengl::GLInfo & _version)
VertexShaderTexturedTriangle(const opengl::GLInfo & _glinfo)
{
m_part =
"IN highp vec4 aPosition; \n"
@ -276,7 +279,7 @@ public:
" vShadeColor.a = clamp(fp, 0.0, 1.0); \n"
" } \n"
;
if (!_version.isGLESX) {
if (!_glinfo.isGLESX) {
m_part +=
" gl_ClipDistance[0] = gl_Position.w - gl_Position.z; \n"
;
@ -290,7 +293,7 @@ public:
class VertexShaderTriangle : public ShaderPart
{
public:
VertexShaderTriangle(const opengl::GLInfo & _version)
VertexShaderTriangle(const opengl::GLInfo & _glinfo)
{
m_part =
"IN highp vec4 aPosition; \n"
@ -329,7 +332,7 @@ public:
" vShadeColor.a = clamp(fp, 0.0, 1.0); \n"
" } \n"
;
if (!_version.isGLESX) {
if (!_glinfo.isGLESX) {
m_part +=
" gl_ClipDistance[0] = gl_Position.w - gl_Position.z; \n"
;
@ -343,7 +346,7 @@ public:
class VertexShaderTexturedRect : public ShaderPart
{
public:
VertexShaderTexturedRect(const opengl::GLInfo & _version)
VertexShaderTexturedRect(const opengl::GLInfo & _glinfo)
{
m_part =
"IN highp vec4 aRectPosition; \n"
@ -361,7 +364,7 @@ public:
" vTexCoord0 = aTexCoord0; \n"
" vTexCoord1 = aTexCoord1; \n"
;
if (!_version.isGLESX) {
if (!_glinfo.isGLESX) {
m_part +=
" gl_ClipDistance[0] = gl_Position.w - gl_Position.z; \n"
;
@ -375,7 +378,7 @@ public:
class VertexShaderRect : public ShaderPart
{
public:
VertexShaderRect(const opengl::GLInfo & _version)
VertexShaderRect(const opengl::GLInfo & _glinfo)
{
m_part =
"IN highp vec4 aRectPosition; \n"
@ -387,7 +390,7 @@ public:
" gl_Position = aRectPosition; \n"
" vShadeColor = aRectColor; \n"
;
if (!_version.isGLESX) {
if (!_glinfo.isGLESX) {
m_part +=
" gl_ClipDistance[0] = gl_Position.w - gl_Position.z; \n"
;
@ -401,9 +404,9 @@ public:
class FragmentShaderHeader : public ShaderPart
{
public:
FragmentShaderHeader(const opengl::GLInfo & _version)
FragmentShaderHeader(const opengl::GLInfo & _glinfo)
{
if (_version.isGLES2) {
if (_glinfo.isGLES2) {
m_part = "#version 100 \n";
m_part += "#extension GL_EXT_shader_texture_lod : enable \n";
m_part += "#extension GL_OES_standard_derivatives : enable \n";
@ -417,14 +420,14 @@ public:
"#endif // __VERSION __ \n"
;
}
else if (_version.isGLESX) {
else if (_glinfo.isGLESX) {
std::stringstream ss;
ss << "#version " << _version.majorVersion << _version.minorVersion << "0 es " << std::endl;
ss << "#version " << _glinfo.majorVersion << _glinfo.minorVersion << "0 es " << std::endl;
ss << "# define IN in" << std::endl << "# define OUT out" << std::endl;
m_part = ss.str();
} else {
std::stringstream ss;
ss << "#version " << _version.majorVersion << _version.minorVersion << "0 core " << std::endl;
ss << "#version " << _glinfo.majorVersion << _glinfo.minorVersion << "0 core " << std::endl;
ss << "# define IN in" << std::endl << "# define OUT out" << std::endl;
m_part = ss.str();
}
@ -434,9 +437,9 @@ public:
class ShaderBlender1 : public ShaderPart
{
public:
ShaderBlender1(const opengl::GLInfo & _version)
ShaderBlender1(const opengl::GLInfo & _glinfo)
{
if (_version.isGLES2) {
if (_glinfo.isGLES2) {
m_part =
" if (uForceBlendCycle1 != 0) { \n"
" muxPM[0] = clampedColor; \n"
@ -500,9 +503,9 @@ public:
class ShaderBlender2 : public ShaderPart
{
public:
ShaderBlender2(const opengl::GLInfo & _version)
ShaderBlender2(const opengl::GLInfo & _glinfo)
{
if (_version.isGLES2) {
if (_glinfo.isGLES2) {
m_part =
" if (uForceBlendCycle2 != 0) { \n"
" muxPM[0] = clampedColor; \n"
@ -689,9 +692,9 @@ public:
class ShaderCallDither : public ShaderPart
{
public:
ShaderCallDither(const opengl::GLInfo & _version)
ShaderCallDither(const opengl::GLInfo & _glinfo)
{
if (!_version.isGLES2 && config.generalEmulation.enableNoise != 0) {
if (!_glinfo.isGLES2 && config.generalEmulation.enableNoise != 0) {
m_part =
" if (uColorDitherMode == 2) colorNoiseDither(snoise(), clampedColor.rgb); \n"
" if (uAlphaDitherMode == 2) alphaNoiseDither(snoise(), clampedColor.a); \n"
@ -703,7 +706,7 @@ public:
class ShaderFragmentGlobalVariablesTex : public ShaderPart
{
public:
ShaderFragmentGlobalVariablesTex(const opengl::GLInfo & _version)
ShaderFragmentGlobalVariablesTex(const opengl::GLInfo & _glinfo)
{
m_part =
"uniform sampler2D uTex0; \n"
@ -738,7 +741,7 @@ public:
;
}
if (!_version.isGLES2) {
if (!_glinfo.isGLES2) {
m_part +=
"uniform sampler2D uDepthTex; \n"
"uniform lowp int uAlphaDitherMode; \n"
@ -746,7 +749,7 @@ public:
"uniform lowp int uRenderTarget; \n"
"uniform mediump vec2 uDepthScale; \n"
;
if (_version.imageTextures && config.frameBufferEmulation.N64DepthCompare != 0) {
if (_glinfo.imageTextures && config.frameBufferEmulation.N64DepthCompare != 0) {
m_part +=
"uniform lowp int uEnableDepthCompare; \n"
;
@ -759,9 +762,9 @@ public:
if (config.video.multisampling > 0) {
m_part +=
"uniform lowp ivec2 uMSTexEnabled; \n";
"uniform lowp sampler2DMS uMSTex0; \n";
"uniform lowp sampler2DMS uMSTex1; \n";
"uniform lowp ivec2 uMSTexEnabled; \n"
"uniform lowp sampler2DMS uMSTex0; \n"
"uniform lowp sampler2DMS uMSTex1; \n"
;
}
@ -779,7 +782,7 @@ public:
class ShaderFragmentGlobalVariablesNotex : public ShaderPart
{
public:
ShaderFragmentGlobalVariablesNotex(const opengl::GLInfo & _version)
ShaderFragmentGlobalVariablesNotex(const opengl::GLInfo & _glinfo)
{
m_part =
"uniform lowp vec4 uFogColor; \n"
@ -812,7 +815,7 @@ public:
;
}
if (!_version.isGLES2) {
if (!_glinfo.isGLES2) {
m_part +=
"uniform sampler2D uDepthTex; \n"
"uniform lowp int uAlphaDitherMode; \n"
@ -820,7 +823,7 @@ public:
"uniform lowp int uRenderTarget; \n"
"uniform mediump vec2 uDepthScale; \n"
;
if (_version.imageTextures && config.frameBufferEmulation.N64DepthCompare != 0) {
if (_glinfo.imageTextures && config.frameBufferEmulation.N64DepthCompare != 0) {
m_part +=
"uniform lowp int uEnableDepthCompare; \n"
;
@ -841,7 +844,7 @@ public:
class ShaderFragmentHeaderNoise : public ShaderPart
{
public:
ShaderFragmentHeaderNoise(const opengl::GLInfo & _version)
ShaderFragmentHeaderNoise(const opengl::GLInfo & _glinfo)
{
m_part =
"lowp float snoise();\n";
@ -852,9 +855,9 @@ public:
class ShaderFragmentHeaderWriteDepth : public ShaderPart
{
public:
ShaderFragmentHeaderWriteDepth(const opengl::GLInfo & _version)
ShaderFragmentHeaderWriteDepth(const opengl::GLInfo & _glinfo)
{
if (!_version.isGLES2) {
if (!_glinfo.isGLES2) {
m_part =
"void writeDepth();\n";
;
@ -865,7 +868,7 @@ public:
class ShaderFragmentHeaderCalcLight : public ShaderPart
{
public:
ShaderFragmentHeaderCalcLight(const opengl::GLInfo & _version)
ShaderFragmentHeaderCalcLight(const opengl::GLInfo & _glinfo)
{
m_part =
"void calc_light(in lowp float fLights, in lowp vec3 input_color, out lowp vec3 output_color);\n";
@ -876,7 +879,7 @@ public:
class ShaderFragmentHeaderMipMap : public ShaderPart
{
public:
ShaderFragmentHeaderMipMap(const opengl::GLInfo & _version)
ShaderFragmentHeaderMipMap(const opengl::GLInfo & _glinfo)
{
m_part =
"mediump float mipmap(out lowp vec4 readtex0, out lowp vec4 readtex1);\n";
@ -887,9 +890,9 @@ public:
class ShaderFragmentHeaderReadMSTex : public ShaderPart
{
public:
ShaderFragmentHeaderReadMSTex(const opengl::GLInfo & _version)
ShaderFragmentHeaderReadMSTex(const opengl::GLInfo & _glinfo)
{
if (!_version.isGLES2 && config.video.multisampling > 0) {
if (!_glinfo.isGLES2 && config.video.multisampling > 0) {
m_part =
"lowp vec4 readTexMS(in lowp sampler2DMS mstex, in mediump vec2 texCoord, in lowp int fbMonochrome, in lowp int fbFixedAlpha);\n";
;
@ -900,9 +903,9 @@ public:
class ShaderFragmentHeaderDither : public ShaderPart
{
public:
ShaderFragmentHeaderDither(const opengl::GLInfo & _version)
ShaderFragmentHeaderDither(const opengl::GLInfo & _glinfo)
{
if (!_version.isGLES2 && config.generalEmulation.enableNoise != 0) {
if (!_glinfo.isGLES2 && config.generalEmulation.enableNoise != 0) {
m_part =
"void colorNoiseDither(in lowp float _noise, inout lowp vec3 _color);\n"
"void alphaNoiseDither(in lowp float _noise, inout lowp float _alpha);\n";
@ -914,9 +917,9 @@ public:
class ShaderFragmentHeaderDepthCompare : public ShaderPart
{
public:
ShaderFragmentHeaderDepthCompare(const opengl::GLInfo & _version)
ShaderFragmentHeaderDepthCompare(const opengl::GLInfo & _glinfo)
{
if (_version.imageTextures && config.frameBufferEmulation.N64DepthCompare != 0) {
if (_glinfo.imageTextures && config.frameBufferEmulation.N64DepthCompare != 0) {
m_part =
"bool depth_compare();\n"
"bool depth_render(highp float Z);\n";
@ -928,9 +931,9 @@ public:
class ShaderFragmentHeaderReadTex : public ShaderPart
{
public:
ShaderFragmentHeaderReadTex (const opengl::GLInfo & _version)
ShaderFragmentHeaderReadTex (const opengl::GLInfo & _glinfo)
{
if (!_version.isGLES2) {
if (!_glinfo.isGLES2) {
if (config.texture.bilinearMode == BILINEAR_3POINT) {
m_part =
"uniform lowp int uTextureFilterMode; \n"
@ -977,13 +980,13 @@ public:
class ShaderFragmentMain : public ShaderPart
{
public:
ShaderFragmentMain(const opengl::GLInfo & _version)
ShaderFragmentMain(const opengl::GLInfo & _glinfo)
{
m_part =
"void main() \n"
"{ \n"
;
if (!_version.isGLES2) {
if (!_glinfo.isGLES2) {
m_part +=
" writeDepth(); \n"
;
@ -999,13 +1002,13 @@ public:
class ShaderFragmentMain2Cycle : public ShaderPart
{
public:
ShaderFragmentMain2Cycle(const opengl::GLInfo & _version)
ShaderFragmentMain2Cycle(const opengl::GLInfo & _glinfo)
{
m_part =
"void main() \n"
"{ \n"
;
if (!_version.isGLES2) {
if (!_glinfo.isGLES2) {
m_part +=
" writeDepth(); \n"
;
@ -1021,7 +1024,7 @@ public:
class ShaderFragmentBlendMux : public ShaderPart
{
public:
ShaderFragmentBlendMux(const opengl::GLInfo & _version)
ShaderFragmentBlendMux(const opengl::GLInfo & _glinfo)
{
if (config.generalEmulation.enableLegacyBlending == 0) {
m_part =
@ -1036,7 +1039,7 @@ public:
class ShaderFragmentReadTexMipmap : public ShaderPart
{
public:
ShaderFragmentReadTexMipmap(const opengl::GLInfo & _version)
ShaderFragmentReadTexMipmap(const opengl::GLInfo & _glinfo)
{
m_part =
" lowp vec4 readtex0, readtex1; \n"
@ -1048,26 +1051,26 @@ public:
class ShaderFragmentReadTex0 : public ShaderPart
{
public:
ShaderFragmentReadTex0(const opengl::GLInfo & _version)
ShaderFragmentReadTex0(const opengl::GLInfo & _glinfo)
{
if (_version.isGLES2) {
if (_glinfo.isGLES2) {
m_part =
" nCurrentTile = 0; \n"
" lowp vec4 readtex0 = readTex(uTex0, vTexCoord0, uFbMonochrome[0], uFbFixedAlpha[0]); \n"
;
} else {
if (config.video.multisampling > 0) {
m_part =
" lowp vec4 readtex0; \n"
" if (uMSTexEnabled[0] == 0) READ_TEX(readtex0, uTex0, vTexCoord0, uFbMonochrome[0], uFbFixedAlpha[0]) \n"
" else readtex0 = readTexMS(uMSTex0, vTexCoord0, uFbMonochrome[0], uFbFixedAlpha[0]); \n"
;
;
} else {
m_part =
" lowp vec4 readtex0; \n"
" READ_TEX(readtex0, uTex0, vTexCoord0, uFbMonochrome[0], uFbFixedAlpha[0]); \n"
;
;
}
} else {
m_part =
" nCurrentTile = 0; \n"
" lowp vec4 readtex0 = readTex(uTex0, vTexCoord0, uFbMonochrome[0], uFbFixedAlpha[0]); \n"
;
}
}
};
@ -1075,38 +1078,36 @@ public:
class ShaderFragmentReadTex1 : public ShaderPart
{
public:
ShaderFragmentReadTex1(const opengl::GLInfo & _version)
ShaderFragmentReadTex1(const opengl::GLInfo & _glinfo)
{
if (_version.isGLES2) {
if (_glinfo.isGLES2) {
m_part =
" nCurrentTile = 1; \n"
" lowp vec4 readtex1 = readTex(uTex1, vTexCoord1, uFbMonochrome[1], uFbFixedAlpha[1]); \n"
;
} else {
if (config.video.multisampling > 0) {
m_part =
" lowp vec4 readtex1; \n"
" if (uMSTexEnabled[1] == 0) READ_TEX(readtex1, uTex1, vTexCoord1, uFbMonochrome[1], uFbFixedAlpha[1]) \n"
" else readtex1 = readTexMS(uMSTex1, vTexCoord1, uFbMonochrome[1], uFbFixedAlpha[1]); \n"
;
}
else {
;
} else {
m_part =
" lowp vec4 readtex1; \n"
" READ_TEX(readtex1, uTex1, vTexCoord1, uFbMonochrome[1], uFbFixedAlpha[1]); \n"
;
;
}
}
else {
m_part =
" nCurrentTile = 1; \n"
" lowp vec4 readtex1 = readTex(uTex1, vTexCoord1, uFbMonochrome[1], uFbFixedAlpha[1]); \n"
;
}
}
};
class ShaderFragmentCallN64Depth : public ShaderPart
{
public:
ShaderFragmentCallN64Depth(const opengl::GLInfo & _version)
ShaderFragmentCallN64Depth(const opengl::GLInfo & _glinfo)
{
if (!_version.isGLES2 && _version.imageTextures && config.frameBufferEmulation.N64DepthCompare != 0) {
if (!_glinfo.isGLES2 && _glinfo.imageTextures && config.frameBufferEmulation.N64DepthCompare != 0) {
m_part =
" if (uRenderTarget != 0) { if (!depth_render(fragColor.r)) discard; } \n"
" else if (!depth_compare()) discard; \n"
@ -1118,9 +1119,9 @@ public:
class ShaderFragmentRenderTarget : public ShaderPart
{
public:
ShaderFragmentRenderTarget(const opengl::GLInfo & _version)
ShaderFragmentRenderTarget(const opengl::GLInfo & _glinfo)
{
if (!_version.isGLES2 && config.generalEmulation.enableFragmentDepthWrite != 0) {
if (!_glinfo.isGLES2 && config.generalEmulation.enableFragmentDepthWrite != 0) {
m_part =
" if (uRenderTarget != 0) { \n"
" if (uRenderTarget > 1) { \n"
@ -1137,7 +1138,7 @@ public:
class ShaderNoise : public ShaderPart
{
public:
ShaderNoise(const opengl::GLInfo & _version)
ShaderNoise(const opengl::GLInfo & _glinfo)
{
if (config.generalEmulation.enableNoise == 0) {
// Dummy noise
@ -1148,7 +1149,7 @@ public:
"} \n"
;
} else {
if (_version.isGLES2) {
if (_glinfo.isGLES2) {
m_part =
"uniform sampler2D uTexNoise; \n"
"lowp float snoise() \n"
@ -1175,9 +1176,9 @@ public:
class ShaderDither : public ShaderPart
{
public:
ShaderDither(const opengl::GLInfo & _version)
ShaderDither(const opengl::GLInfo & _glinfo)
{
if (!_version.isGLES2 && config.generalEmulation.enableNoise != 0) {
if (!_glinfo.isGLES2 && config.generalEmulation.enableNoise != 0) {
m_part =
"void colorNoiseDither(in lowp float _noise, inout lowp vec3 _color) \n"
"{ \n"
@ -1203,9 +1204,9 @@ public:
class ShaderWriteDepth : public ShaderPart
{
public:
ShaderWriteDepth(const opengl::GLInfo & _version)
ShaderWriteDepth(const opengl::GLInfo & _glinfo)
{
if (!_version.isGLES2) {
if (!_glinfo.isGLES2) {
if (config.generalEmulation.enableFragmentDepthWrite == 0) {
// Dummy write depth
m_part =
@ -1228,9 +1229,9 @@ public:
class ShaderMipmap : public ShaderPart
{
public:
ShaderMipmap(const opengl::GLInfo & _version)
ShaderMipmap(const opengl::GLInfo & _glinfo)
{
if (_version.isGLES2) {
if (_glinfo.isGLES2) {
if (config.generalEmulation.enableLOD == 0) {
// Fake mipmap
m_part =
@ -1390,7 +1391,7 @@ public:
class ShaderCalcLight : public ShaderPart
{
public:
ShaderCalcLight(const opengl::GLInfo & _version)
ShaderCalcLight(const opengl::GLInfo & _glinfo)
{
m_part =
"uniform mediump vec3 uLightDirection[8]; \n"
@ -1415,9 +1416,9 @@ public:
class ShaderReadtex : public ShaderPart
{
public:
ShaderReadtex(const opengl::GLInfo & _version)
ShaderReadtex(const opengl::GLInfo & _glinfo)
{
if (_version.isGLES2) {
if (_glinfo.isGLES2) {
if (config.texture.bilinearMode == BILINEAR_3POINT) {
m_part =
"uniform mediump vec2 uTextureSize[2]; \n"
@ -1502,10 +1503,10 @@ public:
class ShaderN64DepthCompare : public ShaderPart
{
public:
ShaderN64DepthCompare(const opengl::GLInfo & _version)
ShaderN64DepthCompare(const opengl::GLInfo & _glinfo)
{
if (_version.imageTextures && config.frameBufferEmulation.N64DepthCompare != 0) {
m_part = _version.isGLESX
if (_glinfo.imageTextures && config.frameBufferEmulation.N64DepthCompare != 0) {
m_part = _glinfo.isGLESX
? "layout(binding = 2, rgba32f) highp uniform coherent image2D uDepthImage;\n"
: "layout(binding = 2, rg32f) highp uniform coherent image2D uDepthImage;\n"
;
@ -1564,10 +1565,10 @@ public:
class ShaderN64DepthRender : public ShaderPart
{
public:
ShaderN64DepthRender(const opengl::GLInfo & _version)
ShaderN64DepthRender(const opengl::GLInfo & _glinfo)
{
if (_version.imageTextures && config.frameBufferEmulation.N64DepthCompare != 0) {
m_part = _version.isGLESX
if (_glinfo.imageTextures && config.frameBufferEmulation.N64DepthCompare != 0) {
m_part = _glinfo.isGLESX
? "layout(binding = 2, rgba32f) highp uniform coherent image2D uDepthImage;\n"
: "layout(binding = 2, rg32f) highp uniform coherent image2D uDepthImage;\n"
;
@ -1645,7 +1646,7 @@ int CombinerProgramBuilder::compileCombiner(const CombinerKey & _key, Combiner &
_correctFirstStageParams(_alpha.stage[0]);
_correctFirstStageParams(_color.stage[0]);
}
_strShader.append(" alpha1 = ");
ssShader << " alpha1 = ";
int nInputs = _compileCombiner(_alpha.stage[0], AlphaInput, ssShader);
// Simulate N64 color sign-extend.
if (combinedAlphaC(combine))
@ -1655,7 +1656,7 @@ int CombinerProgramBuilder::compileCombiner(const CombinerKey & _key, Combiner &
m_alphaTest->write(ssShader);
_strShader.append(" color1 = ");
ssShader << " color1 = ";
nInputs |= _compileCombiner(_color.stage[0], ColorInput, ssShader);
// Simulate N64 color sign-extend.
if (combinedColorC(combine))
@ -1712,7 +1713,7 @@ int CombinerProgramBuilder::compileCombiner(const CombinerKey & _key, Combiner &
m_legacyBlender->write(ssShader);
}
_strShader = ssShader.str();
_strShader = std::move(ssShader.str());
return nInputs;
}
@ -1842,10 +1843,11 @@ graphics::CombinerProgram * CombinerProgramBuilder::buildCombinerProgram(Combine
glLinkProgram(program);
assert(Utils::checkProgramLinkStatus(program));
glDeleteShader(fragmentShader);
// _locateUniforms();
UniformGroups uniforms;
m_uniformFactory->buildUniforms(program, combinerInputs, bIsRect, uniforms);
return nullptr;
return new CombinerProgramImpl(program, combinerInputs, std::move(uniforms));
}
static
@ -1864,9 +1866,9 @@ GLuint _createVertexShader(ShaderPart * _header, ShaderPart * _body)
return shader_object;
}
CombinerProgramBuilder::CombinerProgramBuilder(const opengl::GLInfo & _version)
: m_blender1(new ShaderBlender1(_version))
, m_blender2(new ShaderBlender2(_version))
CombinerProgramBuilder::CombinerProgramBuilder(const opengl::GLInfo & _glinfo)
: m_blender1(new ShaderBlender1(_glinfo))
, m_blender2(new ShaderBlender2(_glinfo))
, m_legacyBlender(new ShaderLegacyBlender)
, m_clamp(new ShaderClamp)
, m_signExtendColorC(new ShaderSignExtendColorC)
@ -1874,44 +1876,47 @@ CombinerProgramBuilder::CombinerProgramBuilder(const opengl::GLInfo & _version)
, m_signExtendColorABD(new ShaderSignExtendColorABD)
, m_signExtendAlphaABD(new ShaderSignExtendAlphaABD)
, m_alphaTest(new ShaderAlphaTest)
, m_callDither(new ShaderCallDither(_version))
, m_vertexHeader(new VertexShaderHeader(_version))
, m_vertexRect(new VertexShaderRect(_version))
, m_vertexTexturedRect(new VertexShaderTexturedRect(_version))
, m_vertexTriangle(new VertexShaderTriangle(_version))
, m_vertexTexturedTriangle(new VertexShaderTexturedTriangle(_version))
, m_fragmentHeader(new FragmentShaderHeader(_version))
, m_fragmentGlobalVariablesTex(new ShaderFragmentGlobalVariablesTex(_version))
, m_fragmentGlobalVariablesNotex(new ShaderFragmentGlobalVariablesNotex(_version))
, m_fragmentHeaderNoise(new ShaderFragmentHeaderNoise(_version))
, m_fragmentHeaderWriteDepth(new ShaderFragmentHeaderWriteDepth(_version))
, m_fragmentHeaderCalcLight(new ShaderFragmentHeaderCalcLight(_version))
, m_fragmentHeaderMipMap(new ShaderFragmentHeaderMipMap(_version))
, m_fragmentHeaderReadMSTex(new ShaderFragmentHeaderReadMSTex(_version))
, m_fragmentHeaderDither(new ShaderFragmentHeaderDither(_version))
, m_fragmentHeaderDepthCompare(new ShaderFragmentHeaderDepthCompare(_version))
, m_fragmentHeaderReadTex(new ShaderFragmentHeaderReadTex(_version))
, m_fragmentMain(new ShaderFragmentMain(_version))
, m_fragmentMain2Cycle(new ShaderFragmentMain2Cycle(_version))
, m_fragmentBlendMux(new ShaderFragmentBlendMux(_version))
, m_fragmentReadTex0(new ShaderFragmentReadTex0(_version))
, m_fragmentReadTex1(new ShaderFragmentReadTex1(_version))
, m_fragmentReadTexMipmap(new ShaderFragmentReadTexMipmap(_version))
, m_fragmentCallN64Depth(new ShaderFragmentCallN64Depth(_version))
, m_fragmentRenderTarget(new ShaderFragmentRenderTarget(_version))
, m_shaderNoise(new ShaderNoise(_version))
, m_shaderDither(new ShaderDither(_version))
, m_shaderWriteDepth(new ShaderWriteDepth(_version))
, m_shaderMipmap(new ShaderMipmap(_version))
, m_shaderCalcLight(new ShaderCalcLight(_version))
, m_shaderReadtex(new ShaderReadtex(_version))
, m_shaderN64DepthCompare(new ShaderN64DepthCompare(_version))
, m_shaderN64DepthRender(new ShaderN64DepthRender(_version))
, m_callDither(new ShaderCallDither(_glinfo))
, m_vertexHeader(new VertexShaderHeader(_glinfo))
, m_vertexRect(new VertexShaderRect(_glinfo))
, m_vertexTexturedRect(new VertexShaderTexturedRect(_glinfo))
, m_vertexTriangle(new VertexShaderTriangle(_glinfo))
, m_vertexTexturedTriangle(new VertexShaderTexturedTriangle(_glinfo))
, m_fragmentHeader(new FragmentShaderHeader(_glinfo))
, m_fragmentGlobalVariablesTex(new ShaderFragmentGlobalVariablesTex(_glinfo))
, m_fragmentGlobalVariablesNotex(new ShaderFragmentGlobalVariablesNotex(_glinfo))
, m_fragmentHeaderNoise(new ShaderFragmentHeaderNoise(_glinfo))
, m_fragmentHeaderWriteDepth(new ShaderFragmentHeaderWriteDepth(_glinfo))
, m_fragmentHeaderCalcLight(new ShaderFragmentHeaderCalcLight(_glinfo))
, m_fragmentHeaderMipMap(new ShaderFragmentHeaderMipMap(_glinfo))
, m_fragmentHeaderReadMSTex(new ShaderFragmentHeaderReadMSTex(_glinfo))
, m_fragmentHeaderDither(new ShaderFragmentHeaderDither(_glinfo))
, m_fragmentHeaderDepthCompare(new ShaderFragmentHeaderDepthCompare(_glinfo))
, m_fragmentHeaderReadTex(new ShaderFragmentHeaderReadTex(_glinfo))
, m_fragmentMain(new ShaderFragmentMain(_glinfo))
, m_fragmentMain2Cycle(new ShaderFragmentMain2Cycle(_glinfo))
, m_fragmentBlendMux(new ShaderFragmentBlendMux(_glinfo))
, m_fragmentReadTex0(new ShaderFragmentReadTex0(_glinfo))
, m_fragmentReadTex1(new ShaderFragmentReadTex1(_glinfo))
, m_fragmentReadTexMipmap(new ShaderFragmentReadTexMipmap(_glinfo))
, m_fragmentCallN64Depth(new ShaderFragmentCallN64Depth(_glinfo))
, m_fragmentRenderTarget(new ShaderFragmentRenderTarget(_glinfo))
, m_shaderNoise(new ShaderNoise(_glinfo))
, m_shaderDither(new ShaderDither(_glinfo))
, m_shaderWriteDepth(new ShaderWriteDepth(_glinfo))
, m_shaderMipmap(new ShaderMipmap(_glinfo))
, m_shaderCalcLight(new ShaderCalcLight(_glinfo))
, m_shaderReadtex(new ShaderReadtex(_glinfo))
, m_shaderN64DepthCompare(new ShaderN64DepthCompare(_glinfo))
, m_shaderN64DepthRender(new ShaderN64DepthRender(_glinfo))
{
m_vertexShaderRect = _createVertexShader(m_vertexHeader.get(), m_vertexRect.get());
m_vertexShaderTriangle = _createVertexShader(m_vertexHeader.get(), m_vertexTriangle.get());
m_vertexShaderTexturedRect = _createVertexShader(m_vertexHeader.get(), m_vertexTexturedRect.get());
m_vertexShaderTexturedTriangle = _createVertexShader(m_vertexHeader.get(), m_vertexTexturedTriangle.get());
if (config.generalEmulation.enableNoise != 0)
m_noiseTexture.reset(new NoiseTexture);
m_uniformFactory.reset(new CombinerProgramUniformFactory(_glinfo, m_noiseTexture.get()));
}
CombinerProgramBuilder::~CombinerProgramBuilder()

View File

@ -4,10 +4,16 @@
#include <sstream>
#include <Combiner.h>
#include <Graphics/OpenGLContext/opengl_GLInfo.h>
#include <Graphics/CombinerProgram.h>
namespace graphics {
class CombinerProgram;
}
namespace glsl {
class NoiseTexture;
class CombinerProgramUniformFactory;
class ShaderPart
{
public:
@ -23,7 +29,7 @@ namespace glsl {
class CombinerProgramBuilder
{
public:
CombinerProgramBuilder(const opengl::GLInfo & _version);
CombinerProgramBuilder(const opengl::GLInfo & _glinfo);
~CombinerProgramBuilder();
graphics::CombinerProgram * buildCombinerProgram(Combiner & _color, Combiner & _alpha, const CombinerKey & _key);
@ -77,6 +83,9 @@ namespace glsl {
ShaderPartPtr m_shaderN64DepthCompare;
ShaderPartPtr m_shaderN64DepthRender;
std::unique_ptr<NoiseTexture> m_noiseTexture;
std::unique_ptr<CombinerProgramUniformFactory> m_uniformFactory;
GLuint m_vertexShaderRect;
GLuint m_vertexShaderTriangle;
GLuint m_vertexShaderTexturedRect;

View File

@ -3,50 +3,11 @@
using namespace glsl;
/*---------------CombinerInputs-------------*/
bool CombinerInputs::usesTile(u32 _t) const
{
if (_t == 0)
return (m_inputs & ((1 << TEXEL0) | (1 << TEXEL0_ALPHA))) != 0;
return (m_inputs & ((1 << TEXEL1) | (1 << TEXEL1_ALPHA))) != 0;
}
bool CombinerInputs::usesTexture() const
{
return (m_inputs & ((1 << TEXEL1) | (1 << TEXEL1_ALPHA) | (1 << TEXEL0) | (1 << TEXEL0_ALPHA))) != 0;
}
bool CombinerInputs::usesLOD() const
{
return (m_inputs & (1 << LOD_FRACTION)) != 0;
}
bool CombinerInputs::usesShade() const
{
return (m_inputs & ((1 << SHADE) | (1 << SHADE_ALPHA))) != 0;
}
bool CombinerInputs::usesShadeColor() const
{
return (m_inputs & (1 << SHADE)) != 0;
}
bool CombinerInputs::usesHwLighting() const
{
return (m_inputs & (1 << HW_LIGHT)) != 0;
}
void CombinerInputs::addInput(int _input)
{
m_inputs |= 1 << _input;
}
/*---------------CombinerProgramImpl-------------*/
CombinerProgramImpl::CombinerProgramImpl()
CombinerProgramImpl::CombinerProgramImpl(GLuint _program, const CombinerInputs & _inputs, UniformGroups && _uniforms)
: m_bNeedUpdate(true)
, m_program(_program)
, m_inputs(_inputs)
, m_uniforms(std::move(_uniforms))
{
}
@ -57,14 +18,51 @@ CombinerProgramImpl::~CombinerProgramImpl()
void CombinerProgramImpl::activate()
{
glUseProgram(m_program);
}
void CombinerProgramImpl::update(bool _force)
{
_force |= m_bNeedUpdate;
m_bNeedUpdate = false;
glUseProgram(m_program);
for (auto it = m_uniforms.begin(); it != m_uniforms.end(); ++it)
(*it)->update(_force);
}
CombinerKey CombinerProgramImpl::getKey() const
{
return CombinerKey();
}
bool CombinerProgramImpl::usesTexture() const
{
return m_inputs.usesTexture();
}
bool CombinerProgramImpl::usesTile(u32 _t) const {
return m_inputs.usesTile(_t);
}
bool CombinerProgramImpl::usesShade() const {
return m_inputs.usesShade();
}
bool CombinerProgramImpl::usesLOD() const {
return m_inputs.usesLOD();
}
namespace graphics {
// TODO implement
std::ostream & operator<< (std::ostream & _os, const CombinerProgram & _combiner)
{
return _os;
}
std::istream & operator>> (std::istream & _is, CombinerProgram & _combiner)
{
return _is;
}
}

View File

@ -1,40 +1,39 @@
#pragma once
#include <memory>
#include <vector>
#include <Graphics/CombinerProgram.h>
#include "glsl_CombinerInputs.h"
namespace glsl {
class CombinerInputs
{
class UniformGroup {
public:
explicit CombinerInputs(int _inputs) : m_inputs(_inputs) {}
bool usesTile(u32 _t) const;
bool usesTexture() const;
bool usesLOD() const;
bool usesShade() const;
bool usesShadeColor() const;
bool usesHwLighting() const;
void addInput(int _input);
private:
int m_inputs;
virtual ~UniformGroup() {}
virtual void update(bool _force) = 0;
};
typedef std::vector< std::unique_ptr<UniformGroup> > UniformGroups;
class CombinerProgramImpl : public graphics::CombinerProgram
{
public:
CombinerProgramImpl();
CombinerProgramImpl(GLuint _program, const CombinerInputs & _inputs, UniformGroups && _uniforms);
~CombinerProgramImpl();
void activate() override;
void update(bool _force) override;
CombinerKey getKey() const override;
bool usesTexture() const override;
bool usesTile(u32 _t) const override;
bool usesShade() const override;
bool usesLOD() const override;
private:
bool m_bNeedUpdate;
GLuint m_program;
CombinerInputs m_inputs;
UniformGroups m_uniforms;
};
}

View File

@ -0,0 +1,861 @@
#include <Config.h>
#include "glsl_CombinerProgramUniformFactory.h"
#include "glsl_NoiseTexture.h"
#include <Textures.h>
#include <FrameBuffer.h>
#include <GBI.h>
#include <RSP.h>
#include <gSP.h>
#include <gDP.h>
#include <VI.h>
namespace glsl {
/*---------------Uniform-------------*/
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 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 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);
}
}
};
/*---------------UniformGroup-------------*/
#define LocateUniform(A) \
A.loc = glGetUniformLocation(_program, #A);
class UNoiseTex : public UniformGroup
{
public:
UNoiseTex(GLuint _program) {
LocateUniform(uTexNoise);
}
void update(bool _force) override
{
uTexNoise.set(g_noiseTexIndex, _force);
}
private:
iUniform uTexNoise;
};
class UDepthTex : public UniformGroup
{
public:
UDepthTex(GLuint _program) {
LocateUniform(uDepthTex);
}
void update(bool _force) override
{
uDepthTex.set(g_depthTexIndex, _force);
}
private:
iUniform uDepthTex;
};
class UTextures : public UniformGroup
{
public:
UTextures(GLuint _program) {
LocateUniform(uTex0);
LocateUniform(uTex1);
}
void update(bool _force) override
{
uTex0.set(0, _force);
uTex1.set(1, _force);
}
private:
iUniform uTex0;
iUniform uTex1;
};
class UMSAATextures : public UniformGroup
{
public:
UMSAATextures(GLuint _program) {
LocateUniform(uMSTex0);
LocateUniform(uMSTex1);
LocateUniform(uMSAASamples);
LocateUniform(uMSAAScale);
}
void update(bool _force) override
{
uMSTex0.set(g_MSTex0Index + 0, _force);
uMSTex1.set(g_MSTex0Index + 1, _force);
uMSAASamples.set(config.video.multisampling, _force);
uMSAAScale.set(1.0f / (float)config.video.multisampling, _force);
}
private:
iUniform uMSTex0;
iUniform uMSTex1;
iUniform uMSAASamples;
fUniform uMSAAScale;
};
class UFrameBufferInfo : public UniformGroup
{
public:
UFrameBufferInfo(GLuint _program) {
LocateUniform(uFbMonochrome);
LocateUniform(uFbFixedAlpha);
LocateUniform(uMSTexEnabled);
}
void update(bool _force) override
{
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;
nMSTex0Enabled = cache.current[0]->frameBufferTexture == CachedTexture::fbMultiSample ? 1 : 0;
}
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;
nMSTex1Enabled = cache.current[1]->frameBufferTexture == CachedTexture::fbMultiSample ? 1 : 0;
}
uFbMonochrome.set(nFbMonochromeMode0, nFbMonochromeMode1, _force);
uFbFixedAlpha.set(nFbFixedAlpha0, nFbFixedAlpha1, _force);
uMSTexEnabled.set(nMSTex0Enabled, nMSTex1Enabled, _force);
gDP.changed &= ~CHANGED_FB_TEXTURE;
}
private:
iv2Uniform uFbMonochrome;
iv2Uniform uFbFixedAlpha;
iv2Uniform uMSTexEnabled;
};
class UFog : public UniformGroup
{
public:
UFog(GLuint _program) {
LocateUniform(uFogUsage);
LocateUniform(uFogScale);
}
void update(bool _force) override
{
if (RSP.bLLE) {
uFogUsage.set(0, _force);
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;
uFogUsage.set(nFogUsage, _force);
uFogScale.set((float)gSP.fog.multiplier / 256.0f, (float)gSP.fog.offset / 256.0f, _force);
}
private:
iUniform uFogUsage;
fv2Uniform uFogScale;
};
class UBlendMode1Cycle : public UniformGroup
{
public:
UBlendMode1Cycle(GLuint _program) {
LocateUniform(uBlendMux1);
LocateUniform(uForceBlendCycle1);
}
void update(bool _force) override
{
uBlendMux1.set(gDP.otherMode.c1_m1a,
gDP.otherMode.c1_m1b,
gDP.otherMode.c1_m2a,
gDP.otherMode.c1_m2b,
_force);
int forceBlend1 = gDP.otherMode.forceBlender;
uForceBlendCycle1.set(forceBlend1, _force);
}
private:
i4Uniform uBlendMux1;
iUniform uForceBlendCycle1;
};
class UBlendMode2Cycle : public UniformGroup
{
public:
UBlendMode2Cycle(GLuint _program) {
LocateUniform(uBlendMux1);
LocateUniform(uBlendMux2);
LocateUniform(uForceBlendCycle1);
LocateUniform(uForceBlendCycle2);
}
void update(bool _force) override
{
int forceBlend1 = 1;
uBlendMux1.set(gDP.otherMode.c1_m1a,
gDP.otherMode.c1_m1b,
gDP.otherMode.c1_m2a,
gDP.otherMode.c1_m2b,
_force);
int forceBlend2 = gDP.otherMode.forceBlender;
if (forceBlend2 != 0) {
uBlendMux2.set(gDP.otherMode.c2_m1a,
gDP.otherMode.c2_m1b,
gDP.otherMode.c2_m2a,
gDP.otherMode.c2_m2b,
_force);
}
uForceBlendCycle1.set(forceBlend1, _force);
uForceBlendCycle2.set(forceBlend2, _force);
}
private:
i4Uniform uBlendMux1;
i4Uniform uBlendMux2;
iUniform uForceBlendCycle1;
iUniform uForceBlendCycle2;
};
class UDitherMode : public UniformGroup
{
public:
UDitherMode(GLuint _program, bool _usesNoise, NoiseTexture * _noiseTexture)
: m_usesNoise(m_usesNoise)
, m_noiseTexture(_noiseTexture)
{
LocateUniform(uAlphaCompareMode);
LocateUniform(uAlphaDitherMode);
LocateUniform(uColorDitherMode);
}
~UDitherMode()
{
m_noiseTexture = nullptr;
}
void update(bool _force) override
{
if (gDP.otherMode.cycleType < G_CYC_COPY) {
uAlphaCompareMode.set(gDP.otherMode.alphaCompare, _force);
uAlphaDitherMode.set(gDP.otherMode.alphaDither, _force);
uColorDitherMode.set(gDP.otherMode.colorDither, _force);
}
else {
uAlphaCompareMode.set(0, _force);
uAlphaDitherMode.set(0, _force);
uColorDitherMode.set(0, _force);
}
bool updateNoiseTex = m_usesNoise;
updateNoiseTex |= (gDP.otherMode.cycleType < G_CYC_COPY) && (gDP.otherMode.colorDither == G_CD_NOISE || gDP.otherMode.alphaDither == G_AD_NOISE || gDP.otherMode.alphaCompare == G_AC_DITHER);
if (updateNoiseTex && m_noiseTexture != nullptr)
m_noiseTexture->update();
}
private:
iUniform uAlphaCompareMode;
iUniform uAlphaDitherMode;
iUniform uColorDitherMode;
bool m_usesNoise;
NoiseTexture * m_noiseTexture;
};
class UScreenScale : public UniformGroup
{
public:
UScreenScale(GLuint _program) {
LocateUniform(uScreenScale);
}
void update(bool _force) override
{
if (config.frameBufferEmulation.nativeResFactor == 0)
// TODO fix me
//uScreenScale.set(video().getScaleX(), video().getScaleY(), _force);
uScreenScale.set(1.0f, 1.0f, _force);
else
uScreenScale.set(float(config.frameBufferEmulation.nativeResFactor), float(config.frameBufferEmulation.nativeResFactor), _force);
}
private:
fv2Uniform uScreenScale;
};
class UMipmap1 : public UniformGroup
{
public:
UMipmap1(GLuint _program) {
LocateUniform(uMinLod);
LocateUniform(uMaxTile);
}
void update(bool _force) override
{
uMinLod.set(gDP.primColor.m, _force);
uMaxTile.set(gSP.texture.level, _force);
}
private:
fUniform uMinLod;
iUniform uMaxTile;
};
class UMipmap2 : public UniformGroup
{
public:
UMipmap2(GLuint _program) {
LocateUniform(uEnableLod);
LocateUniform(uTextureDetail);
}
void update(bool _force) override
{
const int uCalcLOD = (gDP.otherMode.textureLOD == G_TL_LOD) ? 1 : 0;
uEnableLod.set(uCalcLOD, _force);
uTextureDetail.set(gDP.otherMode.textureDetail, _force);
}
private:
iUniform uEnableLod;
iUniform uTextureDetail;
};
class UTexturePersp : public UniformGroup
{
public:
UTexturePersp(GLuint _program) {
LocateUniform(uTexturePersp);
}
void update(bool _force) override
{
const u32 texturePersp = (RSP.bLLE || GBI.isTexturePersp()) ? gDP.otherMode.texturePersp : 1U;
uTexturePersp.set(texturePersp, _force);
}
private:
iUniform uTexturePersp;
};
class UTextureFilterMode : public UniformGroup
{
public:
UTextureFilterMode(GLuint _program) {
LocateUniform(uTextureFilterMode);
}
void update(bool _force) override
{
uTextureFilterMode.set(gDP.otherMode.textureFilter | (gSP.objRendermode&G_OBJRM_BILERP), _force);
}
private:
iUniform uTextureFilterMode;
};
class UAlphaTestInfo : public UniformGroup
{
public:
UAlphaTestInfo(GLuint _program) {
LocateUniform(uEnableAlphaTest);
LocateUniform(uAlphaCvgSel);
LocateUniform(uCvgXAlpha);
LocateUniform(uAlphaTestValue);
}
void update(bool _force) override
{
if (gDP.otherMode.cycleType == G_CYC_FILL) {
uEnableAlphaTest.set(0, _force);
}
else if (gDP.otherMode.cycleType == G_CYC_COPY) {
if (gDP.otherMode.alphaCompare & G_AC_THRESHOLD) {
uEnableAlphaTest.set(1, _force);
uAlphaCvgSel.set(0, _force);
uAlphaTestValue.set(0.5f, _force);
}
else {
uEnableAlphaTest.set(0, _force);
}
}
else if ((gDP.otherMode.alphaCompare & G_AC_THRESHOLD) != 0) {
uEnableAlphaTest.set(1, _force);
uAlphaTestValue.set(gDP.blendColor.a, _force);
uAlphaCvgSel.set(gDP.otherMode.alphaCvgSel, _force);
}
else {
uEnableAlphaTest.set(0, _force);
}
uCvgXAlpha.set(gDP.otherMode.cvgXAlpha, _force);
}
private:
iUniform uEnableAlphaTest;
iUniform uAlphaCvgSel;
iUniform uCvgXAlpha;
fUniform uAlphaTestValue;
};
class UDepthScale : public UniformGroup
{
public:
UDepthScale(GLuint _program) {
LocateUniform(uDepthScale);
}
void update(bool _force) override
{
if (RSP.bLLE)
uDepthScale.set(0.5f, 0.5f, _force);
else
uDepthScale.set(gSP.viewport.vscale[2], gSP.viewport.vtrans[2], _force);
}
private:
fv2Uniform uDepthScale;
};
class UDepthInfo : public UniformGroup
{
public:
UDepthInfo(GLuint _program) {
LocateUniform(uEnableDepth);
LocateUniform(uEnableDepthCompare);
LocateUniform(uEnableDepthUpdate);
LocateUniform(uDepthMode);
LocateUniform(uDepthSource);
LocateUniform(uDeltaZ);
}
void update(bool _force) override
{
FrameBuffer * pBuffer = frameBufferList().getCurrent();
if (pBuffer == nullptr || pBuffer->m_pDepthBuffer == nullptr)
return;
const int nDepthEnabled = (gSP.geometryMode & G_ZBUFFER) > 0 ? 1 : 0;
uEnableDepth.set(nDepthEnabled, _force);
if (nDepthEnabled == 0) {
uEnableDepthCompare.set(0, _force);
uEnableDepthUpdate.set(0, _force);
}
else {
uEnableDepthCompare.set(gDP.otherMode.depthCompare, _force);
uEnableDepthUpdate.set(gDP.otherMode.depthUpdate, _force);
}
uDepthMode.set(gDP.otherMode.depthMode, _force);
uDepthSource.set(gDP.otherMode.depthSource, _force);
if (gDP.otherMode.depthSource == G_ZS_PRIM)
uDeltaZ.set(gDP.primDepth.deltaZ, _force);
}
private:
iUniform uEnableDepth;
iUniform uEnableDepthCompare;
iUniform uEnableDepthUpdate;
iUniform uDepthMode;
iUniform uDepthSource;
fUniform uDeltaZ;
};
class URenderTarget : public UniformGroup
{
public:
URenderTarget(GLuint _program) {
LocateUniform(uRenderTarget);
}
void update(bool _force) override
{
int renderTarget = 0;
if (gDP.colorImage.address == gDP.depthImageAddress &&
(config.generalEmulation.hacks & hack_ZeldaMM) == 0
) {
renderTarget = gDP.otherMode.depthCompare + 1;
}
uRenderTarget.set(renderTarget, _force);
}
private:
iUniform uRenderTarget;
};
class UScreenCoordsScale : public UniformGroup
{
public:
UScreenCoordsScale(GLuint _program) {
LocateUniform(uScreenCoordsScale);
}
void update(bool _force) override
{
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;
uScreenCoordsScale.set(2.0f*scaleX, -2.0f*scaleY, _force);
}
private:
fv2Uniform uScreenCoordsScale;
};
class UColors : public UniformGroup
{
public:
UColors(GLuint _program) {
LocateUniform(uFogColor);
LocateUniform(uCenterColor);
LocateUniform(uScaleColor);
LocateUniform(uBlendColor);
LocateUniform(uEnvColor);
LocateUniform(uPrimColor);
LocateUniform(uPrimLod);
LocateUniform(uK4);
LocateUniform(uK5);
}
void update(bool _force) override
{
uFogColor.set(&gDP.fogColor.r, _force);
uCenterColor.set(&gDP.key.center.r, _force);
uScaleColor.set(&gDP.key.scale.r, _force);
uBlendColor.set(&gDP.blendColor.r, _force);
uEnvColor.set(&gDP.envColor.r, _force);
uPrimColor.set(&gDP.primColor.r, _force);
uPrimLod.set(gDP.primColor.l, _force);
uK4.set(gDP.convert.k4*0.0039215689f, _force);
uK5.set(gDP.convert.k5*0.0039215689f, _force);
}
private:
fv4Uniform uFogColor;
fv4Uniform uCenterColor;
fv4Uniform uScaleColor;
fv4Uniform uBlendColor;
fv4Uniform uEnvColor;
fv4Uniform uPrimColor;
fUniform uPrimLod;
fUniform uK4;
fUniform uK5;
};
class UTextureSize : public UniformGroup
{
public:
UTextureSize(GLuint _program, bool _useT0, bool _useT1)
: m_useT0(m_useT0)
, m_useT1(m_useT1)
{
LocateUniform(uTextureSize[0]);
LocateUniform(uTextureSize[1]);
}
void update(bool _force) override
{
TextureCache & cache = textureCache();
if (m_useT0 && cache.current[0] != NULL)
uTextureSize[0].set((float)cache.current[0]->realWidth, (float)cache.current[0]->realHeight, _force);
if (m_useT1 && cache.current[1] != NULL)
uTextureSize[1].set((float)cache.current[1]->realWidth, (float)cache.current[1]->realHeight, _force);
}
private:
fv2Uniform uTextureSize[2];
bool m_useT0;
bool m_useT1;
};
class UTextureParams : public UniformGroup
{
public:
UTextureParams(GLuint _program, bool _useT0, bool _useT1)
{
m_useTile[0] = _useT0;
m_useTile[1] = _useT1;
LocateUniform(uTexOffset[0]);
LocateUniform(uTexOffset[1]);
LocateUniform(uCacheShiftScale[0]);
LocateUniform(uCacheShiftScale[1]);
LocateUniform(uCacheScale[0]);
LocateUniform(uCacheScale[1]);
LocateUniform(uCacheOffset[0]);
LocateUniform(uCacheOffset[1]);
LocateUniform(uTexScale);
LocateUniform(uCacheFrameBuffer);
}
void update(bool _force) override
{
int nFB[2] = { 0, 0 };
TextureCache & cache = textureCache();
for (u32 t = 0; t < 2; ++t) {
if (!m_useTile[t])
continue;
if (gSP.textureTile[t] != NULL) {
if (gSP.textureTile[t]->textureMode == TEXTUREMODE_BGIMAGE || gSP.textureTile[t]->textureMode == TEXTUREMODE_FRAMEBUFFER_BG)
uTexOffset[t].set(0.0f, 0.0f, _force);
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));
}
uTexOffset[t].set(fuls, fult, _force);
}
}
if (cache.current[t] != NULL) {
f32 shiftScaleS = 1.0f;
f32 shiftScaleT = 1.0f;
getTextureShiftScale(t, cache, shiftScaleS, shiftScaleT);
uCacheShiftScale[t].set(shiftScaleS, shiftScaleT, _force);
uCacheScale[t].set(cache.current[t]->scaleS, cache.current[t]->scaleT, _force);
uCacheOffset[t].set(cache.current[t]->offsetS, cache.current[t]->offsetT, _force);
nFB[t] = cache.current[t]->frameBufferTexture;
}
}
uCacheFrameBuffer.set(nFB[0], nFB[1], _force);
uTexScale.set(gSP.texture.scales, gSP.texture.scalet, _force);
}
private:
bool m_useTile[2];
fv2Uniform uTexOffset[2];
fv2Uniform uCacheShiftScale[2];
fv2Uniform uCacheScale[2];
fv2Uniform uCacheOffset[2];
fv2Uniform uTexScale;
iv2Uniform uCacheFrameBuffer;
};
class ULights : public UniformGroup
{
public:
ULights(GLuint _program)
{
char buf[32];
for (s32 i = 0; i < 8; ++i) {
sprintf(buf, "uLightDirection[%d]", i);
uLightDirection[i].loc = glGetUniformLocation(_program, buf);
sprintf(buf, "uLightColor[%d]", i);
uLightColor[i].loc = glGetUniformLocation(_program, buf);
}
}
void update(bool _force) override
{
for (s32 i = 0; i <= gSP.numLights; ++i) {
uLightDirection[i].set(&gSP.lights[i].ix, _force);
uLightColor[i].set(&gSP.lights[i].r, _force);
}
}
private:
fv3Uniform uLightDirection[8];
fv3Uniform uLightColor[8];
};
/*---------------CombinerProgramUniformFactory-------------*/
void CombinerProgramUniformFactory::buildUniforms(GLuint _program,
const CombinerInputs & _inputs,
bool _rect,
UniformGroups & _uniforms)
{
if (config.generalEmulation.enableNoise != 0)
_uniforms.emplace_back(new UNoiseTex(_program));
if (!m_glInfo.isGLES2)
_uniforms.emplace_back(new UDepthTex(_program));
if (_inputs.usesTexture())
_uniforms.emplace_back(new UTextures(_program));
if (config.video.multisampling != 0)
_uniforms.emplace_back(new UMSAATextures(_program));
if (_inputs.usesTexture())
_uniforms.emplace_back(new UFrameBufferInfo(_program));
_uniforms.emplace_back(new UFog(_program));
if (config.generalEmulation.enableLegacyBlending == 0) {
switch (gDP.otherMode.cycleType) {
case G_CYC_1CYCLE:
_uniforms.emplace_back(new UBlendMode1Cycle(_program));
break;
case G_CYC_2CYCLE:
_uniforms.emplace_back(new UBlendMode2Cycle(_program));
break;
}
}
_uniforms.emplace_back(new UDitherMode(_program, _inputs.usesNoise(), m_noiseTexture));
_uniforms.emplace_back(new UScreenScale(_program));
if (_inputs.usesLOD()) {
_uniforms.emplace_back(new UMipmap1(_program));
if (config.generalEmulation.enableLOD != 0)
_uniforms.emplace_back(new UMipmap2(_program));
}
_uniforms.emplace_back(new UTexturePersp(_program));
if (config.texture.bilinearMode == BILINEAR_3POINT)
_uniforms.emplace_back(new UTextureFilterMode(_program));
_uniforms.emplace_back(new UAlphaTestInfo(_program));
if (!m_glInfo.isGLES2)
_uniforms.emplace_back(new UDepthScale(_program));
if (m_glInfo.imageTextures && config.frameBufferEmulation.N64DepthCompare != 0)
_uniforms.emplace_back(new UDepthInfo(_program));
if (config.generalEmulation.enableFragmentDepthWrite != 0)
_uniforms.emplace_back(new URenderTarget(_program));
_uniforms.emplace_back(new UScreenCoordsScale(_program));
_uniforms.emplace_back(new UColors(_program));
if (_inputs.usesTexture()) {
_uniforms.emplace_back(new UTextureSize(_program, _inputs.usesTile(0), _inputs.usesTile(1)));
if (!_rect)
_uniforms.emplace_back(new UTextureParams(_program, _inputs.usesTile(0), _inputs.usesTile(1)));
}
if (_inputs.usesHwLighting())
_uniforms.emplace_back(new ULights(_program));
}
CombinerProgramUniformFactory::CombinerProgramUniformFactory(const opengl::GLInfo & _glInfo,
NoiseTexture * _noiseTexture)
: m_glInfo(_glInfo)
, m_noiseTexture(_noiseTexture)
{
}
CombinerProgramUniformFactory::~CombinerProgramUniformFactory()
{
m_noiseTexture = nullptr;
}
}

View File

@ -0,0 +1,22 @@
#pragma once
#include <Graphics/OpenGLContext/opengl_GLInfo.h>
#include "glsl_CombinerProgramImpl.h"
namespace glsl {
class NoiseTexture;
class CombinerProgramUniformFactory
{
public:
CombinerProgramUniformFactory(const opengl::GLInfo & _glInfo, NoiseTexture * _noiseTexture);
~CombinerProgramUniformFactory();
void buildUniforms(GLuint _program, const CombinerInputs & _inputs, bool _rect, UniformGroups & _uniforms);
private:
const opengl::GLInfo & m_glInfo;
NoiseTexture * m_noiseTexture;
};
}

View File

@ -0,0 +1,116 @@
#include "glsl_NoiseTexture.h"
#include <Graphics/Context.h>
#include <Graphics/Parameters.h>
#include <Config.h>
#include <GBI.h>
#include <VI.h>
#include <Textures.h>
namespace glsl {
struct PBOBinder {
PBOBinder(GLenum _target, GLuint _PBO) : m_target(_target)
{
glBindBuffer(m_target, _PBO);
}
~PBOBinder() {
glBindBuffer(m_target, 0);
}
GLenum m_target;
};
NoiseTexture::NoiseTexture()
: m_pTexture(nullptr)
, m_PBO(0)
, m_DList(0)
{
init();
}
NoiseTexture::~NoiseTexture()
{
destroy();
}
void NoiseTexture::init()
{
if (config.generalEmulation.enableNoise == 0)
return;
m_pTexture = textureCache().addFrameBufferTexture(false);
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);
{
graphics::Context::InitTextureParams params;
params.handle = graphics::ObjectHandle(m_pTexture->glName);
params.width = m_pTexture->realWidth;
params.height = m_pTexture->realHeight;
params.internalFormat = graphics::internalcolor::RED;
params.format = graphics::color::RED;
params.dataType = graphics::datatype::UNSIGNED_BYTE;
gfxContext.init2DTexture(params);
}
{
graphics::Context::TexParameters params;
params.handle = graphics::ObjectHandle(m_pTexture->glName);
params.target = graphics::target::TEXTURE_2D;
params.textureUnitIndex = 0;
params.minFilter = graphics::textureParameters::FILTER_NEAREST;
params.magFilter = graphics::textureParameters::FILTER_NEAREST;
gfxContext.setTextureParameters(params);
}
// TODO rewrite in GL independent way
// Generate Pixel Buffer Object. Initialize it with max buffer size.
glGenBuffers(1, &m_PBO);
PBOBinder binder(GL_PIXEL_UNPACK_BUFFER, m_PBO);
glBufferData(GL_PIXEL_UNPACK_BUFFER, 640 * 580, nullptr, GL_DYNAMIC_DRAW);
}
void NoiseTexture::destroy()
{
if (m_pTexture != nullptr) {
textureCache().removeFrameBufferTexture(m_pTexture);
m_pTexture = nullptr;
}
glDeleteBuffers(1, &m_PBO);
m_PBO = 0;
}
void NoiseTexture::update()
{
if (m_PBO == 0 || m_pTexture == nullptr)
return;
if (m_DList == video().getBuffersSwapCount() || config.generalEmulation.enableNoise == 0)
return;
const u32 dataSize = VI.width*VI.height;
if (dataSize == 0)
return;
PBOBinder binder(GL_PIXEL_UNPACK_BUFFER, m_PBO);
GLubyte* ptr = (GLubyte*)glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, dataSize, GL_MAP_WRITE_BIT);
if (ptr == nullptr)
return;
for (u32 y = 0; y < VI.height; ++y) {
for (u32 x = 0; x < VI.width; ++x)
ptr[x + y*VI.width] = rand() & 0xFF;
}
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); // release the mapped buffer
glActiveTexture(GL_TEXTURE0 + g_noiseTexIndex);
glBindTexture(GL_TEXTURE_2D, m_pTexture->glName);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, VI.width, VI.height, GL_RED, GL_UNSIGNED_BYTE, 0);
m_DList = video().getBuffersSwapCount();
}
}

View File

@ -0,0 +1,24 @@
#pragma once
#include <Types.h>
#include <Graphics/OpenGLContext/GLFunctions.h>
struct CachedTexture;
namespace glsl {
class NoiseTexture
{
public:
NoiseTexture();
~NoiseTexture();
void init();
void destroy();
void update();
private:
CachedTexture * m_pTexture;
GLuint m_PBO;
u32 m_DList;
};
}

View File

@ -1,6 +1,7 @@
#include <assert.h>
#include <Log.h>
#include "opengl_ContextImpl.h"
#include "GLSL/glsl_CombinerProgramBuilder.h"
using namespace opengl;
@ -35,6 +36,8 @@ void ContextImpl::init()
m_initRenderbuffer.reset(bufferObjectFactory.getInitRenderbuffer());
m_addFramebufferRenderTarget.reset(bufferObjectFactory.getAddFramebufferRenderTarget());
}
m_combinerProgramBuilder.reset(new glsl::CombinerProgramBuilder(m_glInfo));
}
void ContextImpl::destroy()
@ -48,6 +51,9 @@ void ContextImpl::destroy()
m_createRenderbuffer.reset(nullptr);
m_initRenderbuffer.reset(nullptr);
m_addFramebufferRenderTarget.reset(nullptr);
m_combinerProgramBuilder.reset(nullptr);
}
graphics::ObjectHandle ContextImpl::createTexture(graphics::Parameter _target)
@ -103,5 +109,5 @@ void ContextImpl::addFrameBufferRenderTarget(const graphics::Context::FrameBuffe
graphics::CombinerProgram * ContextImpl::createCombinerProgram(Combiner & _color, Combiner & _alpha, const CombinerKey & _key)
{
return nullptr;
return m_combinerProgramBuilder->buildCombinerProgram(_color, _alpha, _key);
}

View File

@ -6,6 +6,10 @@
#include "opengl_GLInfo.h"
#include "opengl_CachedFunctions.h"
namespace glsl {
class CombinerProgramBuilder;
}
namespace opengl {
class ContextImpl : public graphics::ContextImpl
@ -49,6 +53,7 @@ namespace opengl {
std::unique_ptr<InitRenderbuffer> m_initRenderbuffer;
std::unique_ptr<AddFramebufferRenderTarget> m_addFramebufferRenderTarget;
std::unique_ptr<glsl::CombinerProgramBuilder> m_combinerProgramBuilder;
GLInfo m_glInfo;
};