parent
dcbe28c94e
commit
9d6f284681
|
@ -192,6 +192,7 @@ void NDS_DeInit(void)
|
|||
Screen_DeInit();
|
||||
MMU_DeInit();
|
||||
Render3D_DeInit();
|
||||
gfx3d_deinit();
|
||||
|
||||
WIFI_DeInit();
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue