diff --git a/src/GLES2/GLSLCombiner_gles2.cpp b/src/GLES2/GLSLCombiner_gles2.cpp index 5227de85..ce67515e 100644 --- a/src/GLES2/GLSLCombiner_gles2.cpp +++ b/src/GLES2/GLSLCombiner_gles2.cpp @@ -256,6 +256,7 @@ void ShaderCombiner::_locateUniforms() { LocateUniform(uDepthImage); LocateUniform(uFogMode); LocateUniform(uFogUsage); + LocateUniform(uScreenCoordsScale); LocateUniform(uAlphaCompareMode); LocateUniform(uCvgXAlpha); LocateUniform(uAlphaCvgSel); @@ -290,6 +291,7 @@ void ShaderCombiner::_locate_attributes() const { glBindAttribLocation(m_program, SC_TEXCOORD0, "aTexCoord0"); glBindAttribLocation(m_program, SC_TEXCOORD1, "aTexCoord1"); glBindAttribLocation(m_program, SC_NUMLIGHTS, "aNumLights"); + glBindAttribLocation(m_program, SC_MODIFY, "aModify"); } void ShaderCombiner::update(bool _bForce) { @@ -311,6 +313,7 @@ void ShaderCombiner::update(bool _bForce) { updateTextureInfo(_bForce); updateAlphaTestInfo(_bForce); updateDepthInfo(_bForce); + updateScreenCoordsScale(_bForce); } void ShaderCombiner::updateRenderState(bool _bForce) @@ -318,6 +321,14 @@ void ShaderCombiner::updateRenderState(bool _bForce) m_uniforms.uRenderState.set(video().getRender().getRenderState(), _bForce); } +void ShaderCombiner::updateScreenCoordsScale(bool _bForce) +{ + FrameBuffer * pCurrentBuffer = frameBufferList().getCurrent(); + const float scaleX = pCurrentBuffer != NULL ? 1.0f / pCurrentBuffer->m_width : VI.rwidth; + const float scaleY = pCurrentBuffer != NULL ? 1.0f / pCurrentBuffer->m_height : VI.rheight; + m_uniforms.uScreenCoordsScale.set(2.0f*scaleX, -2.0f*scaleY, _bForce); +} + void ShaderCombiner::updateFogMode(bool _bForce) { const u32 blender = (gDP.otherMode.l >> 16); diff --git a/src/GLES2/Shaders_gles2.h b/src/GLES2/Shaders_gles2.h index 415971ba..a6407273 100644 --- a/src/GLES2/Shaders_gles2.h +++ b/src/GLES2/Shaders_gles2.h @@ -14,6 +14,7 @@ SHADER_VERSION "IN highp vec2 aTexCoord0; \n" "IN highp vec2 aTexCoord1; \n" "IN lowp float aNumLights; \n" +"IN highp vec4 aModify; \n" " \n" "uniform int uRenderState; \n" "uniform int uTexturePersp; \n" @@ -22,13 +23,14 @@ SHADER_VERSION "uniform lowp int uFogUsage; \n" "uniform lowp float uFogAlpha; \n" "uniform mediump vec2 uFogScale; \n" +"uniform mediump vec2 uScreenCoordsScale; \n" " \n" -"uniform mediump vec2 uTexScale; \n" -"uniform mediump vec2 uTexOffset[2]; \n" -"uniform mediump vec2 uCacheScale[2]; \n" -"uniform mediump vec2 uCacheOffset[2]; \n" -"uniform mediump vec2 uCacheShiftScale[2]; \n" -"uniform lowp ivec2 uCacheFrameBuffer; \n" +"uniform mediump vec2 uTexScale; \n" +"uniform mediump vec2 uTexOffset[2]; \n" +"uniform mediump vec2 uCacheScale[2]; \n" +"uniform mediump vec2 uCacheOffset[2]; \n" +"uniform mediump vec2 uCacheShiftScale[2]; \n" +"uniform lowp ivec2 uCacheFrameBuffer; \n" "OUT lowp vec4 vShadeColor; \n" "OUT mediump vec2 vTexCoord0; \n" "OUT mediump vec2 vTexCoord1; \n" @@ -58,6 +60,18 @@ SHADER_VERSION " vTexCoord1 = calcTexCoord(texCoord, 1); \n" " vLodTexCoord = texCoord * uCacheShiftScale[0]; \n" " vNumLights = aNumLights; \n" +" if (aModify != vec4(0.0)) { \n" +" if (aModify[0] != 0.0) { \n" +" gl_Position.xy = gl_Position.xy * uScreenCoordsScale + vec2(-1.0, 1.0); \n" +" gl_Position.xy *= gl_Position.w; \n" +" } \n" +" if (aModify[1] != 0.0) \n" +" gl_Position.z *= gl_Position.w; \n" +" if (aModify[2] != 0.0 && uTexturePersp == 0) \n" +" texCoord *= 2.0; \n" +" if (aModify[3] != 0.0) \n" +" vNumLights = 0.0; \n" +" } \n" " if (uFogMode == 0) { \n" " if (aPosition.z < -aPosition.w) \n" " vFogFragCoord = -uFogScale.s + uFogScale.t; \n" @@ -96,6 +110,7 @@ SHADER_VERSION "IN highp vec4 aPosition; \n" "IN lowp vec4 aColor; \n" "IN lowp float aNumLights; \n" +"IN highp vec4 aModify; \n" " \n" "uniform int uRenderState; \n" " \n" @@ -103,6 +118,7 @@ SHADER_VERSION "uniform lowp int uFogUsage; \n" "uniform lowp float uFogAlpha; \n" "uniform mediump vec2 uFogScale; \n" +"uniform mediump vec2 uScreenCoordsScale;\n" " \n" "OUT lowp vec4 vShadeColor; \n" "OUT lowp float vNumLights; \n" @@ -115,6 +131,16 @@ SHADER_VERSION " vShadeColor = aColor; \n" " if (uRenderState == 1) { \n" " vNumLights = aNumLights; \n" +" if (aModify != vec4(0.0)) { \n" +" if (aModify[0] != 0.0) { \n" +" gl_Position.xy = gl_Position.xy * uScreenCoordsScale + vec2(-1.0, 1.0); \n" +" gl_Position.xy *= gl_Position.w; \n" +" } \n" +" if (aModify[1] != 0.0) \n" +" gl_Position.z *= gl_Position.w; \n" +" if (aModify[3] != 0.0) \n" +" vNumLights = 0.0; \n" +" } \n" " if (uFogMode == 0) { \n" " if (aPosition.z < -aPosition.w) \n" " vFogFragCoord = -uFogScale.s + uFogScale.t; \n" diff --git a/src/GLSLCombiner.h b/src/GLSLCombiner.h index 6fa651ab..3c6fec2f 100644 --- a/src/GLSLCombiner.h +++ b/src/GLSLCombiner.h @@ -21,6 +21,7 @@ public: void updateAlphaTestInfo(bool _bForce = false); void updateTextureInfo(bool _bForce = false); void updateRenderState(bool _bForce = false); + void updateScreenCoordsScale(bool _bForce = false); u64 getMux() const {return m_combine.mux;} @@ -101,7 +102,7 @@ private: fUniform uFogAlpha, uMinLod, uDeltaZ, uAlphaTestValue, uMSAAScale; - fv2Uniform uScreenScale, uDepthScale, uFogScale; + fv2Uniform uScreenScale, uDepthScale, uFogScale, uScreenCoordsScale; iv2Uniform uMSTexEnabled, uFbMonochrome, uFbFixedAlpha; }; diff --git a/src/OGL3X/GLSLCombiner_ogl3x.cpp b/src/OGL3X/GLSLCombiner_ogl3x.cpp index 1df54bf6..373fa679 100644 --- a/src/OGL3X/GLSLCombiner_ogl3x.cpp +++ b/src/OGL3X/GLSLCombiner_ogl3x.cpp @@ -515,6 +515,7 @@ void ShaderCombiner::_locateUniforms() { LocateUniform(uScreenScale); LocateUniform(uDepthScale); LocateUniform(uFogScale); + LocateUniform(uScreenCoordsScale); #ifdef GL_MULTISAMPLING_SUPPORT LocateUniform(uMSTex0); @@ -531,6 +532,7 @@ void ShaderCombiner::_locate_attributes() const { glBindAttribLocation(m_program, SC_TEXCOORD0, "aTexCoord0"); glBindAttribLocation(m_program, SC_TEXCOORD1, "aTexCoord1"); glBindAttribLocation(m_program, SC_NUMLIGHTS, "aNumLights"); + glBindAttribLocation(m_program, SC_MODIFY, "aModify"); } void ShaderCombiner::update(bool _bForce) { @@ -562,6 +564,7 @@ void ShaderCombiner::update(bool _bForce) { updateTextureInfo(_bForce); updateAlphaTestInfo(_bForce); updateDepthInfo(_bForce); + updateScreenCoordsScale(_bForce); } void ShaderCombiner::updateRenderState(bool _bForce) @@ -569,6 +572,14 @@ void ShaderCombiner::updateRenderState(bool _bForce) m_uniforms.uRenderState.set(video().getRender().getRenderState(), _bForce); } +void ShaderCombiner::updateScreenCoordsScale(bool _bForce) +{ + FrameBuffer * pCurrentBuffer = frameBufferList().getCurrent(); + const float scaleX = pCurrentBuffer != NULL ? 1.0f / pCurrentBuffer->m_width : VI.rwidth; + const float scaleY = pCurrentBuffer != NULL ? 1.0f / pCurrentBuffer->m_height : VI.rheight; + m_uniforms.uScreenCoordsScale.set(2.0f*scaleX, -2.0f*scaleY, _bForce); +} + void ShaderCombiner::updateFogMode(bool _bForce) { const u32 blender = (gDP.otherMode.l >> 16); diff --git a/src/OGL3X/Shaders_ogl3x.h b/src/OGL3X/Shaders_ogl3x.h index 64ca6ece..123470e2 100644 --- a/src/OGL3X/Shaders_ogl3x.h +++ b/src/OGL3X/Shaders_ogl3x.h @@ -11,11 +11,12 @@ static const char* vertex_shader = 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" +"in highp vec4 aPosition; \n" +"in lowp vec4 aColor; \n" +"in highp vec2 aTexCoord0; \n" +"in highp vec2 aTexCoord1; \n" +"in lowp float aNumLights; \n" +"in highp vec4 aModify; \n" " \n" "uniform int uRenderState; \n" "uniform int uTexturePersp; \n" @@ -24,6 +25,7 @@ MAIN_SHADER_VERSION "uniform lowp int uFogUsage; \n" "uniform lowp float uFogAlpha; \n" "uniform mediump vec2 uFogScale; \n" +"uniform mediump vec2 uScreenCoordsScale; \n" " \n" "layout (std140) uniform TextureBlock { \n" " mediump vec2 uTexScale; \n" @@ -60,8 +62,20 @@ MAIN_SHADER_VERSION " if (uTexturePersp == 0) texCoord *= 0.5; \n" " vTexCoord0 = calcTexCoord(texCoord, 0); \n" " vTexCoord1 = calcTexCoord(texCoord, 1); \n" -" vLodTexCoord = texCoord; \n" +" vLodTexCoord = texCoord; \n" " vNumLights = aNumLights; \n" +" if (aModify != vec4(0.0)) { \n" +" if ((aModify[0]) != 0.0) { \n" +" gl_Position.xy = gl_Position.xy * uScreenCoordsScale + vec2(-1.0, 1.0); \n" +" gl_Position.xy *= gl_Position.w; \n" +" } \n" +" if ((aModify[1]) != 0.0) \n" +" gl_Position.z *= gl_Position.w; \n" +" if ((aModify[2]) != 0.0 && uTexturePersp == 0) \n" +" texCoord *= 2.0; \n" +" if ((aModify[3]) != 0.0) \n" +" vNumLights = 0.0; \n" +" } \n" " if (uFogMode == 0) { \n" " if (aPosition.z < -aPosition.w) \n" " vFogFragCoord = -uFogScale.s + uFogScale.t; \n" @@ -96,6 +110,7 @@ MAIN_SHADER_VERSION "in highp vec4 aPosition; \n" "in lowp vec4 aColor; \n" "in lowp float aNumLights; \n" +"in highp vec4 aModify; \n" " \n" "uniform int uRenderState; \n" " \n" @@ -103,6 +118,7 @@ MAIN_SHADER_VERSION "uniform lowp int uFogUsage; \n" "uniform lowp float uFogAlpha; \n" "uniform mediump vec2 uFogScale; \n" +"uniform mediump vec2 uScreenCoordsScale;\n" " \n" "out lowp vec4 vShadeColor; \n" "out lowp float vNumLights; \n" @@ -115,6 +131,16 @@ MAIN_SHADER_VERSION " vShadeColor = aColor; \n" " if (uRenderState == 1) { \n" " vNumLights = aNumLights; \n" +" if (aModify != vec4(0.0)) { \n" +" if ((aModify[0]) != 0.0) { \n" +" gl_Position.xy = gl_Position.xy * uScreenCoordsScale + vec2(-1.0, 1.0); \n" +" gl_Position.xy *= gl_Position.w; \n" +" } \n" +" if ((aModify[1]) != 0.0) \n" +" gl_Position.z *= gl_Position.w; \n" +" if ((aModify[3]) != 0.0) \n" +" vNumLights = 0.0; \n" +" } \n" " if (uFogMode == 0) { \n" " if (aPosition.z < -aPosition.w) \n" " vFogFragCoord = -uFogScale.s + uFogScale.t; \n" diff --git a/src/OpenGL.cpp b/src/OpenGL.cpp index c853836b..3eb35c22 100644 --- a/src/OpenGL.cpp +++ b/src/OpenGL.cpp @@ -747,7 +747,8 @@ void OGLRender::_prepareDrawTriangle(bool _dma) glEnableVertexAttribArray(SC_NUMLIGHTS); glVertexAttribPointer(SC_NUMLIGHTS, 1, GL_BYTE, GL_FALSE, sizeof(SPVertex), &pVtx->HWLight); } - + glEnableVertexAttribArray(SC_MODIFY); + glVertexAttribPointer(SC_MODIFY, 4, GL_BYTE, GL_FALSE, sizeof(SPVertex), &pVtx->modify); } else if (updateColorArrays) { SPVertex * pVtx = _dma ? triangles.dmaVertices.data() : &triangles.vertices[0]; if (m_bFlatColors) @@ -755,6 +756,16 @@ void OGLRender::_prepareDrawTriangle(bool _dma) else glVertexAttribPointer(SC_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(SPVertex), &pVtx->r); } + + if (triangles.vertices[0].modify != 0) { + OGLVideo & ogl = video(); + FrameBuffer * pCurrentBuffer = frameBufferList().getCurrent(); + if (pCurrentBuffer == NULL) + glViewport(0, ogl.getHeightOffset(), ogl.getScreenWidth(), ogl.getScreenHeight()); + else + glViewport(0, 0, pCurrentBuffer->m_width*pCurrentBuffer->m_scaleX, pCurrentBuffer->m_height*pCurrentBuffer->m_scaleY); + gSP.changed |= CHANGED_VIEWPORT; + } } bool OGLRender::_canDraw() const @@ -767,39 +778,20 @@ void OGLRender::drawLLETriangle(u32 _numVtx) if (_numVtx == 0 || !_canDraw()) return; + for (u32 i = 0; i < _numVtx; ++i) { + SPVertex & vtx = triangles.vertices[i]; + vtx.modify = MODIFY_ALL; + } + gSP.changed &= ~CHANGED_GEOMETRYMODE; // Don't update cull mode _prepareDrawTriangle(false); glDisable(GL_CULL_FACE); - OGLVideo & ogl = video(); - FrameBuffer * pCurrentBuffer = frameBufferList().getCurrent(); - if (pCurrentBuffer == NULL) - glViewport( 0, ogl.getHeightOffset(), ogl.getScreenWidth(), ogl.getScreenHeight()); - else - glViewport(0, 0, pCurrentBuffer->m_width*pCurrentBuffer->m_scaleX, pCurrentBuffer->m_height*pCurrentBuffer->m_scaleY); - - const float scaleX = pCurrentBuffer != NULL ? 1.0f / pCurrentBuffer->m_width : VI.rwidth; - const float scaleY = pCurrentBuffer != NULL ? 1.0f / pCurrentBuffer->m_height : VI.rheight; - - for (u32 i = 0; i < _numVtx; ++i) { - SPVertex & vtx = triangles.vertices[i]; - vtx.HWLight = 0; - vtx.x = vtx.x * (2.0f * scaleX) - 1.0f; - vtx.x *= vtx.w; - vtx.y = vtx.y * (-2.0f * scaleY) + 1.0f; - vtx.y *= vtx.w; - vtx.z *= vtx.w; - if (gDP.otherMode.texturePersp == 0) { - vtx.s *= 2.0f; - vtx.t *= 2.0f; - } - } - glDrawArrays(GL_TRIANGLE_STRIP, 0, _numVtx); triangles.num = 0; frameBufferList().setBufferChanged(); - gSP.changed |= CHANGED_VIEWPORT | CHANGED_GEOMETRYMODE; + gSP.changed |= CHANGED_GEOMETRYMODE; } void OGLRender::drawDMATriangles(u32 _numVtx) @@ -868,6 +860,8 @@ void OGLRender::drawRect(int _ulx, int _uly, int _lrx, int _lry, float *_pColor) glDisableVertexAttribArray(SC_COLOR); glDisableVertexAttribArray(SC_TEXCOORD0); glDisableVertexAttribArray(SC_TEXCOORD1); + glDisableVertexAttribArray(SC_NUMLIGHTS); + glDisableVertexAttribArray(SC_MODIFY); } if (updateArrays) @@ -1070,6 +1064,8 @@ void OGLRender::drawTexturedRect(const TexturedRectParams & _params) glVertexAttribPointer(SC_POSITION, 4, GL_FLOAT, GL_FALSE, sizeof(GLVertex), &m_rect[0].x); glVertexAttribPointer(SC_TEXCOORD0, 2, GL_FLOAT, GL_FALSE, sizeof(GLVertex), &m_rect[0].s0); glVertexAttribPointer(SC_TEXCOORD1, 2, GL_FLOAT, GL_FALSE, sizeof(GLVertex), &m_rect[0].s1); + glDisableVertexAttribArray(SC_NUMLIGHTS); + glDisableVertexAttribArray(SC_MODIFY); } currentCombiner()->updateRenderState(); diff --git a/src/PostProcessor.cpp b/src/PostProcessor.cpp index df765e0d..92a5bd46 100644 --- a/src/PostProcessor.cpp +++ b/src/PostProcessor.cpp @@ -497,6 +497,7 @@ void _setGLState() { glDisableVertexAttribArray(SC_COLOR); glDisableVertexAttribArray(SC_TEXCOORD1); glDisableVertexAttribArray(SC_NUMLIGHTS); + glDisableVertexAttribArray(SC_MODIFY); glViewport(0, 0, video().getWidth(), video().getHeight()); gSP.changed |= CHANGED_VIEWPORT; gDP.changed |= CHANGED_RENDERMODE; diff --git a/src/gSP.cpp b/src/gSP.cpp index cf41db5e..666b2e0e 100644 --- a/src/gSP.cpp +++ b/src/gSP.cpp @@ -333,6 +333,7 @@ void gSPProcessVertex4(u32 v) vPos[i][0] = vtx.x; vPos[i][1] = vtx.y; vPos[i][2] = vtx.z; + vtx.modify = 0; } gSPTransformVertex4(v, gSP.matrix.combined ); @@ -398,7 +399,7 @@ static void gSPTransformVertex_default(float vtx[4], float mtx[4][4]) static void gSPLightVertex_default(SPVertex & _vtx) { - if (!config.generalEmulation.enableHWLighting) { + if (config.generalEmulation.enableHWLighting == 0) { _vtx.HWLight = 0; _vtx.r = gSP.lights[gSP.numLights].r; _vtx.g = gSP.lights[gSP.numLights].g; @@ -575,6 +576,7 @@ void gSPProcessVertex(u32 v) } gSPClipVertex(v); + vtx.modify = 0; if (gSP.geometryMode & G_LIGHTING) { TransformVectorNormalize( &vtx.nx, gSP.matrix.modelView[gSP.matrix.modelViewi] ); diff --git a/src/gSP.h b/src/gSP.h index 69e65d6a..e54e3370 100644 --- a/src/gSP.h +++ b/src/gSP.h @@ -25,11 +25,18 @@ #define CLIP_ALL 0x1F // CLIP_NEGX|CLIP_POSX|CLIP_NEGY|CLIP_POSY|CLIP_Z +#define MODIFY_XY 0x000000FF +#define MODIFY_Z 0x0000FF00 +#define MODIFY_ST 0x00FF0000 +#define MODIFY_RGBA 0xFF000000 +#define MODIFY_ALL 0xFFFFFFFF + #define SC_POSITION 1 #define SC_COLOR 2 #define SC_TEXCOORD0 3 #define SC_TEXCOORD1 4 #define SC_NUMLIGHTS 5 +#define SC_MODIFY 6 struct SPVertex { @@ -38,9 +45,10 @@ struct SPVertex f32 r, g, b, a; f32 flat_r, flat_g, flat_b, flat_a; f32 s, t; + u32 modify; u8 HWLight; + u8 clip; s16 flag; - u32 clip; }; struct SPLight