mirror of
https://github.com/simple64/simple64.git
synced 2026-11-13 13:38:42 +01:00
update gliden64
This commit is contained in:
1 parent
525b136e9c
commit
d753e48ca1
28 files changed
+590
-441
No files matched your search
@@ -12,17 +12,6 @@
|
||||
#include "Log.h"
|
||||
#include "MemoryStatus.h"
|
||||
|
||||
/*
|
||||
#include "ColorBufferToRDRAM_GL.h"
|
||||
#include "ColorBufferToRDRAM_BufferStorageExt.h"
|
||||
#elif defined(OS_ANDROID) && defined (GLES2)
|
||||
#include "ColorBufferToRDRAM_GL.h"
|
||||
#include "ColorBufferToRDRAM_GLES.h"
|
||||
#else
|
||||
#include "ColorBufferToRDRAMStub.h"
|
||||
#endif
|
||||
*/
|
||||
|
||||
#include <Graphics/Context.h>
|
||||
#include <Graphics/Parameters.h>
|
||||
#include <Graphics/ColorBufferReader.h>
|
||||
@@ -32,16 +21,10 @@
|
||||
using namespace graphics;
|
||||
|
||||
ColorBufferToRDRAM::ColorBufferToRDRAM()
|
||||
: m_FBO(0)
|
||||
, m_pTexture(nullptr)
|
||||
, m_pCurFrameBuffer(nullptr)
|
||||
: m_pCurFrameBuffer(nullptr)
|
||||
, m_frameCount(-1)
|
||||
, m_startAddress(-1)
|
||||
, m_lastBufferWidth(-1)
|
||||
{
|
||||
m_allowedRealWidths[0] = 320;
|
||||
m_allowedRealWidths[1] = 480;
|
||||
m_allowedRealWidths[2] = 640;
|
||||
}
|
||||
|
||||
u32 ColorBufferToRDRAM::m_blueNoiseIdx = 0;
|
||||
@@ -52,88 +35,10 @@ ColorBufferToRDRAM::~ColorBufferToRDRAM()
|
||||
|
||||
void ColorBufferToRDRAM::init()
|
||||
{
|
||||
m_FBO = gfxContext.createFramebuffer();
|
||||
}
|
||||
|
||||
void ColorBufferToRDRAM::destroy() {
|
||||
_destroyFBTexure();
|
||||
|
||||
if (m_FBO.isNotNull()) {
|
||||
gfxContext.deleteFramebuffer(m_FBO);
|
||||
m_FBO.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void ColorBufferToRDRAM::_initFBTexture(void)
|
||||
{
|
||||
const FramebufferTextureFormats & fbTexFormat = gfxContext.getFramebufferTextureFormats();
|
||||
|
||||
m_pTexture = textureCache().addFrameBufferTexture(Context::EglImage ? textureTarget::TEXTURE_EXTERNAL : textureTarget::TEXTURE_2D);
|
||||
m_pTexture->format = G_IM_FMT_RGBA;
|
||||
m_pTexture->size = 2;
|
||||
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;
|
||||
//The actual VI width is not used for texture width because most texture widths
|
||||
//cause slowdowns in the glReadPixels call, at least on Android
|
||||
m_pTexture->width = m_lastBufferWidth;
|
||||
m_pTexture->height = VI_GetMaxBufferHeight(m_lastBufferWidth);
|
||||
m_pTexture->textureBytes = m_pTexture->width * m_pTexture->height * fbTexFormat.colorFormatBytes;
|
||||
|
||||
|
||||
m_bufferReader.reset(gfxContext.createColorBufferReader(m_pTexture));
|
||||
|
||||
// Skip this since texture is initialized in the EGL color buffer reader
|
||||
if (!Context::EglImage)
|
||||
{
|
||||
Context::InitTextureParams params;
|
||||
params.handle = m_pTexture->name;
|
||||
params.target = textureTarget::TEXTURE_2D;
|
||||
params.width = m_pTexture->width;
|
||||
params.height = m_pTexture->height;
|
||||
params.internalFormat = fbTexFormat.colorInternalFormat;
|
||||
params.format = fbTexFormat.colorFormat;
|
||||
params.dataType = fbTexFormat.colorType;
|
||||
gfxContext.init2DTexture(params);
|
||||
}
|
||||
|
||||
{
|
||||
Context::TexParameters params;
|
||||
params.handle = m_pTexture->name;
|
||||
params.target = Context::EglImage ? textureTarget::TEXTURE_EXTERNAL : textureTarget::TEXTURE_2D;
|
||||
params.textureUnitIndex = textureIndices::Tex[0];
|
||||
params.minFilter = textureParameters::FILTER_LINEAR;
|
||||
params.magFilter = textureParameters::FILTER_LINEAR;
|
||||
gfxContext.setTextureParameters(params);
|
||||
}
|
||||
{
|
||||
Context::FrameBufferRenderTarget bufTarget;
|
||||
bufTarget.bufferHandle = ObjectHandle(m_FBO);
|
||||
bufTarget.bufferTarget = bufferTarget::DRAW_FRAMEBUFFER;
|
||||
bufTarget.attachment = bufferAttachment::COLOR_ATTACHMENT0;
|
||||
bufTarget.textureTarget = Context::EglImageFramebuffer ? textureTarget::TEXTURE_EXTERNAL : textureTarget::TEXTURE_2D;
|
||||
bufTarget.textureHandle = m_pTexture->name;
|
||||
gfxContext.addFrameBufferRenderTarget(bufTarget);
|
||||
}
|
||||
|
||||
// check if everything is OK
|
||||
assert(!gfxContext.isFramebufferError());
|
||||
|
||||
gfxContext.bindFramebuffer(graphics::bufferTarget::DRAW_FRAMEBUFFER, graphics::ObjectHandle::defaultFramebuffer);
|
||||
}
|
||||
|
||||
void ColorBufferToRDRAM::_destroyFBTexure(void)
|
||||
{
|
||||
m_bufferReader.reset();
|
||||
|
||||
if (m_pTexture != nullptr) {
|
||||
textureCache().removeFrameBufferTexture(m_pTexture);
|
||||
m_pTexture = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool ColorBufferToRDRAM::_prepareCopy(u32& _startAddress)
|
||||
@@ -164,15 +69,7 @@ bool ColorBufferToRDRAM::_prepareCopy(u32& _startAddress)
|
||||
if (bufferHeight == 0)
|
||||
return false;
|
||||
|
||||
if(m_pTexture == nullptr ||
|
||||
m_pTexture->width != _getRealWidth(pBuffer->m_width) ||
|
||||
m_pTexture->height != VI_GetMaxBufferHeight(_getRealWidth(pBuffer->m_width)))
|
||||
{
|
||||
_destroyFBTexure();
|
||||
|
||||
m_lastBufferWidth = _getRealWidth(pBuffer->m_width);
|
||||
_initFBTexture();
|
||||
}
|
||||
CachedTexture* colorBufferTexture = pBuffer->getColorFbTexture();
|
||||
|
||||
m_pCurFrameBuffer = pBuffer;
|
||||
|
||||
@@ -190,47 +87,43 @@ bool ColorBufferToRDRAM::_prepareCopy(u32& _startAddress)
|
||||
readBuffer = m_pCurFrameBuffer->m_FBO;
|
||||
}
|
||||
|
||||
if (m_pCurFrameBuffer->m_scale != 1.0f) {
|
||||
u32 x0 = 0;
|
||||
u32 width;
|
||||
if (config.frameBufferEmulation.nativeResFactor == 0) {
|
||||
const u32 screenWidth = wnd.getWidth();
|
||||
width = screenWidth;
|
||||
if (wnd.isAdjustScreen()) {
|
||||
width = static_cast<u32>(screenWidth*wnd.getAdjustScale());
|
||||
x0 = (screenWidth - width) / 2;
|
||||
}
|
||||
} else {
|
||||
width = m_pCurFrameBuffer->m_pTexture->width;
|
||||
u32 x0 = 0;
|
||||
u32 width;
|
||||
if (config.frameBufferEmulation.nativeResFactor == 0) {
|
||||
const u32 screenWidth = wnd.getWidth();
|
||||
width = screenWidth;
|
||||
if (wnd.isAdjustScreen()) {
|
||||
width = static_cast<u32>(screenWidth*wnd.getAdjustScale());
|
||||
x0 = (screenWidth - width) / 2;
|
||||
}
|
||||
u32 height = (u32)(bufferHeight * m_pCurFrameBuffer->m_scale);
|
||||
|
||||
CachedTexture * pInputTexture = m_pCurFrameBuffer->m_pTexture;
|
||||
GraphicsDrawer::BlitOrCopyRectParams blitParams;
|
||||
blitParams.srcX0 = x0;
|
||||
blitParams.srcY0 = 0;
|
||||
blitParams.srcX1 = x0 + width;
|
||||
blitParams.srcY1 = height;
|
||||
blitParams.srcWidth = pInputTexture->width;
|
||||
blitParams.srcHeight = pInputTexture->height;
|
||||
blitParams.dstX0 = 0;
|
||||
blitParams.dstY0 = 0;
|
||||
blitParams.dstX1 = m_pCurFrameBuffer->m_width;
|
||||
blitParams.dstY1 = bufferHeight;
|
||||
blitParams.dstWidth = m_pTexture->width;
|
||||
blitParams.dstHeight = m_pTexture->height;
|
||||
blitParams.filter = textureParameters::FILTER_LINEAR;
|
||||
blitParams.tex[0] = pInputTexture;
|
||||
blitParams.combiner = CombinerInfo::get().getTexrectDownscaleCopyProgram();
|
||||
blitParams.readBuffer = readBuffer;
|
||||
blitParams.drawBuffer = m_FBO;
|
||||
blitParams.mask = blitMask::COLOR_BUFFER;
|
||||
wnd.getDrawer().blitOrCopyTexturedRect(blitParams);
|
||||
|
||||
gfxContext.bindFramebuffer(bufferTarget::READ_FRAMEBUFFER, m_FBO);
|
||||
} else {
|
||||
gfxContext.bindFramebuffer(bufferTarget::READ_FRAMEBUFFER, readBuffer);
|
||||
width = m_pCurFrameBuffer->m_pTexture->width;
|
||||
}
|
||||
u32 height = (u32)(bufferHeight * m_pCurFrameBuffer->m_scale);
|
||||
|
||||
CachedTexture * pInputTexture = m_pCurFrameBuffer->m_pTexture;
|
||||
GraphicsDrawer::BlitOrCopyRectParams blitParams;
|
||||
blitParams.srcX0 = x0;
|
||||
blitParams.srcY0 = 0;
|
||||
blitParams.srcX1 = x0 + width;
|
||||
blitParams.srcY1 = height;
|
||||
blitParams.srcWidth = pInputTexture->width;
|
||||
blitParams.srcHeight = pInputTexture->height;
|
||||
blitParams.dstX0 = 0;
|
||||
blitParams.dstY0 = 0;
|
||||
blitParams.dstX1 = m_pCurFrameBuffer->m_width;
|
||||
blitParams.dstY1 = bufferHeight;
|
||||
blitParams.dstWidth = colorBufferTexture->width;
|
||||
blitParams.dstHeight = colorBufferTexture->height;
|
||||
blitParams.filter = m_pCurFrameBuffer->m_scale == 1.0f ? textureParameters::FILTER_NEAREST : textureParameters::FILTER_LINEAR;
|
||||
blitParams.tex[0] = pInputTexture;
|
||||
blitParams.combiner = CombinerInfo::get().getTexrectDownscaleCopyProgram();
|
||||
blitParams.readBuffer = readBuffer;
|
||||
blitParams.drawBuffer = pBuffer->getColorFbFbo();
|
||||
blitParams.mask = blitMask::COLOR_BUFFER;
|
||||
wnd.getDrawer().blitOrCopyTexturedRect(blitParams);
|
||||
|
||||
gfxContext.bindFramebuffer(bufferTarget::READ_FRAMEBUFFER, pBuffer->getColorFbFbo());
|
||||
|
||||
m_frameCount = curFrame;
|
||||
m_startAddress = _startAddress;
|
||||
@@ -312,7 +205,7 @@ void ColorBufferToRDRAM::_copy(u32 _startAddress, u32 _endAddress, bool _sync)
|
||||
const u32 y1 = (_endAddress - m_pCurFrameBuffer->m_startAddress) / stride;
|
||||
const u32 height = std::min(max_height, 1u + y1 - y0);
|
||||
|
||||
const u8* pPixels = m_bufferReader->readPixels(x0, y0, width, height, m_pCurFrameBuffer->m_size, _sync);
|
||||
const u8* pPixels = m_pCurFrameBuffer->readPixels(x0, y0, width, height, m_pCurFrameBuffer->m_size, _sync);
|
||||
frameBufferList().setCurrentDrawBuffer();
|
||||
if (pPixels == nullptr)
|
||||
return;
|
||||
@@ -336,23 +229,11 @@ void ColorBufferToRDRAM::_copy(u32 _startAddress, u32 _endAddress, bool _sync)
|
||||
m_pCurFrameBuffer->copyRdram();
|
||||
m_pCurFrameBuffer->m_cleared = false;
|
||||
|
||||
m_bufferReader->cleanUp();
|
||||
m_pCurFrameBuffer->cleanUp();
|
||||
|
||||
gDP.changed |= CHANGED_SCISSOR;
|
||||
}
|
||||
|
||||
u32 ColorBufferToRDRAM::_getRealWidth(u32 _viWidth)
|
||||
{
|
||||
u32 index = 0;
|
||||
const u32 maxIndex = static_cast<u32>(m_allowedRealWidths.size()) - 1;
|
||||
while (index < maxIndex && _viWidth > m_allowedRealWidths[index])
|
||||
{
|
||||
++index;
|
||||
}
|
||||
|
||||
return m_allowedRealWidths[index];
|
||||
}
|
||||
|
||||
void ColorBufferToRDRAM::copyToRDRAM(u32 _address, bool _sync)
|
||||
{
|
||||
if (!isMemoryWritable(RDRAM + _address, gDP.colorImage.width << gDP.colorImage.size >> 1))
|
||||
|
||||
@@ -29,8 +29,6 @@ private:
|
||||
ColorBufferToRDRAM(const ColorBufferToRDRAM &) = delete;
|
||||
virtual ~ColorBufferToRDRAM();
|
||||
|
||||
CachedTexture * m_pTexture;
|
||||
|
||||
union RGBA {
|
||||
struct {
|
||||
u8 r, g, b, a;
|
||||
@@ -38,32 +36,20 @@ private:
|
||||
u32 raw;
|
||||
};
|
||||
|
||||
void _initFBTexture(void);
|
||||
|
||||
void _destroyFBTexure(void);
|
||||
|
||||
bool _prepareCopy(u32& _startAddress);
|
||||
|
||||
void _copy(u32 _startAddress, u32 _endAddress, bool _sync);
|
||||
|
||||
u32 _getRealWidth(u32 _viWidth);
|
||||
|
||||
// Convert pixel from video memory to N64 buffer format.
|
||||
static u8 _RGBAtoR8(u8 _c, u32 x, u32 y);
|
||||
static u16 _RGBAtoRGBA16(u32 _c, u32 x, u32 y);
|
||||
static u32 _RGBAtoRGBA32(u32 _c, u32 x, u32 y);
|
||||
|
||||
graphics::ObjectHandle m_FBO;
|
||||
FrameBuffer * m_pCurFrameBuffer;
|
||||
u32 m_frameCount;
|
||||
u32 m_startAddress;
|
||||
|
||||
u32 m_lastBufferWidth;
|
||||
|
||||
static u32 m_blueNoiseIdx;
|
||||
|
||||
std::array<u32, 3> m_allowedRealWidths;
|
||||
std::unique_ptr<graphics::ColorBufferReader> m_bufferReader;
|
||||
};
|
||||
|
||||
void copyWhiteToRDRAM(FrameBuffer * _pBuffer);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -64,6 +64,7 @@ void Config::resetToDefaults()
|
||||
graphics2D.correctTexrectCoords = tcDisable;
|
||||
graphics2D.enableNativeResTexrects = NativeResTexrectsMode::ntDisable;
|
||||
graphics2D.bgMode = BGMode::bgStripped;
|
||||
graphics2D.enableTexCoordBounds = 0;
|
||||
|
||||
frameBufferEmulation.enable = 1;
|
||||
frameBufferEmulation.copyDepthToRDRAM = cdSoftwareRender;
|
||||
@@ -173,6 +174,10 @@ const char* Config::hotkeyIniName(u32 _idx)
|
||||
return "hkHdTexReload";
|
||||
case Config::HotKey::hkHdTexToggle:
|
||||
return "hkHdTexToggle";
|
||||
case Config::HotKey::hkTexCoordBounds:
|
||||
return "hkTexCoordBounds";
|
||||
case Config::HotKey::hkNativeResTexrects:
|
||||
return "hkNativeResTexrects";
|
||||
case Config::HotKey::hkVsync:
|
||||
return "hkVsync";
|
||||
case Config::HotKey::hkFBEmulation:
|
||||
|
||||
@@ -92,6 +92,7 @@ struct Config
|
||||
u32 correctTexrectCoords;
|
||||
u32 enableNativeResTexrects;
|
||||
u32 bgMode;
|
||||
u32 enableTexCoordBounds;
|
||||
} graphics2D;
|
||||
|
||||
enum Aspect {
|
||||
@@ -221,6 +222,8 @@ struct Config
|
||||
hkTexDump = 0,
|
||||
hkHdTexReload,
|
||||
hkHdTexToggle,
|
||||
hkTexCoordBounds,
|
||||
hkNativeResTexrects,
|
||||
hkVsync,
|
||||
hkFBEmulation,
|
||||
hkN64DepthCompare,
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "gSP.h"
|
||||
#include "Combiner.h"
|
||||
#include "ClipPolygon.h"
|
||||
#include "DisplayWindow.h"
|
||||
|
||||
/*
|
||||
* vbp is a pointer to a vertex array. The first 3 vertices in that
|
||||
@@ -289,6 +290,7 @@ void clipInHomogeneousSpace(SPVertex * _pVertices, std::vector<SPVertex> & _vRes
|
||||
const bool usesColor = pCurrCmb->usesShade();
|
||||
const bool usesTexture = pCurrCmb->usesTexture();
|
||||
const float wScale = static_cast<float>(gSP.clipRatio);
|
||||
const float xScale = dwnd().getAdjustScale();
|
||||
|
||||
auto clipVertex = [usesColor, usesTexture](SPVertex const* src, SPVertex * dst, float t)
|
||||
{
|
||||
@@ -363,10 +365,10 @@ void clipInHomogeneousSpace(SPVertex * _pVertices, std::vector<SPVertex> & _vRes
|
||||
|
||||
switch (_clipPlane) {
|
||||
case 1:
|
||||
visible = -pVertex->w * wScale <= pVertex->x;
|
||||
visible = -pVertex->w * wScale <= pVertex->x * xScale;
|
||||
break;
|
||||
case 2:
|
||||
visible = pVertex->x <= pVertex->w * wScale;
|
||||
visible = pVertex->x * xScale <= pVertex->w * wScale;
|
||||
break;
|
||||
case 3:
|
||||
visible = -pVertex->w * wScale <= pVertex->y;
|
||||
@@ -402,36 +404,49 @@ void clipInHomogeneousSpace(SPVertex * _pVertices, std::vector<SPVertex> & _vRes
|
||||
SPVertex *Vertex3 = _pVertices + fifocp;
|
||||
|
||||
float t1, t2;
|
||||
const float scaledW1 = Vertex1->w * wScale;
|
||||
const float scaledW2 = Vertex2->w * wScale;
|
||||
const float scaledW3 = Vertex3->w * wScale;
|
||||
|
||||
switch (_clipPlane) {
|
||||
case 1:
|
||||
t1 = (Vertex1->x + Vertex1->w * wScale) / (Vertex1->x - Vertex3->x + Vertex1->w * wScale - Vertex3->w * wScale);
|
||||
t2 = (Vertex2->x + Vertex2->w * wScale) / (Vertex2->x - Vertex3->x + Vertex2->w * wScale - Vertex3->w * wScale);
|
||||
{
|
||||
const float scaledX1 = Vertex1->x * xScale;
|
||||
const float scaledX2 = Vertex2->x * xScale;
|
||||
const float scaledX3 = Vertex3->x * xScale;
|
||||
t1 = (scaledX1 + scaledW1) / (scaledX1 - scaledX3 + scaledW1 - scaledW3);
|
||||
t2 = (scaledX2 + scaledW2) / (scaledX2 - scaledX3 + scaledW2 - scaledW3);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
t1 = (Vertex1->x - Vertex1->w * wScale) / (Vertex1->x - Vertex3->x - Vertex1->w * wScale + Vertex3->w * wScale);
|
||||
t2 = (Vertex2->x - Vertex2->w * wScale) / (Vertex2->x - Vertex3->x - Vertex2->w * wScale + Vertex3->w * wScale);
|
||||
{
|
||||
const float scaledX1 = Vertex1->x * xScale;
|
||||
const float scaledX2 = Vertex2->x * xScale;
|
||||
const float scaledX3 = Vertex3->x * xScale;
|
||||
t1 = (scaledX1 - scaledW1) / (scaledX1 - scaledX3 - scaledW1 + scaledW3);
|
||||
t2 = (scaledX2 - scaledW2) / (scaledX2 - scaledX3 - scaledW2 + scaledW3);
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
t1 = (Vertex1->y + Vertex1->w * wScale) / (Vertex1->y - Vertex3->y + Vertex1->w * wScale - Vertex3->w * wScale);
|
||||
t2 = (Vertex2->y + Vertex2->w * wScale) / (Vertex2->y - Vertex3->y + Vertex2->w * wScale - Vertex3->w * wScale);
|
||||
t1 = (Vertex1->y + scaledW1) / (Vertex1->y - Vertex3->y + scaledW1 - scaledW3);
|
||||
t2 = (Vertex2->y + scaledW2) / (Vertex2->y - Vertex3->y + scaledW2 - scaledW3);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
t1 = (Vertex1->y - Vertex1->w * wScale) / (Vertex1->y - Vertex3->y - Vertex1->w * wScale + Vertex3->w * wScale);
|
||||
t2 = (Vertex2->y - Vertex2->w * wScale) / (Vertex2->y - Vertex3->y - Vertex2->w * wScale + Vertex3->w * wScale);
|
||||
t1 = (Vertex1->y - scaledW1) / (Vertex1->y - Vertex3->y - scaledW1 + scaledW3);
|
||||
t2 = (Vertex2->y - scaledW2) / (Vertex2->y - Vertex3->y - scaledW2 + scaledW3);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
t1 = (Vertex1->z + Vertex1->w * wScale) / (Vertex1->z - Vertex3->z + Vertex1->w * wScale - Vertex3->w * wScale);
|
||||
t2 = (Vertex2->z + Vertex2->w * wScale) / (Vertex2->z - Vertex3->z + Vertex2->w * wScale - Vertex3->w * wScale);
|
||||
t1 = (Vertex1->z + scaledW1) / (Vertex1->z - Vertex3->z + scaledW1 - scaledW3);
|
||||
t2 = (Vertex2->z + scaledW2) / (Vertex2->z - Vertex3->z + scaledW2 - scaledW3);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
t1 = (Vertex1->z - Vertex1->w * wScale) / (Vertex1->z - Vertex3->z - Vertex1->w * wScale + Vertex3->w * wScale);
|
||||
t2 = (Vertex2->z - Vertex2->w * wScale) / (Vertex2->z - Vertex3->z - Vertex2->w * wScale + Vertex3->w * wScale);
|
||||
t1 = (Vertex1->z - scaledW1) / (Vertex1->z - Vertex3->z - scaledW1 + scaledW3);
|
||||
t2 = (Vertex2->z - scaledW2) / (Vertex2->z - Vertex3->z - scaledW2 + scaledW3);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -453,36 +468,49 @@ void clipInHomogeneousSpace(SPVertex * _pVertices, std::vector<SPVertex> & _vRes
|
||||
SPVertex *NewVertex3 = NewVertices + fbcp;
|
||||
|
||||
float t1, t2;
|
||||
const float scaledW1 = Vertex1->w * wScale;
|
||||
const float scaledW2 = Vertex2->w * wScale;
|
||||
const float scaledW3 = Vertex3->w * wScale;
|
||||
|
||||
switch (_clipPlane) {
|
||||
case 1:
|
||||
t1 = (Vertex3->x + Vertex3->w * wScale) / (Vertex3->x - Vertex1->x + Vertex3->w * wScale - Vertex1->w * wScale);
|
||||
t2 = (Vertex3->x + Vertex3->w * wScale) / (Vertex3->x - Vertex2->x + Vertex3->w * wScale - Vertex2->w * wScale);
|
||||
{
|
||||
const float scaledX1 = Vertex1->x * xScale;
|
||||
const float scaledX2 = Vertex2->x * xScale;
|
||||
const float scaledX3 = Vertex3->x * xScale;
|
||||
t1 = (scaledX3 + scaledW3) / (scaledX3 - scaledX1 + scaledW3 - scaledW1);
|
||||
t2 = (scaledX3 + scaledW3) / (scaledX3 - scaledX2 + scaledW3 - scaledW2);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
t1 = (Vertex3->x - Vertex3->w * wScale) / (Vertex3->x - Vertex1->x - Vertex3->w * wScale + Vertex1->w * wScale);
|
||||
t2 = (Vertex3->x - Vertex3->w * wScale) / (Vertex3->x - Vertex2->x - Vertex3->w * wScale + Vertex2->w * wScale);
|
||||
{
|
||||
const float scaledX1 = Vertex1->x * xScale;
|
||||
const float scaledX2 = Vertex2->x * xScale;
|
||||
const float scaledX3 = Vertex3->x * xScale;
|
||||
t1 = (scaledX3 - scaledW3) / (scaledX3 - scaledX1 - scaledW3 + scaledW1);
|
||||
t2 = (scaledX3 - scaledW3) / (scaledX3 - scaledX2 - scaledW3 + scaledW2);
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
t1 = (Vertex3->y + Vertex3->w * wScale) / (Vertex3->y - Vertex1->y + Vertex3->w * wScale - Vertex1->w * wScale);
|
||||
t2 = (Vertex3->y + Vertex3->w * wScale) / (Vertex3->y - Vertex2->y + Vertex3->w * wScale - Vertex2->w * wScale);
|
||||
t1 = (Vertex3->y + scaledW3) / (Vertex3->y - Vertex1->y + scaledW3 - scaledW1);
|
||||
t2 = (Vertex3->y + scaledW3) / (Vertex3->y - Vertex2->y + scaledW3 - scaledW2);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
t1 = (Vertex3->y - Vertex3->w * wScale) / (Vertex3->y - Vertex1->y - Vertex3->w * wScale + Vertex1->w * wScale);
|
||||
t2 = (Vertex3->y - Vertex3->w * wScale) / (Vertex3->y - Vertex2->y - Vertex3->w * wScale + Vertex2->w * wScale);
|
||||
t1 = (Vertex3->y - scaledW3) / (Vertex3->y - Vertex1->y - scaledW3 + scaledW1);
|
||||
t2 = (Vertex3->y - scaledW3) / (Vertex3->y - Vertex2->y - scaledW3 + scaledW2);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
t1 = (Vertex3->z + Vertex3->w * wScale) / (Vertex3->z - Vertex1->z + Vertex3->w * wScale - Vertex1->w * wScale);
|
||||
t2 = (Vertex3->z + Vertex3->w * wScale) / (Vertex3->z - Vertex2->z + Vertex3->w * wScale - Vertex2->w * wScale);
|
||||
t1 = (Vertex3->z + scaledW3) / (Vertex3->z - Vertex1->z + scaledW3 - scaledW1);
|
||||
t2 = (Vertex3->z + scaledW3) / (Vertex3->z - Vertex2->z + scaledW3 - scaledW2);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
t1 = (Vertex3->z - Vertex3->w * wScale) / (Vertex3->z - Vertex1->z - Vertex3->w * wScale + Vertex1->w * wScale);
|
||||
t2 = (Vertex3->z - Vertex3->w * wScale) / (Vertex3->z - Vertex2->z - Vertex3->w * wScale + Vertex2->w * wScale);
|
||||
t1 = (Vertex3->z - scaledW3) / (Vertex3->z - Vertex1->z - scaledW3 + scaledW1);
|
||||
t2 = (Vertex3->z - scaledW3) / (Vertex3->z - Vertex2->z - scaledW3 + scaledW2);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -63,9 +63,9 @@ protected:
|
||||
u32 m_resizeWidth = 0;
|
||||
u32 m_resizeHeight = 0;
|
||||
u32 m_maxMsaa = 0;
|
||||
f32 m_scaleX = 0;
|
||||
f32 m_scaleY = 0;
|
||||
f32 m_adjustScale = 0;
|
||||
f32 m_scaleX = 0.0f;
|
||||
f32 m_scaleY = 0.0f;
|
||||
f32 m_adjustScale = 1.0f;
|
||||
|
||||
wchar_t m_strScreenDirectory[PLUGIN_PATH_SIZE];
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include <Graphics/Context.h>
|
||||
#include <Graphics/Parameters.h>
|
||||
#include <Graphics/ColorBufferReader.h>
|
||||
#include "DisplayWindow.h"
|
||||
|
||||
using namespace std;
|
||||
@@ -32,6 +33,8 @@ using namespace graphics;
|
||||
|
||||
FrameBuffer::FrameBuffer()
|
||||
: m_copyFBO(ObjectHandle::defaultFramebuffer)
|
||||
, m_ColorBufferFBO(0)
|
||||
, m_pColorBufferTexture(nullptr)
|
||||
{
|
||||
m_pTexture = textureCache().addFrameBufferTexture(config.video.multisampling != 0 ?
|
||||
textureTarget::TEXTURE_2D_MULTISAMPLE : textureTarget::TEXTURE_2D);
|
||||
@@ -54,6 +57,8 @@ FrameBuffer::~FrameBuffer()
|
||||
textureCache().removeFrameBufferTexture(m_pResolveTexture);
|
||||
textureCache().removeFrameBufferTexture(m_pSubTexture);
|
||||
textureCache().removeFrameBufferTexture(m_pFrameBufferCopyTexture);
|
||||
|
||||
_destroyColorFBTexure();
|
||||
}
|
||||
|
||||
static
|
||||
@@ -529,6 +534,110 @@ CachedTexture * FrameBuffer::getTextureBG()
|
||||
return pTexture;
|
||||
}
|
||||
|
||||
CachedTexture * FrameBuffer::getColorFbTexture()
|
||||
{
|
||||
if(m_pColorBufferTexture == nullptr ||
|
||||
m_pColorBufferTexture->width != m_width ||
|
||||
m_pColorBufferTexture->height != VI_GetMaxBufferHeight(m_width))
|
||||
{
|
||||
_destroyColorFBTexure();
|
||||
_initColorFBTexture(m_width);
|
||||
}
|
||||
|
||||
return m_pColorBufferTexture;
|
||||
}
|
||||
|
||||
graphics::ObjectHandle FrameBuffer::getColorFbFbo()
|
||||
{
|
||||
return m_ColorBufferFBO;
|
||||
}
|
||||
|
||||
const u8 * FrameBuffer::readPixels(s32 _x0, s32 _y0, u32 _width, u32 _height, u32 _size, bool _sync)
|
||||
{
|
||||
return m_bufferReader->readPixels(_x0, _y0, _width, _height, _size, _sync);
|
||||
}
|
||||
|
||||
void FrameBuffer::cleanUp()
|
||||
{
|
||||
m_bufferReader->cleanUp();
|
||||
}
|
||||
|
||||
void FrameBuffer::_initColorFBTexture(int _width)
|
||||
{
|
||||
m_ColorBufferFBO = gfxContext.createFramebuffer();
|
||||
|
||||
const FramebufferTextureFormats & fbTexFormat = gfxContext.getFramebufferTextureFormats();
|
||||
|
||||
m_pColorBufferTexture = textureCache().addFrameBufferTexture(Context::EglImage ? textureTarget::TEXTURE_EXTERNAL : textureTarget::TEXTURE_2D);
|
||||
m_pColorBufferTexture->format = G_IM_FMT_RGBA;
|
||||
m_pColorBufferTexture->size = 2;
|
||||
m_pColorBufferTexture->clampS = 1;
|
||||
m_pColorBufferTexture->clampT = 1;
|
||||
m_pColorBufferTexture->frameBufferTexture = CachedTexture::fbOneSample;
|
||||
m_pColorBufferTexture->maskS = 0;
|
||||
m_pColorBufferTexture->maskT = 0;
|
||||
m_pColorBufferTexture->mirrorS = 0;
|
||||
m_pColorBufferTexture->mirrorT = 0;
|
||||
m_pColorBufferTexture->width = _width;
|
||||
m_pColorBufferTexture->height = VI_GetMaxBufferHeight(_width);
|
||||
m_pColorBufferTexture->textureBytes = m_pColorBufferTexture->width * m_pColorBufferTexture->height * fbTexFormat.colorFormatBytes;
|
||||
|
||||
m_bufferReader.reset(gfxContext.createColorBufferReader(m_pColorBufferTexture));
|
||||
|
||||
// Skip this since texture is initialized in the EGL color buffer reader
|
||||
if (!Context::EglImage)
|
||||
{
|
||||
Context::InitTextureParams params;
|
||||
params.handle = m_pColorBufferTexture->name;
|
||||
params.target = textureTarget::TEXTURE_2D;
|
||||
params.width = m_pColorBufferTexture->width;
|
||||
params.height = m_pColorBufferTexture->height;
|
||||
params.internalFormat = fbTexFormat.colorInternalFormat;
|
||||
params.format = fbTexFormat.colorFormat;
|
||||
params.dataType = fbTexFormat.colorType;
|
||||
gfxContext.init2DTexture(params);
|
||||
}
|
||||
|
||||
{
|
||||
Context::TexParameters params;
|
||||
params.handle = m_pColorBufferTexture->name;
|
||||
params.target = Context::EglImage ? textureTarget::TEXTURE_EXTERNAL : textureTarget::TEXTURE_2D;
|
||||
params.textureUnitIndex = textureIndices::Tex[0];
|
||||
params.minFilter = textureParameters::FILTER_LINEAR;
|
||||
params.magFilter = textureParameters::FILTER_LINEAR;
|
||||
gfxContext.setTextureParameters(params);
|
||||
}
|
||||
{
|
||||
Context::FrameBufferRenderTarget bufTarget;
|
||||
bufTarget.bufferHandle = ObjectHandle(m_ColorBufferFBO);
|
||||
bufTarget.bufferTarget = bufferTarget::DRAW_FRAMEBUFFER;
|
||||
bufTarget.attachment = bufferAttachment::COLOR_ATTACHMENT0;
|
||||
bufTarget.textureTarget = Context::EglImageFramebuffer ? textureTarget::TEXTURE_EXTERNAL : textureTarget::TEXTURE_2D;
|
||||
bufTarget.textureHandle = m_pColorBufferTexture->name;
|
||||
gfxContext.addFrameBufferRenderTarget(bufTarget);
|
||||
}
|
||||
|
||||
// check if everything is OK
|
||||
assert(!gfxContext.isFramebufferError());
|
||||
|
||||
gfxContext.bindFramebuffer(graphics::bufferTarget::DRAW_FRAMEBUFFER, graphics::ObjectHandle::defaultFramebuffer);
|
||||
}
|
||||
|
||||
void FrameBuffer::_destroyColorFBTexure()
|
||||
{
|
||||
m_bufferReader.reset();
|
||||
|
||||
if (m_pColorBufferTexture != nullptr) {
|
||||
textureCache().removeFrameBufferTexture(m_pColorBufferTexture);
|
||||
m_pColorBufferTexture = nullptr;
|
||||
}
|
||||
|
||||
if (m_ColorBufferFBO.isNotNull()) {
|
||||
gfxContext.deleteFramebuffer(m_ColorBufferFBO);
|
||||
m_ColorBufferFBO.reset();
|
||||
}
|
||||
}
|
||||
|
||||
FrameBufferList & FrameBufferList::get()
|
||||
{
|
||||
static FrameBufferList frameBufferList;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include "gDP.h"
|
||||
#include "Textures.h"
|
||||
@@ -13,6 +14,10 @@ struct DepthBuffer;
|
||||
|
||||
const u32 fingerprint[4] = { 2, 6, 4, 3 };
|
||||
|
||||
namespace graphics {
|
||||
class ColorBufferReader;
|
||||
}
|
||||
|
||||
struct FrameBuffer
|
||||
{
|
||||
FrameBuffer();
|
||||
@@ -28,6 +33,10 @@ struct FrameBuffer
|
||||
void setDirty();
|
||||
bool isValid(bool _forceCheck) const;
|
||||
bool isAuxiliary() const;
|
||||
CachedTexture * getColorFbTexture();
|
||||
graphics::ObjectHandle getColorFbFbo();
|
||||
const u8 * readPixels(s32 _x0, s32 _y0, u32 _width, u32 _height, u32 _size, bool _sync);
|
||||
void cleanUp();
|
||||
|
||||
u32 m_startAddress = 0;
|
||||
u32 m_endAddress = 0;
|
||||
@@ -62,6 +71,10 @@ struct FrameBuffer
|
||||
graphics::ObjectHandle m_depthFBO;
|
||||
CachedTexture *m_pDepthTexture = nullptr;
|
||||
|
||||
std::unique_ptr<graphics::ColorBufferReader> m_bufferReader;
|
||||
graphics::ObjectHandle m_ColorBufferFBO;
|
||||
CachedTexture *m_pColorBufferTexture = nullptr;
|
||||
|
||||
DepthBuffer *m_pDepthBuffer = nullptr;
|
||||
|
||||
// multisampling
|
||||
@@ -94,6 +107,8 @@ private:
|
||||
void _initCopyTexture();
|
||||
CachedTexture * _copyFrameBufferTexture();
|
||||
CachedTexture * _getSubTexture(u32 _t);
|
||||
void _initColorFBTexture(int _width);
|
||||
void _destroyColorFBTexure();
|
||||
|
||||
mutable u32 m_validityChecked = false;
|
||||
};
|
||||
|
||||
@@ -80,6 +80,10 @@ QString ConfigDialog::_hotkeyDescription(quint32 _idx) const
|
||||
return tr("Reload HD textures");
|
||||
case Config::HotKey::hkHdTexToggle:
|
||||
return tr("Toggle HD textures");
|
||||
case Config::HotKey::hkTexCoordBounds:
|
||||
return tr("Toggle texcoords bounds");
|
||||
case Config::HotKey::hkNativeResTexrects:
|
||||
return tr("Toggle 2D texrects in native resolution");
|
||||
case Config::HotKey::hkVsync:
|
||||
return tr("Toggle VSync");
|
||||
case Config::HotKey::hkFBEmulation:
|
||||
@@ -241,6 +245,7 @@ void ConfigDialog::_init(bool reInit, bool blockCustomSettings)
|
||||
}
|
||||
|
||||
ui->halosRemovalCheckBox->setChecked(config.texture.enableHalosRemoval != 0);
|
||||
ui->texCoordBoundsCheckBox->setChecked(config.graphics2D.enableTexCoordBounds != 0);
|
||||
|
||||
ui->nativeRes2DComboBox->setCurrentIndex(config.graphics2D.enableNativeResTexrects);
|
||||
|
||||
@@ -574,6 +579,7 @@ void ConfigDialog::accept(bool justSave) {
|
||||
config.graphics2D.bgMode = Config::BGMode::bgStripped;
|
||||
|
||||
config.texture.enableHalosRemoval = ui->halosRemovalCheckBox->isChecked() ? 1 : 0;
|
||||
config.graphics2D.enableTexCoordBounds = ui->texCoordBoundsCheckBox->isChecked() ? 1 : 0;
|
||||
config.graphics2D.enableNativeResTexrects = ui->nativeRes2DComboBox->currentIndex();
|
||||
|
||||
config.frameBufferEmulation.enable = ui->frameBufferCheckBox->isChecked() ? 1 : 0;
|
||||
|
||||
@@ -57,6 +57,7 @@ void _loadSettings(QSettings & settings)
|
||||
config.graphics2D.correctTexrectCoords = settings.value("correctTexrectCoords", config.graphics2D.correctTexrectCoords).toInt();
|
||||
config.graphics2D.enableNativeResTexrects = settings.value("enableNativeResTexrects", config.graphics2D.enableNativeResTexrects).toInt();
|
||||
config.graphics2D.bgMode = settings.value("bgMode", config.graphics2D.bgMode).toInt();
|
||||
config.graphics2D.enableTexCoordBounds = settings.value("enableTexCoordBounds", config.graphics2D.enableTexCoordBounds).toInt();
|
||||
settings.endGroup();
|
||||
|
||||
settings.beginGroup("frameBufferEmulation");
|
||||
@@ -240,6 +241,7 @@ void writeSettings(const QString & _strIniFolder)
|
||||
settings.setValue("correctTexrectCoords", config.graphics2D.correctTexrectCoords);
|
||||
settings.setValue("enableNativeResTexrects", config.graphics2D.enableNativeResTexrects);
|
||||
settings.setValue("bgMode", config.graphics2D.bgMode);
|
||||
settings.setValue("enableTexCoordBounds", config.graphics2D.enableTexCoordBounds);
|
||||
settings.endGroup();
|
||||
|
||||
settings.beginGroup("frameBufferEmulation");
|
||||
@@ -437,6 +439,7 @@ void saveCustomRomSettings(const QString & _strIniFolder, const char * _strRomNa
|
||||
WriteCustomSetting(graphics2D, correctTexrectCoords);
|
||||
WriteCustomSetting(graphics2D, enableNativeResTexrects);
|
||||
WriteCustomSetting(graphics2D, bgMode);
|
||||
WriteCustomSetting(graphics2D, enableTexCoordBounds);
|
||||
settings.endGroup();
|
||||
|
||||
settings.beginGroup("frameBufferEmulation");
|
||||
|
||||
@@ -1502,11 +1502,25 @@
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="halosRemovalCheckBox">
|
||||
<property name="text">
|
||||
<string>Try to remove colored halos around transparent objects</string>
|
||||
</property>
|
||||
</widget>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_29">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="halosRemovalCheckBox">
|
||||
<property name="text">
|
||||
<string>Remove colored halos around transparent objects</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="texCoordBoundsCheckBox">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Bound texture rectangle texture coordinates to the values they take in native resolutions. It prevents garbage due to fetching out of texture bounds, but can result in hard edges.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable native-res bounds for texture coordinates</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
|
||||
@@ -267,7 +267,7 @@ public:
|
||||
ss << "# define IN in" << std::endl << "# define OUT out" << std::endl;
|
||||
m_part = ss.str();
|
||||
}
|
||||
m_part += "uniform lowp float uClipRatio; \n";
|
||||
m_part += "uniform lowp vec2 uVertexOffset; \n";
|
||||
}
|
||||
};
|
||||
|
||||
@@ -296,6 +296,10 @@ 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 mediump vec2 uAdjustTrans; \n"
|
||||
"uniform mediump vec2 uAdjustScale; \n"
|
||||
"uniform lowp ivec2 uCacheFrameBuffer; \n"
|
||||
"OUT highp vec2 vTexCoord0; \n"
|
||||
"OUT highp vec2 vTexCoord1; \n"
|
||||
@@ -314,8 +318,8 @@ public:
|
||||
" vec2 texCoordOut = texCoord*uCacheShiftScale[idx]; \n"
|
||||
" texCoordOut -= uTexOffset[idx]; \n"
|
||||
" texCoordOut += uCacheOffset[idx]; \n"
|
||||
" if (uTextureFilterMode != 0 && uCacheFrameBuffer[idx] != 0) \n"
|
||||
" texCoordOut -= vec2(0.5); \n"
|
||||
" if (uTextureFilterMode != 0 && uCacheFrameBuffer[idx] != 0) \n" /* Workaround for framebuffer textures. */
|
||||
" texCoordOut -= vec2(0.0,1.0); \n" /* They contain garbage at the bottom. */
|
||||
" return texCoordOut * uCacheScale[idx]; \n"
|
||||
"} \n"
|
||||
" \n"
|
||||
@@ -330,17 +334,18 @@ 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"
|
||||
" gl_Position.xy = gl_Position.xy * uAdjustScale + gl_Position.ww * uAdjustTrans; \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 +379,10 @@ 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"
|
||||
"uniform mediump vec2 uAdjustTrans; \n"
|
||||
"uniform mediump vec2 uAdjustScale; \n"
|
||||
" \n"
|
||||
"OUT lowp float vNumLights; \n"
|
||||
"OUT lowp vec4 vShadeColor; \n"
|
||||
@@ -390,17 +399,18 @@ 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"
|
||||
" gl_Position.xy = gl_Position.xy * uAdjustScale + gl_Position.ww * uAdjustTrans; \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 +513,8 @@ public:
|
||||
m_part = " gl_Position.z /= 8.0; \n";
|
||||
}
|
||||
m_part +=
|
||||
" gl_Position.zw *= vec2(uClipRatio); \n"
|
||||
" gl_Position.xy += uVertexOffset * vec2(gl_Position.w); \n"
|
||||
" gl_Position.zw *= vec2(1024.0f); \n"
|
||||
"} \n"
|
||||
;
|
||||
}
|
||||
@@ -946,6 +957,10 @@ public:
|
||||
"uniform lowp vec2 uTexMirrorEn1; \n"
|
||||
"uniform lowp vec2 uTexClampEn0; \n"
|
||||
"uniform lowp vec2 uTexClampEn1; \n"
|
||||
"uniform highp vec2 uTexCoordOffset[2]; \n"
|
||||
"uniform lowp int uUseTexCoordBounds; \n"
|
||||
"uniform highp vec4 uTexCoordBounds0; \n"
|
||||
"uniform highp vec4 uTexCoordBounds1; \n"
|
||||
"uniform lowp int uScreenSpaceTriangle; \n"
|
||||
"highp vec2 texCoord0; \n"
|
||||
"highp vec2 texCoord1; \n"
|
||||
@@ -2575,6 +2590,23 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class ShaderFragmentCorrectTexCoords : public ShaderPart {
|
||||
public:
|
||||
ShaderFragmentCorrectTexCoords() {
|
||||
m_part +=
|
||||
" highp vec2 mTexCoord0 = vTexCoord0 + vec2(0.0001); \n"
|
||||
" highp vec2 mTexCoord1 = vTexCoord1 + vec2(0.0001); \n"
|
||||
" mTexCoord0 += uTexCoordOffset[0]; \n"
|
||||
" mTexCoord1 += uTexCoordOffset[1]; \n"
|
||||
" if (uUseTexCoordBounds != 0) { \n"
|
||||
" mTexCoord0 = clamp(mTexCoord0, uTexCoordBounds0.xy, uTexCoordBounds0.zw); \n"
|
||||
" mTexCoord1 = clamp(mTexCoord1, uTexCoordBounds1.xy, uTexCoordBounds1.zw); \n"
|
||||
" } \n"
|
||||
;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class ShaderTextureEngine : public ShaderPart
|
||||
{
|
||||
public:
|
||||
@@ -2637,7 +2669,7 @@ public:
|
||||
ShaderFragmentTextureEngineTex0(const opengl::GLInfo _glinfo)
|
||||
{
|
||||
m_part =
|
||||
"textureEngine0(vTexCoord0, tcData0); \n"
|
||||
"textureEngine0(mTexCoord0, tcData0); \n"
|
||||
;
|
||||
}
|
||||
};
|
||||
@@ -2647,7 +2679,7 @@ public:
|
||||
ShaderFragmentTextureEngineTex1(const opengl::GLInfo _glinfo)
|
||||
{
|
||||
m_part =
|
||||
"textureEngine1(vTexCoord1, tcData1); \n"
|
||||
"textureEngine1(mTexCoord1, tcData1); \n"
|
||||
;
|
||||
}
|
||||
};
|
||||
@@ -2891,6 +2923,7 @@ graphics::CombinerProgram * CombinerProgramBuilder::buildCombinerProgram(Combine
|
||||
|
||||
|
||||
if (bUseTextures) {
|
||||
m_fragmentCorrectTexCoords->write(ssShader);
|
||||
if (combinerInputs.usesTile(0))
|
||||
{
|
||||
m_fragmentTextureEngineTex0->write(ssShader);
|
||||
@@ -3060,6 +3093,7 @@ CombinerProgramBuilder::CombinerProgramBuilder(const opengl::GLInfo & _glinfo, o
|
||||
, m_fragmentBlendMux(new ShaderFragmentBlendMux(_glinfo))
|
||||
, m_fragmentReadTex0(new ShaderFragmentReadTex0(_glinfo))
|
||||
, m_fragmentReadTex1(new ShaderFragmentReadTex1(_glinfo))
|
||||
, m_fragmentCorrectTexCoords(new ShaderFragmentCorrectTexCoords())
|
||||
, m_fragmentTextureEngineTex0(new ShaderFragmentTextureEngineTex0(_glinfo))
|
||||
, m_fragmentTextureEngineTex1(new ShaderFragmentTextureEngineTex1(_glinfo))
|
||||
, m_fragmentReadTexCopyMode(new ShaderFragmentReadTexCopyMode(_glinfo))
|
||||
|
||||
@@ -74,6 +74,7 @@ namespace glsl {
|
||||
ShaderPartPtr m_fragmentBlendMux;
|
||||
ShaderPartPtr m_fragmentReadTex0;
|
||||
ShaderPartPtr m_fragmentReadTex1;
|
||||
ShaderPartPtr m_fragmentCorrectTexCoords;
|
||||
ShaderPartPtr m_fragmentTextureEngineTex0;
|
||||
ShaderPartPtr m_fragmentTextureEngineTex1;
|
||||
ShaderPartPtr m_fragmentReadTexCopyMode;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include <cmath>
|
||||
#include <Config.h>
|
||||
#include "glsl_CombinerProgramUniformFactory.h"
|
||||
#include <Graphics/Parameters.h>
|
||||
@@ -216,6 +217,113 @@ private:
|
||||
iUniform uScreenSpaceTriangle;
|
||||
};
|
||||
|
||||
class URasterInfo : public UniformGroup {
|
||||
public:
|
||||
URasterInfo(GLuint _program) {
|
||||
LocateUniform(uVertexOffset);
|
||||
LocateUniform(uTexCoordOffset[0]);
|
||||
LocateUniform(uTexCoordOffset[1]);
|
||||
LocateUniform(uUseTexCoordBounds);
|
||||
LocateUniform(uTexCoordBounds0);
|
||||
LocateUniform(uTexCoordBounds1);
|
||||
}
|
||||
|
||||
void update(bool _force) override {
|
||||
const bool isNativeRes = config.frameBufferEmulation.nativeResFactor == 1 && config.video.multisampling == 0;
|
||||
const bool isTexRect = dwnd().getDrawer().getDrawingState() == DrawingState::TexRect;
|
||||
const bool useTexCoordBounds = isTexRect && !isNativeRes && config.graphics2D.enableTexCoordBounds;
|
||||
/* At rasterization stage, the N64 places samples on the top left of the fragment while OpenGL */
|
||||
/* places them in the fragment center. As a result, a normal approach results in shifted texture */
|
||||
/* coordinates. In native resolution, this difference can be negated by shifting vertices by 0.5. */
|
||||
/* In higher resolutions, there are more samples than the game intends, so shifting is not very */
|
||||
/* effective. Still, an heuristic is applied to render texture rectangles as correctly as possible */
|
||||
/* in higher resolutions too. See issue #2324 for details. */
|
||||
const float vertexOffset = isNativeRes ? 0.5f : 0.0f;
|
||||
float texCoordOffset[2][2] = { 0.0f, 0.0f };
|
||||
if (isTexRect && !isNativeRes) {
|
||||
float scale[2] = { 0.0f, 0.0f };
|
||||
if (config.graphics2D.enableNativeResTexrects != 0) {
|
||||
scale[0] = scale[1] = 1.0f;
|
||||
} else if (config.frameBufferEmulation.nativeResFactor != 0) {
|
||||
scale[0] = scale[1] = static_cast<float>(config.frameBufferEmulation.nativeResFactor);
|
||||
} else {
|
||||
scale[0] = dwnd().getScaleX();
|
||||
scale[1] = dwnd().getScaleY();
|
||||
}
|
||||
|
||||
for (int t = 0; t < 2; t++) {
|
||||
const CachedTexture* _pTexture = textureCache().current[t];
|
||||
if (_pTexture != nullptr) {
|
||||
texCoordOffset[t][0] = (gDP.lastTexRectInfo.dsdx >= 0.0f ? -0.5f / scale[0] : -1.0f + 0.5f / scale[0]) * gDP.lastTexRectInfo.dsdx * _pTexture->hdRatioS;
|
||||
texCoordOffset[t][1] = (gDP.lastTexRectInfo.dtdy >= 0.0f ? -0.5f / scale[1] : -1.0f + 0.5f / scale[1]) * gDP.lastTexRectInfo.dtdy * _pTexture->hdRatioT;
|
||||
}
|
||||
}
|
||||
}
|
||||
float tcbounds[2][4] = {};
|
||||
if (useTexCoordBounds) {
|
||||
f32 uls, lrs, ult, lrt, S, T, shiftScaleS, shiftScaleT;
|
||||
s16 shiftedS, shiftedT;
|
||||
u32 shifts, shiftt;
|
||||
for (int t = 0; t < 2; t++) {
|
||||
const CachedTexture * _pTexture = textureCache().current[t];
|
||||
const gDPTile * _pTile = gSP.textureTile[t];
|
||||
if (_pTexture != nullptr && _pTile != nullptr){
|
||||
if (_pTile->shifts > 10) {
|
||||
shifts = 16 - _pTile->shifts;
|
||||
shiftedS = static_cast<s16>(gDP.lastTexRectInfo.s << shifts);
|
||||
shiftScaleS = static_cast<f32>(1 << shifts);
|
||||
} else {
|
||||
shifts = _pTile->shifts;
|
||||
shiftedS = static_cast<s16>(gDP.lastTexRectInfo.s >> shifts);
|
||||
shiftScaleS = 1.0f / static_cast<f32>(1 << shifts);
|
||||
}
|
||||
if (_pTile->shiftt > 10) {
|
||||
shiftt = 16 - _pTile->shiftt;
|
||||
shiftedT = static_cast<s16>(gDP.lastTexRectInfo.t << shiftt);
|
||||
shiftScaleT = static_cast<f32>(1 << shiftt);
|
||||
} else {
|
||||
shiftt = _pTile->shiftt;
|
||||
shiftedT = static_cast<s16>(gDP.lastTexRectInfo.t >> shiftt);
|
||||
shiftScaleT = 1.0f / static_cast<f32>(1 << shiftt);
|
||||
}
|
||||
|
||||
S = _FIXED2FLOAT(shiftedS, 5);
|
||||
T = _FIXED2FLOAT(shiftedT, 5);
|
||||
uls = S + (ceilf(gDP.lastTexRectInfo.ulx) - gDP.lastTexRectInfo.ulx) * gDP.lastTexRectInfo.dsdx * shiftScaleS;
|
||||
lrs = S + (ceilf(gDP.lastTexRectInfo.lrx) - gDP.lastTexRectInfo.ulx - 1.0f) * gDP.lastTexRectInfo.dsdx * shiftScaleS;
|
||||
ult = T + (ceilf(gDP.lastTexRectInfo.uly) - gDP.lastTexRectInfo.uly) * gDP.lastTexRectInfo.dtdy * shiftScaleT;
|
||||
lrt = T + (ceilf(gDP.lastTexRectInfo.lry) - gDP.lastTexRectInfo.uly - 1.0f) * gDP.lastTexRectInfo.dtdy * shiftScaleT;
|
||||
|
||||
tcbounds[t][0] = (fmin(uls, lrs) - _pTile->fuls) * _pTexture->hdRatioS;
|
||||
tcbounds[t][1] = (fmin(ult, lrt) - _pTile->fult) * _pTexture->hdRatioT;
|
||||
tcbounds[t][2] = (fmax(uls, lrs) - _pTile->fuls) * _pTexture->hdRatioS;
|
||||
tcbounds[t][3] = (fmax(ult, lrt) - _pTile->fult) * _pTexture->hdRatioT;
|
||||
if (_pTexture->frameBufferTexture != CachedTexture::fbNone) {
|
||||
tcbounds[t][0] += _pTexture->offsetS * _pTexture->hdRatioS;
|
||||
tcbounds[t][1] += _pTexture->offsetT * _pTexture->hdRatioT;
|
||||
tcbounds[t][2] += _pTexture->offsetS * _pTexture->hdRatioS;
|
||||
tcbounds[t][3] += _pTexture->offsetT * _pTexture->hdRatioT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uVertexOffset.set(vertexOffset, vertexOffset, _force);
|
||||
uTexCoordOffset[0].set(texCoordOffset[0][0], texCoordOffset[0][1], _force);
|
||||
uTexCoordOffset[1].set(texCoordOffset[1][0], texCoordOffset[1][1], _force);
|
||||
uUseTexCoordBounds.set(useTexCoordBounds ? 1 : 0, _force);
|
||||
uTexCoordBounds0.set(tcbounds[0], _force);
|
||||
uTexCoordBounds1.set(tcbounds[1], _force);
|
||||
}
|
||||
|
||||
private:
|
||||
fv2Uniform uVertexOffset;
|
||||
fv2Uniform uTexCoordOffset[2];
|
||||
iUniform uUseTexCoordBounds;
|
||||
fv4Uniform uTexCoordBounds0;
|
||||
fv4Uniform uTexCoordBounds1;
|
||||
};
|
||||
|
||||
class UFrameBufferInfo : public UniformGroup
|
||||
{
|
||||
public:
|
||||
@@ -603,6 +711,43 @@ private:
|
||||
fUniform uAlphaTestValue;
|
||||
};
|
||||
|
||||
class UViewportInfo : public UniformGroup
|
||||
{
|
||||
public:
|
||||
UViewportInfo(GLuint _program) {
|
||||
LocateUniform(uVTrans);
|
||||
LocateUniform(uVScale);
|
||||
LocateUniform(uAdjustTrans);
|
||||
LocateUniform(uAdjustScale);
|
||||
}
|
||||
|
||||
void update(bool _force) override
|
||||
{
|
||||
const bool isOrthographicProjection = gSP.matrix.projection[3][2] == -1.f;
|
||||
float adjustTrans[2] = { 0.0f, 0.0f };
|
||||
float adjustScale[2] = { 1.0f, 1.0f };
|
||||
if (dwnd().isAdjustScreen() && (gDP.colorImage.width > VI.width * 98 / 100)) {
|
||||
if (isOrthographicProjection) {
|
||||
adjustScale[1] = 1.0f / dwnd().getAdjustScale();
|
||||
adjustTrans[1] = static_cast<f32>(gDP.colorImage.width) * 3.0f / 4.0f * (1.0f - adjustScale[1]) / 2.0f;
|
||||
} else {
|
||||
adjustScale[0] = dwnd().getAdjustScale();
|
||||
adjustTrans[0] = static_cast<f32>(gDP.colorImage.width) * (1.0f - adjustScale[0]) / 2.0f;
|
||||
}
|
||||
}
|
||||
uVTrans.set(gSP.viewport.vtrans[0], gSP.viewport.vtrans[1], _force);
|
||||
uVScale.set(gSP.viewport.vscale[0], -gSP.viewport.vscale[1], _force);
|
||||
uAdjustTrans.set(adjustTrans[0], adjustTrans[1], _force);
|
||||
uAdjustScale.set(adjustScale[0], adjustScale[1], _force);
|
||||
}
|
||||
|
||||
private:
|
||||
fv2Uniform uVTrans;
|
||||
fv2Uniform uVScale;
|
||||
fv2Uniform uAdjustTrans;
|
||||
fv2Uniform uAdjustScale;
|
||||
};
|
||||
|
||||
class UDepthScale : public UniformGroup
|
||||
{
|
||||
public:
|
||||
@@ -738,22 +883,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 +1223,8 @@ void CombinerProgramUniformFactory::buildUniforms(GLuint _program,
|
||||
{
|
||||
_uniforms.emplace_back(new UNoiseTex(_program));
|
||||
_uniforms.emplace_back(new UScreenSpaceTriangleInfo(_program));
|
||||
_uniforms.emplace_back(new URasterInfo(_program));
|
||||
_uniforms.emplace_back(new UViewportInfo(_program));
|
||||
|
||||
if (!m_glInfo.isGLES2) {
|
||||
_uniforms.emplace_back(new UDepthTex(_program));
|
||||
@@ -1165,8 +1296,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));
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace glsl {
|
||||
bool _saveCombinerKeys(const graphics::Combiners & _combiners) const;
|
||||
bool _loadFromCombinerKeys(graphics::Combiners & _combiners);
|
||||
|
||||
const u32 m_formatVersion = 0x33U;
|
||||
const u32 m_formatVersion = 0x34U;
|
||||
const u32 m_keysFormatVersion = 0x05;
|
||||
const opengl::GLInfo & m_glinfo;
|
||||
opengl::CachedUseProgram * m_useProgram;
|
||||
|
||||
@@ -22,6 +22,8 @@ GraphicBufferWrapper::GraphicBufferWrapper() {
|
||||
m_private = true;
|
||||
m_privateGraphicBuffer = new GraphicBuffer();
|
||||
}
|
||||
|
||||
m_stride = 0;
|
||||
}
|
||||
|
||||
GraphicBufferWrapper::~GraphicBufferWrapper() {
|
||||
@@ -51,7 +53,6 @@ bool GraphicBufferWrapper::allocate(const AHardwareBuffer_Desc *desc) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int GraphicBufferWrapper::lock(uint64_t usage, void **out_virtual_address) {
|
||||
|
||||
int returnValue = 0;
|
||||
@@ -64,7 +65,6 @@ int GraphicBufferWrapper::lock(uint64_t usage, void **out_virtual_address) {
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
|
||||
void GraphicBufferWrapper::release() {
|
||||
if (!m_private) {
|
||||
AndroidHardwareBufferCompat::GetInstance().Release(m_publicGraphicBuffer);
|
||||
@@ -81,7 +81,6 @@ void GraphicBufferWrapper::unlock() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
EGLClientBuffer GraphicBufferWrapper::getClientBuffer() {
|
||||
EGLClientBuffer clientBuffer = nullptr;
|
||||
if (m_private) {
|
||||
@@ -93,6 +92,15 @@ EGLClientBuffer GraphicBufferWrapper::getClientBuffer() {
|
||||
return clientBuffer;
|
||||
}
|
||||
|
||||
unsigned GraphicBufferWrapper::getStride() const {
|
||||
if (m_private) {
|
||||
return m_privateGraphicBuffer->getStride();
|
||||
} else {
|
||||
AHardwareBuffer_Desc bufferInfo;
|
||||
AndroidHardwareBufferCompat::GetInstance().Describe(m_publicGraphicBuffer, &bufferInfo);
|
||||
return bufferInfo.stride;
|
||||
}
|
||||
}
|
||||
|
||||
int GraphicBufferWrapper::getApiLevel()
|
||||
{
|
||||
|
||||
@@ -28,6 +28,7 @@ public:
|
||||
void release();
|
||||
void unlock();
|
||||
EGLClientBuffer getClientBuffer();
|
||||
unsigned int getStride() const;
|
||||
|
||||
private:
|
||||
|
||||
@@ -36,6 +37,7 @@ private:
|
||||
bool m_private;
|
||||
GraphicBuffer* m_privateGraphicBuffer;
|
||||
AHardwareBuffer* m_publicGraphicBuffer;
|
||||
unsigned int m_stride;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ const u8 * ColorBufferReaderWithEGLImage::_readPixels(const ReadColorBufferParam
|
||||
m_hardwareBuffer.lock(AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN, &gpuData);
|
||||
m_bufferLocked = true;
|
||||
_heightOffset = static_cast<u32>(_params.y0);
|
||||
_stride = m_pTexture->width;
|
||||
_stride = m_hardwareBuffer.getStride();
|
||||
} else {
|
||||
gpuData = m_pixelData.data();
|
||||
glReadPixels(_params.x0, _params.y0, m_pTexture->width, _params.height, format, type, gpuData);
|
||||
|
||||
+37
-123
@@ -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;
|
||||
@@ -1101,8 +1035,11 @@ void GraphicsDrawer::drawRect(int _ulx, int _uly, int _lrx, int _lry)
|
||||
DisplayWindow & wnd = dwnd();
|
||||
if (wnd.isAdjustScreen() && (gDP.colorImage.width > VI.width * 98 / 100) && (static_cast<u32>(_lrx - _ulx) < VI.width * 9 / 10)) {
|
||||
const float scale = wnd.getAdjustScale();
|
||||
for (u32 i = 0; i < 4; ++i)
|
||||
const float offsetx = static_cast<f32>(gDP.colorImage.width) * (1.0f - scale) / 2.0f;
|
||||
for (u32 i = 0; i < 4; ++i) {
|
||||
m_rect[i].x *= scale;
|
||||
m_rect[i].x += offsetx;
|
||||
}
|
||||
}
|
||||
|
||||
Context::DrawRectParameters rectParams;
|
||||
@@ -1265,7 +1202,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 +1241,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;
|
||||
@@ -1380,15 +1315,6 @@ void GraphicsDrawer::drawTexturedRect(const TexturedRectParams & _params)
|
||||
texST[t].t0 = ult - gSP.textureTile[t]->fult;
|
||||
texST[t].t1 = lrt - gSP.textureTile[t]->fult;
|
||||
|
||||
if (uls > lrs) {
|
||||
texST[t].s0 -= _params.dsdx * shiftScaleS;
|
||||
texST[t].s1 -= _params.dsdx * shiftScaleS;
|
||||
}
|
||||
if (ult > lrt) {
|
||||
texST[t].t0 -= _params.dtdy * shiftScaleT;
|
||||
texST[t].t1 -= _params.dtdy * shiftScaleT;
|
||||
}
|
||||
|
||||
if (cache.current[t]->frameBufferTexture != CachedTexture::fbNone) {
|
||||
texST[t].s0 = cache.current[t]->offsetS + texST[t].s0;
|
||||
texST[t].t0 = cache.current[t]->offsetT + texST[t].t0;
|
||||
@@ -1425,13 +1351,6 @@ void GraphicsDrawer::drawTexturedRect(const TexturedRectParams & _params)
|
||||
texST[t].s1 *= cache.current[t]->hdRatioS;
|
||||
texST[t].t1 *= cache.current[t]->hdRatioT;
|
||||
|
||||
if (gDP.otherMode.textureFilter != G_TF_POINT && gDP.otherMode.cycleType != G_CYC_COPY) {
|
||||
texST[t].s0 -= 0.5f;
|
||||
texST[t].t0 -= 0.5f;
|
||||
texST[t].s1 -= 0.5f;
|
||||
texST[t].t1 -= 0.5f;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1482,8 +1401,11 @@ void GraphicsDrawer::drawTexturedRect(const TexturedRectParams & _params)
|
||||
((gDP.colorImage.width > VI.width * 98 / 100) && (static_cast<u32>(_params.lrx - _params.ulx) < VI.width * 9 / 10))))
|
||||
{
|
||||
const float scale = wnd.getAdjustScale();
|
||||
for (u32 i = 0; i < 4; ++i)
|
||||
const float offsetx = static_cast<f32>(gDP.colorImage.width) * (1.0f-scale) / 2.0f;
|
||||
for (u32 i = 0; i < 4; ++i) {
|
||||
m_rect[i].x *= scale;
|
||||
m_rect[i].x += offsetx;
|
||||
}
|
||||
}
|
||||
|
||||
m_rect[0].bc0 = 0.0f;
|
||||
@@ -1505,7 +1427,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 +1435,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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -29,8 +29,6 @@ TexrectDrawer::TexrectDrawer()
|
||||
, m_Z(0)
|
||||
, m_max_lrx(0)
|
||||
, m_max_lry(0)
|
||||
, m_stepY(0.0f)
|
||||
, m_stepX(0.0f)
|
||||
, m_scissor(gDPScissor())
|
||||
, m_pTexture(nullptr)
|
||||
, m_pBuffer(nullptr)
|
||||
@@ -54,8 +52,6 @@ void TexrectDrawer::init()
|
||||
m_pTexture->width = 640;
|
||||
m_pTexture->height = 580;
|
||||
m_pTexture->textureBytes = m_pTexture->width * m_pTexture->height * fbTexFormats.colorFormatBytes;
|
||||
m_stepX = 2.0f / 640.0f;
|
||||
m_stepY = 2.0f / 580.0f;
|
||||
|
||||
Context::InitTextureParams initParams;
|
||||
initParams.handle = m_pTexture->name;
|
||||
@@ -108,8 +104,7 @@ void TexrectDrawer::destroy()
|
||||
|
||||
void TexrectDrawer::_setViewport() const
|
||||
{
|
||||
const u32 bufferWidth = m_pBuffer == nullptr ? VI.width : m_pBuffer->m_width;
|
||||
gfxContext.setViewport(0, 0, bufferWidth, VI_GetMaxBufferHeight(bufferWidth));
|
||||
dwnd().getDrawer()._updateViewport(nullptr, 1.0f);
|
||||
}
|
||||
|
||||
void TexrectDrawer::_setDrawBuffer()
|
||||
@@ -381,13 +376,14 @@ bool TexrectDrawer::draw()
|
||||
scaleX *= 2.0f;
|
||||
scaleY *= 2.0f;
|
||||
|
||||
const float s0 = (m_ulx + 1.0f) / scaleX / (float)m_pTexture->width + 0.5f / (float)m_pTexture->width;
|
||||
const float t0 = (m_lry + 1.0f) / scaleY / (float)m_pTexture->height;// +0.5f / (float)m_pTexture->height;
|
||||
const float s1 = (m_lrx + 1.0f) / scaleX / (float)m_pTexture->width;
|
||||
const float t1 = (m_uly + 1.0f) / scaleY / (float)m_pTexture->height;
|
||||
const float W = 1.0f;
|
||||
const float s0 = m_ulx / (float)m_pTexture->width; // +0.5f / (float)m_pTexture->width;
|
||||
const float t0 = m_lry / (float)m_pTexture->height;// +0.5f / (float)m_pTexture->height;
|
||||
const float s1 = m_lrx / (float)m_pTexture->width;
|
||||
const float t1 = m_uly / (float)m_pTexture->height;
|
||||
const float W = 1024.0f;
|
||||
const float Z = m_Z * 1024.0f;
|
||||
|
||||
drawer._updateScreenCoordsViewport(m_pBuffer);
|
||||
drawer._updateViewport(m_pBuffer);
|
||||
|
||||
textureCache().activateTexture(0, m_pTexture);
|
||||
// Disable filtering to avoid black outlines
|
||||
@@ -404,25 +400,25 @@ bool TexrectDrawer::draw()
|
||||
|
||||
rect[0].x = m_ulx;
|
||||
rect[0].y = m_lry;
|
||||
rect[0].z = m_Z;
|
||||
rect[0].z = Z;
|
||||
rect[0].w = W;
|
||||
rect[0].s0 = s0;
|
||||
rect[0].t0 = t0;
|
||||
rect[1].x = m_lrx;
|
||||
rect[1].y = m_lry;
|
||||
rect[1].z = m_Z;
|
||||
rect[1].z = Z;
|
||||
rect[1].w = W;
|
||||
rect[1].s0 = s1;
|
||||
rect[1].t0 = t0;
|
||||
rect[2].x = m_ulx;
|
||||
rect[2].y = m_uly;
|
||||
rect[2].z = m_Z;
|
||||
rect[2].z = Z;
|
||||
rect[2].w = W;
|
||||
rect[2].s0 = s0;
|
||||
rect[2].t0 = t1;
|
||||
rect[3].x = m_lrx;
|
||||
rect[3].y = m_uly;
|
||||
rect[3].z = m_Z;
|
||||
rect[3].z = Z;
|
||||
rect[3].w = W;
|
||||
rect[3].s0 = s1;
|
||||
rect[3].t0 = t1;
|
||||
@@ -440,15 +436,15 @@ bool TexrectDrawer::draw()
|
||||
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, m_FBO);
|
||||
m_programClear->activate();
|
||||
|
||||
const f32 ulx = std::max(-1.0f, m_ulx - m_stepX);
|
||||
const f32 lrx = std::min( 1.0f, m_lrx + m_stepX);
|
||||
const f32 ulx = std::max(0.0f, m_ulx - 1.0f);
|
||||
const f32 lrx = std::min(640.0f, m_lrx + 1.0f);
|
||||
rect[0].x = ulx;
|
||||
rect[1].x = lrx;
|
||||
rect[2].x = ulx;
|
||||
rect[3].x = lrx;
|
||||
|
||||
const f32 uly = std::max(-1.0f, m_uly - m_stepY);
|
||||
const f32 lry = std::min( 1.0f, m_lry + m_stepY);
|
||||
const f32 uly = std::max(0.0f, m_uly - 1.0f);
|
||||
const f32 lry = std::min(580.0f, m_lry + 1.0f);
|
||||
rect[0].y = uly;
|
||||
rect[1].y = uly;
|
||||
rect[2].y = lry;
|
||||
|
||||
@@ -34,8 +34,6 @@ private:
|
||||
f32 m_ulx, m_lrx, m_uly, m_lry, m_Z;
|
||||
s32 m_ulx_i, m_uly_i, m_lry_i;
|
||||
f32 m_max_lrx, m_max_lry;
|
||||
f32 m_stepY;
|
||||
f32 m_stepX;
|
||||
graphics::ObjectHandle m_FBO;
|
||||
gDPScissor m_scissor;
|
||||
CachedTexture * m_pTexture;
|
||||
|
||||
@@ -130,6 +130,27 @@ static void checkHotkeys()
|
||||
textureCache().toggleDumpTex();
|
||||
}
|
||||
|
||||
if (osal_is_key_pressed(config.hotkeys.keys[Config::hkTexCoordBounds], 0x0001)) {
|
||||
if (config.graphics2D.enableTexCoordBounds == 0)
|
||||
dwnd().getDrawer().showMessage("Bound texrect texture coordinates on\n", Milliseconds(1000));
|
||||
else
|
||||
dwnd().getDrawer().showMessage("Bound texrect texture coordinates off\n", Milliseconds(1000));
|
||||
config.graphics2D.enableTexCoordBounds = !config.graphics2D.enableTexCoordBounds;
|
||||
}
|
||||
|
||||
if (osal_is_key_pressed(config.hotkeys.keys[Config::hkNativeResTexrects], 0x0001)) {
|
||||
static u32 s_nativeResTexrects = Config::NativeResTexrectsMode::ntOptimized;
|
||||
if (config.graphics2D.enableNativeResTexrects != Config::NativeResTexrectsMode::ntDisable) {
|
||||
s_nativeResTexrects = config.graphics2D.enableNativeResTexrects;
|
||||
config.graphics2D.enableNativeResTexrects = Config::NativeResTexrectsMode::ntDisable;
|
||||
}
|
||||
else
|
||||
config.graphics2D.enableNativeResTexrects = s_nativeResTexrects;
|
||||
if (config.graphics2D.enableNativeResTexrects == Config::NativeResTexrectsMode::ntDisable)
|
||||
dwnd().getDrawer().showMessage("Disable 2D texrects in native resolution\n", Milliseconds(1000));
|
||||
else
|
||||
dwnd().getDrawer().showMessage("Enable 2D texrects in native resolution\n", Milliseconds(1000));
|
||||
}
|
||||
|
||||
if (osal_is_key_pressed(config.hotkeys.keys[Config::hkVsync], 0x0001)) {
|
||||
config.video.verticalSync = !config.video.verticalSync;
|
||||
|
||||
@@ -866,6 +866,15 @@ void gDPTextureRectangle(f32 ulx, f32 uly, f32 lrx, f32 lry, s32 tile, s16 s, s1
|
||||
|
||||
gDP.rectColor = gDPInfo::Color();
|
||||
|
||||
gDP.lastTexRectInfo.ulx = ulx;
|
||||
gDP.lastTexRectInfo.lrx = lrx;
|
||||
gDP.lastTexRectInfo.uly = uly;
|
||||
gDP.lastTexRectInfo.lry = lry;
|
||||
gDP.lastTexRectInfo.s = !flip ? s : t;
|
||||
gDP.lastTexRectInfo.t = !flip ? t : s;
|
||||
gDP.lastTexRectInfo.dsdx = !flip ? dsdx : dtdy;
|
||||
gDP.lastTexRectInfo.dtdy = !flip ? dtdy : dsdx;
|
||||
|
||||
GraphicsDrawer & drawer = dwnd().getDrawer();
|
||||
GraphicsDrawer::TexturedRectParams params(ulx, uly, lrx, lry, dsdx, dtdy, s, t,
|
||||
flip, false, true, frameBufferList().getCurrent());
|
||||
|
||||
+9
-1
@@ -122,6 +122,13 @@ struct gDPScissor
|
||||
s16 xh, yh, xl, yl;
|
||||
};
|
||||
|
||||
struct gDPTexrectInfo
|
||||
{
|
||||
f32 ulx, lrx, uly, lry;
|
||||
s16 s, t;
|
||||
f32 dsdx, dtdy;
|
||||
};
|
||||
|
||||
struct gDPInfo
|
||||
{
|
||||
struct OtherMode
|
||||
@@ -255,7 +262,8 @@ struct gDPInfo
|
||||
u64 paletteCRC256;
|
||||
u32 half_1, half_2;
|
||||
|
||||
gDPLoadTileInfo loadInfo[512];
|
||||
gDPLoadTileInfo loadInfo[512];
|
||||
gDPTexrectInfo lastTexRectInfo;
|
||||
};
|
||||
|
||||
extern gDPInfo gDP;
|
||||
|
||||
+10
-38
@@ -440,7 +440,7 @@ void gSPLookAt( u32 _l, u32 _n )
|
||||
static
|
||||
void gSPUpdateLightVectors()
|
||||
{
|
||||
InverseTransformVectorNormalizeN(&gSP.lights.xyz[0], &gSP.lights.i_xyz[0],
|
||||
InverseTransformVectorNormalizeN(&gSP.lights.xyz[0], &gSP.lights.i_xyz[0],
|
||||
gSP.matrix.modelView[gSP.matrix.modelViewi], gSP.numLights);
|
||||
gSP.changed ^= CHANGED_LIGHT;
|
||||
gSP.changed |= CHANGED_HW_LIGHT;
|
||||
@@ -763,11 +763,13 @@ void gSPBillboardVertex(u32 v, SPVertex * spVtx)
|
||||
template <u32 VNUM>
|
||||
void gSPClipVertex(u32 v, SPVertex * spVtx)
|
||||
{
|
||||
const f32 scale = dwnd().getAdjustScale();
|
||||
for (u32 j = 0; j < VNUM; ++j) {
|
||||
SPVertex & vtx = spVtx[v+j];
|
||||
vtx.clip = 0;
|
||||
if (vtx.x > +vtx.w) vtx.clip |= CLIP_POSX;
|
||||
if (vtx.x < -vtx.w) vtx.clip |= CLIP_NEGX;
|
||||
const f32 scaledX = vtx.x * scale;
|
||||
if (scaledX > +vtx.w) vtx.clip |= CLIP_POSX;
|
||||
if (scaledX < -vtx.w) vtx.clip |= CLIP_NEGX;
|
||||
if (vtx.y > +vtx.w) vtx.clip |= CLIP_POSY;
|
||||
if (vtx.y < -vtx.w) vtx.clip |= CLIP_NEGY;
|
||||
if (vtx.w < 0.01f) vtx.clip |= CLIP_W;
|
||||
@@ -817,28 +819,6 @@ void gSPProcessVertex(u32 v, SPVertex * spVtx)
|
||||
|
||||
gSPTransformVertex<VNUM>(v, spVtx, gSP.matrix.combined );
|
||||
|
||||
if (dwnd().isAdjustScreen() && (gDP.colorImage.width > VI.width * 98 / 100)) {
|
||||
const f32 adjustScale = dwnd().getAdjustScale();
|
||||
for(int i = 0; i < VNUM; ++i) {
|
||||
SPVertex & vtx = spVtx[v+i];
|
||||
vtx.x *= adjustScale;
|
||||
if (gSP.matrix.projection[3][2] == -1.f)
|
||||
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 +1650,24 @@ 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();
|
||||
const f32 adjustOffset = static_cast<f32>(VI.width) * (1.0f - adjustScale) / 2.0f;
|
||||
vtx0.x *= adjustScale;
|
||||
vtx0.x += adjustOffset;
|
||||
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:
|
||||
{
|
||||
|
||||
@@ -29,6 +29,10 @@ const char* _hotkeyDescription(u32 _idx)
|
||||
return "Hotkey: reload HD textures";
|
||||
case Config::HotKey::hkHdTexToggle:
|
||||
return "Hotkey: toggle HD textures";
|
||||
case Config::HotKey::hkTexCoordBounds:
|
||||
return "Hotkey: toggle texcoords bounds";
|
||||
case Config::HotKey::hkNativeResTexrects:
|
||||
return "Hotkey: toggle 2D texrects in native resolution";
|
||||
case Config::HotKey::hkVsync:
|
||||
return "Hotkey: toggle VSync";
|
||||
case Config::HotKey::hkFBEmulation:
|
||||
@@ -178,6 +182,8 @@ bool Config_SetDefault()
|
||||
assert(res == M64ERR_SUCCESS);
|
||||
res = ConfigSetDefaultInt(g_configVideoGliden64, "BackgroundsMode", config.graphics2D.bgMode, "Render backgrounds mode (HLE only). (0=One piece (fast), 1=Stripped (precise))");
|
||||
assert(res == M64ERR_SUCCESS);
|
||||
res = ConfigSetDefaultInt(g_configVideoGliden64, "EnableTexCoordBounds", config.graphics2D.enableTexCoordBounds, "Bound texture rectangle texture coordinates to the values they take in native resolutions. It prevents garbage due to fetching out of texture bounds, but can result in hard edges. (0=Off, 1=On)");
|
||||
assert(res == M64ERR_SUCCESS);
|
||||
|
||||
//#Frame Buffer Settings:"
|
||||
res = ConfigSetDefaultBool(g_configVideoGliden64, "EnableFBEmulation", config.frameBufferEmulation.enable, "Enable frame and|or depth buffer emulation.");
|
||||
@@ -383,6 +389,8 @@ void Config_LoadCustomConfig()
|
||||
if (result == M64ERR_SUCCESS) config.graphics2D.enableNativeResTexrects = atoi(value);
|
||||
result = ConfigExternalGetParameter(fileHandle, sectionName, "graphics2D\\bgMode", value, sizeof(value));
|
||||
if (result == M64ERR_SUCCESS) config.graphics2D.bgMode = atoi(value);
|
||||
result = ConfigExternalGetParameter(fileHandle, sectionName, "graphics2D\\enableTexCoordBounds", value, sizeof(value));
|
||||
if (result == M64ERR_SUCCESS) config.graphics2D.enableTexCoordBounds = atoi(value);
|
||||
|
||||
result = ConfigExternalGetParameter(fileHandle, sectionName, "frameBufferEmulation\\enable", value, sizeof(value));
|
||||
if (result == M64ERR_SUCCESS) config.frameBufferEmulation.enable = atoi(value);
|
||||
@@ -509,6 +517,7 @@ void Config_LoadConfig()
|
||||
config.graphics2D.correctTexrectCoords = ConfigGetParamInt(g_configVideoGliden64, "CorrectTexrectCoords");
|
||||
config.graphics2D.enableNativeResTexrects = ConfigGetParamInt(g_configVideoGliden64, "EnableNativeResTexrects");
|
||||
config.graphics2D.bgMode = ConfigGetParamInt(g_configVideoGliden64, "BackgroundsMode");
|
||||
config.graphics2D.enableTexCoordBounds = ConfigGetParamInt(g_configVideoGliden64, "EnableTexCoordBounds");
|
||||
//#Frame Buffer Settings:"
|
||||
config.frameBufferEmulation.enable = ConfigGetParamBool(g_configVideoGliden64, "EnableFBEmulation");
|
||||
config.frameBufferEmulation.copyAuxToRDRAM = ConfigGetParamBool(g_configVideoGliden64, "EnableCopyAuxiliaryToRDRAM");
|
||||
|
||||
Reference in new issue
Block a user