- Do more code cleanup and refactoring.
This commit is contained in:
rogerman 2015-05-08 22:45:09 +00:00
parent dcbe28c94e
commit 9d6f284681
10 changed files with 380 additions and 283 deletions

View File

@ -192,6 +192,7 @@ void NDS_DeInit(void)
Screen_DeInit();
MMU_DeInit();
Render3D_DeInit();
gfx3d_deinit();
WIFI_DeInit();

View File

@ -790,20 +790,31 @@ OpenGLRenderer::OpenGLRenderer()
// Init OpenGL rendering states
ref = new OGLRenderRef;
ref->workingDepthBuffer = (GLuint *)calloc(_framebufferWidth * _framebufferHeight, sizeof(GLuint));
ref->workingDepthStencilBuffer = (GLuint *)calloc(_framebufferWidth * _framebufferHeight, sizeof(GLuint));
ref->workingFogAttributesBuffer = (GLuint *)calloc(_framebufferWidth * _framebufferHeight, sizeof(GLuint));
ref->workingPolyIDBuffer = (GLuint *)calloc(_framebufferWidth * _framebufferHeight, sizeof(GLuint));
ref->fboRenderID = 0;
ref->fboMSIntermediateRenderID = 0;
ref->fboPostprocessID = 0;
ref->selectedRenderingFBO = 0;
memset(GPU_screen3D, 0, sizeof(GPU_screen3D));
currTexture = NULL;
gpuScreen3DHasNewData[0] = false;
gpuScreen3DHasNewData[1] = false;
doubleBufferIndex = 0;
_pixelReadNeedsFinish = false;
_currentPolyIndex = 0;
}
OpenGLRenderer::~OpenGLRenderer()
{
// Destroy OpenGL rendering states
free(ref->workingDepthBuffer);
free(ref->workingDepthStencilBuffer);
free(ref->workingFogAttributesBuffer);
free(ref->workingPolyIDBuffer);
delete ref;
ref = NULL;
}
bool OpenGLRenderer::IsExtensionPresent(const std::set<std::string> *oglExtensionSet, const std::string extensionName) const
{
if (oglExtensionSet == NULL || oglExtensionSet->size() == 0)
@ -880,44 +891,34 @@ void OpenGLRenderer::SetVersion(unsigned int major, unsigned int minor, unsigned
this->versionRevision = revision;
}
void OpenGLRenderer::ConvertFramebuffer(const u32 *__restrict srcBuffer, u32 *dstBuffer)
Render3DError OpenGLRenderer::FlushFramebuffer(FragmentColor *dstBuffer)
{
if (srcBuffer == NULL || dstBuffer == NULL)
{
return;
}
// Convert from 32-bit BGRA8888 format to 32-bit RGBA6665 reversed format. OpenGL
// stores pixels using a flipped Y-coordinate, so this needs to be flipped back
// to the DS Y-coordinate.
for(int i = 0, y = 191; y >= 0; y--)
for (size_t y = 0, ir = 0, iw = ((this->_framebufferHeight - 1) * this->_framebufferWidth); y < this->_framebufferHeight; y++, iw -= (this->_framebufferWidth * 2))
{
u32 *__restrict dst = dstBuffer + (y * GFX3D_FRAMEBUFFER_WIDTH);
for(size_t x = 0; x < GFX3D_FRAMEBUFFER_WIDTH; x++, i++)
for (size_t x = 0; x < this->_framebufferWidth; x++, ir++, iw++)
{
// Use the correct endian format since OpenGL uses the native endian of
// the architecture it is running on.
#ifdef WORDS_BIGENDIAN
*dst++ = BGRA8888_32_To_RGBA6665_32(srcBuffer[i]);
dstBuffer[iw].color = BGRA8888_32_To_RGBA6665_32(this->_framebufferColor[ir].color);
#else
*dst++ = BGRA8888_32Rev_To_RGBA6665_32Rev(srcBuffer[i]);
dstBuffer[iw].color = BGRA8888_32Rev_To_RGBA6665_32Rev(this->_framebufferColor[ir].color);
#endif
}
}
return RENDER3DERROR_NOERR;
}
OpenGLRenderer_1_2::~OpenGLRenderer_1_2()
{
if (ref == NULL)
{
return;
}
glFinish();
gpuScreen3DHasNewData[0] = false;
gpuScreen3DHasNewData[1] = false;
_pixelReadNeedsFinish = false;
delete[] ref->color4fBuffer;
ref->color4fBuffer = NULL;
@ -944,10 +945,6 @@ OpenGLRenderer_1_2::~OpenGLRenderer_1_2()
}
glFinish();
// Destroy OpenGL rendering states
delete ref;
ref = NULL;
}
Render3DError OpenGLRenderer_1_2::InitExtensions()
@ -1110,14 +1107,11 @@ void OpenGLRenderer_1_2::DestroyVBOs()
Render3DError OpenGLRenderer_1_2::CreatePBOs()
{
glGenBuffersARB(2, this->ref->pboRenderDataID);
for (size_t i = 0; i < 2; i++)
{
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, this->ref->pboRenderDataID[i]);
glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT * sizeof(u32), NULL, GL_STREAM_READ_ARB);
}
OGLRenderRef &OGLRef = *this->ref;
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
glGenBuffersARB(1, &OGLRef.pboRenderDataID);
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, OGLRef.pboRenderDataID);
glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, this->_framebufferColorSizeBytes, NULL, GL_STREAM_READ_ARB);
return OGLERROR_NOERR;
}
@ -1130,7 +1124,7 @@ void OpenGLRenderer_1_2::DestroyPBOs()
}
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
glDeleteBuffersARB(2, this->ref->pboRenderDataID);
glDeleteBuffersARB(1, &this->ref->pboRenderDataID);
this->isPBOSupported = false;
}
@ -1357,14 +1351,14 @@ Render3DError OpenGLRenderer_1_2::CreateFBOs()
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8_EXT, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, NULL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8_EXT, this->_framebufferWidth, this->_framebufferHeight, 0, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, NULL);
glBindTexture(GL_TEXTURE_2D, OGLRef.texGColorID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, this->_framebufferWidth, this->_framebufferHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_GDepth);
glBindTexture(GL_TEXTURE_2D, OGLRef.texGDepthID);
@ -1372,7 +1366,7 @@ Render3DError OpenGLRenderer_1_2::CreateFBOs()
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, this->_framebufferWidth, this->_framebufferHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_GPolyID);
glBindTexture(GL_TEXTURE_2D, OGLRef.texGPolyID);
@ -1380,7 +1374,7 @@ Render3DError OpenGLRenderer_1_2::CreateFBOs()
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, this->_framebufferWidth, this->_framebufferHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_FogAttr);
glBindTexture(GL_TEXTURE_2D, OGLRef.texGFogAttrID);
@ -1388,7 +1382,7 @@ Render3DError OpenGLRenderer_1_2::CreateFBOs()
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, this->_framebufferWidth, this->_framebufferHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, OGLRef.texPostprocessFogID);
@ -1396,7 +1390,7 @@ Render3DError OpenGLRenderer_1_2::CreateFBOs()
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, this->_framebufferWidth, this->_framebufferHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glBindTexture(GL_TEXTURE_2D, 0);
@ -1517,15 +1511,15 @@ Render3DError OpenGLRenderer_1_2::CreateMultisampledFBO()
glGenRenderbuffersEXT(1, &OGLRef.rboMSGDepthStencilID);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, OGLRef.rboMSGColorID);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, maxSamples, GL_RGBA, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, maxSamples, GL_RGBA, this->_framebufferWidth, this->_framebufferHeight);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, OGLRef.rboMSGDepthID);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, maxSamples, GL_RGBA, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, maxSamples, GL_RGBA, this->_framebufferWidth, this->_framebufferHeight);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, OGLRef.rboMSGPolyID);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, maxSamples, GL_RGBA, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, maxSamples, GL_RGBA, this->_framebufferWidth, this->_framebufferHeight);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, OGLRef.rboMSGFogAttrID);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, maxSamples, GL_RGBA, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, maxSamples, GL_RGBA, this->_framebufferWidth, this->_framebufferHeight);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, OGLRef.rboMSGDepthStencilID);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, maxSamples, GL_DEPTH24_STENCIL8_EXT, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, maxSamples, GL_DEPTH24_STENCIL8_EXT, this->_framebufferWidth, this->_framebufferHeight);
// Set up multisampled rendering FBO
glGenFramebuffersEXT(1, &OGLRef.fboMSIntermediateRenderID);
@ -1708,35 +1702,41 @@ Render3DError OpenGLRenderer_1_2::UploadClearImage(const u16 *__restrict colorBu
{
OGLRenderRef &OGLRef = *this->ref;
static GLuint depth[GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT];
static GLuint depthStencil[GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT];
static GLuint fogAttributes[GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT];
static GLuint polyID[GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT];
for (size_t i = 0; i < GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT; i++)
if (this->isShaderSupported)
{
depth[i] = depthBuffer[i] | 0xFF000000;
depthStencil[i] = depthBuffer[i] << 8;
fogAttributes[i] = (fogBuffer[i]) ? 0xFF0000FF : 0xFF000000;
polyID[i] = (GLuint)polyIDBuffer[i] | 0xFF000000;
for (size_t i = 0; i < this->_framebufferWidth * this->_framebufferHeight; i++)
{
OGLRef.workingDepthStencilBuffer[i] = depthBuffer[i] << 8;
OGLRef.workingDepthBuffer[i] = depthBuffer[i] | 0xFF000000;
OGLRef.workingFogAttributesBuffer[i] = (fogBuffer[i]) ? 0xFF0000FF : 0xFF000000;
OGLRef.workingPolyIDBuffer[i] = (GLuint)polyIDBuffer[i] | 0xFF000000;
}
}
else
{
for (size_t i = 0; i < this->_framebufferWidth * this->_framebufferHeight; i++)
{
OGLRef.workingDepthStencilBuffer[i] = depthBuffer[i] << 8;
}
}
glActiveTextureARB(GL_TEXTURE0_ARB + OGLTextureUnitID_GColor);
glBindTexture(GL_TEXTURE_2D, OGLRef.texGDepthStencilID);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, depthStencil);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, this->_framebufferWidth, this->_framebufferHeight, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, OGLRef.workingDepthStencilBuffer);
glBindTexture(GL_TEXTURE_2D, OGLRef.texGColorID);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, colorBuffer);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, this->_framebufferWidth, this->_framebufferHeight, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, colorBuffer);
glActiveTextureARB(GL_TEXTURE0_ARB + OGLTextureUnitID_GDepth);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, depth);
glActiveTextureARB(GL_TEXTURE0_ARB + OGLTextureUnitID_GPolyID);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, polyID);
glActiveTextureARB(GL_TEXTURE0_ARB + OGLTextureUnitID_FogAttr);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, fogAttributes);
glActiveTextureARB(GL_TEXTURE0_ARB);
if (this->isShaderSupported)
{
glActiveTextureARB(GL_TEXTURE0_ARB + OGLTextureUnitID_GDepth);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, this->_framebufferWidth, this->_framebufferHeight, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, OGLRef.workingDepthBuffer);
glActiveTextureARB(GL_TEXTURE0_ARB + OGLTextureUnitID_FogAttr);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, this->_framebufferWidth, this->_framebufferHeight, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, OGLRef.workingFogAttributesBuffer);
glActiveTextureARB(GL_TEXTURE0_ARB + OGLTextureUnitID_GPolyID);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, this->_framebufferWidth, this->_framebufferHeight, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, OGLRef.workingPolyIDBuffer);
}
return OGLERROR_NOERR;
}
@ -1860,22 +1860,22 @@ Render3DError OpenGLRenderer_1_2::DownsampleFBO()
// Blit the color buffer
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
glBlitFramebufferEXT(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBlitFramebufferEXT(0, 0, this->_framebufferWidth, this->_framebufferHeight, 0, 0, this->_framebufferWidth, this->_framebufferHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
// Blit the working depth buffer
glReadBuffer(GL_COLOR_ATTACHMENT1_EXT);
glDrawBuffer(GL_COLOR_ATTACHMENT1_EXT);
glBlitFramebufferEXT(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBlitFramebufferEXT(0, 0, this->_framebufferWidth, this->_framebufferHeight, 0, 0, this->_framebufferWidth, this->_framebufferHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
// Blit the polygon ID buffer
glReadBuffer(GL_COLOR_ATTACHMENT2_EXT);
glDrawBuffer(GL_COLOR_ATTACHMENT2_EXT);
glBlitFramebufferEXT(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBlitFramebufferEXT(0, 0, this->_framebufferWidth, this->_framebufferHeight, 0, 0, this->_framebufferWidth, this->_framebufferHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
// Blit the fog buffer
glReadBuffer(GL_COLOR_ATTACHMENT3_EXT);
glDrawBuffer(GL_COLOR_ATTACHMENT3_EXT);
glBlitFramebufferEXT(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBlitFramebufferEXT(0, 0, this->_framebufferWidth, this->_framebufferHeight, 0, 0, this->_framebufferWidth, this->_framebufferHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
// Reset framebuffer targets
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
@ -1888,16 +1888,12 @@ Render3DError OpenGLRenderer_1_2::DownsampleFBO()
Render3DError OpenGLRenderer_1_2::ReadBackPixels()
{
const size_t i = this->doubleBufferIndex;
if (this->isPBOSupported)
{
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, this->ref->pboRenderDataID[i]);
glReadPixels(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_BGRA, GL_UNSIGNED_BYTE, 0);
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
glReadPixels(0, 0, this->_framebufferWidth, this->_framebufferHeight, GL_BGRA, GL_UNSIGNED_BYTE, 0);
}
this->gpuScreen3DHasNewData[i] = true;
this->_pixelReadNeedsFinish = true;
return OGLERROR_NOERR;
}
@ -1916,7 +1912,6 @@ Render3DError OpenGLRenderer_1_2::DeleteTexture(const TexCacheItem *item)
Render3DError OpenGLRenderer_1_2::BeginRender(const GFX3D &engine)
{
OGLRenderRef &OGLRef = *this->ref;
this->doubleBufferIndex = (this->doubleBufferIndex + 1) & 0x01;
if(!BEGINGL())
{
@ -2211,22 +2206,22 @@ Render3DError OpenGLRenderer_1_2::ClearUsingImage(const u16 *__restrict colorBuf
// Blit the working depth buffer
glReadBuffer(GL_COLOR_ATTACHMENT1_EXT);
glDrawBuffer(GL_COLOR_ATTACHMENT1_EXT);
glBlitFramebufferEXT(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBlitFramebufferEXT(0, 0, this->_framebufferWidth, this->_framebufferHeight, 0, 0, this->_framebufferWidth, this->_framebufferHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
// Blit the polygon ID buffer
glReadBuffer(GL_COLOR_ATTACHMENT2_EXT);
glDrawBuffer(GL_COLOR_ATTACHMENT2_EXT);
glBlitFramebufferEXT(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBlitFramebufferEXT(0, 0, this->_framebufferWidth, this->_framebufferHeight, 0, 0, this->_framebufferWidth, this->_framebufferHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
// Blit the fog buffer
glReadBuffer(GL_COLOR_ATTACHMENT3_EXT);
glDrawBuffer(GL_COLOR_ATTACHMENT3_EXT);
glBlitFramebufferEXT(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBlitFramebufferEXT(0, 0, this->_framebufferWidth, this->_framebufferHeight, 0, 0, this->_framebufferWidth, this->_framebufferHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
// Blit the color buffer. Do this last so that color attachment 0 is set to the read FBO.
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
glBlitFramebufferEXT(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);
glBlitFramebufferEXT(0, 0, this->_framebufferWidth, this->_framebufferHeight, 0, 0, this->_framebufferWidth, this->_framebufferHeight, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);
}
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.selectedRenderingFBO);
@ -2492,13 +2487,7 @@ Render3DError OpenGLRenderer_1_2::Reset()
ENDGL();
this->gpuScreen3DHasNewData[0] = false;
this->gpuScreen3DHasNewData[1] = false;
for (size_t i = 0; i < 2; i++)
{
memset(this->GPU_screen3D[i], 0, sizeof(this->GPU_screen3D[i]));
}
this->_pixelReadNeedsFinish = false;
if (OGLRef.color4fBuffer != NULL)
{
@ -2511,13 +2500,14 @@ Render3DError OpenGLRenderer_1_2::Reset()
}
this->currTexture = NULL;
this->doubleBufferIndex = 0;
this->_currentPolyIndex = 0;
OGLRef.vtxPtrPosition = (GLvoid *)offsetof(VERT, coord);
OGLRef.vtxPtrTexCoord = (GLvoid *)offsetof(VERT, texcoord);
OGLRef.vtxPtrColor = (this->isShaderSupported) ? (GLvoid *)offsetof(VERT, color) : OGLRef.color4fBuffer;
memset(this->clearImageColor16Buffer, 0, sizeof(this->clearImageColor16Buffer));
memset(this->clearImageDepthBuffer, 0, sizeof(this->clearImageDepthBuffer));
memset(this->clearImagePolyIDBuffer, 0, sizeof(this->clearImagePolyIDBuffer));
@ -2530,15 +2520,11 @@ Render3DError OpenGLRenderer_1_2::Reset()
Render3DError OpenGLRenderer_1_2::RenderFinish()
{
const size_t i = this->doubleBufferIndex;
if (!this->gpuScreen3DHasNewData[i])
if (!this->_pixelReadNeedsFinish)
{
return OGLERROR_NOERR;
}
OGLRenderRef &OGLRef = *this->ref;
if(!BEGINGL())
{
return OGLERROR_BEGINGL_FAILED;
@ -2546,31 +2532,38 @@ Render3DError OpenGLRenderer_1_2::RenderFinish()
if (this->isPBOSupported)
{
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, OGLRef.pboRenderDataID[i]);
const u32 *__restrict mappedBufferPtr = (u32 *__restrict)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY_ARB);
const FragmentColor *__restrict mappedBufferPtr = (FragmentColor *__restrict)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY_ARB);
if (mappedBufferPtr != NULL)
{
this->ConvertFramebuffer(mappedBufferPtr, (u32 *)gfx3d_convertedScreen);
memcpy(this->_framebufferColor, mappedBufferPtr, this->_framebufferColorSizeBytes);
glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
}
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
}
else
{
u32 *__restrict workingBuffer = this->GPU_screen3D[i];
glReadPixels(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_BGRA, GL_UNSIGNED_BYTE, workingBuffer);
this->ConvertFramebuffer(workingBuffer, (u32 *)gfx3d_convertedScreen);
glReadPixels(0, 0, this->_framebufferWidth, this->_framebufferHeight, GL_BGRA, GL_UNSIGNED_BYTE, this->_framebufferColor);
}
ENDGL();
this->gpuScreen3DHasNewData[i] = false;
this->FlushFramebuffer((FragmentColor *)gfx3d_convertedScreen);
this->_pixelReadNeedsFinish = false;
return OGLERROR_NOERR;
}
Render3DError OpenGLRenderer_1_2::SetFramebufferSize(size_t w, size_t h)
{
if (w < GFX3D_FRAMEBUFFER_WIDTH || h < GFX3D_FRAMEBUFFER_HEIGHT)
{
return RENDER3DERROR_NOERR;
}
// TODO: We're not prepared to do this yet, so do nothing for now.
return RENDER3DERROR_NOERR;
}
Render3DError OpenGLRenderer_1_3::CreateToonTable()
{
OGLRenderRef &OGLRef = *this->ref;
@ -2605,33 +2598,41 @@ Render3DError OpenGLRenderer_1_3::UploadClearImage(const u16 *__restrict colorBu
{
OGLRenderRef &OGLRef = *this->ref;
static GLuint depth[GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT];
static GLuint depthStencil[GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT];
static GLuint fogAttributes[GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT];
static GLuint polyID[GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT];
for (size_t i = 0; i < GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT; i++)
if (this->isShaderSupported)
{
depth[i] = depthBuffer[i] | 0xFF000000;
depthStencil[i] = depthBuffer[i] << 8;
fogAttributes[i] = (fogBuffer[i]) ? 0xFF0000FF : 0xFF000000;
polyID[i] = (GLuint)polyIDBuffer[i] | 0xFF000000;
for (size_t i = 0; i < this->_framebufferWidth * this->_framebufferHeight; i++)
{
OGLRef.workingDepthStencilBuffer[i] = depthBuffer[i] << 8;
OGLRef.workingDepthBuffer[i] = depthBuffer[i] | 0xFF000000;
OGLRef.workingFogAttributesBuffer[i] = (fogBuffer[i]) ? 0xFF0000FF : 0xFF000000;
OGLRef.workingPolyIDBuffer[i] = (GLuint)polyIDBuffer[i] | 0xFF000000;
}
}
else
{
for (size_t i = 0; i < this->_framebufferWidth * this->_framebufferHeight; i++)
{
OGLRef.workingDepthStencilBuffer[i] = depthBuffer[i] << 8;
}
}
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_GColor);
glBindTexture(GL_TEXTURE_2D, OGLRef.texGDepthStencilID);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, depthStencil);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, this->_framebufferWidth, this->_framebufferHeight, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, OGLRef.workingDepthStencilBuffer);
glBindTexture(GL_TEXTURE_2D, OGLRef.texGColorID);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, colorBuffer);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, this->_framebufferWidth, this->_framebufferHeight, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, colorBuffer);
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_GDepth);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, depth);
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_GPolyID);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, polyID);
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_FogAttr);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, fogAttributes);
if (this->isShaderSupported)
{
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_GDepth);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, this->_framebufferWidth, this->_framebufferHeight, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, OGLRef.workingDepthBuffer);
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_FogAttr);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, this->_framebufferWidth, this->_framebufferHeight, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, OGLRef.workingFogAttributesBuffer);
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_GPolyID);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, this->_framebufferWidth, this->_framebufferHeight, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, OGLRef.workingPolyIDBuffer);
}
return OGLERROR_NOERR;
}
@ -2729,14 +2730,9 @@ Render3DError OpenGLRenderer_1_5::CreatePBOs()
{
OGLRenderRef &OGLRef = *this->ref;
glGenBuffers(2, OGLRef.pboRenderDataID);
for (size_t i = 0; i < 2; i++)
{
glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, OGLRef.pboRenderDataID[i]);
glBufferData(GL_PIXEL_PACK_BUFFER_ARB, GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT * sizeof(u32), NULL, GL_STREAM_READ);
}
glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
glGenBuffers(1, &OGLRef.pboRenderDataID);
glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, OGLRef.pboRenderDataID);
glBufferData(GL_PIXEL_PACK_BUFFER_ARB, this->_framebufferColorSizeBytes, NULL, GL_STREAM_READ);
return OGLERROR_NOERR;
}
@ -2749,7 +2745,7 @@ void OpenGLRenderer_1_5::DestroyPBOs()
}
glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
glDeleteBuffers(2, this->ref->pboRenderDataID);
glDeleteBuffers(1, &this->ref->pboRenderDataID);
this->isPBOSupported = false;
}
@ -2855,7 +2851,6 @@ Render3DError OpenGLRenderer_1_5::DisableVertexAttributes()
Render3DError OpenGLRenderer_1_5::BeginRender(const GFX3D &engine)
{
OGLRenderRef &OGLRef = *this->ref;
this->doubleBufferIndex = (this->doubleBufferIndex + 1) & 0x01;
if(!BEGINGL())
{
@ -2929,31 +2924,23 @@ Render3DError OpenGLRenderer_1_5::BeginRender(const GFX3D &engine)
Render3DError OpenGLRenderer_1_5::ReadBackPixels()
{
const size_t i = this->doubleBufferIndex;
if (this->isPBOSupported)
{
glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, this->ref->pboRenderDataID[i]);
glReadPixels(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_BGRA, GL_UNSIGNED_BYTE, 0);
glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
glReadPixels(0, 0, this->_framebufferWidth, this->_framebufferHeight, GL_BGRA, GL_UNSIGNED_BYTE, 0);
}
this->gpuScreen3DHasNewData[i] = true;
this->_pixelReadNeedsFinish = true;
return OGLERROR_NOERR;
}
Render3DError OpenGLRenderer_1_5::RenderFinish()
{
const size_t i = this->doubleBufferIndex;
if (!this->gpuScreen3DHasNewData[i])
if (!this->_pixelReadNeedsFinish)
{
return OGLERROR_NOERR;
}
OGLRenderRef &OGLRef = *this->ref;
if(!BEGINGL())
{
return OGLERROR_BEGINGL_FAILED;
@ -2961,27 +2948,22 @@ Render3DError OpenGLRenderer_1_5::RenderFinish()
if (this->isPBOSupported)
{
glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, OGLRef.pboRenderDataID[i]);
const u32 *__restrict mappedBufferPtr = (u32 *__restrict)glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
const FragmentColor *__restrict mappedBufferPtr = (FragmentColor *__restrict)glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
if (mappedBufferPtr != NULL)
{
this->ConvertFramebuffer(mappedBufferPtr, (u32 *)gfx3d_convertedScreen);
memcpy(this->_framebufferColor, mappedBufferPtr, this->_framebufferColorSizeBytes);
glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB);
}
glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
}
else
{
u32 *__restrict workingBuffer = this->GPU_screen3D[i];
glReadPixels(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_BGRA, GL_UNSIGNED_BYTE, workingBuffer);
this->ConvertFramebuffer(workingBuffer, (u32 *)gfx3d_convertedScreen);
glReadPixels(0, 0, this->_framebufferWidth, this->_framebufferHeight, GL_BGRA, GL_UNSIGNED_BYTE, this->_framebufferColor);
}
ENDGL();
this->gpuScreen3DHasNewData[i] = false;
this->FlushFramebuffer((FragmentColor *)gfx3d_convertedScreen);
this->_pixelReadNeedsFinish = false;
return OGLERROR_NOERR;
}
@ -3392,7 +3374,6 @@ Render3DError OpenGLRenderer_2_0::DisableVertexAttributes()
Render3DError OpenGLRenderer_2_0::BeginRender(const GFX3D &engine)
{
OGLRenderRef &OGLRef = *this->ref;
this->doubleBufferIndex = (this->doubleBufferIndex + 1) & 0x01;
if(!BEGINGL())
{
@ -3489,10 +3470,10 @@ Render3DError OpenGLRenderer_2_0::RenderEdgeMarking(const u16 *colorTable, const
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboRenderID);
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
glUseProgram(OGLRef.programEdgeMarkID);
glUniform2f(OGLRef.uniformFramebufferSize, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT);
glUniform2f(OGLRef.uniformFramebufferSize, this->_framebufferWidth, this->_framebufferHeight);
glUniform4fv(OGLRef.uniformStateEdgeColor, 8, oglColor);
glViewport(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT);
glViewport(0, 0, this->_framebufferWidth, this->_framebufferHeight);
glDisable(GL_DEPTH_TEST);
glDisable(GL_STENCIL_TEST);
glEnable(GL_BLEND);
@ -3559,7 +3540,7 @@ Render3DError OpenGLRenderer_2_0::RenderFog(const u8 *densityTable, const u32 co
glUniform1f(OGLRef.uniformStateFogStep, oglFogStep);
glUniform1fv(OGLRef.uniformStateFogDensity, 32, oglDensityTable);
glViewport(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT);
glViewport(0, 0, this->_framebufferWidth, this->_framebufferHeight);
glDisable(GL_DEPTH_TEST);
glDisable(GL_STENCIL_TEST);
glDisable(GL_BLEND);
@ -3737,22 +3718,15 @@ Render3DError OpenGLRenderer_2_0::SetupTexture(const POLY &thePoly, bool enableT
Render3DError OpenGLRenderer_2_1::ReadBackPixels()
{
const size_t i = this->doubleBufferIndex;
glBindBuffer(GL_PIXEL_PACK_BUFFER, this->ref->pboRenderDataID[i]);
glReadPixels(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_BGRA, GL_UNSIGNED_BYTE, 0);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
this->gpuScreen3DHasNewData[i] = true;
glReadPixels(0, 0, this->_framebufferWidth, this->_framebufferHeight, GL_BGRA, GL_UNSIGNED_BYTE, 0);
this->_pixelReadNeedsFinish = true;
return OGLERROR_NOERR;
}
Render3DError OpenGLRenderer_2_1::RenderFinish()
{
const size_t i = this->doubleBufferIndex;
if (!this->gpuScreen3DHasNewData[i])
if (!this->_pixelReadNeedsFinish)
{
return OGLERROR_NOERR;
}
@ -3762,20 +3736,17 @@ Render3DError OpenGLRenderer_2_1::RenderFinish()
return OGLERROR_BEGINGL_FAILED;
}
glBindBuffer(GL_PIXEL_PACK_BUFFER, this->ref->pboRenderDataID[i]);
const u32 *__restrict mappedBufferPtr = (u32 *__restrict)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
const FragmentColor *__restrict mappedBufferPtr = (FragmentColor *__restrict)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
if (mappedBufferPtr != NULL)
{
this->ConvertFramebuffer(mappedBufferPtr, (u32 *)gfx3d_convertedScreen);
memcpy(this->_framebufferColor, mappedBufferPtr, this->_framebufferColorSizeBytes);
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
}
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
ENDGL();
this->gpuScreen3DHasNewData[i] = false;
this->FlushFramebuffer((FragmentColor *)gfx3d_convertedScreen);
this->_pixelReadNeedsFinish = false;
return OGLERROR_NOERR;
}

View File

@ -405,7 +405,7 @@ struct OGLRenderRef
GLuint iboPostprocessIndexID;
// PBO
GLuint pboRenderDataID[2];
GLuint pboRenderDataID;
// UBO / TBO
GLuint uboRenderStatesID;
@ -482,6 +482,10 @@ struct OGLRenderRef
// Client-side Buffers
GLfloat *color4fBuffer;
GLushort *vertIndexBuffer;
GLuint *workingDepthBuffer;
GLuint *workingDepthStencilBuffer;
GLuint *workingFogAttributesBuffer;
GLuint *workingPolyIDBuffer;
// Vertex Attributes Pointers
GLvoid *vtxPtrPosition;
@ -561,11 +565,11 @@ protected:
// Textures
TexCacheItem *currTexture;
CACHE_ALIGN u32 GPU_screen3D[2][GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT * sizeof(u32)];
bool gpuScreen3DHasNewData[2];
size_t doubleBufferIndex;
bool _pixelReadNeedsFinish;
size_t _currentPolyIndex;
Render3DError FlushFramebuffer(FragmentColor *dstBuffer);
// OpenGL-specific methods
virtual Render3DError CreateVBOs() = 0;
virtual void DestroyVBOs() = 0;
@ -607,7 +611,7 @@ protected:
public:
OpenGLRenderer();
virtual ~OpenGLRenderer() {};
virtual ~OpenGLRenderer();
virtual Render3DError InitExtensions() = 0;
virtual Render3DError DeleteTexture(const TexCacheItem *item) = 0;
@ -617,7 +621,6 @@ public:
bool ValidateShaderProgramLink(GLuint theProgram) const;
void GetVersion(unsigned int *major, unsigned int *minor, unsigned int *revision) const;
void SetVersion(unsigned int major, unsigned int minor, unsigned int revision);
void ConvertFramebuffer(const u32 *__restrict srcBuffer, u32 *dstBuffer);
};
class OpenGLRenderer_1_2 : public OpenGLRenderer
@ -681,6 +684,7 @@ public:
virtual Render3DError UpdateToonTable(const u16 *toonTableBuffer);
virtual Render3DError Reset();
virtual Render3DError RenderFinish();
virtual Render3DError SetFramebufferSize(size_t w, size_t h);
virtual Render3DError DeleteTexture(const TexCacheItem *item);
};

View File

@ -606,14 +606,14 @@ Render3DError OpenGLRenderer_3_2::CreateFBOs()
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, this->_framebufferWidth, this->_framebufferHeight, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL);
glBindTexture(GL_TEXTURE_2D, OGLRef.texGColorID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, this->_framebufferWidth, this->_framebufferHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_GDepth);
glBindTexture(GL_TEXTURE_2D, OGLRef.texGDepthID);
@ -621,7 +621,7 @@ Render3DError OpenGLRenderer_3_2::CreateFBOs()
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, this->_framebufferWidth, this->_framebufferHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_GPolyID);
glBindTexture(GL_TEXTURE_2D, OGLRef.texGPolyID);
@ -629,7 +629,7 @@ Render3DError OpenGLRenderer_3_2::CreateFBOs()
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, this->_framebufferWidth, this->_framebufferHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_FogAttr);
glBindTexture(GL_TEXTURE_2D, OGLRef.texGFogAttrID);
@ -637,7 +637,7 @@ Render3DError OpenGLRenderer_3_2::CreateFBOs()
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, this->_framebufferWidth, this->_framebufferHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, OGLRef.texPostprocessFogID);
@ -645,7 +645,7 @@ Render3DError OpenGLRenderer_3_2::CreateFBOs()
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, this->_framebufferWidth, this->_framebufferHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glBindTexture(GL_TEXTURE_2D, 0);
@ -769,15 +769,15 @@ Render3DError OpenGLRenderer_3_2::CreateMultisampledFBO()
glGenRenderbuffers(1, &OGLRef.rboMSGDepthStencilID);
glBindRenderbuffer(GL_RENDERBUFFER, OGLRef.rboMSGColorID);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, maxSamples, GL_RGBA, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, maxSamples, GL_RGBA, this->_framebufferWidth, this->_framebufferHeight);
glBindRenderbuffer(GL_RENDERBUFFER, OGLRef.rboMSGDepthID);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, maxSamples, GL_RGBA, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, maxSamples, GL_RGBA, this->_framebufferWidth, this->_framebufferHeight);
glBindRenderbuffer(GL_RENDERBUFFER, OGLRef.rboMSGPolyID);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, maxSamples, GL_RGBA, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, maxSamples, GL_RGBA, this->_framebufferWidth, this->_framebufferHeight);
glBindRenderbuffer(GL_RENDERBUFFER, OGLRef.rboMSGFogAttrID);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, maxSamples, GL_RGBA, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, maxSamples, GL_RGBA, this->_framebufferWidth, this->_framebufferHeight);
glBindRenderbuffer(GL_RENDERBUFFER, OGLRef.rboMSGDepthStencilID);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, maxSamples, GL_DEPTH24_STENCIL8, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, maxSamples, GL_DEPTH24_STENCIL8, this->_framebufferWidth, this->_framebufferHeight);
// Set up multisampled rendering FBO
glGenFramebuffers(1, &OGLRef.fboMSIntermediateRenderID);
@ -1014,22 +1014,22 @@ Render3DError OpenGLRenderer_3_2::DownsampleFBO()
// Blit the color buffer
glReadBuffer(GL_COLOR_ATTACHMENT0);
glDrawBuffer(GL_COLOR_ATTACHMENT0);
glBlitFramebuffer(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBlitFramebuffer(0, 0, this->_framebufferWidth, this->_framebufferHeight, 0, 0, this->_framebufferWidth, this->_framebufferHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
// Blit the working depth buffer
glReadBuffer(GL_COLOR_ATTACHMENT1);
glDrawBuffer(GL_COLOR_ATTACHMENT1);
glBlitFramebuffer(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBlitFramebuffer(0, 0, this->_framebufferWidth, this->_framebufferHeight, 0, 0, this->_framebufferWidth, this->_framebufferHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
// Blit the polygon ID buffer
glReadBuffer(GL_COLOR_ATTACHMENT2);
glDrawBuffer(GL_COLOR_ATTACHMENT2);
glBlitFramebuffer(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBlitFramebuffer(0, 0, this->_framebufferWidth, this->_framebufferHeight, 0, 0, this->_framebufferWidth, this->_framebufferHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
// Blit the fog buffer
glReadBuffer(GL_COLOR_ATTACHMENT3);
glDrawBuffer(GL_COLOR_ATTACHMENT3);
glBlitFramebuffer(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBlitFramebuffer(0, 0, this->_framebufferWidth, this->_framebufferHeight, 0, 0, this->_framebufferWidth, this->_framebufferHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
// Reset framebuffer targets
glReadBuffer(GL_COLOR_ATTACHMENT0);
@ -1043,7 +1043,6 @@ Render3DError OpenGLRenderer_3_2::DownsampleFBO()
Render3DError OpenGLRenderer_3_2::BeginRender(const GFX3D &engine)
{
OGLRenderRef &OGLRef = *this->ref;
this->doubleBufferIndex = (this->doubleBufferIndex + 1) & 0x01;
if(!BEGINGL())
{
@ -1057,8 +1056,8 @@ Render3DError OpenGLRenderer_3_2::BeginRender(const GFX3D &engine)
glBindBuffer(GL_UNIFORM_BUFFER, OGLRef.uboRenderStatesID);
OGLRenderStates *state = (OGLRenderStates *)glMapBufferRange(GL_UNIFORM_BUFFER, 0, sizeof(OGLRenderStates), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
state->framebufferSize.x = GFX3D_FRAMEBUFFER_WIDTH;
state->framebufferSize.y = GFX3D_FRAMEBUFFER_HEIGHT;
state->framebufferSize.x = this->_framebufferWidth;
state->framebufferSize.y = this->_framebufferHeight;
state->toonShadingMode = engine.renderState.shading;
state->enableAlphaTest = (engine.renderState.enableAlphaTest) ? GL_TRUE : GL_FALSE;
state->enableAntialiasing = (engine.renderState.enableAntialiasing) ? GL_TRUE : GL_FALSE;
@ -1171,7 +1170,7 @@ Render3DError OpenGLRenderer_3_2::RenderEdgeMarking(const u16 *colorTable, const
glDrawBuffer(GL_COLOR_ATTACHMENT0);
glUseProgram(OGLRef.programEdgeMarkID);
glViewport(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT);
glViewport(0, 0, this->_framebufferWidth, this->_framebufferHeight);
glDisable(GL_DEPTH_TEST);
glDisable(GL_STENCIL_TEST);
glEnable(GL_BLEND);
@ -1195,7 +1194,7 @@ Render3DError OpenGLRenderer_3_2::RenderFog(const u8 *densityTable, const u32 co
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboPostprocessID);
glUseProgram(OGLRef.programFogID);
glViewport(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT);
glViewport(0, 0, this->_framebufferWidth, this->_framebufferHeight);
glDisable(GL_DEPTH_TEST);
glDisable(GL_STENCIL_TEST);
glDisable(GL_BLEND);
@ -1245,22 +1244,22 @@ Render3DError OpenGLRenderer_3_2::ClearUsingImage(const u16 *__restrict colorBuf
// Blit the working depth buffer
glReadBuffer(GL_COLOR_ATTACHMENT1);
glDrawBuffer(GL_COLOR_ATTACHMENT1);
glBlitFramebuffer(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBlitFramebuffer(0, 0, this->_framebufferWidth, this->_framebufferHeight, 0, 0, this->_framebufferWidth, this->_framebufferHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
// Blit the polygon ID buffer
glReadBuffer(GL_COLOR_ATTACHMENT2);
glDrawBuffer(GL_COLOR_ATTACHMENT2);
glBlitFramebuffer(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBlitFramebuffer(0, 0, this->_framebufferWidth, this->_framebufferHeight, 0, 0, this->_framebufferWidth, this->_framebufferHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
// Blit the fog buffer
glReadBuffer(GL_COLOR_ATTACHMENT3);
glDrawBuffer(GL_COLOR_ATTACHMENT3);
glBlitFramebuffer(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBlitFramebuffer(0, 0, this->_framebufferWidth, this->_framebufferHeight, 0, 0, this->_framebufferWidth, this->_framebufferHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
// Blit the color buffer. Do this last so that color attachment 0 is set to the read FBO.
glReadBuffer(GL_COLOR_ATTACHMENT0);
glDrawBuffer(GL_COLOR_ATTACHMENT0);
glBlitFramebuffer(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
glBlitFramebuffer(0, 0, this->_framebufferWidth, this->_framebufferHeight, 0, 0, this->_framebufferWidth, this->_framebufferHeight, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
}
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.selectedRenderingFBO);

View File

@ -308,7 +308,10 @@ static float normalTable[1024];
#define fix2float(v) (((float)((s32)(v))) / (float)(1<<12))
#define fix10_2float(v) (((float)((s32)(v))) / (float)(1<<9))
CACHE_ALIGN u8 gfx3d_convertedScreen[GFX3D_FRAMEBUFFER_WIDTH*GFX3D_FRAMEBUFFER_HEIGHT*4];
// Color buffer that is filled by the 3D renderer and is read by the GPU engine.
u8 *gfx3d_convertedScreen = NULL;
static size_t gfx3d_framebufferWidth = GFX3D_FRAMEBUFFER_WIDTH;
static size_t gfx3d_framebufferHeight = GFX3D_FRAMEBUFFER_HEIGHT;
// Matrix stack handling
CACHE_ALIGN MatrixStack mtxStack[4] = {
@ -537,6 +540,14 @@ void gfx3d_init()
vertlist = &vertlists[0];
}
gfx3d_framebufferWidth = GFX3D_FRAMEBUFFER_WIDTH;
gfx3d_framebufferHeight = GFX3D_FRAMEBUFFER_HEIGHT;
if (gfx3d_convertedScreen == NULL)
{
gfx3d_convertedScreen = (u8 *)malloc(gfx3d_framebufferWidth * gfx3d_framebufferHeight * sizeof(FragmentColor));
}
gfx3d.state.fogDensityTable = MMU.MMU_MEM[ARMCPU_ARM9][0x40]+0x0360;
gfx3d.state.edgeMarkColorTable = (u16 *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]+0x0330);
@ -544,6 +555,20 @@ void gfx3d_init()
gfx3d_reset();
}
void gfx3d_deinit()
{
free(polylists);
polylists = NULL;
polylist = NULL;
free(vertlists);
vertlists = NULL;
vertlist = NULL;
free(gfx3d_convertedScreen);
gfx3d_convertedScreen = NULL;
}
void gfx3d_reset()
{
CurrentRenderer->RenderFinish();
@ -616,7 +641,7 @@ void gfx3d_reset()
last_s = 0;
viewport = 0xBFFF0000;
memset(gfx3d_convertedScreen,0,sizeof(gfx3d_convertedScreen));
memset(gfx3d_convertedScreen, 0, sizeof(gfx3d_framebufferWidth * gfx3d_framebufferHeight * sizeof(FragmentColor)));
gfx3d.state.clearDepth = DS_DEPTH15TO24(0x7FFF);
@ -629,6 +654,31 @@ void gfx3d_reset()
CurrentRenderer->Reset();
}
size_t gfx3d_getFramebufferWidth()
{
return gfx3d_framebufferWidth;
}
size_t gfx3d_getFramebufferHeight()
{
return gfx3d_framebufferHeight;
}
void gfx3d_setFramebufferSize(size_t w, size_t h)
{
if (w < GFX3D_FRAMEBUFFER_WIDTH || h < GFX3D_FRAMEBUFFER_HEIGHT)
{
return;
}
CurrentRenderer->RenderFinish();
gfx3d_framebufferWidth = w;
gfx3d_framebufferHeight = h;
gfx3d_convertedScreen = (u8 *)realloc(gfx3d_convertedScreen, w * h * sizeof(FragmentColor));
CurrentRenderer->SetFramebufferSize(w, h);
}
//================================================================================= Geometry Engine
//=================================================================================
@ -2282,7 +2332,7 @@ void gfx3d_VBlankEndSignal(bool skipFrame)
if(!CommonSettings.showGpu.main)
{
memset(gfx3d_convertedScreen,0,sizeof(gfx3d_convertedScreen));
memset(gfx3d_convertedScreen, 0, sizeof(gfx3d_framebufferWidth * gfx3d_framebufferHeight * sizeof(FragmentColor)));
return;
}

View File

@ -217,8 +217,13 @@ enum
};
void gfx3d_init();
void gfx3d_deinit();
void gfx3d_reset();
size_t gfx3d_getFramebufferWidth();
size_t gfx3d_getFramebufferHeight();
void gfx3d_setFramebufferSize(size_t w, size_t h);
typedef struct
{
u8 enableLightFlags;
@ -715,9 +720,7 @@ extern CACHE_ALIGN const u8 material_3bit_to_8bit[8];
//these contain the 3d framebuffer converted into the most useful format
//they are stored here instead of in the renderers in order to consolidate the buffers
extern CACHE_ALIGN u8 gfx3d_convertedScreen[GFX3D_FRAMEBUFFER_WIDTH*GFX3D_FRAMEBUFFER_HEIGHT*4];
extern CACHE_ALIGN u8 gfx3d_convertedAlpha[GFX3D_FRAMEBUFFER_WIDTH*GFX3D_FRAMEBUFFER_HEIGHT*2]; //see cpp for explanation of illogical *2
extern u8 *gfx3d_convertedScreen;
extern BOOL isSwapBuffers;
int _hack_getMatrixStackLevel(int);

View File

@ -713,7 +713,7 @@ public:
}
//draws a single scanline
FORCEINLINE void drawscanline(const PolygonAttributes &polyAttr, const size_t framebufferWidth, const size_t framebufferHeight, edge_fx_fl *pLeft, edge_fx_fl *pRight, bool lineHack)
FORCEINLINE void drawscanline(const PolygonAttributes &polyAttr, FragmentColor *dstColor, const size_t framebufferWidth, const size_t framebufferHeight, edge_fx_fl *pLeft, edge_fx_fl *pRight, bool lineHack)
{
int XStart = pLeft->X;
int width = pRight->X - XStart;
@ -755,20 +755,22 @@ public:
//CONSIDER: in case some other math is wrong (shouldve been clipped OK), we might go out of bounds here.
//better check the Y value.
if(RENDERER && (pLeft->Y<0 || pLeft->Y>191)) {
if (RENDERER && (pLeft->Y<0 || pLeft->Y > (framebufferHeight - 1)))
{
printf("rasterizer rendering at y=%d! oops!\n",pLeft->Y);
return;
}
if(!RENDERER && (pLeft->Y<0 || pLeft->Y>=framebufferHeight)) {
if (!RENDERER && (pLeft->Y<0 || pLeft->Y >= framebufferHeight))
{
printf("rasterizer rendering at y=%d! oops!\n",pLeft->Y);
return;
}
int x = XStart;
if(x<0)
if (x<0)
{
if(RENDERER && !lineHack)
if (RENDERER && !lineHack)
{
printf("rasterizer rendering at x=%d! oops!\n",x);
return;
@ -784,19 +786,19 @@ public:
width -= -x;
x = 0;
}
if(x+width > (RENDERER?GFX3D_FRAMEBUFFER_WIDTH:framebufferWidth))
if (x+width > framebufferWidth)
{
if(RENDERER && !lineHack)
if (RENDERER && !lineHack)
{
printf("rasterizer rendering at x=%d! oops!\n",x+width-1);
return;
}
width = (RENDERER?GFX3D_FRAMEBUFFER_WIDTH:framebufferWidth)-x;
width = framebufferWidth - x;
}
while(width-- > 0)
while (width-- > 0)
{
pixel(polyAttr, this->_softRender->screenAttributes[adr], this->_softRender->screenColor[adr], color[0], color[1], color[2], u, v, 1.0f/invw, z);
pixel(polyAttr, this->_softRender->_framebufferAttributes[adr], dstColor[adr], color[0], color[1], color[2], u, v, 1.0f/invw, z);
adr++;
x++;
@ -812,7 +814,7 @@ public:
//runs several scanlines, until an edge is finished
template<bool SLI>
void runscanlines(const PolygonAttributes &polyAttr, FragmentColor *color, const size_t framebufferWidth, const size_t framebufferHeight, edge_fx_fl *left, edge_fx_fl *right, bool horizontal, bool lineHack)
void runscanlines(const PolygonAttributes &polyAttr, FragmentColor *dstColor, const size_t framebufferWidth, const size_t framebufferHeight, edge_fx_fl *left, edge_fx_fl *right, bool horizontal, bool lineHack)
{
//oh lord, hack city for edge drawing
@ -821,16 +823,16 @@ public:
bool first=true;
//HACK: special handling for horizontal line poly
if (lineHack && left->Height == 0 && right->Height == 0 && left->Y<GFX3D_FRAMEBUFFER_HEIGHT && left->Y>=0)
if (lineHack && left->Height == 0 && right->Height == 0 && left->Y<framebufferHeight && left->Y>=0)
{
bool draw = (!SLI || (left->Y & SLI_MASK) == SLI_VALUE);
if(draw) drawscanline(polyAttr, framebufferWidth, framebufferHeight, left,right,lineHack);
if(draw) drawscanline(polyAttr, dstColor, framebufferWidth, framebufferHeight, left,right,lineHack);
}
while(Height--)
{
bool draw = (!SLI || (left->Y & SLI_MASK) == SLI_VALUE);
if(draw) drawscanline(polyAttr, framebufferWidth, framebufferHeight, left,right,lineHack);
if(draw) drawscanline(polyAttr, dstColor, framebufferWidth, framebufferHeight, left,right,lineHack);
const int xl = left->X;
const int xr = right->X;
const int y = left->Y;
@ -855,9 +857,9 @@ public:
for (int x = xs; x <= xe; x++)
{
int adr = (y*framebufferWidth)+x;
color[adr].r = 63;
color[adr].g = 0;
color[adr].b = 0;
dstColor[adr].r = 63;
dstColor[adr].g = 0;
dstColor[adr].b = 0;
}
}
else if(bottom)
@ -867,9 +869,9 @@ public:
for (int x = xs; x <= xe; x++)
{
int adr = (y*framebufferWidth)+x;
color[adr].r = 63;
color[adr].g = 0;
color[adr].b = 0;
dstColor[adr].r = 63;
dstColor[adr].g = 0;
dstColor[adr].b = 0;
}
}
else
@ -879,18 +881,18 @@ public:
for (int x = xs; x <= xe; x++)
{
int adr = (y*framebufferWidth)+x;
color[adr].r = 63;
color[adr].g = 0;
color[adr].b = 0;
dstColor[adr].r = 63;
dstColor[adr].g = 0;
dstColor[adr].b = 0;
}
xs = min(xr,nxr);
xe = max(xr,nxr);
for (int x = xs; x <= xe; x++)
{
int adr = (y*framebufferWidth)+x;
color[adr].r = 63;
color[adr].g = 0;
color[adr].b = 0;
dstColor[adr].r = 63;
dstColor[adr].g = 0;
dstColor[adr].b = 0;
}
}
@ -951,7 +953,7 @@ public:
//I didnt reference anything for this algorithm but it seems like I've seen it somewhere before.
//Maybe it is like crow's algorithm
template<bool SLI>
void shape_engine(const PolygonAttributes &polyAttr, FragmentColor *color, const size_t framebufferWidth, const size_t framebufferHeight, int type, const bool backwards, bool lineHack)
void shape_engine(const PolygonAttributes &polyAttr, FragmentColor *dstColor, const size_t framebufferWidth, const size_t framebufferHeight, int type, const bool backwards, bool lineHack)
{
bool failure = false;
@ -991,7 +993,7 @@ public:
return;
bool horizontal = left.Y == right.Y;
runscanlines<SLI>(polyAttr, color, framebufferWidth, framebufferHeight, &left, &right, horizontal, lineHack);
runscanlines<SLI>(polyAttr, dstColor, framebufferWidth, framebufferHeight, &left, &right, horizontal, lineHack);
//if we ran out of an edge, step to the next one
if (right.Height == 0)
@ -1013,6 +1015,10 @@ public:
template<bool SLI>
FORCEINLINE void mainLoop()
{
FragmentColor *dstColor = this->_softRender->GetFramebuffer();
size_t dstWidth = this->_softRender->GetFramebufferWidth();
size_t dstHeight = this->_softRender->GetFramebufferHeight();
lastTexKey = NULL;
PolygonAttributes polyAttr;
@ -1054,7 +1060,7 @@ public:
for (int j = type; j < MAX_CLIPPED_VERTS; j++)
this->verts[j] = NULL;
shape_engine<SLI>(polyAttr, this->_softRender->screenColor, this->_softRender->_framebufferWidth, this->_softRender->_framebufferHeight, type, !this->_softRender->polyBackfacing[i], (thePoly->vtxFormat & 4) && CommonSettings.GFX3D_LineHack);
shape_engine<SLI>(polyAttr, dstColor, dstWidth, dstHeight, type, !this->_softRender->polyBackfacing[i], (thePoly->vtxFormat & 4) && CommonSettings.GFX3D_LineHack);
}
}
@ -1154,10 +1160,7 @@ SoftRasterizerRenderer::SoftRasterizerRenderer()
_stateSetupNeedsFinish = false;
_renderGeometryNeedsFinish = false;
_framebufferWidth = GFX3D_FRAMEBUFFER_WIDTH;
_framebufferHeight = GFX3D_FRAMEBUFFER_HEIGHT;
screenAttributes = (FragmentAttributes *)malloc(_framebufferWidth * _framebufferHeight * sizeof(FragmentAttributes));
screenColor = (FragmentColor *)malloc(_framebufferWidth * _framebufferHeight * sizeof(FragmentColor));
_framebufferAttributes = (FragmentAttributes *)calloc(_framebufferWidth * _framebufferHeight, sizeof(FragmentAttributes));
if (!rasterizerUnitTasksInited)
{
@ -1232,8 +1235,7 @@ SoftRasterizerRenderer::~SoftRasterizerRenderer()
delete[] postprocessParam;
postprocessParam = NULL;
free(screenAttributes);
free(screenColor);
free(_framebufferAttributes);
}
Render3DError SoftRasterizerRenderer::InitTables()
@ -1302,8 +1304,8 @@ template<bool CUSTOM> void SoftRasterizerRenderer::performViewportTransforms()
{
const float xfactor = (float)this->_framebufferWidth/(float)GFX3D_FRAMEBUFFER_WIDTH;
const float yfactor = (float)this->_framebufferHeight/(float)GFX3D_FRAMEBUFFER_HEIGHT;
const float xmax = GFX3D_FRAMEBUFFER_WIDTH*xfactor-(CUSTOM?0.001f:0); //fudge factor to keep from overrunning render buffers
const float ymax = GFX3D_FRAMEBUFFER_HEIGHT*yfactor-(CUSTOM?0.001f:0);
const float xmax = (float)this->_framebufferWidth-(CUSTOM?0.001f:0); //fudge factor to keep from overrunning render buffers
const float ymax = (float)this->_framebufferHeight-(CUSTOM?0.001f:0);
//viewport transforms
for (size_t i = 0; i < this->_clippedPolyCount; i++)
@ -1558,7 +1560,7 @@ Render3DError SoftRasterizerRenderer::RenderEdgeMarking(const u16 *colorTable, c
{
for (size_t x = 0; x < this->_framebufferWidth; x++, i++)
{
const FragmentAttributes dstAttributes = this->screenAttributes[i];
const FragmentAttributes dstAttributes = this->_framebufferAttributes[i];
const u8 polyID = dstAttributes.opaquePolyID;
if(this->edgeMarkDisabled[polyID>>3]) continue;
@ -1572,8 +1574,8 @@ Render3DError SoftRasterizerRenderer::RenderEdgeMarking(const u16 *colorTable, c
FragmentColor edgeColor = this->edgeMarkTable[polyID>>3];
#define PIXOFFSET(dx,dy) ((dx)+(this->_framebufferWidth*(dy)))
#define ISEDGE(dx,dy) ((x+(dx) < this->_framebufferWidth) && (y+(dy) < this->_framebufferHeight) && polyID > this->screenAttributes[i+PIXOFFSET(dx,dy)].opaquePolyID)
#define DRAWEDGE(dx,dy) alphaBlend(screenColor[i+PIXOFFSET(dx,dy)], edgeColor)
#define ISEDGE(dx,dy) ((x+(dx) < this->_framebufferWidth) && (y+(dy) < this->_framebufferHeight) && polyID > this->_framebufferAttributes[i+PIXOFFSET(dx,dy)].opaquePolyID)
#define DRAWEDGE(dx,dy) alphaBlend(_framebufferColor[i+PIXOFFSET(dx,dy)], edgeColor)
bool upleft = ISEDGE(-1,-1);
bool up = ISEDGE( 0,-1);
@ -1714,12 +1716,12 @@ Render3DError SoftRasterizerRenderer::RenderFog(const u8 *densityTable, const u3
{
for (size_t i = 0; i < framebufferFragmentCount; i++)
{
const FragmentAttributes &destFragment = screenAttributes[i];
const FragmentAttributes &destFragment = _framebufferAttributes[i];
const size_t fogIndex = destFragment.depth >> 9;
assert(fogIndex < 32768);
const u8 fog = (destFragment.isFogged) ? this->fogTable[fogIndex] : 0;
FragmentColor &destFragmentColor = screenColor[i];
FragmentColor &destFragmentColor = _framebufferColor[i];
destFragmentColor.r = ((128-fog)*destFragmentColor.r + r*fog)>>7;
destFragmentColor.g = ((128-fog)*destFragmentColor.g + g*fog)>>7;
destFragmentColor.b = ((128-fog)*destFragmentColor.b + b*fog)>>7;
@ -1730,12 +1732,12 @@ Render3DError SoftRasterizerRenderer::RenderFog(const u8 *densityTable, const u3
{
for (size_t i = 0; i < framebufferFragmentCount; i++)
{
const FragmentAttributes &destFragment = screenAttributes[i];
const FragmentAttributes &destFragment = _framebufferAttributes[i];
const size_t fogIndex = destFragment.depth >> 9;
assert(fogIndex < 32768);
const u8 fog = (destFragment.isFogged) ? this->fogTable[fogIndex] : 0;
FragmentColor &destFragmentColor = screenColor[i];
FragmentColor &destFragmentColor = _framebufferColor[i];
destFragmentColor.a = ((128-fog)*destFragmentColor.a + a*fog)>>7;
}
}
@ -1749,8 +1751,8 @@ Render3DError SoftRasterizerRenderer::RenderEdgeMarkingAndFog(const SoftRasteriz
{
for (size_t x = 0; x < this->_framebufferWidth; x++, i++)
{
FragmentColor &dstColor = screenColor[i];
const FragmentAttributes dstAttributes = this->screenAttributes[i];
FragmentColor &dstColor = _framebufferColor[i];
const FragmentAttributes dstAttributes = this->_framebufferAttributes[i];
const u32 depth = dstAttributes.depth;
const u8 polyID = dstAttributes.opaquePolyID;
@ -1772,7 +1774,7 @@ Render3DError SoftRasterizerRenderer::RenderEdgeMarkingAndFog(const SoftRasteriz
bool up = false;
#define PIXOFFSET(dx,dy) ((dx)+(this->_framebufferWidth*(dy)))
#define ISEDGE(dx,dy) ((x+(dx) < this->_framebufferWidth) && (y+(dy) < this->_framebufferHeight) && polyID != this->screenAttributes[i+PIXOFFSET(dx,dy)].opaquePolyID && depth >= this->screenAttributes[i+PIXOFFSET(dx,dy)].depth)
#define ISEDGE(dx,dy) ((x+(dx) < this->_framebufferWidth) && (y+(dy) < this->_framebufferHeight) && polyID != this->_framebufferAttributes[i+PIXOFFSET(dx,dy)].opaquePolyID && depth >= this->_framebufferAttributes[i+PIXOFFSET(dx,dy)].depth)
up = ISEDGE( 0,-1);
left = ISEDGE(-1, 0);
@ -1784,22 +1786,22 @@ Render3DError SoftRasterizerRenderer::RenderEdgeMarkingAndFog(const SoftRasteriz
if (right)
{
edgeColor = this->edgeMarkTable[this->screenAttributes[i+PIXOFFSET( 1, 0)].opaquePolyID >> 3];
edgeColor = this->edgeMarkTable[this->_framebufferAttributes[i+PIXOFFSET( 1, 0)].opaquePolyID >> 3];
alphaBlend(dstColor, edgeColor);
}
else if (down)
{
edgeColor = this->edgeMarkTable[this->screenAttributes[i+PIXOFFSET( 0, 1)].opaquePolyID >> 3];
edgeColor = this->edgeMarkTable[this->_framebufferAttributes[i+PIXOFFSET( 0, 1)].opaquePolyID >> 3];
alphaBlend(dstColor, edgeColor);
}
else if (left)
{
edgeColor = this->edgeMarkTable[this->screenAttributes[i+PIXOFFSET(-1, 0)].opaquePolyID >> 3];
edgeColor = this->edgeMarkTable[this->_framebufferAttributes[i+PIXOFFSET(-1, 0)].opaquePolyID >> 3];
alphaBlend(dstColor, edgeColor);
}
else if (up)
{
edgeColor = this->edgeMarkTable[this->screenAttributes[i+PIXOFFSET( 0,-1)].opaquePolyID >> 3];
edgeColor = this->edgeMarkTable[this->_framebufferAttributes[i+PIXOFFSET( 0,-1)].opaquePolyID >> 3];
alphaBlend(dstColor, edgeColor);
}
@ -1865,13 +1867,13 @@ Render3DError SoftRasterizerRenderer::ClearUsingImage(const u16 *__restrict colo
size_t ir = x + (y * this->_framebufferWidth);
size_t iw = x + ((this->_framebufferHeight - 1 - y) * this->_framebufferWidth);
((u32 *)this->screenColor)[iw] = RGB15TO6665(colorBuffer[ir] & 0x7FFF, (colorBuffer[ir] >> 15) * 31);
this->screenAttributes[iw].isFogged = fogBuffer[ir];
this->screenAttributes[iw].depth = depthBuffer[ir];
this->screenAttributes[iw].opaquePolyID = polyIDBuffer[ir];
this->screenAttributes[iw].translucentPolyID = kUnsetTranslucentPolyID;
this->screenAttributes[iw].isTranslucentPoly = false;
this->screenAttributes[iw].stencil = 0;
this->_framebufferColor[iw].color = RGB15TO6665(colorBuffer[ir] & 0x7FFF, (colorBuffer[ir] >> 15) * 31);
this->_framebufferAttributes[iw].isFogged = fogBuffer[ir];
this->_framebufferAttributes[iw].depth = depthBuffer[ir];
this->_framebufferAttributes[iw].opaquePolyID = polyIDBuffer[ir];
this->_framebufferAttributes[iw].translucentPolyID = kUnsetTranslucentPolyID;
this->_framebufferAttributes[iw].isTranslucentPoly = false;
this->_framebufferAttributes[iw].stencil = 0;
}
}
@ -1888,8 +1890,8 @@ Render3DError SoftRasterizerRenderer::ClearUsingValues(const FragmentColor &clea
for (size_t i = 0; i < (this->_framebufferWidth * this->_framebufferHeight); i++)
{
this->screenAttributes[i] = clearAttributes;
this->screenColor[i] = convertedClearColor;
this->_framebufferAttributes[i] = clearAttributes;
this->_framebufferColor[i] = convertedClearColor;
}
return RENDER3DERROR_NOERR;
@ -1957,7 +1959,7 @@ Render3DError SoftRasterizerRenderer::EndRender(const u64 frameCount)
this->RenderEdgeMarkingAndFog(this->postprocessParam[0]);
}
memcpy(gfx3d_convertedScreen, this->screenColor, this->_framebufferWidth * this->_framebufferHeight * sizeof(FragmentColor));
this->FlushFramebuffer((FragmentColor *)gfx3d_convertedScreen);
}
return RENDER3DERROR_NOERR;
@ -1997,7 +1999,19 @@ Render3DError SoftRasterizerRenderer::RenderFinish()
}
}
memcpy(gfx3d_convertedScreen, this->screenColor, this->_framebufferWidth * this->_framebufferHeight * sizeof(FragmentColor));
this->FlushFramebuffer((FragmentColor *)gfx3d_convertedScreen);
return RENDER3DERROR_NOERR;
}
Render3DError SoftRasterizerRenderer::SetFramebufferSize(size_t w, size_t h)
{
if (w < GFX3D_FRAMEBUFFER_WIDTH || h < GFX3D_FRAMEBUFFER_HEIGHT)
{
return RENDER3DERROR_NOERR;
}
// TODO: We're not prepared to do this yet, so do nothing for now.
return RENDER3DERROR_NOERR;
}

View File

@ -68,13 +68,10 @@ public:
size_t _clippedPolyCount;
FragmentColor toonColor32LUT[32];
GFX3D_Clipper::TClippedPoly *clippedPolys;
FragmentAttributes *screenAttributes;
FragmentColor *screenColor;
FragmentAttributes *_framebufferAttributes;
TexCacheItem *polyTexKeys[POLYLIST_SIZE];
bool polyVisible[POLYLIST_SIZE];
bool polyBackfacing[POLYLIST_SIZE];
size_t _framebufferWidth;
size_t _framebufferHeight;
GFX3D_State *currentRenderState;
SoftRasterizerPostProcessParams *postprocessParam;
@ -94,6 +91,7 @@ public:
virtual Render3DError Reset();
virtual Render3DError Render(const GFX3D &engine);
virtual Render3DError RenderFinish();
virtual Render3DError SetFramebufferSize(size_t w, size_t h);
};
#endif

View File

@ -125,11 +125,17 @@ Render3D::Render3D()
needTableInit = false;
}
_framebufferWidth = GFX3D_FRAMEBUFFER_WIDTH;
_framebufferHeight = GFX3D_FRAMEBUFFER_HEIGHT;
_framebufferColorSizeBytes = _framebufferWidth * _framebufferHeight * sizeof(FragmentColor);
_framebufferColor = (FragmentColor *)calloc(_framebufferWidth * _framebufferHeight, sizeof(FragmentColor));
Reset();
}
Render3D::~Render3D()
{
free(_framebufferColor);
TexCache_Reset();
}
@ -143,6 +149,38 @@ std::string Render3D::GetName()
return this->_renderName;
}
FragmentColor* Render3D::GetFramebuffer()
{
return this->_framebufferColor;
}
size_t Render3D::GetFramebufferWidth()
{
return this->_framebufferWidth;
}
size_t Render3D::GetFramebufferHeight()
{
return this->_framebufferHeight;
}
Render3DError Render3D::SetFramebufferSize(size_t w, size_t h)
{
if (w < GFX3D_FRAMEBUFFER_WIDTH || h < GFX3D_FRAMEBUFFER_HEIGHT)
{
return RENDER3DERROR_NOERR;
}
this->RenderFinish();
this->_framebufferWidth = w;
this->_framebufferHeight = h;
this->_framebufferColorSizeBytes = w * h * sizeof(FragmentColor);
this->_framebufferColor = (FragmentColor *)realloc(this->_framebufferColor, w * h * sizeof(FragmentColor));
return RENDER3DERROR_NOERR;
}
Render3DError Render3D::BeginRender(const GFX3D &engine)
{
return RENDER3DERROR_NOERR;
@ -168,6 +206,12 @@ Render3DError Render3D::EndRender(const u64 frameCount)
return RENDER3DERROR_NOERR;
}
Render3DError Render3D::FlushFramebuffer(FragmentColor *dstBuffer)
{
memcpy(dstBuffer, this->_framebufferColor, this->_framebufferColorSizeBytes);
return RENDER3DERROR_NOERR;
}
Render3DError Render3D::UpdateToonTable(const u16 *toonTableBuffer)
{
return RENDER3DERROR_NOERR;
@ -274,6 +318,7 @@ Render3DError Render3D::SetupViewport(const u32 viewportValue)
Render3DError Render3D::Reset()
{
memset(this->_framebufferColor, 0, this->_framebufferColorSizeBytes);
memset(this->clearImageColor16Buffer, 0, sizeof(this->clearImageColor16Buffer));
memset(this->clearImageDepthBuffer, 0, sizeof(this->clearImageDepthBuffer));
memset(this->clearImagePolyIDBuffer, 0, sizeof(this->clearImagePolyIDBuffer));
@ -316,7 +361,7 @@ Render3DError Render3D::Render(const GFX3D &engine)
Render3DError Render3D::RenderFinish()
{
memset(gfx3d_convertedScreen, 0, sizeof(gfx3d_convertedScreen));
this->FlushFramebuffer((FragmentColor *)gfx3d_convertedScreen);
return RENDER3DERROR_NOERR;
}

View File

@ -103,6 +103,11 @@ protected:
RendererID _renderID;
std::string _renderName;
size_t _framebufferWidth;
size_t _framebufferHeight;
size_t _framebufferColorSizeBytes;
FragmentColor *_framebufferColor;
CACHE_ALIGN u16 clearImageColor16Buffer[GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT];
CACHE_ALIGN u32 clearImageDepthBuffer[GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT];
CACHE_ALIGN bool clearImageFogBuffer[GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT];
@ -113,6 +118,7 @@ protected:
virtual Render3DError RenderEdgeMarking(const u16 *colorTable, const bool useAntialias);
virtual Render3DError RenderFog(const u8 *densityTable, const u32 color, const u32 offset, const u8 shift, const bool alphaOnly);
virtual Render3DError EndRender(const u64 frameCount);
virtual Render3DError FlushFramebuffer(FragmentColor *dstBuffer);
virtual Render3DError ClearUsingImage(const u16 *__restrict colorBuffer, const u32 *__restrict depthBuffer, const bool *__restrict fogBuffer, const u8 *__restrict polyIDBuffer);
virtual Render3DError ClearUsingValues(const FragmentColor &clearColor, const FragmentAttributes &clearAttributes) const;
@ -128,6 +134,10 @@ public:
RendererID GetRenderID();
std::string GetName();
FragmentColor* GetFramebuffer();
size_t GetFramebufferWidth();
size_t GetFramebufferHeight();
virtual Render3DError UpdateToonTable(const u16 *toonTableBuffer);
virtual Render3DError ClearFramebuffer(const GFX3D_State &renderState);
@ -140,6 +150,8 @@ public:
// sure to always call this function.)
virtual Render3DError VramReconfigureSignal(); // Called when the emulator reconfigures its VRAM. You may need to invalidate your texture cache.
virtual Render3DError SetFramebufferSize(size_t w, size_t h); // Called whenever the output framebuffer size changes.
};
#endif