1
0
mirror of https://github.com/blawar/GLideN64.git synced 2024-07-02 09:03:37 +00:00

Use screen coordinates to render primitives

This commit is contained in:
s2s 2021-03-05 18:28:25 +01:00 committed by Sergey Lipskiy
parent 1d90610782
commit 81318c5445
7 changed files with 79 additions and 174 deletions

View File

@ -179,7 +179,6 @@ u32 RGBA32ToABGR32(u32 col, bool _fullAlpha)
void RDRAMtoColorBuffer::_copyFromRDRAM(u32 _height, bool _fullAlpha)
{
Cleaner cleaner(this);
ValueKeeper<u32> otherMode(gSP.clipRatio, 1U);
const u32 address = m_pCurBuffer->m_startAddress;
const u32 width = m_pCurBuffer->m_width;
const u32 height = _height;

View File

@ -267,7 +267,6 @@ public:
ss << "# define IN in" << std::endl << "# define OUT out" << std::endl;
m_part = ss.str();
}
m_part += "uniform lowp float uClipRatio; \n";
}
};
@ -296,6 +295,8 @@ public:
"uniform mediump vec2 uCacheScale[2]; \n"
"uniform mediump vec2 uCacheOffset[2]; \n"
"uniform mediump vec2 uCacheShiftScale[2]; \n"
"uniform mediump vec2 uVTrans; \n"
"uniform mediump vec2 uVScale; \n"
"uniform lowp ivec2 uCacheFrameBuffer; \n"
"OUT highp vec2 vTexCoord0; \n"
"OUT highp vec2 vTexCoord1; \n"
@ -330,17 +331,17 @@ public:
" vTexCoord1 = calcTexCoord(texCoord, 1); \n"
" vLodTexCoord = texCoord; \n"
" vNumLights = aNumLights; \n"
" if (aModify != vec4(0.0)) { \n"
" if ((aModify[0]) != 0.0) { \n"
" gl_Position.xy = gl_Position.xy * uScreenCoordsScale + vec2(-1.0, 1.0); \n"
" gl_Position.xy *= gl_Position.w; \n"
" } \n"
" if ((aModify[1]) != 0.0) \n"
" gl_Position.z *= gl_Position.w; \n"
" if ((aModify[3]) != 0.0) \n"
" vNumLights = 0.0; \n"
" if ((aModify[0]) != 0.0) { \n"
" gl_Position.xy *= gl_Position.w; \n"
" } \n"
" gl_Position.y = -gl_Position.y; \n"
" else { \n"
" gl_Position.xy = gl_Position.xy * uVScale.xy + uVTrans.xy * gl_Position.ww; \n"
" gl_Position.xy = floor(gl_Position.xy * vec2(4.0)) * vec2(0.25); \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"
" if (uFogUsage > 0) { \n"
" lowp float fp; \n"
" if (aPosition.z < -aPosition.w && aModify[1] == 0.0) \n"
@ -374,6 +375,8 @@ public:
"uniform lowp int uFogUsage; \n"
"uniform mediump vec2 uFogScale; \n"
"uniform mediump vec2 uScreenCoordsScale; \n"
"uniform mediump vec2 uVTrans; \n"
"uniform mediump vec2 uVScale; \n"
" \n"
"OUT lowp float vNumLights; \n"
"OUT lowp vec4 vShadeColor; \n"
@ -390,17 +393,17 @@ public:
" gl_Position = aPosition; \n"
" vShadeColor = aColor; \n"
" vNumLights = aNumLights; \n"
" if (aModify != vec4(0.0)) { \n"
" if ((aModify[0]) != 0.0) { \n"
" gl_Position.xy = gl_Position.xy * uScreenCoordsScale + vec2(-1.0, 1.0); \n"
" gl_Position.xy *= gl_Position.w; \n"
" } \n"
" if ((aModify[1]) != 0.0) \n"
" gl_Position.z *= gl_Position.w; \n"
" if ((aModify[3]) != 0.0) \n"
" vNumLights = 0.0; \n"
" if ((aModify[0]) != 0.0) { \n"
" gl_Position.xy *= gl_Position.w; \n"
" } \n"
" gl_Position.y = -gl_Position.y; \n"
" else { \n"
" gl_Position.xy = gl_Position.xy * uVScale.xy + uVTrans.xy * gl_Position.ww; \n"
" gl_Position.xy = floor(gl_Position.xy * vec2(4.0)) * vec2(0.25); \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"
" if (uFogUsage > 0) { \n"
" lowp float fp; \n"
" if (aPosition.z < -aPosition.w && aModify[1] == 0.0) \n"
@ -503,7 +506,7 @@ public:
m_part = " gl_Position.z /= 8.0; \n";
}
m_part +=
" gl_Position.zw *= vec2(uClipRatio); \n"
" gl_Position.zw *= vec2(1024.0f); \n"
"} \n"
;
}

