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

Refactor TexrectDrawer.

This commit is contained in:
Sergey Lipskiy 2017-02-12 22:21:20 +07:00
parent e5c4b156f1
commit 276018a2fc
15 changed files with 400 additions and 32 deletions

View File

@ -351,6 +351,7 @@
</ClCompile>
<ClCompile Include="..\..\src\RSP.cpp" />
<ClCompile Include="..\..\src\SoftwareRender.cpp" />
<ClCompile Include="..\..\src\TexrectDrawer.cpp" />
<ClCompile Include="..\..\src\TextDrawer.cpp" />
<ClCompile Include="..\..\src\TextureFilterHandler.cpp" />
<ClCompile Include="..\..\src\Textures.cpp" />
@ -473,6 +474,7 @@
<ClInclude Include="..\..\src\GraphicsDrawer.h" />
<ClInclude Include="..\..\src\RSP.h" />
<ClInclude Include="..\..\src\SoftwareRender.h" />
<ClInclude Include="..\..\src\TexrectDrawer.h" />
<ClInclude Include="..\..\src\TextDrawer.h" />
<ClInclude Include="..\..\src\TextureFilterHandler.h" />
<ClInclude Include="..\..\src\Textures.h" />

View File

@ -335,6 +335,9 @@
<ClCompile Include="..\..\src\Graphics\OpenGLContext\opengl_ColorBufferReaderWithReadPixels.cpp">
<Filter>Source Files\Graphics\OpenGL</Filter>
</ClCompile>
<ClCompile Include="..\..\src\TexrectDrawer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\src\3DMath.h">
@ -628,5 +631,8 @@
<ClInclude Include="..\..\src\Graphics\OpenGLContext\opengl_ColorBufferReaderWithReadPixels.h">
<Filter>Header Files\Graphics\OpenGL</Filter>
</ClInclude>
<ClInclude Include="..\..\src\TexrectDrawer.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -48,6 +48,7 @@ set(GLideN64_SOURCES
S2DEX2.cpp
S2DEX.cpp
SoftwareRender.cpp
TexrectDrawer.cpp
TextDrawer.cpp
TextureFilterHandler.cpp
Textures.cpp

View File

@ -224,14 +224,14 @@ ShaderProgram * Context::createMonochromeShader()
return m_impl->createMonochromeShader();
}
TexDrawerShaderProgram * Context::createTexDrawerDrawShader()
TexrectDrawerShaderProgram * Context::createTexrectDrawerDrawShader()
{
return m_impl->createTexDrawerDrawShader();
return m_impl->createTexrectDrawerDrawShader();
}
ShaderProgram * Context::createTexDrawerClearShader()
ShaderProgram * Context::createTexrectDrawerClearShader()
{
return m_impl->createTexDrawerClearShader();
return m_impl->createTexrectDrawerClearShader();
}
ShaderProgram * Context::createTexrectCopyShader()

View File

