Render3D:

- Add the ability to set the size of the output framebuffer.
- Do some more code cleanup.
This commit is contained in:
rogerman 2015-05-20 23:39:43 +00:00
parent afba637244
commit fec691bd26
12 changed files with 602 additions and 151 deletions

View File

@ -564,12 +564,9 @@ FORCEINLINE FASTCALL void GPU::_master_setFinal3dColor(int dstX, int srcX)
{
int x = dstX;
int passing = dstX<<1;
u8* color = &_3dColorLine[srcX<<2];
u8 red = color[0];
u8 green = color[1];
u8 blue = color[2];
u8 alpha = color[3];
u8* dst = currDst;
const FragmentColor color = _3dColorLine[srcX];
u8 alpha = color.a;
u8 *dst = currDst;
u16 final;
bool windowEffect = blend1; //bomberman land touch dialogbox will fail without setting to blend1
@ -596,17 +593,17 @@ FORCEINLINE FASTCALL void GPU::_master_setFinal3dColor(int dstX, int srcX)
c2.val = HostReadWord(dst, passing);
cfinal.bits.red = ((red * alpha) + ((c2.bits.red<<1) * (32 - alpha)))>>6;
cfinal.bits.green = ((green * alpha) + ((c2.bits.green<<1) * (32 - alpha)))>>6;
cfinal.bits.blue = ((blue * alpha) + ((c2.bits.blue<<1) * (32 - alpha)))>>6;
cfinal.bits.red = ((color.r * alpha) + ((c2.bits.red<<1) * (32 - alpha)))>>6;
cfinal.bits.green = ((color.g * alpha) + ((c2.bits.green<<1) * (32 - alpha)))>>6;
cfinal.bits.blue = ((color.b * alpha) + ((c2.bits.blue<<1) * (32 - alpha)))>>6;
final = cfinal.val;
}
else final = R6G6B6TORGB15(red,green,blue);
else final = R6G6B6TORGB15(color.r, color.g, color.b);
}
else
{
final = R6G6B6TORGB15(red,green,blue);
final = R6G6B6TORGB15(color.r, color.g, color.b);
//perform the special effect
if(windowEffect)
switch(FUNC) {
@ -2068,7 +2065,7 @@ PLAIN_CLEAR:
// render BGs
if (BG_enabled)
{
for (int i=0; i < item->nbBGs; i++)
for (size_t i = 0; i < item->nbBGs; i++)
{
i16 = item->BGs[i];
if (gpu->LayersEnable[i16])
@ -2088,17 +2085,16 @@ PLAIN_CLEAR:
const u16 hofs = gpu->getHOFS(i16);
gfx3d_GetLineData(l, &gpu->_3dColorLine);
u8* colorLine = gpu->_3dColorLine;
const FragmentColor *colorLine = gpu->_3dColorLine;
for(int k = 0; k < 256; k++)
for (size_t k = 0; k < 256; k++)
{
int q = ((k + hofs) & 0x1FF);
const size_t q = ((k + hofs) & 0x1FF);
if((q < 0) || (q > 255))
if (q > 255 || colorLine[q].a == 0)
continue;
if(colorLine[(q<<2)+3])
gpu->setFinalColor3d(k, q);
gpu->setFinalColor3d(k, q);
}
continue;

View File

@ -110,6 +110,15 @@ struct _DISPCNT
};
#endif
union FragmentColor
{
u32 color;
struct
{
u8 r,g,b,a;
};
};
typedef union
{
struct _DISPCNT bits;
@ -688,7 +697,7 @@ struct GPU
bool blend1;
u8* currDst;
u8* _3dColorLine;
FragmentColor *_3dColorLine;
static struct MosaicLookup {
@ -919,5 +928,11 @@ void gpu_SetRotateScreen(u16 angle);
//#undef FORCEINLINE
//#define FORCEINLINE __forceinline
#endif
inline FragmentColor MakeFragmentColor(const u8 r, const u8 g, const u8 b, const u8 a)
{
FragmentColor ret;
ret.r = r; ret.g = g; ret.b = b; ret.a = a;
return ret;
}
#endif

View File

@ -790,10 +790,6 @@ 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;
@ -807,10 +803,6 @@ OpenGLRenderer::OpenGLRenderer()
OpenGLRenderer::~OpenGLRenderer()
{
// Destroy OpenGL rendering states
free(ref->workingDepthBuffer);
free(ref->workingDepthStencilBuffer);
free(ref->workingFogAttributesBuffer);
free(ref->workingPolyIDBuffer);
delete ref;
ref = NULL;
}
@ -1337,10 +1329,16 @@ Render3DError OpenGLRenderer_1_2::CreateFBOs()
OGLRenderRef &OGLRef = *this->ref;
// Set up FBO render targets
glGenTextures(1, &OGLRef.texCIColorID);
glGenTextures(1, &OGLRef.texCIDepthID);
glGenTextures(1, &OGLRef.texCIFogAttrID);
glGenTextures(1, &OGLRef.texCIPolyID);
glGenTextures(1, &OGLRef.texCIDepthStencilID);
glGenTextures(1, &OGLRef.texGColorID);
glGenTextures(1, &OGLRef.texGDepthID);
glGenTextures(1, &OGLRef.texGPolyID);
glGenTextures(1, &OGLRef.texGFogAttrID);
glGenTextures(1, &OGLRef.texGPolyID);
glGenTextures(1, &OGLRef.texGDepthStencilID);
glGenTextures(1, &OGLRef.texPostprocessFogID);
@ -1385,6 +1383,7 @@ Render3DError OpenGLRenderer_1_2::CreateFBOs()
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);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@ -1392,12 +1391,88 @@ Render3DError OpenGLRenderer_1_2::CreateFBOs()
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
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, OGLRef.texCIColorID);
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);
glBindTexture(GL_TEXTURE_2D, OGLRef.texCIDepthStencilID);
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);
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_EXT, GL_UNSIGNED_INT_24_8_EXT, NULL);
glBindTexture(GL_TEXTURE_2D, OGLRef.texCIDepthID);
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);
glBindTexture(GL_TEXTURE_2D, OGLRef.texCIPolyID);
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);
glBindTexture(GL_TEXTURE_2D, OGLRef.texCIFogAttrID);
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);
glBindTexture(GL_TEXTURE_2D, 0);
// Set up FBOs
glGenFramebuffersEXT(1, &OGLRef.fboClearImageID);
glGenFramebuffersEXT(1, &OGLRef.fboRenderID);
glGenFramebuffersEXT(1, &OGLRef.fboPostprocessID);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboClearImageID);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, OGLRef.texCIColorID, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, OGLRef.texCIDepthID, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT2_EXT, GL_TEXTURE_2D, OGLRef.texCIPolyID, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT3_EXT, GL_TEXTURE_2D, OGLRef.texCIFogAttrID, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, OGLRef.texCIDepthStencilID, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_TEXTURE_2D, OGLRef.texCIDepthStencilID, 0);
if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT)
{
INFO("OpenGL: Failed to created FBOs. Some emulation features will be disabled.\n");
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glDeleteFramebuffersEXT(1, &OGLRef.fboClearImageID);
glDeleteFramebuffersEXT(1, &OGLRef.fboRenderID);
glDeleteFramebuffersEXT(1, &OGLRef.fboPostprocessID);
glDeleteTextures(1, &OGLRef.texCIColorID);
glDeleteTextures(1, &OGLRef.texCIDepthID);
glDeleteTextures(1, &OGLRef.texCIFogAttrID);
glDeleteTextures(1, &OGLRef.texCIPolyID);
glDeleteTextures(1, &OGLRef.texCIDepthStencilID);
glDeleteTextures(1, &OGLRef.texGColorID);
glDeleteTextures(1, &OGLRef.texGDepthID);
glDeleteTextures(1, &OGLRef.texGPolyID);
glDeleteTextures(1, &OGLRef.texGFogAttrID);
glDeleteTextures(1, &OGLRef.texGDepthStencilID);
glDeleteTextures(1, &OGLRef.texPostprocessFogID);
OGLRef.fboClearImageID = 0;
OGLRef.fboRenderID = 0;
OGLRef.fboPostprocessID = 0;
this->isFBOSupported = false;
return OGLERROR_FBO_CREATE_ERROR;
}
glDrawBuffers(4, RenderDrawList);
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboRenderID);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, OGLRef.texGColorID, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, OGLRef.texGDepthID, 0);
@ -1411,8 +1486,14 @@ Render3DError OpenGLRenderer_1_2::CreateFBOs()
INFO("OpenGL: Failed to created FBOs. Some emulation features will be disabled.\n");
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glDeleteFramebuffersEXT(1, &OGLRef.fboClearImageID);
glDeleteFramebuffersEXT(1, &OGLRef.fboRenderID);
glDeleteFramebuffersEXT(1, &OGLRef.fboPostprocessID);
glDeleteTextures(1, &OGLRef.texCIColorID);
glDeleteTextures(1, &OGLRef.texCIDepthID);
glDeleteTextures(1, &OGLRef.texCIFogAttrID);
glDeleteTextures(1, &OGLRef.texCIPolyID);
glDeleteTextures(1, &OGLRef.texCIDepthStencilID);
glDeleteTextures(1, &OGLRef.texGColorID);
glDeleteTextures(1, &OGLRef.texGDepthID);
glDeleteTextures(1, &OGLRef.texGPolyID);
@ -1420,6 +1501,10 @@ Render3DError OpenGLRenderer_1_2::CreateFBOs()
glDeleteTextures(1, &OGLRef.texGDepthStencilID);
glDeleteTextures(1, &OGLRef.texPostprocessFogID);
OGLRef.fboClearImageID = 0;
OGLRef.fboRenderID = 0;
OGLRef.fboPostprocessID = 0;
this->isFBOSupported = false;
return OGLERROR_FBO_CREATE_ERROR;
}
@ -1435,8 +1520,14 @@ Render3DError OpenGLRenderer_1_2::CreateFBOs()
INFO("OpenGL: Failed to created FBOs. Some emulation features will be disabled.\n");
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glDeleteFramebuffersEXT(1, &OGLRef.fboClearImageID);
glDeleteFramebuffersEXT(1, &OGLRef.fboRenderID);
glDeleteFramebuffersEXT(1, &OGLRef.fboPostprocessID);
glDeleteTextures(1, &OGLRef.texCIColorID);
glDeleteTextures(1, &OGLRef.texCIDepthID);
glDeleteTextures(1, &OGLRef.texCIFogAttrID);
glDeleteTextures(1, &OGLRef.texCIPolyID);
glDeleteTextures(1, &OGLRef.texCIDepthStencilID);
glDeleteTextures(1, &OGLRef.texGColorID);
glDeleteTextures(1, &OGLRef.texGDepthID);
glDeleteTextures(1, &OGLRef.texGPolyID);
@ -1444,6 +1535,10 @@ Render3DError OpenGLRenderer_1_2::CreateFBOs()
glDeleteTextures(1, &OGLRef.texGDepthStencilID);
glDeleteTextures(1, &OGLRef.texPostprocessFogID);
OGLRef.fboClearImageID = 0;
OGLRef.fboRenderID = 0;
OGLRef.fboPostprocessID = 0;
this->isFBOSupported = false;
return OGLERROR_FBO_CREATE_ERROR;
}
@ -1468,8 +1563,14 @@ void OpenGLRenderer_1_2::DestroyFBOs()
OGLRenderRef &OGLRef = *this->ref;
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glDeleteFramebuffersEXT(1, &OGLRef.fboClearImageID);
glDeleteFramebuffersEXT(1, &OGLRef.fboRenderID);
glDeleteFramebuffersEXT(1, &OGLRef.fboPostprocessID);
glDeleteTextures(1, &OGLRef.texCIColorID);
glDeleteTextures(1, &OGLRef.texCIDepthID);
glDeleteTextures(1, &OGLRef.texCIFogAttrID);
glDeleteTextures(1, &OGLRef.texCIPolyID);
glDeleteTextures(1, &OGLRef.texCIDepthStencilID);
glDeleteTextures(1, &OGLRef.texGColorID);
glDeleteTextures(1, &OGLRef.texGDepthID);
glDeleteTextures(1, &OGLRef.texGPolyID);
@ -1477,6 +1578,7 @@ void OpenGLRenderer_1_2::DestroyFBOs()
glDeleteTextures(1, &OGLRef.texGDepthStencilID);
glDeleteTextures(1, &OGLRef.texPostprocessFogID);
OGLRef.fboClearImageID = 0;
OGLRef.fboRenderID = 0;
OGLRef.fboPostprocessID = 0;
@ -1704,40 +1806,43 @@ Render3DError OpenGLRenderer_1_2::UploadClearImage(const u16 *__restrict colorBu
if (this->isShaderSupported)
{
for (size_t i = 0; i < this->_framebufferWidth * this->_framebufferHeight; i++)
for (size_t i = 0; i < GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT; 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;
OGLRef.workingCIDepthStencilBuffer[i] = depthBuffer[i] << 8;
OGLRef.workingCIDepthBuffer[i] = depthBuffer[i] | 0xFF000000;
OGLRef.workingCIFogAttributesBuffer[i] = (fogBuffer[i]) ? 0xFF0000FF : 0xFF000000;
OGLRef.workingCIPolyIDBuffer[i] = (GLuint)polyIDBuffer[i] | 0xFF000000;
}
}
else
{
for (size_t i = 0; i < this->_framebufferWidth * this->_framebufferHeight; i++)
{
OGLRef.workingDepthStencilBuffer[i] = depthBuffer[i] << 8;
OGLRef.workingCIDepthStencilBuffer[i] = depthBuffer[i] << 8;
}
}
glActiveTextureARB(GL_TEXTURE0_ARB + OGLTextureUnitID_GColor);
glBindTexture(GL_TEXTURE_2D, OGLRef.texGDepthStencilID);
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, this->_framebufferWidth, this->_framebufferHeight, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, colorBuffer);
glActiveTextureARB(GL_TEXTURE0_ARB);
glBindTexture(GL_TEXTURE_2D, OGLRef.texCIColorID);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, colorBuffer);
glBindTexture(GL_TEXTURE_2D, OGLRef.texCIDepthStencilID);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, OGLRef.workingCIDepthStencilBuffer);
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);
glBindTexture(GL_TEXTURE_2D, OGLRef.texCIDepthID);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, OGLRef.workingCIDepthBuffer);
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);
glBindTexture(GL_TEXTURE_2D, OGLRef.texCIFogAttrID);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, OGLRef.workingCIFogAttributesBuffer);
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);
glBindTexture(GL_TEXTURE_2D, OGLRef.texCIPolyID);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, OGLRef.workingCIPolyIDBuffer);
}
glBindTexture(GL_TEXTURE_2D, 0);
return OGLERROR_NOERR;
}
@ -2186,20 +2291,49 @@ Render3DError OpenGLRenderer_1_2::ClearUsingImage(const u16 *__restrict colorBuf
this->UploadClearImage(colorBuffer, depthBuffer, fogBuffer, polyIDBuffer);
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, OGLRef.fboClearImageID);
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, OGLRef.fboRenderID);
// It might seem wasteful to be doing a separate glClear(GL_STENCIL_BUFFER_BIT) instead
// of simply blitting the stencil buffer with everything else.
//
// We do this because glBlitFramebufferEXT() for GL_STENCIL_BUFFER_BIT has been tested
// to be unsupported on ATI/AMD GPUs running in compatibility mode. So we do the separate
// glClear() for GL_STENCIL_BUFFER_BIT to keep these GPUs working.
glClearStencil(0);
glClear(GL_STENCIL_BUFFER_BIT);
// 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, 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, 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, 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, this->_framebufferWidth, this->_framebufferHeight, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboRenderID);
glDrawBuffers(4, RenderDrawList);
if (this->isMultisampledFBOSupported)
{
OGLRef.selectedRenderingFBO = (CommonSettings.GFX3D_Renderer_Multisample) ? OGLRef.fboMSIntermediateRenderID : OGLRef.fboRenderID;
if (OGLRef.selectedRenderingFBO == OGLRef.fboMSIntermediateRenderID)
{
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, OGLRef.fboRenderID);
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, OGLRef.fboMSIntermediateRenderID);
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, OGLRef.selectedRenderingFBO);
// It might seem wasteful to be doing a separate glClear(GL_STENCIL_BUFFER_BIT) instead
// of simply blitting the stencil buffer with everything else.
//
// We do this because glBlitFramebufferEXT() for GL_STENCIL_BUFFER_BIT has been tested
// to be unsupported on ATI/AMD GPUs running in compatibility mode. So we do the separate
// glClear() for GL_STENCIL_BUFFER_BIT to keep these GPUs working.
glClearStencil(0);
glClear(GL_STENCIL_BUFFER_BIT);
@ -2222,10 +2356,10 @@ Render3DError OpenGLRenderer_1_2::ClearUsingImage(const u16 *__restrict colorBuf
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
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);
glDrawBuffers(4, RenderDrawList);
}
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.selectedRenderingFBO);
glDrawBuffers(4, RenderDrawList);
}
return OGLERROR_NOERR;
@ -2457,9 +2591,12 @@ Render3DError OpenGLRenderer_1_2::SetupTexture(const POLY &thePoly, bool enableT
Render3DError OpenGLRenderer_1_2::SetupViewport(const u32 viewportValue)
{
const GLfloat wScalar = this->_framebufferWidth / GFX3D_FRAMEBUFFER_WIDTH;
const GLfloat hScalar = this->_framebufferHeight / GFX3D_FRAMEBUFFER_HEIGHT;
VIEWPORT viewport;
viewport.decode(viewportValue);
glViewport(viewport.x, viewport.y, viewport.width, viewport.height);
glViewport(viewport.x * wScalar, viewport.y * hScalar, viewport.width * wScalar, viewport.height * hScalar);
return OGLERROR_NOERR;
}
@ -2506,8 +2643,6 @@ Render3DError OpenGLRenderer_1_2::Reset()
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));
@ -2546,7 +2681,7 @@ Render3DError OpenGLRenderer_1_2::RenderFinish()
ENDGL();
this->FlushFramebuffer((FragmentColor *)gfx3d_convertedScreen);
this->FlushFramebuffer(gfx3d_convertedScreen);
this->_pixelReadNeedsFinish = false;
return OGLERROR_NOERR;
@ -2554,14 +2689,63 @@ Render3DError OpenGLRenderer_1_2::RenderFinish()
Render3DError OpenGLRenderer_1_2::SetFramebufferSize(size_t w, size_t h)
{
OGLRenderRef &OGLRef = *this->ref;
if (w < GFX3D_FRAMEBUFFER_WIDTH || h < GFX3D_FRAMEBUFFER_HEIGHT)
{
return RENDER3DERROR_NOERR;
return OGLERROR_NOERR;
}
// TODO: We're not prepared to do this yet, so do nothing for now.
this->_framebufferWidth = w;
this->_framebufferHeight = h;
this->_framebufferColorSizeBytes = w * h * sizeof(FragmentColor);
this->_framebufferColor = (FragmentColor *)realloc(this->_framebufferColor, this->_framebufferColorSizeBytes);
return RENDER3DERROR_NOERR;
if (this->isFBOSupported)
{
glActiveTextureARB(GL_TEXTURE0_ARB + OGLTextureUnitID_GColor);
glBindTexture(GL_TEXTURE_2D, OGLRef.texGDepthStencilID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8_EXT, w, h, 0, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, NULL);
glBindTexture(GL_TEXTURE_2D, OGLRef.texGColorID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glActiveTextureARB(GL_TEXTURE0_ARB + OGLTextureUnitID_GDepth);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glActiveTextureARB(GL_TEXTURE0_ARB + OGLTextureUnitID_GPolyID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glActiveTextureARB(GL_TEXTURE0_ARB + OGLTextureUnitID_FogAttr);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glActiveTextureARB(GL_TEXTURE0_ARB);
glBindTexture(GL_TEXTURE_2D, OGLRef.texPostprocessFogID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
}
if (this->isMultisampledFBOSupported)
{
GLint maxSamples = 0;
glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSamples);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, OGLRef.rboMSGColorID);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, maxSamples, GL_RGBA, w, h);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, OGLRef.rboMSGDepthID);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, maxSamples, GL_RGBA, w, h);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, OGLRef.rboMSGPolyID);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, maxSamples, GL_RGBA, w, h);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, OGLRef.rboMSGFogAttrID);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, maxSamples, GL_RGBA, w, h);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, OGLRef.rboMSGDepthStencilID);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, maxSamples, GL_DEPTH24_STENCIL8_EXT, w, h);
}
if (this->isPBOSupported)
{
glBufferData(GL_PIXEL_PACK_BUFFER_ARB, this->_framebufferColorSizeBytes, NULL, GL_STREAM_READ);
}
return OGLERROR_NOERR;
}
Render3DError OpenGLRenderer_1_3::CreateToonTable()
@ -2600,38 +2784,102 @@ Render3DError OpenGLRenderer_1_3::UploadClearImage(const u16 *__restrict colorBu
if (this->isShaderSupported)
{
for (size_t i = 0; i < this->_framebufferWidth * this->_framebufferHeight; i++)
for (size_t i = 0; i < GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT; 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;
OGLRef.workingCIDepthStencilBuffer[i] = depthBuffer[i] << 8;
OGLRef.workingCIDepthBuffer[i] = depthBuffer[i] | 0xFF000000;
OGLRef.workingCIFogAttributesBuffer[i] = (fogBuffer[i]) ? 0xFF0000FF : 0xFF000000;
OGLRef.workingCIPolyIDBuffer[i] = (GLuint)polyIDBuffer[i] | 0xFF000000;
}
}
else
{
for (size_t i = 0; i < this->_framebufferWidth * this->_framebufferHeight; i++)
{
OGLRef.workingDepthStencilBuffer[i] = depthBuffer[i] << 8;
OGLRef.workingCIDepthStencilBuffer[i] = depthBuffer[i] << 8;
}
}
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_GColor);
glBindTexture(GL_TEXTURE_2D, OGLRef.texGDepthStencilID);
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, this->_framebufferWidth, this->_framebufferHeight, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, colorBuffer);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, OGLRef.texCIColorID);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, colorBuffer);
glBindTexture(GL_TEXTURE_2D, OGLRef.texCIDepthStencilID);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, OGLRef.workingCIDepthStencilBuffer);
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);
glBindTexture(GL_TEXTURE_2D, OGLRef.texCIDepthID);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, OGLRef.workingCIDepthBuffer);
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);
glBindTexture(GL_TEXTURE_2D, OGLRef.texCIFogAttrID);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, OGLRef.workingCIFogAttributesBuffer);
glBindTexture(GL_TEXTURE_2D, OGLRef.texCIPolyID);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, OGLRef.workingCIPolyIDBuffer);
}
glBindTexture(GL_TEXTURE_2D, 0);
return OGLERROR_NOERR;
}
Render3DError OpenGLRenderer_1_3::SetFramebufferSize(size_t w, size_t h)
{
OGLRenderRef &OGLRef = *this->ref;
if (w < GFX3D_FRAMEBUFFER_WIDTH || h < GFX3D_FRAMEBUFFER_HEIGHT)
{
return OGLERROR_NOERR;
}
this->_framebufferWidth = w;
this->_framebufferHeight = h;
this->_framebufferColorSizeBytes = w * h * sizeof(FragmentColor);
this->_framebufferColor = (FragmentColor *)realloc(this->_framebufferColor, this->_framebufferColorSizeBytes);
if (this->isFBOSupported)
{
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_GColor);
glBindTexture(GL_TEXTURE_2D, OGLRef.texGDepthStencilID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8_EXT, w, h, 0, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, NULL);
glBindTexture(GL_TEXTURE_2D, OGLRef.texGColorID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_GDepth);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
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);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_FogAttr);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, OGLRef.texPostprocessFogID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
}
if (this->isMultisampledFBOSupported)
{
GLint maxSamples = 0;
glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSamples);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, OGLRef.rboMSGColorID);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, maxSamples, GL_RGBA, w, h);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, OGLRef.rboMSGDepthID);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, maxSamples, GL_RGBA, w, h);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, OGLRef.rboMSGPolyID);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, maxSamples, GL_RGBA, w, h);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, OGLRef.rboMSGFogAttrID);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, maxSamples, GL_RGBA, w, h);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, OGLRef.rboMSGDepthStencilID);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, maxSamples, GL_DEPTH24_STENCIL8_EXT, w, h);
}
if (this->isPBOSupported)
{
glBufferData(GL_PIXEL_PACK_BUFFER_ARB, this->_framebufferColorSizeBytes, NULL, GL_STREAM_READ);
}
return OGLERROR_NOERR;
@ -2962,7 +3210,7 @@ Render3DError OpenGLRenderer_1_5::RenderFinish()
ENDGL();
this->FlushFramebuffer((FragmentColor *)gfx3d_convertedScreen);
this->FlushFramebuffer(gfx3d_convertedScreen);
this->_pixelReadNeedsFinish = false;
return OGLERROR_NOERR;
@ -3745,7 +3993,7 @@ Render3DError OpenGLRenderer_2_1::RenderFinish()
ENDGL();
this->FlushFramebuffer((FragmentColor *)gfx3d_convertedScreen);
this->FlushFramebuffer(gfx3d_convertedScreen);
this->_pixelReadNeedsFinish = false;
return OGLERROR_NOERR;