View File

@ -603,6 +603,25 @@ private:
fUniform uAlphaTestValue;
};
class UViewportInfo : public UniformGroup
{
public:
UViewportInfo(GLuint _program) {
LocateUniform(uVTrans);
LocateUniform(uVScale);
}
void update(bool _force) override
{
uVTrans.set(gSP.viewport.vtrans[0], gSP.viewport.vtrans[1], _force);
uVScale.set(gSP.viewport.vscale[0], -gSP.viewport.vscale[1], _force);
}
private:
fv2Uniform uVTrans;
fv2Uniform uVScale;
};
class UDepthScale : public UniformGroup
{
public:
@ -738,22 +757,6 @@ private:
iUniform uClampMode;
};
class UClipRatio : public UniformGroup
{
public:
UClipRatio(GLuint _program) {
LocateUniform(uClipRatio);
}
void update(bool _force) override
{
uClipRatio.set(float(gSP.clipRatio), _force);
}
private:
fUniform uClipRatio;
};
class UPolygonOffset : public UniformGroup
{
public:
@ -1094,6 +1097,7 @@ void CombinerProgramUniformFactory::buildUniforms(GLuint _program,
{
_uniforms.emplace_back(new UNoiseTex(_program));
_uniforms.emplace_back(new UScreenSpaceTriangleInfo(_program));
_uniforms.emplace_back(new UViewportInfo(_program));
if (!m_glInfo.isGLES2) {
_uniforms.emplace_back(new UDepthTex(_program));
@ -1165,8 +1169,6 @@ void CombinerProgramUniformFactory::buildUniforms(GLuint _program,
_uniforms.emplace_back(new UPolygonOffset(_program));
}
_uniforms.emplace_back(new UClipRatio(_program));
_uniforms.emplace_back(new UScreenCoordsScale(_program));
_uniforms.emplace_back(new UColors(_program));

View File

@ -238,86 +238,25 @@ void GraphicsDrawer::updateScissor(FrameBuffer * _pBuffer) const
gDP.changed &= ~CHANGED_SCISSOR;
}
inline
float _adjustViewportX(f32 _X0)
void GraphicsDrawer::_updateViewport(const FrameBuffer* _pBuffer, const f32 scale) const
{
const f32 halfX = gDP.colorImage.width / 2.0f;
const f32 halfVP = gSP.viewport.width / 2.0f;
return (_X0 + halfVP - halfX) * dwnd().getAdjustScale() + halfX - halfVP;
}
inline
void _adjustViewportToClipRatio(s32 & x, s32 & y, s32 & width, s32 & height)
{
x -= static_cast<s32>(gSP.clipRatio - 1) * width / 2;
y -= static_cast<s32>(gSP.clipRatio - 1) * height / 2;
width *= gSP.clipRatio;
height *= gSP.clipRatio;
}
void GraphicsDrawer::_updateViewport() const
{
DisplayWindow & wnd = DisplayWindow::get();
FrameBuffer * pCurrentBuffer = frameBufferList().getCurrent();
if (pCurrentBuffer == nullptr) {
const f32 scaleX = wnd.getScaleX();
const f32 scaleY = wnd.getScaleY();
float Xf = gSP.viewport.vscale[0] < 0 ? (gSP.viewport.x + gSP.viewport.vscale[0] * 2.0f) : gSP.viewport.x;
if (_needAdjustCoordinate(wnd))
Xf = _adjustViewportX(Xf);
s32 X = static_cast<s32>(Xf * scaleX);
s32 Y = static_cast<s32>(gSP.viewport.y * scaleY);
s32 WIDTH = std::max(static_cast<s32>(gSP.viewport.width * scaleX), 0);
s32 HEIGHT = std::max(static_cast<s32>(gSP.viewport.height * scaleY), 0);
_adjustViewportToClipRatio(X, Y, WIDTH, HEIGHT);
gfxContext.setViewport(X, Y, WIDTH, HEIGHT);
} else {
const f32 scaleX = pCurrentBuffer->m_scale;
const f32 scaleY = pCurrentBuffer->m_scale;
float Xf = gSP.viewport.vscale[0] < 0 ? (gSP.viewport.x + gSP.viewport.vscale[0] * 2.0f) : gSP.viewport.x;
Xf += f32(pCurrentBuffer->m_originX);
if (_needAdjustCoordinate(wnd))
Xf = _adjustViewportX(Xf);
s32 X = roundup(Xf, scaleX);
float Yf = gSP.viewport.vscale[1] < 0 ? (gSP.viewport.y + gSP.viewport.vscale[1] * 2.0f) : gSP.viewport.y;
Yf += f32(pCurrentBuffer->m_originY);
s32 Y = roundup(Yf, scaleY);
s32 WIDTH = std::max(roundup(gSP.viewport.width, scaleX), 0);
s32 HEIGHT = std::max(roundup(gSP.viewport.height, scaleY), 0);
_adjustViewportToClipRatio(X, Y, WIDTH, HEIGHT);
gfxContext.setViewport(X, Y, WIDTH, HEIGHT);
}
gSP.changed &= ~CHANGED_VIEWPORT;
}
void GraphicsDrawer::_updateScreenCoordsViewport(const FrameBuffer * _pBuffer) const
{
DisplayWindow & wnd = DisplayWindow::get();
const FrameBuffer * pCurrentBuffer = _pBuffer != nullptr ? _pBuffer : frameBufferList().getCurrent();
u32 bufferWidth, bufferHeight;
f32 viewportScaleX, viewportScaleY;
s32 X = 0, Y = 0;
if (pCurrentBuffer == nullptr) {
bufferWidth = VI.width;
bufferHeight = VI.height;
viewportScaleX = wnd.getScaleX();
viewportScaleY = wnd.getScaleY();
} else {
bufferWidth = pCurrentBuffer->m_width;
bufferHeight = VI_GetMaxBufferHeight(static_cast<u16>(bufferWidth));
viewportScaleX = viewportScaleY = pCurrentBuffer->m_scale;
X = roundup(f32(pCurrentBuffer->m_originX), viewportScaleX);
Y = roundup(f32(pCurrentBuffer->m_originY), viewportScaleY);
if (RSP.LLE || gSP.viewport.width == 0.0f) {
gSP.viewport.width = f32(bufferWidth);
gSP.viewport.height = f32(bufferHeight);
s32 X, Y, WIDTH, HEIGHT;
f32 scaleX, scaleY;
if (scale == 0.0f) {
const FrameBuffer* pCurrentBuffer = _pBuffer != nullptr ? _pBuffer : frameBufferList().getCurrent();
if (pCurrentBuffer != nullptr) {
scaleX = scaleY = pCurrentBuffer->m_scale;
} else {
scaleX = dwnd().getScaleX();
scaleY = dwnd().getScaleY();
}
} else {
scaleX = scaleY = scale;
}
s32 WIDTH = roundup(f32(bufferWidth), viewportScaleX);
s32 HEIGHT = roundup(f32(bufferHeight), viewportScaleY);
_adjustViewportToClipRatio(X, Y, WIDTH, HEIGHT);
X = roundup(-1024.0f, scaleX);
Y = roundup(-1024.0f, scaleY);
WIDTH = roundup(2048.0f, scaleX);
HEIGHT = roundup(2048.0f, scaleY);
gfxContext.setViewport(X, Y, WIDTH, HEIGHT);
gSP.changed |= CHANGED_VIEWPORT;
}
@ -796,7 +735,7 @@ void GraphicsDrawer::_prepareDrawTriangle(DrawingState _drawingState)
m_bFlatColors = bFlatColors;
if ((m_modifyVertices & MODIFY_XY) != 0)
_updateScreenCoordsViewport();
_updateViewport();
m_modifyVertices = 0;
}
@ -853,8 +792,6 @@ void GraphicsDrawer::drawScreenSpaceTriangle(u32 _numVtx, graphics::DrawModePara
if (_numVtx == 0 || !_canDraw())
return;
ValueKeeper<u32> otherMode(gSP.clipRatio, 1U);
f32 maxY = 0;
for (u32 i = 0; i < _numVtx; ++i) {
SPVertex & vtx = m_dmaVertices[i];
@ -1042,7 +979,7 @@ void GraphicsDrawer::drawLine(u32 _v0, u32 _v1, float _width)
m_drawingState = DrawingState::Line;
if ((triangles.vertices[_v0].modify & MODIFY_XY) != 0)
_updateScreenCoordsViewport();
_updateViewport();
SPVertex vertexBuf[2] = { triangles.vertices[_v0], triangles.vertices[_v1] };
gfxContext.drawLine(lineWidth, vertexBuf);
@ -1050,7 +987,6 @@ void GraphicsDrawer::drawLine(u32 _v0, u32 _v1, float _width)
void GraphicsDrawer::drawRect(int _ulx, int _uly, int _lrx, int _lry)
{
ValueKeeper<u32> otherMode(gSP.clipRatio, 1U);
m_texrectDrawer.draw();
m_statistics.fillRects++;
@ -1064,24 +1000,22 @@ void GraphicsDrawer::drawRect(int _ulx, int _uly, int _lrx, int _lry)
m_drawingState = DrawingState::Rect;
_updateScreenCoordsViewport();
_updateViewport();
gfxContext.enable(enable::CULL_FACE, false);
f32 scaleX, scaleY;
calcCoordsScales(frameBufferList().getCurrent(), scaleX, scaleY);
const float Z = (gDP.otherMode.depthSource == G_ZS_PRIM) ? gDP.primDepth.z : 0.0f;
const float W = 1.0f;
m_rect[0].x = static_cast<f32>(_ulx) * (2.0f * scaleX) - 1.0f;
m_rect[0].y = static_cast<f32>(_uly) * (2.0f * scaleY) - 1.0f;
m_rect[0].x = static_cast<f32>(_ulx);
m_rect[0].y = static_cast<f32>(_uly);
m_rect[0].z = Z;
m_rect[0].w = W;
m_rect[1].x = static_cast<f32>(_lrx) * (2.0f * scaleX) - 1.0f;
m_rect[1].x = static_cast<f32>(_lrx);
m_rect[1].y = m_rect[0].y;
m_rect[1].z = Z;
m_rect[1].w = W;
m_rect[2].x = m_rect[0].x;
m_rect[2].y = static_cast<f32>(_lry) * (2.0f * scaleY) - 1.0f;
m_rect[2].y = static_cast<f32>(_lry);
m_rect[2].z = Z;
m_rect[2].w = W;
m_rect[3].x = m_rect[1].x;
@ -1265,7 +1199,6 @@ void GraphicsDrawer::drawTexturedRect(const TexturedRectParams & _params)
gSP.changed &= ~CHANGED_GEOMETRYMODE; // Don't update cull mode
m_drawingState = DrawingState::TexRect;
m_statistics.texRects++;
ValueKeeper<u32> otherMode(gSP.clipRatio, 1U);
if (m_texrectDrawer.canContinue()) {
CombinerInfo & cmbInfo = CombinerInfo::get();
@ -1305,14 +1238,13 @@ void GraphicsDrawer::drawTexturedRect(const TexturedRectParams & _params)
&& ((cache.current[0]->frameBufferTexture == CachedTexture::fbNone && !cache.current[0]->bHDTexture))
&& (cache.current[1] == nullptr || (cache.current[1]->frameBufferTexture == CachedTexture::fbNone && !cache.current[1]->bHDTexture)));
f32 scaleX, scaleY;
calcCoordsScales(pCurrentBuffer, scaleX, scaleY);
const float Z = (gDP.otherMode.depthSource == G_ZS_PRIM) ? gDP.primDepth.z : 0.0f;
const float W = 1.0f;
const f32 ulx = _params.ulx * (2.0f * scaleX) - 1.0f;
const f32 uly = _params.uly * (2.0f * scaleY) - 1.0f;
const f32 lrx = _params.lrx * (2.0f * scaleX) - 1.0f;
const f32 lry = _params.lry * (2.0f * scaleY) - 1.0f;
const f32 ulx = _params.ulx;
const f32 uly = _params.uly;
const f32 lrx = _params.lrx;
const f32 lry = _params.lry;
m_rect[0].x = ulx;
m_rect[0].y = uly;
m_rect[0].z = Z;
@ -1505,7 +1437,7 @@ void GraphicsDrawer::drawTexturedRect(const TexturedRectParams & _params)
return;
}
_updateScreenCoordsViewport(_params.pBuffer);
_updateViewport(_params.pBuffer);
Context::DrawRectParameters rectParams;
rectParams.mode = drawmode::TRIANGLE_STRIP;
rectParams.verticesCount = 4;
@ -1513,14 +1445,6 @@ void GraphicsDrawer::drawTexturedRect(const TexturedRectParams & _params)
rectParams.combiner = currentCombiner();
gfxContext.drawRects(rectParams);
if (g_debugger.isCaptureMode()) {
m_rect[0].x = _params.ulx;
m_rect[0].y = _params.uly;
m_rect[1].x = _params.lrx;
m_rect[1].y = _params.uly;
m_rect[2].x = _params.ulx;
m_rect[2].y = _params.lry;
m_rect[3].x = _params.lrx;
m_rect[3].y = _params.lry;
g_debugger.addRects(rectParams);
}

View File

@ -190,8 +190,7 @@ private:
void _ordinaryBlending() const;
void _dualSourceBlending() const;
void _updateCullFace() const;
void _updateViewport() const;
void _updateScreenCoordsViewport(const FrameBuffer * _pBuffer = nullptr) const;
void _updateViewport(const FrameBuffer * _pBuffer = nullptr, const f32 scale = 0.0f) const;
void _updateDepthUpdate() const;
void _updateDepthCompare() const;
void _updateTextures() const;

View File

@ -387,7 +387,7 @@ bool TexrectDrawer::draw()
const float t1 = (m_uly + 1.0f) / scaleY / (float)m_pTexture->height;
const float W = 1.0f;
drawer._updateScreenCoordsViewport(m_pBuffer);
drawer._updateViewport(m_pBuffer);
textureCache().activateTexture(0, m_pTexture);
// Disable filtering to avoid black outlines

View File

@ -826,18 +826,6 @@ void gSPProcessVertex(u32 v, SPVertex * spVtx)
vtx.w *= adjustScale;
}
}
if (gSP.viewport.vscale[0] < 0) {
for(int i = 0; i < VNUM; ++i) {
SPVertex & vtx = spVtx[v+i];
vtx.x = -vtx.x;
}
}
if (gSP.viewport.vscale[1] < 0) {
for(int i = 0; i < VNUM; ++i) {
SPVertex & vtx = spVtx[v+i];
vtx.y = -vtx.y;
}
}
if (gSP.matrix.billboard)
gSPBillboardVertex<VNUM>(v, spVtx);
@ -1670,32 +1658,22 @@ void gSPModifyVertex( u32 _vtx, u32 _where, u32 _val )
case G_MWO_POINT_XYSCREEN:
vtx0.x = _FIXED2FLOAT((s16)_SHIFTR(_val, 16, 16), 2);
vtx0.y = _FIXED2FLOAT((s16)_SHIFTR(_val, 0, 16), 2);
DebugMsg(DEBUG_NORMAL, "gSPModifyVertex: XY(%02f, %02f);\n", vtx0.x, vtx0.y);
vtx0.modify |= MODIFY_XY;
vtx0.clip &= ~(CLIP_POSX | CLIP_NEGX | CLIP_POSY | CLIP_NEGY);
if ((config.generalEmulation.hacks & hack_ModifyVertexXyInShader) == 0) {
vtx0.x = (vtx0.x - gSP.viewport.vtrans[0]) / gSP.viewport.vscale[0];
if (gSP.viewport.vscale[0] < 0)
vtx0.x = -vtx0.x;
vtx0.x *= vtx0.w;
if (dwnd().isAdjustScreen()) {
const f32 adjustScale = dwnd().getAdjustScale();
vtx0.x *= adjustScale;
if (gSP.matrix.projection[3][2] == -1.f)
vtx0.w *= adjustScale;
}
vtx0.y = -(vtx0.y - gSP.viewport.vtrans[1]) / gSP.viewport.vscale[1];
if (gSP.viewport.vscale[1] < 0)
vtx0.y = -vtx0.y;
vtx0.y *= vtx0.w;
} else {
vtx0.modify |= MODIFY_XY;
if (vtx0.w == 0.0f || gDP.otherMode.depthSource == G_ZS_PRIM) {
vtx0.w = 1.0f;
vtx0.clip &= ~(CLIP_W);
}
}
vtx0.clip &= ~(CLIP_POSX | CLIP_NEGX | CLIP_POSY | CLIP_NEGY);
DebugMsg(DEBUG_NORMAL, "gSPModifyVertex: XY(%02f, %02f);\n", vtx0.x, vtx0.y);
break;
case G_MWO_POINT_ZSCREEN:
{