diff --git a/FrameBuffer.cpp b/FrameBuffer.cpp index eaedcd8f..97414c26 100644 --- a/FrameBuffer.cpp +++ b/FrameBuffer.cpp @@ -86,21 +86,6 @@ public: void CopyFromRDRAM( u32 _address, bool _bUseAlpha); private: - struct PBOBinder { -#ifndef GLES2 - PBOBinder(GLuint _PBO) - { - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _PBO); - } - ~PBOBinder() { - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - } -#else - PBOBinder(GLubyte* _ptr) : ptr(_ptr) {} - ~PBOBinder() {free(ptr);} - GLubyte* ptr; -#endif - }; CachedTexture * m_pTexture; #ifndef GLES2 GLuint m_PBO; diff --git a/FrameBuffer.h b/FrameBuffer.h index ae29e042..9075da7e 100644 --- a/FrameBuffer.h +++ b/FrameBuffer.h @@ -69,6 +69,22 @@ private: GLenum m_drawBuffer; }; +struct PBOBinder { +#ifndef GLES2 + PBOBinder(GLuint _PBO) + { + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _PBO); + } + ~PBOBinder() { + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + } +#else + PBOBinder(GLubyte* _ptr) : ptr(_ptr) {} + ~PBOBinder() { free(ptr); } + GLubyte* ptr; +#endif +}; + inline FrameBufferList & frameBufferList() { diff --git a/GLSLCombiner.cpp b/GLSLCombiner.cpp index aa7d70d0..4a7a2a60 100644 --- a/GLSLCombiner.cpp +++ b/GLSLCombiner.cpp @@ -8,11 +8,12 @@ #include "GLSLCombiner.h" #include "FrameBuffer.h" #include "DepthBuffer.h" +#include "RSP.h" +#include "VI.h" #include "Log.h" #define SHADER_PRECISION #include "Shaders.h" -#include "Noise_shader.h" static GLuint g_vertex_shader_object; static GLuint g_calc_light_shader_object; @@ -63,6 +64,101 @@ bool checkProgramLinkStatus(GLuint obj) return true; } +static const GLuint noiseTexIndex = 2; +class NoiseTexture +{ +public: + NoiseTexture() : m_pTexture(NULL), m_PBO(0), m_DList(0) {} + void init(); + void destroy(); + void update(); + +private: + CachedTexture * m_pTexture; +#ifndef GLES2 + GLuint m_PBO; +#else + GLubyte* m_PBO; +#endif + u32 m_DList; +} noiseTex; + +void NoiseTexture::init() +{ + m_pTexture = textureCache().addFrameBufferTexture(); + m_pTexture->format = G_IM_FMT_RGBA; + m_pTexture->clampS = 1; + m_pTexture->clampT = 1; + m_pTexture->frameBufferTexture = TRUE; + m_pTexture->maskS = 0; + m_pTexture->maskT = 0; + m_pTexture->mirrorS = 0; + m_pTexture->mirrorT = 0; + m_pTexture->realWidth = 640; + m_pTexture->realHeight = 480; + 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_R8, m_pTexture->realWidth, m_pTexture->realHeight, 0, GL_RED, GL_UNSIGNED_BYTE, NULL); + 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() +{ + if (m_pTexture != NULL) { + textureCache().removeFrameBufferTexture(m_pTexture); + m_pTexture = NULL; + } +#ifndef GLES2 + glDeleteBuffers(1, &m_PBO); + m_PBO = 0; +#endif +} + +void NoiseTexture::update() +{ + if (m_DList == RSP.DList) + return; + const u32 dataSize = VI.width*VI.height; + if (dataSize == 0) + return; +#ifndef GLES2 + PBOBinder binder(m_PBO); + glBufferData(GL_PIXEL_UNPACK_BUFFER, dataSize, NULL, GL_DYNAMIC_DRAW); + GLubyte* ptr = (GLubyte*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY); +#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 + 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_RED, GL_UNSIGNED_BYTE, m_PBO); +#endif + m_DList = RSP.DList; +} + + #ifdef GL_IMAGE_TEXTURES_SUPPORT static void InitZlutTexture() @@ -184,7 +280,7 @@ void InitShaderCombiner() assert(checkShaderCompileStatus(g_calc_mipmap_shader_object)); g_calc_noise_shader_object = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(g_calc_noise_shader_object, 1, &noise_fragment_shader, NULL); + glShaderSource(g_calc_noise_shader_object, 1, &fragment_shader_noise, NULL); glCompileShader(g_calc_noise_shader_object); assert(checkShaderCompileStatus(g_calc_noise_shader_object)); @@ -203,6 +299,7 @@ void InitShaderCombiner() InitZlutTexture(); InitShadowMapShader(); + noiseTex.init(); #endif // GL_IMAGE_TEXTURES_SUPPORT #endif // GLES2 } @@ -226,6 +323,7 @@ void DestroyShaderCombiner() { g_calc_depth_shader_object = 0; #ifdef GL_IMAGE_TEXTURES_SUPPORT + noiseTex.destroy(); DestroyZlutTexture(); DestroyShadowMapShader(); #endif // GL_IMAGE_TEXTURES_SUPPORT @@ -249,7 +347,7 @@ const char *ColorInput[] = { "uEnvColor.a", "lod_frac", // TODO: emulate lod_fraction "vec3(uPrimLod)", - "vec3(0.5 + 0.5*snoise(vNoiseCoord2D))", + "vec3(0.5 + 0.5*snoise())", "vec3(uK4)", "vec3(uK5)", "vec3(1.0)", @@ -273,7 +371,7 @@ const char *AlphaInput[] = { "uEnvColor.a", "lod_frac", "uPrimLod", - "0.5 + 0.5*snoise(vNoiseCoord2D)", + "0.5 + 0.5*snoise()", "uK4", "uK5", "1.0", @@ -531,6 +629,7 @@ ShaderCombiner::~ShaderCombiner() { void ShaderCombiner::_locateUniforms() { LocateUniform(uTex0); LocateUniform(uTex1); + LocateUniform(uTexNoise); LocateUniform(uTlutImage); LocateUniform(uZlutImage); LocateUniform(uDepthImage); @@ -559,7 +658,6 @@ void ShaderCombiner::_locateUniforms() { LocateUniform(uK4); LocateUniform(uK5); LocateUniform(uPrimLod); - LocateUniform(uNoiseTime); LocateUniform(uScreenWidth); LocateUniform(uScreenHeight); LocateUniform(uMinLod); @@ -614,6 +712,7 @@ void ShaderCombiner::update(bool _bForce) { _setIUniform(m_uniforms.uTex0, 0, _bForce); _setIUniform(m_uniforms.uTex1, 1, _bForce); + _setIUniform(m_uniforms.uTexNoise, noiseTexIndex, _bForce); _setFUniform(m_uniforms.uScreenWidth, (float)video().getWidth(), _bForce); _setFUniform(m_uniforms.uScreenHeight, (float)video().getHeight(), _bForce); @@ -729,8 +828,10 @@ void ShaderCombiner::updateColors(bool _bForce) _setIUniform(m_uniforms.uGammaCorrectionEnabled, *REG.VI_STATUS & 8, _bForce); const int nDither = (gDP.otherMode.cycleType < G_CYC_COPY) && (gDP.otherMode.colorDither == G_CD_NOISE || gDP.otherMode.alphaDither == G_AD_NOISE || gDP.otherMode.alphaCompare == G_AC_DITHER) ? 1 : 0; - if ((m_nInputs & (1<About GLideN64 - + :/Icon.png:/Icon.png @@ -90,7 +90,7 @@ - Olivier Thacker + Olivieryuyu @@ -134,7 +134,7 @@ - Funder name + Mush Man @@ -222,7 +222,7 @@ - Funder name + zilmar @@ -420,7 +420,7 @@ p, li { white-space: pre-wrap; } p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">Orkin</span><span style=" font-size:10pt;"> - author of original glN64 graphics plugin<br /></span><span style=" font-size:10pt; font-weight:600;">Hiroshi Morii</span><span style=" font-size:10pt;"> - author of GlideHQ texture library</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">Ian McEwan, Ashima Arts</span><span style=" font-size:10pt;"> - authors of the noise shader. Copyright (C) 2011 Ashima Arts.<br /></span><span style=" font-size:10pt; font-weight:600;">Nathaniel Meyer</span><span style=" font-size:10pt;"> - author of the blur shader. Copyright: Nutty Software</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">Nathaniel Meyer</span><span style=" font-size:10pt;"> - author of the blur shader. Copyright: Nutty Software</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt;"><br /></p></body></html> @@ -446,9 +446,7 @@ p, li { white-space: pre-wrap; } - - - + buttonBox diff --git a/Noise_shader.h b/Noise_shader.h deleted file mode 100644 index f041db72..00000000 --- a/Noise_shader.h +++ /dev/null @@ -1,128 +0,0 @@ -const char *noise_fragment_shader = -// -// Description : Array and textureless GLSL 2D simplex noise function. -// Author : Ian McEwan, Ashima Arts. -// Maintainer : ijm -// Lastmod : 20110822 (ijm) -// License : Copyright (C) 2011 Ashima Arts. All rights reserved. -// Distributed under the MIT License. See LICENSE file. -// https://github.com/ashima/webgl-noise -// -// -#ifdef SHADER_PRECISION -"#version 150 core \n" -"mediump vec3 mod289(mediump vec3 x) { \n" -" return x - floor(x * (1.0 / 289.0)) * 289.0; \n" -"} \n" -" \n" -"mediump vec2 mod289(mediump vec2 x) { \n" -" return x - floor(x * (1.0 / 289.0)) * 289.0; \n" -"} \n" -" \n" -"mediump vec3 permute(mediump vec3 x) { \n" -" return mod289(((x*34.0)+1.0)*x); \n" -"} \n" -" \n" -"lowp float snoise(in mediump vec2 v) \n" -"{ \n" -" const mediump vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0 \n" -" 0.366025403784439, // 0.5*(sqrt(3.0)-1.0) \n" -" -0.577350269189626, // -1.0 + 2.0 * C.x \n" -" 0.024390243902439); // 1.0 / 41.0 \n" -// First corner -" mediump vec2 i = floor(v + dot(v, C.yy) ); \n" -" mediump vec2 x0 = v - i + dot(i, C.xx); \n" -" \n" -// Other corners -" mediump vec2 i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); \n" -" mediump vec4 x12 = x0.xyxy + C.xxzz; \n" -" x12.xy -= i1; \n" -" \n" -// Permutations -" i = mod289(i); // Avoid truncation effects in permutation \n" -" mediump vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 )) \n" -" + i.x + vec3(0.0, i1.x, 1.0 )); \n" -" \n" -" mediump vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0);\n" -" m = m*m ; \n" -" m = m*m ; \n" -" \n" -// Gradients: 41 points uniformly over a line, mapped onto a diamond. -// The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287) -" \n" -" mediump vec3 x = 2.0 * fract(p * C.www) - 1.0; \n" -" mediump vec3 h = abs(x) - 0.5; \n" -" mediump vec3 ox = floor(x + 0.5); \n" -" mediump vec3 a0 = x - ox; \n" -" \n" -// Normalise gradients implicitly by scaling m -// Approximation of: m *= inversesqrt( a0*a0 + h*h ); -" m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h ); \n" -" \n" -// Compute final noise value at P -" mediump vec3 g; \n" -" g.x = a0.x * x0.x + h.x * x0.y; \n" -" g.yz = a0.yz * x12.xz + h.yz * x12.yw; \n" -" return 130.0 * dot(m, g); \n" -"} \n" -" \n" -#else -"#version 150 core \n" -"vec3 mod289(vec3 x) { \n" -" return x - floor(x * (1.0 / 289.0)) * 289.0; \n" -"} \n" -" \n" -"vec2 mod289(vec2 x) { \n" -" return x - floor(x * (1.0 / 289.0)) * 289.0; \n" -"} \n" -" \n" -"vec3 permute(vec3 x) { \n" -" return mod289(((x*34.0)+1.0)*x); \n" -"} \n" -" \n" -"float snoise(in vec2 v) \n" -" { \n" -" const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0 \n" -" 0.366025403784439, // 0.5*(sqrt(3.0)-1.0) \n" -" -0.577350269189626, // -1.0 + 2.0 * C.x \n" -" 0.024390243902439); // 1.0 / 41.0 \n" -// First corner -" vec2 i = floor(v + dot(v, C.yy) ); \n" -" vec2 x0 = v - i + dot(i, C.xx); \n" -" \n" -// Other corners -" vec2 i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); \n" -" vec4 x12 = x0.xyxy + C.xxzz; \n" -" x12.xy -= i1; \n" -" \n" -// Permutations -" i = mod289(i); // Avoid truncation effects in permutation \n" -" vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 )) \n" -" + i.x + vec3(0.0, i1.x, 1.0 )); \n" -" \n" -" vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0);\n" -" m = m*m ; \n" -" m = m*m ; \n" -" \n" -// Gradients: 41 points uniformly over a line, mapped onto a diamond. -// The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287) -" \n" -" vec3 x = 2.0 * fract(p * C.www) - 1.0; \n" -" vec3 h = abs(x) - 0.5; \n" -" vec3 ox = floor(x + 0.5); \n" -" vec3 a0 = x - ox; \n" -" \n" -// Normalise gradients implicitly by scaling m -// Approximation of: m *= inversesqrt( a0*a0 + h*h ); -" m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h ); \n" -" \n" -// Compute final noise value at P -" vec3 g; \n" -" g.x = a0.x * x0.x + h.x * x0.y; \n" -" g.yz = a0.yz * x12.xz + h.yz * x12.yw; \n" -" return clamp(130.0 * dot(m, g), -1.0, 1.0); \n" -"} \n" -" \n" -#endif -; - diff --git a/Shaders.h b/Shaders.h index b4ff7f4a..9fd9f519 100644 --- a/Shaders.h +++ b/Shaders.h @@ -9,7 +9,6 @@ static const char* vertex_shader = " \n" "uniform int uRenderState; \n" "uniform int uTexturePersp; \n" -"uniform lowp float uNoiseTime; \n" " \n" "uniform int uFogMode; \n" "uniform lowp int uFogUsage; \n" @@ -29,7 +28,6 @@ static const char* vertex_shader = "out mediump vec2 vTexCoord0; \n" "out mediump vec2 vTexCoord1; \n" "out mediump vec2 vLodTexCoord; \n" -"out mediump vec2 vNoiseCoord2D; \n" "out lowp float vNumLights; \n" "out mediump float vFogFragCoord; \n" #else @@ -42,7 +40,6 @@ static const char* vertex_shader = " \n" "uniform int uRenderState; \n" "uniform int uTexturePersp; \n" -"uniform float uNoiseTime; \n" " \n" "uniform int uFogMode; \n" "uniform int uFogUsage; \n" @@ -62,7 +59,6 @@ static const char* vertex_shader = "out vec2 vTexCoord0; \n" "out vec2 vTexCoord1; \n" "out vec2 vLodTexCoord; \n" -"out vec2 vNoiseCoord2D; \n" "out float vNumLights; \n" "out float vFogFragCoord; \n" #endif @@ -120,7 +116,6 @@ static const char* vertex_shader = " vTexCoord1 = aTexCoord1; \n" " vNumLights = 0.0; \n" " } \n" -" vNoiseCoord2D = vec2(gl_Position.x*uScreenWidth, gl_Position.y*uScreenHeight + uNoiseTime);\n" " gl_ClipDistance[0] = gl_Position.w - gl_Position.z; \n" "} \n" ; @@ -151,7 +146,6 @@ static const char* fragment_shader_header_common_variables = "in mediump vec2 vTexCoord0;\n" "in mediump vec2 vTexCoord1;\n" "in mediump vec2 vLodTexCoord;\n" -"in mediump vec2 vNoiseCoord2D;\n" "in lowp float vNumLights; \n" "in mediump float vFogFragCoord;\n" "lowp vec3 input_color; \n" @@ -181,7 +175,6 @@ static const char* fragment_shader_header_common_variables = "in vec2 vTexCoord0; \n" "in vec2 vTexCoord1; \n" "in vec2 vLodTexCoord; \n" -"in vec2 vNoiseCoord2D; \n" "in float vNumLights; \n" "in float vFogFragCoord; \n" "vec3 input_color; \n" @@ -192,14 +185,14 @@ static const char* fragment_shader_header_common_variables = static const char* fragment_shader_header_common_functions = #ifdef SHADER_PRECISION " \n" -"lowp float snoise(in mediump vec2 v); \n" +"lowp float snoise(); \n" "mediump float 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" "bool depth_compare(); \n" "bool alpha_test(in lowp float alphaValue); \n" #else " \n" -"float snoise(in vec2 v); \n" +"float snoise(); \n" "float calc_light(in float fLights, in vec3 input_color, out vec3 output_color);\n" "float mipmap(out vec4 readtex0, out vec4 readtex1); \n" "bool depth_compare(); \n" @@ -287,7 +280,7 @@ static const char* fragment_shader_header_main = "void main() \n" "{ \n" " if (uAlphaCompareMode == 3) {//dither \n" -" if (snoise(vNoiseCoord2D) < 0.0) discard; \n" +" if (snoise() < 0.0) discard; \n" " } \n" " lowp vec4 vec_color, combined_color; \n" " lowp float alpha1, alpha2; \n" @@ -298,7 +291,7 @@ static const char* fragment_shader_header_main = "void main() \n" "{ \n" " if (uAlphaCompareMode == 3) {//dither \n" -" if (snoise(vNoiseCoord2D) < 0.0) discard; \n" +" if (snoise() < 0.0) discard; \n" " } \n" " vec4 vec_color, combined_color; \n" " float alpha1, alpha2; \n" @@ -308,14 +301,14 @@ static const char* fragment_shader_header_main = static const char* fragment_shader_color_dither = " if (uColorDitherMode == 2) { \n" -" color2 += 0.03125*snoise(vNoiseCoord2D); \n" +" color2 += 0.03125*snoise(); \n" " color2 = clamp(color2, 0.0, 1.0); \n" " } \n" ; static const char* fragment_shader_alpha_dither = " if (uAlphaDitherMode == 2) { \n" -" alpha2 += 0.03125*snoise(vNoiseCoord2D); \n" +" alpha2 += 0.03125*snoise(); \n" " alpha2 = clamp(alpha2, 0.0, 1.0); \n" " } \n" ; @@ -533,6 +526,17 @@ static const char* fragment_shader_mipmap = #endif ; +static const char* fragment_shader_noise = +"#version 330 core \n" +"uniform sampler2D uTexNoise; \n" +"uniform mediump vec2 uScreenScale; \n" +"lowp float snoise() \n" +"{ \n" +" ivec2 coord = ivec2(gl_FragCoord.xy/uScreenScale); \n" +" return (texelFetch(uTexNoise, coord, 0).r - 0.5)*2.0;\n" +"} \n" +; + #ifdef GL_IMAGE_TEXTURES_SUPPORT static const char* depth_compare_shader_float = "#version 430 \n"