View File

@ -413,6 +413,12 @@ struct OGLRenderRef
GLuint texPolyStatesID;
// FBO
GLuint texCIColorID;
GLuint texCIDepthID;
GLuint texCIFogAttrID;
GLuint texCIPolyID;
GLuint texCIDepthStencilID;
GLuint texGColorID;
GLuint texGDepthID;
GLuint texGFogAttrID;
@ -427,6 +433,7 @@ struct OGLRenderRef
GLuint rboMSGDepthStencilID;
GLuint rboMSPostprocessID;
GLuint fboClearImageID;
GLuint fboRenderID;
GLuint fboPostprocessID;
GLuint fboMSIntermediateRenderID;
@ -482,10 +489,10 @@ struct OGLRenderRef
// Client-side Buffers
GLfloat *color4fBuffer;
GLushort *vertIndexBuffer;
GLuint *workingDepthBuffer;
GLuint *workingDepthStencilBuffer;
GLuint *workingFogAttributesBuffer;
GLuint *workingPolyIDBuffer;
CACHE_ALIGN GLuint workingCIDepthBuffer[GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT];
CACHE_ALIGN GLuint workingCIDepthStencilBuffer[GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT];
CACHE_ALIGN GLuint workingCIFogAttributesBuffer[GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT];
CACHE_ALIGN GLuint workingCIPolyIDBuffer[GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT];
// Vertex Attributes Pointers
GLvoid *vtxPtrPosition;
@ -697,6 +704,7 @@ protected:
public:
virtual Render3DError UpdateToonTable(const u16 *toonTableBuffer);
virtual Render3DError SetFramebufferSize(size_t w, size_t h);
};
class OpenGLRenderer_1_4 : public OpenGLRenderer_1_3

View File

@ -592,10 +592,16 @@ Render3DError OpenGLRenderer_3_2::CreateFBOs()
OGLRenderRef &OGLRef = *this->ref;
// Set up FBO render targets
glGenTextures(1, &OGLRef.texCIColorID);
glGenTextures(1, &OGLRef.texCIDepthID);
glGenTextures(1, &OGLRef.texCIFogAttrID);
glGenTextures(1, &OGLRef.texCIPolyID);
glGenTextures(1, &OGLRef.texCIDepthStencilID);
glGenTextures(1, &OGLRef.texGColorID);
glGenTextures(1, &OGLRef.texGDepthID);
glGenTextures(1, &OGLRef.texGPolyID);
glGenTextures(1, &OGLRef.texGFogAttrID);
glGenTextures(1, &OGLRef.texGPolyID);
glGenTextures(1, &OGLRef.texGDepthStencilID);
glGenTextures(1, &OGLRef.texPostprocessFogID);
@ -640,6 +646,7 @@ Render3DError OpenGLRenderer_3_2::CreateFBOs()
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);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@ -647,12 +654,86 @@ Render3DError OpenGLRenderer_3_2::CreateFBOs()
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
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, OGLRef.texCIColorID);
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);
glBindTexture(GL_TEXTURE_2D, OGLRef.texCIDepthStencilID);
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);
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);
glBindTexture(GL_TEXTURE_2D, OGLRef.texCIDepthID);
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);
glBindTexture(GL_TEXTURE_2D, OGLRef.texCIPolyID);
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);
glBindTexture(GL_TEXTURE_2D, OGLRef.texCIFogAttrID);
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);
glBindTexture(GL_TEXTURE_2D, 0);
// Set up FBOs
glGenFramebuffers(1, &OGLRef.fboClearImageID);
glGenFramebuffers(1, &OGLRef.fboRenderID);
glGenFramebuffers(1, &OGLRef.fboPostprocessID);
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboClearImageID);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, OGLRef.texCIColorID, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, OGLRef.texCIDepthID, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, OGLRef.texCIPolyID, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, OGLRef.texCIFogAttrID, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, OGLRef.texCIDepthStencilID, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
INFO("OpenGL: Failed to created FBOs. Some emulation features will be disabled.\n");
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDeleteFramebuffers(1, &OGLRef.fboClearImageID);
glDeleteFramebuffers(1, &OGLRef.fboRenderID);
glDeleteFramebuffers(1, &OGLRef.fboPostprocessID);
glDeleteTextures(1, &OGLRef.texCIColorID);
glDeleteTextures(1, &OGLRef.texCIDepthID);
glDeleteTextures(1, &OGLRef.texCIFogAttrID);
glDeleteTextures(1, &OGLRef.texCIPolyID);
glDeleteTextures(1, &OGLRef.texCIDepthStencilID);
glDeleteTextures(1, &OGLRef.texGColorID);
glDeleteTextures(1, &OGLRef.texGDepthID);
glDeleteTextures(1, &OGLRef.texGPolyID);
glDeleteTextures(1, &OGLRef.texGFogAttrID);
glDeleteTextures(1, &OGLRef.texGDepthStencilID);
glDeleteTextures(1, &OGLRef.texPostprocessFogID);
OGLRef.fboClearImageID = 0;
OGLRef.fboRenderID = 0;
OGLRef.fboPostprocessID = 0;
return OGLERROR_FBO_CREATE_ERROR;
}
glDrawBuffers(4, RenderDrawList);
glReadBuffer(GL_COLOR_ATTACHMENT0);
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboRenderID);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, OGLRef.texGColorID, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, OGLRef.texGDepthID, 0);
@ -665,8 +746,14 @@ Render3DError OpenGLRenderer_3_2::CreateFBOs()
INFO("OpenGL: Failed to created FBOs. Some emulation features will be disabled.\n");
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDeleteFramebuffers(1, &OGLRef.fboClearImageID);
glDeleteFramebuffers(1, &OGLRef.fboRenderID);
glDeleteFramebuffers(1, &OGLRef.fboPostprocessID);
glDeleteTextures(1, &OGLRef.texCIColorID);
glDeleteTextures(1, &OGLRef.texCIDepthID);
glDeleteTextures(1, &OGLRef.texCIFogAttrID);
glDeleteTextures(1, &OGLRef.texCIPolyID);
glDeleteTextures(1, &OGLRef.texCIDepthStencilID);
glDeleteTextures(1, &OGLRef.texGColorID);
glDeleteTextures(1, &OGLRef.texGDepthID);
glDeleteTextures(1, &OGLRef.texGPolyID);
@ -674,6 +761,7 @@ Render3DError OpenGLRenderer_3_2::CreateFBOs()
glDeleteTextures(1, &OGLRef.texGDepthStencilID);
glDeleteTextures(1, &OGLRef.texPostprocessFogID);
OGLRef.fboClearImageID = 0;
OGLRef.fboRenderID = 0;
OGLRef.fboPostprocessID = 0;
@ -691,8 +779,14 @@ Render3DError OpenGLRenderer_3_2::CreateFBOs()
INFO("OpenGL: Failed to created FBOs. Some emulation features will be disabled.\n");
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDeleteFramebuffers(1, &OGLRef.fboClearImageID);
glDeleteFramebuffers(1, &OGLRef.fboRenderID);
glDeleteFramebuffers(1, &OGLRef.fboPostprocessID);
glDeleteTextures(1, &OGLRef.texCIColorID);
glDeleteTextures(1, &OGLRef.texCIDepthID);
glDeleteTextures(1, &OGLRef.texCIFogAttrID);
glDeleteTextures(1, &OGLRef.texCIPolyID);
glDeleteTextures(1, &OGLRef.texCIDepthStencilID);
glDeleteTextures(1, &OGLRef.texGColorID);
glDeleteTextures(1, &OGLRef.texGDepthID);
glDeleteTextures(1, &OGLRef.texGPolyID);
@ -700,6 +794,7 @@ Render3DError OpenGLRenderer_3_2::CreateFBOs()
glDeleteTextures(1, &OGLRef.texGDepthStencilID);
glDeleteTextures(1, &OGLRef.texPostprocessFogID);
OGLRef.fboClearImageID = 0;
OGLRef.fboRenderID = 0;
OGLRef.fboPostprocessID = 0;
@ -726,8 +821,14 @@ void OpenGLRenderer_3_2::DestroyFBOs()
OGLRenderRef &OGLRef = *this->ref;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDeleteFramebuffers(1, &OGLRef.fboClearImageID);
glDeleteFramebuffers(1, &OGLRef.fboRenderID);
glDeleteFramebuffers(1, &OGLRef.fboPostprocessID);
glDeleteTextures(1, &OGLRef.texCIColorID);
glDeleteTextures(1, &OGLRef.texCIDepthID);
glDeleteTextures(1, &OGLRef.texCIFogAttrID);
glDeleteTextures(1, &OGLRef.texCIPolyID);
glDeleteTextures(1, &OGLRef.texCIDepthStencilID);
glDeleteTextures(1, &OGLRef.texGColorID);
glDeleteTextures(1, &OGLRef.texGDepthID);
glDeleteTextures(1, &OGLRef.texGPolyID);
@ -735,6 +836,7 @@ void OpenGLRenderer_3_2::DestroyFBOs()
glDeleteTextures(1, &OGLRef.texGDepthStencilID);
glDeleteTextures(1, &OGLRef.texPostprocessFogID);
OGLRef.fboClearImageID = 0;
OGLRef.fboRenderID = 0;
OGLRef.fboPostprocessID = 0;
@ -1235,11 +1337,37 @@ Render3DError OpenGLRenderer_3_2::ClearUsingImage(const u16 *__restrict colorBuf
this->UploadClearImage(colorBuffer, depthBuffer, fogBuffer, polyIDBuffer);
glBindFramebuffer(GL_READ_FRAMEBUFFER, OGLRef.fboClearImageID);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, OGLRef.fboRenderID);
// Blit the working depth buffer
glReadBuffer(GL_COLOR_ATTACHMENT1);
glDrawBuffer(GL_COLOR_ATTACHMENT1);
glBlitFramebuffer(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 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, 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, 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, this->_framebufferWidth, this->_framebufferHeight, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboRenderID);
glDrawBuffers(4, RenderDrawList);
OGLRef.selectedRenderingFBO = (CommonSettings.GFX3D_Renderer_Multisample) ? OGLRef.fboMSIntermediateRenderID : OGLRef.fboRenderID;
if (OGLRef.selectedRenderingFBO == OGLRef.fboMSIntermediateRenderID)
{
glBindFramebuffer(GL_READ_FRAMEBUFFER, OGLRef.fboRenderID);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, OGLRef.fboMSIntermediateRenderID);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, OGLRef.selectedRenderingFBO);
// Blit the working depth buffer
glReadBuffer(GL_COLOR_ATTACHMENT1);
@ -1260,11 +1388,11 @@ Render3DError OpenGLRenderer_3_2::ClearUsingImage(const u16 *__restrict colorBuf
glReadBuffer(GL_COLOR_ATTACHMENT0);
glDrawBuffer(GL_COLOR_ATTACHMENT0);
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);
glDrawBuffers(4, RenderDrawList);
}
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.selectedRenderingFBO);
glDrawBuffers(4, RenderDrawList);
return OGLERROR_NOERR;
}
@ -1420,3 +1548,58 @@ Render3DError OpenGLRenderer_3_2::SetupTexture(const POLY &thePoly, bool enableT
return OGLERROR_NOERR;
}
Render3DError OpenGLRenderer_3_2::SetFramebufferSize(size_t w, size_t h)
{
OGLRenderRef &OGLRef = *this->ref;
if (w < GFX3D_FRAMEBUFFER_WIDTH || h < GFX3D_FRAMEBUFFER_HEIGHT)
{
return OGLERROR_NOERR;
}
this->_framebufferWidth = w;
this->_framebufferHeight = h;
this->_framebufferColorSizeBytes = w * h * sizeof(FragmentColor);
this->_framebufferColor = (FragmentColor *)realloc(this->_framebufferColor, this->_framebufferColorSizeBytes);
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_GColor);
glBindTexture(GL_TEXTURE_2D, OGLRef.texGDepthStencilID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, w, h, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL);
glBindTexture(GL_TEXTURE_2D, OGLRef.texGColorID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_GDepth);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_GPolyID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_FogAttr);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, OGLRef.texPostprocessFogID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
if (this->isMultisampledFBOSupported)
{
GLint maxSamples = 0;
glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
glBindRenderbuffer(GL_RENDERBUFFER, OGLRef.rboMSGColorID);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, maxSamples, GL_RGBA, w, h);
glBindRenderbuffer(GL_RENDERBUFFER, OGLRef.rboMSGDepthID);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, maxSamples, GL_RGBA, w, h);
glBindRenderbuffer(GL_RENDERBUFFER, OGLRef.rboMSGPolyID);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, maxSamples, GL_RGBA, w, h);
glBindRenderbuffer(GL_RENDERBUFFER, OGLRef.rboMSGFogAttrID);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, maxSamples, GL_RGBA, w, h);
glBindRenderbuffer(GL_RENDERBUFFER, OGLRef.rboMSGDepthStencilID);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, maxSamples, GL_DEPTH24_STENCIL8, w, h);
}
glBufferData(GL_PIXEL_PACK_BUFFER, this->_framebufferColorSizeBytes, NULL, GL_STREAM_READ);
return OGLERROR_NOERR;
}

View File

@ -94,6 +94,7 @@ protected:
virtual void SetPolygonIndex(const size_t index);
virtual Render3DError SetupPolygon(const POLY &thePoly);
virtual Render3DError SetupTexture(const POLY &thePoly, bool enableTexturing);
virtual Render3DError SetFramebufferSize(size_t w, size_t h);
public:
~OpenGLRenderer_3_2();

View File

@ -41,6 +41,7 @@
#include "driver.h"
#include "emufile.h"
#include "matrix.h"
#include "GPU.h"
#include "bits.h"
#include "MMU.h"
#include "render3D.h"
@ -309,7 +310,7 @@ static float normalTable[1024];
#define fix10_2float(v) (((float)((s32)(v))) / (float)(1<<9))
// Color buffer that is filled by the 3D renderer and is read by the GPU engine.
u8 *gfx3d_convertedScreen = NULL;
FragmentColor *gfx3d_convertedScreen = NULL;
static size_t gfx3d_framebufferWidth = GFX3D_FRAMEBUFFER_WIDTH;
static size_t gfx3d_framebufferHeight = GFX3D_FRAMEBUFFER_HEIGHT;
@ -323,8 +324,8 @@ CACHE_ALIGN MatrixStack mtxStack[4] = {
int _hack_getMatrixStackLevel(int which) { return mtxStack[which].position; }
static CACHE_ALIGN s32 mtxCurrent [4][16];
static CACHE_ALIGN s32 mtxTemporal[16];
static CACHE_ALIGN s32 mtxCurrent[4][16];
static CACHE_ALIGN s32 mtxTemporal[16];
static MatrixMode mode = MATRIXMODE_PROJECTION;
// Indexes for matrix loading/multiplication
@ -543,19 +544,12 @@ 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);
makeTables();
Render3D_Init();
gfx3d_setFramebufferSize(gfx3d_framebufferWidth, gfx3d_framebufferHeight);
gfx3d_reset();
}
@ -677,11 +671,16 @@ void gfx3d_setFramebufferSize(size_t w, size_t h)
return;
}
CurrentRenderer->RenderFinish();
// Check if we're calling this function from initialization.
// If we're not initializing, we need to finish rendering first.
if (gfx3d_convertedScreen != NULL)
{
CurrentRenderer->RenderFinish();
}
gfx3d_framebufferWidth = w;
gfx3d_framebufferHeight = h;
gfx3d_convertedScreen = (u8 *)realloc(gfx3d_convertedScreen, w * h * sizeof(FragmentColor));
gfx3d_convertedScreen = (FragmentColor *)realloc(gfx3d_convertedScreen, w * h * sizeof(FragmentColor));
CurrentRenderer->SetFramebufferSize(w, h);
}
@ -1519,8 +1518,8 @@ static void gfx3d_glLightColor(u32 v)
static BOOL gfx3d_glShininess(u32 val)
{
gfx3d.state.shininessTable[shininessInd++] = ((val & 0xFF));
gfx3d.state.shininessTable[shininessInd++] = (((val >> 8) & 0xFF));
gfx3d.state.shininessTable[shininessInd++] = (val & 0xFF);
gfx3d.state.shininessTable[shininessInd++] = (((val >> 8) & 0xFF));
gfx3d.state.shininessTable[shininessInd++] = (((val >> 16) & 0xFF));
gfx3d.state.shininessTable[shininessInd++] = (((val >> 24) & 0xFF));
@ -2458,27 +2457,23 @@ void gfx3d_glGetLightColor(const size_t index, u32 &dst)
dst = lightColor[index];
}
void gfx3d_GetLineData(int line, u8** dst)
void gfx3d_GetLineData(const size_t line, FragmentColor **dst)
{
CurrentRenderer->RenderFinish();
*dst = gfx3d_convertedScreen+((line)<<(8+2));
*dst = gfx3d_convertedScreen + (line * gfx3d_framebufferWidth);
}
void gfx3d_GetLineData15bpp(int line, u16** dst)
void gfx3d_GetLineData15bpp(const size_t line, u16 **dst)
{
//TODO - this is not very thread safe!!!
static u16 buf[GFX3D_FRAMEBUFFER_WIDTH];
*dst = buf;
u8* lineData;
FragmentColor *lineData;
gfx3d_GetLineData(line, &lineData);
for (size_t i = 0; i < GFX3D_FRAMEBUFFER_WIDTH; i++)
{
const u8 r = lineData[i*4+0];
const u8 g = lineData[i*4+1];
const u8 b = lineData[i*4+2];
const u8 a = lineData[i*4+3];
buf[i] = R6G6B6TORGB15(r,g,b) | ((a == 0) ? 0x0000 : 0x8000);
buf[i] = R6G6B6TORGB15(lineData[i].r, lineData[i].g, lineData[i].b) | ((lineData[i].a == 0) ? 0x0000 : 0x8000);
}
}