@ -210,9 +210,9 @@ namespace graphics {
ShaderProgram * createMonochromeShader();
TexDrawerShaderProgram * createTexDrawerDrawShader();
TexrectDrawerShaderProgram * createTexrectDrawerDrawShader();
ShaderProgram * createTexDrawerClearShader();
ShaderProgram * createTexrectDrawerClearShader();
ShaderProgram * createTexrectCopyShader();

View File

@ -50,8 +50,8 @@ namespace graphics {
virtual bool loadShadersStorage(Combiners & _combiners) = 0;
virtual ShaderProgram * createDepthFogShader() = 0;
virtual ShaderProgram * createMonochromeShader() = 0;
virtual TexDrawerShaderProgram * createTexDrawerDrawShader() = 0;
virtual ShaderProgram * createTexDrawerClearShader() = 0;
virtual TexrectDrawerShaderProgram * createTexrectDrawerDrawShader() = 0;
virtual ShaderProgram * createTexrectDrawerClearShader() = 0;
virtual ShaderProgram * createTexrectCopyShader() = 0;
virtual ShaderProgram * createGammaCorrectionShader() = 0;
virtual ShaderProgram * createOrientationCorrectionShader() = 0;

View File

@ -506,7 +506,7 @@ namespace glsl {
/*---------------TexrectDrawerShader-------------*/
class TexrectDrawerShaderDraw : public graphics::TexDrawerShaderProgram
class TexrectDrawerShaderDraw : public graphics::TexrectDrawerShaderProgram
{
public:
TexrectDrawerShaderDraw(const opengl::GLInfo & _glinfo,
@ -708,12 +708,12 @@ namespace glsl {
return new MonochromeShader(m_glinfo, m_useProgram, m_vertexHeader, m_fragmentHeader);
}
graphics::TexDrawerShaderProgram * SpecialShadersFactory::createTexDrawerDrawShader() const
graphics::TexrectDrawerShaderProgram * SpecialShadersFactory::createTexrectDrawerDrawShader() const
{
return new TexrectDrawerShaderDraw(m_glinfo, m_useProgram, m_vertexHeader, m_fragmentHeader);
}
graphics::ShaderProgram * SpecialShadersFactory::createTexDrawerClearShader() const
graphics::ShaderProgram * SpecialShadersFactory::createTexrectDrawerClearShader() const
{
return new TexrectDrawerShaderClear(m_glinfo, m_useProgram, m_vertexHeader, m_fragmentHeader);
}

View File

@ -26,9 +26,9 @@ namespace glsl {
graphics::ShaderProgram * createMonochromeShader() const;
graphics::TexDrawerShaderProgram * createTexDrawerDrawShader() const;
graphics::TexrectDrawerShaderProgram * createTexrectDrawerDrawShader() const;
graphics::ShaderProgram * createTexDrawerClearShader() const;
graphics::ShaderProgram * createTexrectDrawerClearShader() const;
graphics::ShaderProgram * createTexrectCopyShader() const;

View File

@ -340,14 +340,14 @@ graphics::ShaderProgram * ContextImpl::createMonochromeShader()
return m_specialShadersFactory->createMonochromeShader();
}
graphics::TexDrawerShaderProgram * ContextImpl::createTexDrawerDrawShader()
graphics::TexrectDrawerShaderProgram * ContextImpl::createTexrectDrawerDrawShader()
{
return m_specialShadersFactory->createTexDrawerDrawShader();
return m_specialShadersFactory->createTexrectDrawerDrawShader();
}
graphics::ShaderProgram * ContextImpl::createTexDrawerClearShader()
graphics::ShaderProgram * ContextImpl::createTexrectDrawerClearShader()
{
return m_specialShadersFactory->createTexDrawerClearShader();
return m_specialShadersFactory->createTexrectDrawerClearShader();
}
graphics::ShaderProgram * ContextImpl::createTexrectCopyShader()

View File

@ -108,9 +108,9 @@ namespace opengl {
graphics::ShaderProgram * createMonochromeShader() override;
graphics::TexDrawerShaderProgram * createTexDrawerDrawShader() override;
graphics::TexrectDrawerShaderProgram * createTexrectDrawerDrawShader() override;
graphics::ShaderProgram * createTexDrawerClearShader() override;
graphics::ShaderProgram * createTexrectDrawerClearShader() override;
graphics::ShaderProgram * createTexrectCopyShader() override;

View File

@ -19,7 +19,7 @@ namespace graphics {
virtual bool getBinaryForm(std::vector<char> & _buffer) override {return false;}
};
class TexDrawerShaderProgram : public ShaderProgram
class TexrectDrawerShaderProgram : public ShaderProgram
{
public:
virtual void setTextureSize(u32 _width, u32 _height) = 0;

View File

@ -3,6 +3,7 @@
#include <array>
#include <vector>
#include "gSP.h"
#include "TexrectDrawer.h"
#include "Graphics/ObjectHandle.h"
#include "Graphics/Parameter.h"
@ -139,6 +140,7 @@ public:
private:
friend class DisplayWindow;
friend TexrectDrawer;
GraphicsDrawer();
@ -168,18 +170,6 @@ private:
DrawingState m_drawingState;
TexturedRectParams m_texrectParams;
// Dummy TexrectDrawer
class TexrectDrawer
{
public:
TexrectDrawer() {}
void init() {}
void destroy() {}
void add() {}
bool draw() { return false; }
bool isEmpty() { return true; }
};
struct {
std::array<SPVertex, VERTBUFF_SIZE> vertices;
std::array<u8, ELEMBUFF_SIZE> elements;

326
src/TexrectDrawer.cpp Normal file
View File

@ -0,0 +1,326 @@
#include <assert.h>
#include <algorithm>
#include <cstring>
#include <Graphics/Context.h>
#include <Graphics/Parameters.h>
#include "DisplayWindow.h"
#include "Textures.h"
#include "VI.h"
#include "FrameBuffer.h"
#include "TexrectDrawer.h"
using namespace graphics;
TexrectDrawer::TexrectDrawer()
: m_numRects(0)
, m_otherMode(0)
, m_mux(0)
, m_ulx(0)
, m_lrx(0)
, m_uly(0)
, m_lry(0)
, m_Z(0)
, m_max_lrx(0)
, m_max_lry(0)
, m_scissor(gDPScissor())
, m_pTexture(nullptr)
, m_pBuffer(nullptr)
{}
void TexrectDrawer::init()
{
const FramebufferTextureFormats & fbTexFormats = gfxContext.getFramebufferTextureFormats();
m_FBO = gfxContext.createFramebuffer();
m_pTexture = textureCache().addFrameBufferTexture(false);
m_pTexture->format = G_IM_FMT_RGBA;
m_pTexture->clampS = 1;
m_pTexture->clampT = 1;
m_pTexture->frameBufferTexture = CachedTexture::fbOneSample;
m_pTexture->maskS = 0;
m_pTexture->maskT = 0;
m_pTexture->mirrorS = 0;
m_pTexture->mirrorT = 0;
m_pTexture->realWidth = 640;
m_pTexture->realHeight = 580;
m_pTexture->textureBytes = m_pTexture->realWidth * m_pTexture->realHeight * fbTexFormats.colorFormatBytes;
textureCache().addFrameBufferTextureSize(m_pTexture->textureBytes);
Context::InitTextureParams initParams;
initParams.handle = m_pTexture->name;
initParams.textureUnitIndex = textureIndices::Tex[0];
initParams.width = m_pTexture->realWidth;
initParams.height = m_pTexture->realHeight;
initParams.internalFormat = fbTexFormats.colorInternalFormat;
initParams.format = fbTexFormats.colorFormat;
initParams.dataType = fbTexFormats.colorType;
gfxContext.init2DTexture(initParams);
Context::TexParameters texParams;
texParams.handle = m_pTexture->name;
texParams.target = textureTarget::TEXTURE_2D;
texParams.textureUnitIndex = textureIndices::Tex[0];
texParams.minFilter = textureParameters::FILTER_LINEAR;
texParams.magFilter = textureParameters::FILTER_LINEAR;
gfxContext.setTextureParameters(texParams);
Context::FrameBufferRenderTarget bufTarget;
bufTarget.bufferHandle = m_FBO;
bufTarget.bufferTarget = bufferTarget::DRAW_FRAMEBUFFER;
bufTarget.attachment = bufferAttachment::COLOR_ATTACHMENT0;
bufTarget.textureTarget = textureTarget::TEXTURE_2D;
bufTarget.textureHandle = m_pTexture->name;
gfxContext.addFrameBufferRenderTarget(bufTarget);
// check if everything is OK
assert(!gfxContext.isFramebufferError());
m_programTex.reset(gfxContext.createTexrectDrawerDrawShader());
m_programClear.reset(gfxContext.createTexrectDrawerClearShader());
m_vecRectCoords.reserve(256);
}
void TexrectDrawer::destroy()
{
gfxContext.deleteFramebuffer(m_FBO);
if (m_pTexture != nullptr) {
textureCache().removeFrameBufferTexture(m_pTexture);
m_pTexture = nullptr;
}
m_programTex.reset();
m_programClear.reset();
}
void TexrectDrawer::add()
{
DisplayWindow & wnd = dwnd();
GraphicsDrawer & drawer = wnd.getDrawer();
RectVertex * pRect = drawer.m_rect;
bool bDownUp = false;
if (m_numRects != 0) {
bool bContinue = false;
if (m_otherMode == gDP.otherMode._u64 && m_mux == gDP.combine.mux) {
const float scaleY = (m_pBuffer != nullptr ? m_pBuffer->m_height : VI.height) / 2.0f;
if (m_ulx == pRect[0].x) {
// bContinue = m_lry == pRect[0].y;
bContinue = fabs((m_lry - pRect[0].y) * scaleY) < 1.1f; // Fix for Mario Kart
bDownUp = m_uly == pRect[3].y;
bContinue |= bDownUp;
}
else {
for (auto iter = m_vecRectCoords.crbegin(); iter != m_vecRectCoords.crend(); ++iter) {
if (iter->x == pRect[0].x && iter->y == pRect[0].y) {
bContinue = true;
break;
}
}
}
}
if (!bContinue) {
RectVertex rect[4];
memcpy(rect, pRect, sizeof(rect));
draw();
memcpy(pRect, rect, sizeof(rect));
drawer._updateTextures();
CombinerInfo::get().updateParameters();
}
}
if (m_numRects == 0) {
m_pBuffer = frameBufferList().getCurrent();
m_otherMode = gDP.otherMode._u64;
m_mux = gDP.combine.mux;
m_Z = (gDP.otherMode.depthSource == G_ZS_PRIM) ? gDP.primDepth.z : gSP.viewport.nearz;
m_scissor = gDP.scissor;
m_ulx = pRect[0].x;
m_uly = pRect[0].y;
m_lrx = m_max_lrx = pRect[3].x;
m_lry = m_max_lry = pRect[3].y;
CombinerInfo::get().update();
gfxContext.enableDepthWrite(false);
gfxContext.enable(enable::DEPTH_TEST, false);
gfxContext.enable(enable::BLEND, false);
if (m_pBuffer == nullptr)
gfxContext.setViewport(0, 0, VI.width, VI.height);
else
gfxContext.setViewport(0, 0, m_pBuffer->m_width, m_pBuffer->m_height);
gfxContext.setScissor((s32)gDP.scissor.ulx, (s32)gDP.scissor.uly, (s32)(gDP.scissor.lrx - gDP.scissor.ulx), (s32)(gDP.scissor.lry - gDP.scissor.uly));
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, m_FBO);
}
if (bDownUp) {
m_ulx = pRect[0].x;
m_uly = pRect[0].y;
}
else {
m_lrx = pRect[3].x;
m_lry = pRect[3].y;
m_max_lrx = std::max(m_max_lrx, m_lrx);
m_max_lry = std::max(m_max_lry, m_lry);
}
Context::DrawRectParameters rectParams;
rectParams.mode = drawmode::TRIANGLE_STRIP;
rectParams.rectColor.fill(0.0f);
rectParams.verticesCount = 4;
rectParams.vertices = pRect;
rectParams.combiner = currentCombiner();
gfxContext.drawRects(rectParams);
RectCoords coords;
coords.x = pRect[1].x;
coords.y = pRect[1].y;
m_vecRectCoords.push_back(coords);
coords.x = pRect[3].x;
coords.y = pRect[3].y;
m_vecRectCoords.push_back(coords);
++m_numRects;
}
bool TexrectDrawer::draw()
{
if (m_numRects == 0)
return false;
const u64 otherMode = gDP.otherMode._u64;
const gDPScissor scissor = gDP.scissor;
gDP.scissor = m_scissor;
gDP.otherMode._u64 = m_otherMode;
DisplayWindow & wnd = dwnd();
GraphicsDrawer & drawer = wnd.getDrawer();
drawer._setBlendMode();
gDP.changed |= CHANGED_RENDERMODE; // Force update of depth compare parameters
drawer._updateDepthCompare();
int enableAlphaTest = 0;
switch (gDP.otherMode.cycleType) {
case G_CYC_COPY:
if (gDP.otherMode.alphaCompare & G_AC_THRESHOLD)
enableAlphaTest = 1;
break;
case G_CYC_1CYCLE:
case G_CYC_2CYCLE:
if (((gDP.otherMode.alphaCompare & G_AC_THRESHOLD) != 0) && (gDP.otherMode.alphaCvgSel == 0) && (gDP.otherMode.forceBlender == 0 || gDP.blendColor.a > 0))
enableAlphaTest = 1;
else if ((gDP.otherMode.alphaCompare == G_AC_DITHER) && (gDP.otherMode.alphaCvgSel == 0))
enableAlphaTest = 1;
else if (gDP.otherMode.cvgXAlpha != 0)
enableAlphaTest = 1;
break;
}
m_lrx = m_max_lrx;
m_lry = m_max_lry;
RectVertex * rect = drawer.m_rect;
const float scaleX = (m_pBuffer != nullptr ? 1.0f / m_pBuffer->m_width : VI.rwidth) * 2.0f;
const float scaleY = (m_pBuffer != nullptr ? 1.0f / m_pBuffer->m_height : VI.rheight) * 2.0f;
const float s0 = (m_ulx + 1.0f) / scaleX / (float)m_pTexture->realWidth;
const float t1 = (m_uly + 1.0f) / scaleY / (float)m_pTexture->realHeight;
const float s1 = (m_lrx + 1.0f) / scaleX / (float)m_pTexture->realWidth;
const float t0 = (m_lry + 1.0f) / scaleY / (float)m_pTexture->realHeight;
const float W = 1.0f;
if (m_pBuffer == nullptr)
gfxContext.setViewport(0, wnd.getHeightOffset(), wnd.getScreenWidth(), wnd.getScreenHeight());
else
gfxContext.setViewport(0, 0, m_pBuffer->m_width*m_pBuffer->m_scaleX, m_pBuffer->m_height*m_pBuffer->m_scaleY);
textureCache().activateTexture(0, m_pTexture);
// Disable filtering to avoid black outlines
Context::TexParameters texParams;
texParams.handle = m_pTexture->name;
texParams.target = textureTarget::TEXTURE_2D;
texParams.textureUnitIndex = textureIndices::Tex[0];
texParams.minFilter = textureParameters::FILTER_NEAREST;
texParams.magFilter = textureParameters::FILTER_NEAREST;
gfxContext.setTextureParameters(texParams);
m_programTex->activate();
m_programTex->setEnableAlphaTest(enableAlphaTest);
float texBounds[4] = { s0, t0, s1, t1 };
m_programTex->setTextureBounds(texBounds);
rect[0].x = m_ulx;
rect[0].y = -m_lry;
rect[0].z = m_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].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].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].w = W;
rect[3].s0 = s1;
rect[3].t0 = t1;
drawer.updateScissor(m_pBuffer);
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, m_pBuffer != nullptr ? m_pBuffer->m_FBO : ObjectHandle());
Context::DrawRectParameters rectParams;
rectParams.mode = drawmode::TRIANGLE_STRIP;
rectParams.rectColor.fill(0.0f);
rectParams.verticesCount = 4;
rectParams.vertices = rect;
rectParams.combiner = m_programTex.get();
gfxContext.drawRects(rectParams);
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, m_FBO);
m_programClear->activate();
rect[0].y = m_uly;
rect[1].y = m_uly;
rect[2].y = m_lry;
rect[3].y = m_lry;
if (m_pBuffer == nullptr)
gfxContext.setViewport(0, 0, VI.width, VI.height);
else
gfxContext.setViewport(0, 0, m_pBuffer->m_width, m_pBuffer->m_height);
gfxContext.enable(enable::BLEND, false);
gfxContext.enable(enable::SCISSOR_TEST, false);
rectParams.combiner = m_programClear.get();
gfxContext.drawRects(rectParams);
gfxContext.enable(enable::SCISSOR_TEST, true);
m_pBuffer = frameBufferList().getCurrent();
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, m_pBuffer != nullptr ? m_pBuffer->m_FBO : ObjectHandle());
m_numRects = 0;
m_vecRectCoords.clear();
gDP.otherMode._u64 = otherMode;
gDP.scissor = scissor;
gDP.changed |= CHANGED_COMBINE | CHANGED_SCISSOR | CHANGED_RENDERMODE;
gSP.changed |= CHANGED_VIEWPORT | CHANGED_TEXTURE;
return true;
}
bool TexrectDrawer::isEmpty() {
return m_numRects == 0;
}

42
src/TexrectDrawer.h Normal file
View File

@ -0,0 +1,42 @@
#ifndef TEXRECTDRAWER_H
#define TEXRECTDRAWER_H
#include <memory>
#include <vector>
#include "gDP.h"
#include "Graphics/ObjectHandle.h"
#include "Graphics/ShaderProgram.h"
struct CachedTexture;
struct FrameBuffer;
class TexrectDrawer
{
public:
TexrectDrawer();
void init();
void destroy();
void add();
bool draw();
bool isEmpty();
private:
u32 m_numRects;
u64 m_otherMode;
u64 m_mux;
f32 m_ulx, m_lrx, m_uly, m_lry, m_Z;
f32 m_max_lrx, m_max_lry;
graphics::ObjectHandle m_FBO;
gDPScissor m_scissor;
CachedTexture * m_pTexture;
FrameBuffer * m_pBuffer;
std::unique_ptr<graphics::TexrectDrawerShaderProgram> m_programTex;
std::unique_ptr<graphics::ShaderProgram> m_programClear;
struct RectCoords {
f32 x, y;
};
std::vector<RectCoords> m_vecRectCoords;
};
#endif // TEXRECTDRAWER_H

View File

@ -65,6 +65,7 @@ MY_LOCAL_SRC_FILES := \
$(SRCDIR)/S2DEX2.cpp \
$(SRCDIR)/S2DEX.cpp \
$(SRCDIR)/SoftwareRender.cpp \
$(SRCDIR)/TexrectDrawer.cpp \
$(SRCDIR)/TextDrawer.cpp \
$(SRCDIR)/TextureFilterHandler.cpp \
$(SRCDIR)/Textures.cpp \