View File

@ -24,6 +24,7 @@
#include <istream>
#include "types.h"
#include "GPU.h"
class EMUFILE;
@ -749,7 +750,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 u8 *gfx3d_convertedScreen;
extern FragmentColor *gfx3d_convertedScreen;
extern BOOL isSwapBuffers;
int _hack_getMatrixStackLevel(int);
@ -782,8 +783,8 @@ void gfx3d_glGetMatrix(const MatrixMode mode, int index, float *dst);
void gfx3d_glGetLightDirection(const size_t index, u32 &dst);
void gfx3d_glGetLightColor(const size_t index, u32 &dst);
void gfx3d_GetLineData(int line, u8** dst);
void gfx3d_GetLineData15bpp(int line, u16** dst);
void gfx3d_GetLineData(const size_t line, FragmentColor **dst);
void gfx3d_GetLineData15bpp(const size_t line, u16 **dst);
struct SFORMAT;
extern SFORMAT SF_GFX3D[];

View File

@ -1150,7 +1150,7 @@ SoftRasterizerRenderer::SoftRasterizerRenderer()
_stateSetupNeedsFinish = false;
_renderGeometryNeedsFinish = false;
_framebufferAttributes = (FragmentAttributes *)calloc(_framebufferWidth * _framebufferHeight, sizeof(FragmentAttributes));
_framebufferAttributes = NULL;
if (!rasterizerUnitTasksInited)
{
@ -1859,11 +1859,17 @@ Render3DError SoftRasterizerRenderer::UpdateToonTable(const u16 *toonTableBuffer
Render3DError SoftRasterizerRenderer::ClearUsingImage(const u16 *__restrict colorBuffer, const u32 *__restrict depthBuffer, const bool *__restrict fogBuffer, const u8 *__restrict polyIDBuffer)
{
const float lineDecrement = ((float)GFX3D_FRAMEBUFFER_HEIGHT / (float)this->_framebufferHeight) + 0.000001;
const float readIncrement = ((float)GFX3D_FRAMEBUFFER_WIDTH / (float)this->_framebufferWidth) + 0.000001;
float line = GFX3D_FRAMEBUFFER_HEIGHT - 1.0 + lineDecrement;
float readLocation = (GFX3D_FRAMEBUFFER_HEIGHT - 1) * GFX3D_FRAMEBUFFER_WIDTH;
// The clear image buffer is y-flipped, so we need to flip it back to normal here.
for (size_t y = 0, iw = 0, ir = ((this->_framebufferHeight - 1) * this->_framebufferWidth); y < this->_framebufferHeight; y++, ir -= (this->_framebufferWidth * 2))
for (size_t y = 0, iw = 0; y < this->_framebufferHeight; y++, readLocation = ((size_t)line * GFX3D_FRAMEBUFFER_WIDTH))
{
for (size_t x = 0; x < this->_framebufferWidth; x++, iw++, ir++)
for (size_t x = 0; x < this->_framebufferWidth; x++, iw++, readLocation += readIncrement)
{
const size_t ir = (size_t)readLocation;
this->_framebufferColor[iw].color = RGB15TO6665(colorBuffer[ir] & 0x7FFF, (colorBuffer[ir] >> 15) * 0x1F);
this->_framebufferAttributes[iw].isFogged = fogBuffer[ir];
this->_framebufferAttributes[iw].depth = depthBuffer[ir];
@ -1872,6 +1878,8 @@ Render3DError SoftRasterizerRenderer::ClearUsingImage(const u16 *__restrict colo
this->_framebufferAttributes[iw].isTranslucentPoly = false;
this->_framebufferAttributes[iw].stencil = 0;
}
line -= lineDecrement;
}
return RENDER3DERROR_NOERR;
@ -1953,7 +1961,7 @@ Render3DError SoftRasterizerRenderer::EndRender(const u64 frameCount)
this->RenderEdgeMarkingAndFog(this->postprocessParam[0]);
}
this->FlushFramebuffer((FragmentColor *)gfx3d_convertedScreen);
this->FlushFramebuffer(gfx3d_convertedScreen);
}
return RENDER3DERROR_NOERR;
@ -1993,7 +2001,7 @@ Render3DError SoftRasterizerRenderer::RenderFinish()
}
}
this->FlushFramebuffer((FragmentColor *)gfx3d_convertedScreen);
this->FlushFramebuffer(gfx3d_convertedScreen);
return RENDER3DERROR_NOERR;
}
@ -2004,8 +2012,12 @@ Render3DError SoftRasterizerRenderer::SetFramebufferSize(size_t w, size_t h)
{
return RENDER3DERROR_NOERR;
}
// TODO: We're not prepared to do this yet, so do nothing for now.
this->_framebufferWidth = w;
this->_framebufferHeight = h;
this->_framebufferColorSizeBytes = w * h * sizeof(FragmentColor);
this->_framebufferColor = (FragmentColor *)realloc(this->_framebufferColor, this->_framebufferColorSizeBytes);
this->_framebufferAttributes = (FragmentAttributes *)realloc(this->_framebufferAttributes, w * h * sizeof(FragmentAttributes));
return RENDER3DERROR_NOERR;
}

View File

@ -85,6 +85,12 @@ bool NDS_3D_ChangeCore(int newCore)
return result;
}
Render3DError error = newRenderer->SetFramebufferSize(gfx3d_getFramebufferWidth(), gfx3d_getFramebufferHeight());
if (error != RENDER3DERROR_NOERR)
{
return result;
}
gpu3D = newRenderInterface;
cur3DCore = newCore;
CurrentRenderer = newRenderer;
@ -127,8 +133,8 @@ Render3D::Render3D()
_framebufferWidth = GFX3D_FRAMEBUFFER_WIDTH;
_framebufferHeight = GFX3D_FRAMEBUFFER_HEIGHT;
_framebufferColorSizeBytes = _framebufferWidth * _framebufferHeight * sizeof(FragmentColor);
_framebufferColor = (FragmentColor *)calloc(_framebufferWidth * _framebufferHeight, sizeof(FragmentColor));
_framebufferColorSizeBytes = 0;
_framebufferColor = NULL;
Reset();
}
@ -171,12 +177,10 @@ Render3DError Render3D::SetFramebufferSize(size_t w, size_t h)
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));
this->_framebufferColor = (FragmentColor *)realloc(this->_framebufferColor, this->_framebufferColorSizeBytes);
return RENDER3DERROR_NOERR;
}
@ -318,7 +322,11 @@ Render3DError Render3D::SetupViewport(const u32 viewportValue)
Render3DError Render3D::Reset()
{
memset(this->_framebufferColor, 0, this->_framebufferColorSizeBytes);
if (this->_framebufferColor != NULL)
{
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));
@ -361,7 +369,7 @@ Render3DError Render3D::Render(const GFX3D &engine)
Render3DError Render3D::RenderFinish()
{
this->FlushFramebuffer((FragmentColor *)gfx3d_convertedScreen);
this->FlushFramebuffer(gfx3d_convertedScreen);
return RENDER3DERROR_NOERR;
}

View File

@ -71,15 +71,6 @@ enum Render3DErrorCode
typedef int Render3DError;
union FragmentColor
{
u32 color;
struct
{
u8 r,g,b,a;
};
};
struct FragmentAttributes
{
u32 depth;
@ -90,13 +81,6 @@ struct FragmentAttributes
bool isTranslucentPoly;
};
inline FragmentColor MakeFragmentColor(u8 r, u8 g,u8 b,u8 a)
{
FragmentColor ret;
ret.r = r; ret.g = g; ret.b = b; ret.a = a;
return ret;
}
class Render3D
{
protected:

View File

@ -73,7 +73,7 @@ public:
u32 sizeX, sizeY;
float invSizeX, invSizeY;
u64 texid; //used by ogl renderer for the texid
u32 texid; //used by ogl renderer for the texid
TexCache_TexFormat cacheFormat;
struct Dump {