Render3D:

- In the OpenGL renderer, do better handling of the geometry index buffer, and also load its data in OpenGLRenderer::BeginRender().
- In the OpenGL renderer, remove a bunch of extraneous binds.
- Fix bug in SoftRasterizer where clear-image depth wasn’t being written correctly. (Regression from r5176.)
- Reduce the buffer sizes in the core 3D engine.
- Do even more refactoring.
This commit is contained in:
rogerman 2015-05-04 18:30:09 +00:00
parent 7dd90c9948
commit d5bb6fd79e
6 changed files with 407 additions and 396 deletions

View File

@ -963,6 +963,9 @@ OpenGLRenderer_1_2::~OpenGLRenderer_1_2()
delete[] ref->color4fBuffer;
ref->color4fBuffer = NULL;
delete[] ref->vertIndexBuffer;
ref->vertIndexBuffer = NULL;
DestroyGeometryProgram();
DestroyPostprocessingPrograms();
DestroyVAOs();
@ -1014,19 +1017,20 @@ Render3DError OpenGLRenderer_1_2::InitExtensions()
if (error == OGLERROR_NOERR)
{
error = this->InitGeometryProgram(vertexShaderProgram, fragmentShaderProgram);
if (error != OGLERROR_NOERR)
if (error == OGLERROR_NOERR)
{
this->isShaderSupported = false;
std::string edgeMarkVtxShaderString = std::string(EdgeMarkVtxShader_100);
std::string edgeMarkFragShaderString = std::string(EdgeMarkFragShader_100);
std::string fogVtxShaderString = std::string(FogVtxShader_100);
std::string fogFragShaderString = std::string(FogFragShader_100);
error = this->InitPostprocessingPrograms(edgeMarkVtxShaderString, edgeMarkFragShaderString, fogVtxShaderString, fogFragShaderString);
if (error != OGLERROR_NOERR)
{
INFO("OpenGL: Edge mark and fog require OpenGL v2.0 or later. These features will be disabled.\n");
}
}
std::string edgeMarkVtxShaderString = std::string(EdgeMarkVtxShader_100);
std::string edgeMarkFragShaderString = std::string(EdgeMarkFragShader_100);
std::string fogVtxShaderString = std::string(FogVtxShader_100);
std::string fogFragShaderString = std::string(FogFragShader_100);
error = this->InitPostprocessingPrograms(edgeMarkVtxShaderString, edgeMarkFragShaderString, fogVtxShaderString, fogFragShaderString);
if (error != OGLERROR_NOERR)
else
{
this->DestroyGeometryProgram();
this->isShaderSupported = false;
}
}
@ -1046,7 +1050,7 @@ Render3DError OpenGLRenderer_1_2::InitExtensions()
this->CreateVBOs();
}
this->isPBOSupported = this->IsExtensionPresent(&oglExtensionSet, "GL_ARB_vertex_buffer_object") &&
this->isPBOSupported = this->isVBOSupported &&
(this->IsExtensionPresent(&oglExtensionSet, "GL_ARB_pixel_buffer_object") ||
this->IsExtensionPresent(&oglExtensionSet, "GL_EXT_pixel_buffer_object"));
if (this->isPBOSupported)
@ -1648,7 +1652,11 @@ Render3DError OpenGLRenderer_1_2::InitFinalRenderStates(const std::set<std::stri
// because OpenGL needs 4-colors per vertex to support translucency. (The DS
// uses 3-colors per vertex, and adds alpha through the poly, so we can't
// simply reference the colors+alpha from just the vertices by themselves.)
OGLRef.color4fBuffer = this->isShaderSupported ? NULL : new GLfloat[VERTLIST_SIZE * 4];
OGLRef.color4fBuffer = (this->isShaderSupported) ? NULL : new GLfloat[VERTLIST_SIZE * 4];
// If VBOs aren't supported, then we need to create the index buffer on the
// client side so that we have a buffer to update.
OGLRef.vertIndexBuffer = (this->isVBOSupported) ? NULL : new GLushort[OGLRENDER_VERT_INDEX_BUFFER_COUNT];
return OGLERROR_NOERR;
}
@ -1731,34 +1739,26 @@ Render3DError OpenGLRenderer_1_2::DestroyToonTable()
return OGLERROR_NOERR;
}
Render3DError OpenGLRenderer_1_2::UploadToonTable(const u16 *toonTableBuffer)
{
glActiveTextureARB(GL_TEXTURE0_ARB + OGLTextureUnitID_ToonTable);
glBindTexture(GL_TEXTURE_1D, this->ref->texToonTableID);
glTexSubImage1D(GL_TEXTURE_1D, 0, 0, 32, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, toonTableBuffer);
glActiveTextureARB(GL_TEXTURE0_ARB);
return OGLERROR_NOERR;
}
Render3DError OpenGLRenderer_1_2::UploadClearImage(const u16 *__restrict colorBuffer, const u32 *__restrict depthBuffer, const bool *__restrict fogBuffer, const u8 *__restrict polyIDBuffer)
{
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++)
{
depth[i] = depthBuffer[i] | 0xFF000000;
depthStencil[i] = depthBuffer[i] << 8;
fogAttributes[i] = (fogBuffer[i]) ? 0xFF0000FF : 0xFF000000;
polyID[i] = (GLuint)polyIDBuffer[i] | 0xFF000000;
}
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, depthBuffer);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, depthStencil);
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);
@ -1815,95 +1815,13 @@ Render3DError OpenGLRenderer_1_2::ExpandFreeTextures()
return OGLERROR_NOERR;
}
Render3DError OpenGLRenderer_1_2::SetupVertices(const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList, GLushort *outIndexBuffer, size_t *outIndexCount)
{
OGLRenderRef &OGLRef = *this->ref;
const size_t polyCount = polyList->count;
size_t vertIndexCount = 0;
for(size_t i = 0; i < polyCount; i++)
{
const POLY *poly = &polyList->list[indexList->list[i]];
const size_t polyType = poly->type;
if (this->isShaderSupported)
{
for(size_t j = 0; j < polyType; j++)
{
const GLushort vertIndex = poly->vertIndexes[j];
// While we're looping through our vertices, add each vertex index to
// a buffer. For GFX3D_QUADS and GFX3D_QUAD_STRIP, we also add additional
// vertices here to convert them to GL_TRIANGLES, which are much easier
// to work with and won't be deprecated in future OpenGL versions.
outIndexBuffer[vertIndexCount++] = vertIndex;
if (poly->vtxFormat == GFX3D_QUADS || poly->vtxFormat == GFX3D_QUAD_STRIP)
{
if (j == 2)
{
outIndexBuffer[vertIndexCount++] = vertIndex;
}
else if (j == 3)
{
outIndexBuffer[vertIndexCount++] = poly->vertIndexes[0];
}
}
}
}
else
{
const GLfloat thePolyAlpha = (!poly->isWireframe() && poly->isTranslucent()) ? divide5bitBy31_LUT[poly->getAttributeAlpha()] : 1.0f;
for(size_t j = 0; j < polyType; j++)
{
const GLushort vertIndex = poly->vertIndexes[j];
const size_t colorIndex = vertIndex * 4;
// Consolidate the vertex color and the poly alpha to our internal color buffer
// so that OpenGL can use it.
const VERT *vert = &vertList->list[vertIndex];
OGLRef.color4fBuffer[colorIndex+0] = material_8bit_to_float[vert->color[0]];
OGLRef.color4fBuffer[colorIndex+1] = material_8bit_to_float[vert->color[1]];
OGLRef.color4fBuffer[colorIndex+2] = material_8bit_to_float[vert->color[2]];
OGLRef.color4fBuffer[colorIndex+3] = thePolyAlpha;
// While we're looping through our vertices, add each vertex index to a
// buffer. For GFX3D_QUADS and GFX3D_QUAD_STRIP, we also add additional
// vertices here to convert them to GL_TRIANGLES, which are much easier
// to work with and won't be deprecated in future OpenGL versions.
outIndexBuffer[vertIndexCount++] = vertIndex;
if (poly->vtxFormat == GFX3D_QUADS || poly->vtxFormat == GFX3D_QUAD_STRIP)
{
if (j == 2)
{
outIndexBuffer[vertIndexCount++] = vertIndex;
}
else if (j == 3)
{
outIndexBuffer[vertIndexCount++] = poly->vertIndexes[0];
}
}
}
}
}
*outIndexCount = vertIndexCount;
return OGLERROR_NOERR;
}
Render3DError OpenGLRenderer_1_2::EnableVertexAttributes(const VERTLIST *vertList, const GLushort *indexBuffer, const size_t vertIndexCount)
Render3DError OpenGLRenderer_1_2::EnableVertexAttributes()
{
OGLRenderRef &OGLRef = *this->ref;
if (this->isVAOSupported)
{
glBindVertexArray(OGLRef.vaoGeometryStatesID);
glBindBuffer(GL_ARRAY_BUFFER_ARB, OGLRef.vboGeometryVtxID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, OGLRef.iboGeometryIndexID);
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(VERT) * vertList->count, vertList);
glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, vertIndexCount * sizeof(GLushort), indexBuffer);
}
else
{
@ -1912,24 +1830,9 @@ Render3DError OpenGLRenderer_1_2::EnableVertexAttributes(const VERTLIST *vertLis
glEnableVertexAttribArray(OGLVertexAttributeID_Position);
glEnableVertexAttribArray(OGLVertexAttributeID_TexCoord0);
glEnableVertexAttribArray(OGLVertexAttributeID_Color);
if (this->isVBOSupported)
{
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, OGLRef.iboGeometryIndexID);
glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, vertIndexCount * sizeof(GLushort), OGLRef.vertIndexBuffer);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, OGLRef.vboGeometryVtxID);
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(VERT) * vertList->count, vertList);
glVertexAttribPointer(OGLVertexAttributeID_Position, 4, GL_FLOAT, GL_FALSE, sizeof(VERT), (const GLvoid *)offsetof(VERT, coord));
glVertexAttribPointer(OGLVertexAttributeID_TexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(VERT), (const GLvoid *)offsetof(VERT, texcoord));
glVertexAttribPointer(OGLVertexAttributeID_Color, 3, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(VERT), (const GLvoid *)offsetof(VERT, color));
}
else
{
glVertexAttribPointer(OGLVertexAttributeID_Position, 4, GL_FLOAT, GL_FALSE, sizeof(VERT), &vertList->list[0].coord);
glVertexAttribPointer(OGLVertexAttributeID_TexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(VERT), &vertList->list[0].texcoord);
glVertexAttribPointer(OGLVertexAttributeID_Color, 3, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(VERT), &vertList->list[0].color);
}
glVertexAttribPointer(OGLVertexAttributeID_Position, 4, GL_FLOAT, GL_FALSE, sizeof(VERT), OGLRef.vtxPtrPosition);
glVertexAttribPointer(OGLVertexAttributeID_TexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(VERT), OGLRef.vtxPtrTexCoord);
glVertexAttribPointer(OGLVertexAttributeID_Color, 3, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(VERT), OGLRef.vtxPtrColor);
}
else
{
@ -1939,23 +1842,17 @@ Render3DError OpenGLRenderer_1_2::EnableVertexAttributes(const VERTLIST *vertLis
if (this->isVBOSupported)
{
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, OGLRef.iboGeometryIndexID);
glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, vertIndexCount * sizeof(GLushort), OGLRef.vertIndexBuffer);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
glColorPointer(4, GL_FLOAT, 0, OGLRef.color4fBuffer);
glColorPointer(4, GL_FLOAT, 0, OGLRef.vtxPtrColor);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, OGLRef.vboGeometryVtxID);
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(VERT) * vertList->count, vertList);
glVertexPointer(4, GL_FLOAT, sizeof(VERT), (const GLvoid *)offsetof(VERT, coord));
glTexCoordPointer(2, GL_FLOAT, sizeof(VERT), (const GLvoid *)offsetof(VERT, texcoord));
}
else
{
glVertexPointer(4, GL_FLOAT, sizeof(VERT), &vertList->list[0].coord);
glTexCoordPointer(2, GL_FLOAT, sizeof(VERT), &vertList->list[0].texcoord);
glColorPointer(4, GL_FLOAT, 0, OGLRef.color4fBuffer);
glColorPointer(4, GL_FLOAT, 0, OGLRef.vtxPtrColor);
}
glVertexPointer(4, GL_FLOAT, sizeof(VERT), OGLRef.vtxPtrPosition);
glTexCoordPointer(2, GL_FLOAT, sizeof(VERT), OGLRef.vtxPtrTexCoord);
}
}
@ -1982,25 +1879,6 @@ Render3DError OpenGLRenderer_1_2::DisableVertexAttributes()
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
if (this->isVBOSupported)
{
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
}
}
return OGLERROR_NOERR;
}
Render3DError OpenGLRenderer_1_2::SelectRenderingFramebuffer()
{
OGLRenderRef &OGLRef = *this->ref;
if (this->isMultisampledFBOSupported)
{
OGLRef.selectedRenderingFBO = (CommonSettings.GFX3D_Renderer_Multisample) ? OGLRef.fboMSIntermediateRenderID : OGLRef.fboRenderID;
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.selectedRenderingFBO);
}
return OGLERROR_NOERR;
@ -2076,8 +1954,6 @@ Render3DError OpenGLRenderer_1_2::BeginRender(const GFX3D &engine)
OGLRenderRef &OGLRef = *this->ref;
this->doubleBufferIndex = (this->doubleBufferIndex + 1) & 0x01;
this->SelectRenderingFramebuffer();
if (this->isShaderSupported)
{
glUseProgram(OGLRef.programGeometryID);
@ -2087,9 +1963,6 @@ Render3DError OpenGLRenderer_1_2::BeginRender(const GFX3D &engine)
glUniform1i(OGLRef.uniformStateEnableEdgeMarking, (engine.renderState.enableEdgeMarking) ? GL_TRUE : GL_FALSE);
glUniform1i(OGLRef.uniformStateUseWDepth, (engine.renderState.wbuffer) ? GL_TRUE : GL_FALSE);
glUniform1f(OGLRef.uniformStateAlphaTestRef, divide5bitBy31_LUT[engine.renderState.alphaTestRef]);
glEnable(GL_DEPTH_TEST);
glEnable(GL_STENCIL_TEST);
}
else
{
@ -2106,16 +1979,96 @@ Render3DError OpenGLRenderer_1_2::BeginRender(const GFX3D &engine)
glLoadIdentity();
}
if(engine.renderState.enableAlphaBlending)
GLushort *indexPtr = NULL;
if (this->isVBOSupported)
{
glEnable(GL_BLEND);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, OGLRef.vboGeometryVtxID);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, OGLRef.iboGeometryIndexID);
indexPtr = (GLushort *)glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
}
else
{
glDisable(GL_BLEND);
// If VBOs aren't supported, we need to use the client-side buffers here.
OGLRef.vtxPtrPosition = &engine.vertlist->list[0].coord;
OGLRef.vtxPtrTexCoord = &engine.vertlist->list[0].texcoord;
OGLRef.vtxPtrColor = (this->isShaderSupported) ? (GLvoid *)&engine.vertlist->list[0].color : OGLRef.color4fBuffer;
indexPtr = OGLRef.vertIndexBuffer;
}
glDepthMask(GL_TRUE);
size_t vertIndexCount = 0;
for (size_t i = 0; i < engine.polylist->count; i++)
{
const POLY *thePoly = &engine.polylist->list[engine.indexlist.list[i]];
const size_t polyType = thePoly->type;
if (this->isShaderSupported)
{
for (size_t j = 0; j < polyType; j++)
{
const GLushort vertIndex = thePoly->vertIndexes[j];
// While we're looping through our vertices, add each vertex index to
// a buffer. For GFX3D_QUADS and GFX3D_QUAD_STRIP, we also add additional
// vertices here to convert them to GL_TRIANGLES, which are much easier
// to work with and won't be deprecated in future OpenGL versions.
indexPtr[vertIndexCount++] = vertIndex;
if (thePoly->vtxFormat == GFX3D_QUADS || thePoly->vtxFormat == GFX3D_QUAD_STRIP)
{
if (j == 2)
{
indexPtr[vertIndexCount++] = vertIndex;
}
else if (j == 3)
{
indexPtr[vertIndexCount++] = thePoly->vertIndexes[0];
}
}
}
}
else
{
const GLfloat thePolyAlpha = (!thePoly->isWireframe() && thePoly->isTranslucent()) ? divide5bitBy31_LUT[thePoly->getAttributeAlpha()] : 1.0f;
for (size_t j = 0; j < polyType; j++)
{
const GLushort vertIndex = thePoly->vertIndexes[j];
const size_t colorIndex = vertIndex * 4;
// Consolidate the vertex color and the poly alpha to our internal color buffer
// so that OpenGL can use it.
const VERT *vert = &engine.vertlist->list[vertIndex];
OGLRef.color4fBuffer[colorIndex+0] = material_8bit_to_float[vert->color[0]];
OGLRef.color4fBuffer[colorIndex+1] = material_8bit_to_float[vert->color[1]];
OGLRef.color4fBuffer[colorIndex+2] = material_8bit_to_float[vert->color[2]];
OGLRef.color4fBuffer[colorIndex+3] = thePolyAlpha;
// While we're looping through our vertices, add each vertex index to a
// buffer. For GFX3D_QUADS and GFX3D_QUAD_STRIP, we also add additional
// vertices here to convert them to GL_TRIANGLES, which are much easier
// to work with and won't be deprecated in future OpenGL versions.
indexPtr[vertIndexCount++] = vertIndex;
if (thePoly->vtxFormat == GFX3D_QUADS || thePoly->vtxFormat == GFX3D_QUAD_STRIP)
{
if (j == 2)
{
indexPtr[vertIndexCount++] = vertIndex;
}
else if (j == 3)
{
indexPtr[vertIndexCount++] = thePoly->vertIndexes[0];
}
}
}
}
}
if (this->isVBOSupported)
{
glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(VERT) * engine.vertlist->count, engine.vertlist);
}
return OGLERROR_NOERR;
}
@ -2138,9 +2091,19 @@ Render3DError OpenGLRenderer_1_2::RenderGeometry(const GFX3D_State &renderState,
if (polyCount > 0)
{
size_t vertIndexBufferCount = 0;
this->SetupVertices(vertList, polyList, indexList, OGLRef.vertIndexBuffer, &vertIndexBufferCount);
this->EnableVertexAttributes(vertList, OGLRef.vertIndexBuffer, vertIndexBufferCount);
glEnable(GL_DEPTH_TEST);
glEnable(GL_STENCIL_TEST);
if(renderState.enableAlphaBlending)
{
glEnable(GL_BLEND);
}
else
{
glDisable(GL_BLEND);
}
this->EnableVertexAttributes();
const POLY &firstPoly = polyList->list[indexList->list[0]];
u32 lastPolyAttr = firstPoly.polyAttr;
@ -2153,7 +2116,7 @@ Render3DError OpenGLRenderer_1_2::RenderGeometry(const GFX3D_State &renderState,
this->SetupViewport(lastViewport);
GLsizei vertIndexCount = 0;
GLushort *indexBufferPtr = (this->isVBOSupported) ? 0 : OGLRef.vertIndexBuffer;
GLushort *indexBufferPtr = OGLRef.vertIndexBuffer;
// Enumerate through all polygons and render
for (size_t i = 0; i < polyCount; i++)
@ -2240,7 +2203,10 @@ Render3DError OpenGLRenderer_1_2::EndRender(const u64 frameCount)
Render3DError OpenGLRenderer_1_2::UpdateToonTable(const u16 *toonTableBuffer)
{
this->UploadToonTable(toonTableBuffer);
glActiveTextureARB(GL_TEXTURE0_ARB + OGLTextureUnitID_ToonTable);
glBindTexture(GL_TEXTURE_1D, this->ref->texToonTableID);
glTexSubImage1D(GL_TEXTURE_1D, 0, 0, 32, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, toonTableBuffer);
glActiveTextureARB(GL_TEXTURE0_ARB);
return OGLERROR_NOERR;
}
@ -2256,44 +2222,46 @@ Render3DError OpenGLRenderer_1_2::ClearUsingImage(const u16 *__restrict colorBuf
this->UploadClearImage(colorBuffer, depthBuffer, fogBuffer, polyIDBuffer);
if (this->isMultisampledFBOSupported && OGLRef.selectedRenderingFBO == OGLRef.fboMSIntermediateRenderID)
if (this->isMultisampledFBOSupported)
{
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, OGLRef.fboRenderID);
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, OGLRef.fboMSIntermediateRenderID);
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);
// 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, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 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);
// 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);
// 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);
}
// 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_DEPTH_BUFFER_BIT, GL_NEAREST);
// 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, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 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);
// 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);
// Reset framebuffer targets
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.selectedRenderingFBO);
glDrawBuffers(4, RenderDrawList);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboMSIntermediateRenderID);
}
return OGLERROR_NOERR;
@ -2301,6 +2269,16 @@ Render3DError OpenGLRenderer_1_2::ClearUsingImage(const u16 *__restrict colorBuf
Render3DError OpenGLRenderer_1_2::ClearUsingValues(const FragmentColor &clearColor, const FragmentAttributes &clearAttributes) const
{
OGLRenderRef &OGLRef = *this->ref;
if (this->isMultisampledFBOSupported)
{
OGLRef.selectedRenderingFBO = (CommonSettings.GFX3D_Renderer_Multisample) ? OGLRef.fboMSIntermediateRenderID : OGLRef.fboRenderID;
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.selectedRenderingFBO);
}
glDepthMask(GL_TRUE);
if (this->isShaderSupported && this->isFBOSupported)
{
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); // texGColorID
@ -2344,21 +2322,6 @@ Render3DError OpenGLRenderer_1_2::SetupPolygon(const POLY &thePoly)
OGLRenderRef &OGLRef = *this->ref;
const PolygonAttributes attr = thePoly.getAttributes();
// Set up polygon attributes
if (this->isShaderSupported)
{
glUniform1i(OGLRef.uniformPolyMode, attr.polygonMode);
glUniform1i(OGLRef.uniformPolyEnableFog, (attr.enableRenderFog) ? GL_TRUE : GL_FALSE);
glUniform1f(OGLRef.uniformPolyAlpha, (!attr.isWireframe && attr.isTranslucent) ? divide5bitBy31_LUT[attr.alpha] : 1.0f);
glUniform1i(OGLRef.uniformPolyID, attr.polygonID);
}
else
{
// Set the texture blending mode
static const GLint oglTexBlendMode[4] = {GL_MODULATE, GL_DECAL, GL_MODULATE, GL_MODULATE};
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, oglTexBlendMode[attr.polygonMode]);
}
// Set up depth test mode
static const GLenum oglDepthFunc[2] = {GL_LESS, GL_EQUAL};
glDepthFunc(oglDepthFunc[attr.enableDepthTest]);
@ -2430,11 +2393,22 @@ Render3DError OpenGLRenderer_1_2::SetupPolygon(const POLY &thePoly)
glDepthMask(enableDepthWrite);
// Set up polygon attributes
if (this->isShaderSupported)
{
glUniform1i(OGLRef.uniformPolyMode, attr.polygonMode);
glUniform1i(OGLRef.uniformPolyEnableFog, (attr.enableRenderFog) ? GL_TRUE : GL_FALSE);
glUniform1f(OGLRef.uniformPolyAlpha, (!attr.isWireframe && attr.isTranslucent) ? divide5bitBy31_LUT[attr.alpha] : 1.0f);
glUniform1i(OGLRef.uniformPolyID, attr.polygonID);
glUniform1i(OGLRef.uniformPolyEnableDepthWrite, enableDepthWrite);
glUniform1i(OGLRef.uniformPolySetNewDepthForTranslucent, (attr.enableAlphaDepthWrite) ? GL_TRUE : GL_FALSE);
}
else
{
// Set the texture blending mode
static const GLint oglTexBlendMode[4] = {GL_MODULATE, GL_DECAL, GL_MODULATE, GL_MODULATE};
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, oglTexBlendMode[attr.polygonMode]);
}
return OGLERROR_NOERR;
}
@ -2542,7 +2516,7 @@ Render3DError OpenGLRenderer_1_2::Reset()
memset(this->GPU_screen3D[i], 0, sizeof(this->GPU_screen3D[i]));
}
if(!this->isShaderSupported)
if (!this->isShaderSupported)
{
glEnable(GL_NORMALIZE);
glEnable(GL_TEXTURE_1D);
@ -2550,15 +2524,26 @@ Render3DError OpenGLRenderer_1_2::Reset()
glAlphaFunc(GL_GREATER, 0);
glEnable(GL_ALPHA_TEST);
glEnable(GL_BLEND);
}
if (OGLRef.color4fBuffer != NULL)
{
memset(OGLRef.color4fBuffer, 0, VERTLIST_SIZE * 4 * sizeof(GLfloat));
}
memset(OGLRef.vertIndexBuffer, 0, OGLRENDER_VERT_INDEX_BUFFER_COUNT * sizeof(GLushort));
if (OGLRef.vertIndexBuffer != NULL)
{
memset(OGLRef.vertIndexBuffer, 0, OGLRENDER_VERT_INDEX_BUFFER_COUNT * sizeof(GLushort));
}
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;
return OGLERROR_NOERR;
}
@ -2598,7 +2583,7 @@ Render3DError OpenGLRenderer_1_2::RenderFinish()
return OGLERROR_NOERR;
}
Render3DError OpenGLRenderer_1_3::UploadToonTable(const u16 *toonTableBuffer)
Render3DError OpenGLRenderer_1_3::UpdateToonTable(const u16 *toonTableBuffer)
{
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_ToonTable);
glBindTexture(GL_TEXTURE_1D, this->ref->texToonTableID);
@ -2613,19 +2598,21 @@ 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++)
{
depth[i] = depthBuffer[i] | 0xFF000000;
depthStencil[i] = depthBuffer[i] << 8;
fogAttributes[i] = (fogBuffer[i]) ? 0xFF0000FF : 0xFF000000;
polyID[i] = (GLuint)polyIDBuffer[i] | 0xFF000000;
}
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, depthBuffer);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, depthStencil);
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);
@ -2672,7 +2659,11 @@ Render3DError OpenGLRenderer_1_4::InitFinalRenderStates(const std::set<std::stri
// because OpenGL needs 4-colors per vertex to support translucency. (The DS
// uses 3-colors per vertex, and adds alpha through the poly, so we can't
// simply reference the colors+alpha from just the vertices by themselves.)
OGLRef.color4fBuffer = this->isShaderSupported ? NULL : new GLfloat[VERTLIST_SIZE * 4];
OGLRef.color4fBuffer = (this->isShaderSupported) ? NULL : new GLfloat[VERTLIST_SIZE * 4];
// If VBOs aren't supported, then we need to create the index buffer on the
// client side so that we have a buffer to update.
OGLRef.vertIndexBuffer = (this->isVBOSupported) ? NULL : new GLushort[OGLRENDER_VERT_INDEX_BUFFER_COUNT];
return OGLERROR_NOERR;
}
@ -2794,36 +2785,24 @@ Render3DError OpenGLRenderer_1_5::CreateVAOs()
return OGLERROR_NOERR;
}
Render3DError OpenGLRenderer_1_5::EnableVertexAttributes(const VERTLIST *vertList, const GLushort *indexBuffer, const size_t vertIndexCount)
Render3DError OpenGLRenderer_1_5::EnableVertexAttributes()
{
OGLRenderRef &OGLRef = *this->ref;
if (this->isVAOSupported)
{
glBindVertexArray(OGLRef.vaoGeometryStatesID);
glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboGeometryVtxID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, OGLRef.iboGeometryIndexID);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(VERT) * vertList->count, vertList);
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, vertIndexCount * sizeof(GLushort), indexBuffer);
}
else
{
if (this->isShaderSupported)
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, OGLRef.iboGeometryIndexID);
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, vertIndexCount * sizeof(GLushort), indexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboGeometryVtxID);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(VERT) * vertList->count, vertList);
glEnableVertexAttribArray(OGLVertexAttributeID_Position);
glEnableVertexAttribArray(OGLVertexAttributeID_TexCoord0);
glEnableVertexAttribArray(OGLVertexAttributeID_Color);
glVertexAttribPointer(OGLVertexAttributeID_Position, 4, GL_FLOAT, GL_FALSE, sizeof(VERT), (const GLvoid *)offsetof(VERT, coord));
glVertexAttribPointer(OGLVertexAttributeID_TexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(VERT), (const GLvoid *)offsetof(VERT, texcoord));
glVertexAttribPointer(OGLVertexAttributeID_Color, 3, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(VERT), (const GLvoid *)offsetof(VERT, color));
glVertexAttribPointer(OGLVertexAttributeID_Position, 4, GL_FLOAT, GL_FALSE, sizeof(VERT), OGLRef.vtxPtrPosition);
glVertexAttribPointer(OGLVertexAttributeID_TexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(VERT), OGLRef.vtxPtrTexCoord);
glVertexAttribPointer(OGLVertexAttributeID_Color, 3, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(VERT), OGLRef.vtxPtrColor);
}
else
{
@ -2831,16 +2810,12 @@ Render3DError OpenGLRenderer_1_5::EnableVertexAttributes(const VERTLIST *vertLis
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, OGLRef.iboGeometryIndexID);
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, vertIndexCount * sizeof(GLushort), indexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glColorPointer(4, GL_FLOAT, 0, OGLRef.color4fBuffer);
glColorPointer(4, GL_FLOAT, 0, OGLRef.vtxPtrColor);
glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboGeometryVtxID);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(VERT) * vertList->count, vertList);
glVertexPointer(4, GL_FLOAT, sizeof(VERT), (const GLvoid *)offsetof(VERT, coord));
glTexCoordPointer(2, GL_FLOAT, sizeof(VERT), (const GLvoid *)offsetof(VERT, texcoord));
glVertexPointer(4, GL_FLOAT, sizeof(VERT), OGLRef.vtxPtrPosition);
glTexCoordPointer(2, GL_FLOAT, sizeof(VERT), OGLRef.vtxPtrTexCoord);
}
}
@ -2867,14 +2842,81 @@ Render3DError OpenGLRenderer_1_5::DisableVertexAttributes()
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
return OGLERROR_NOERR;
}
Render3DError OpenGLRenderer_1_5::BeginRender(const GFX3D &engine)
{
OGLRenderRef &OGLRef = *this->ref;
this->doubleBufferIndex = (this->doubleBufferIndex + 1) & 0x01;
if (this->isShaderSupported)
{
glUseProgram(OGLRef.programGeometryID);
glUniform1i(OGLRef.uniformStateToonShadingMode, engine.renderState.shading);
glUniform1i(OGLRef.uniformStateEnableAlphaTest, (engine.renderState.enableAlphaTest) ? GL_TRUE : GL_FALSE);
glUniform1i(OGLRef.uniformStateEnableAntialiasing, (engine.renderState.enableAntialiasing) ? GL_TRUE : GL_FALSE);
glUniform1i(OGLRef.uniformStateEnableEdgeMarking, (engine.renderState.enableEdgeMarking) ? GL_TRUE : GL_FALSE);
glUniform1i(OGLRef.uniformStateUseWDepth, (engine.renderState.wbuffer) ? GL_TRUE : GL_FALSE);
glUniform1f(OGLRef.uniformStateAlphaTestRef, divide5bitBy31_LUT[engine.renderState.alphaTestRef]);
}
else
{
if(engine.renderState.enableAlphaTest && (engine.renderState.alphaTestRef > 0))
{
glAlphaFunc(GL_GEQUAL, divide5bitBy31_LUT[engine.renderState.alphaTestRef]);
}
else
{
glAlphaFunc(GL_GREATER, 0);
}
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
}
glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboGeometryVtxID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, OGLRef.iboGeometryIndexID);
size_t vertIndexCount = 0;
GLushort *indexPtr = (GLushort *)glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
for (size_t i = 0; i < engine.polylist->count; i++)
{
const POLY *thePoly = &engine.polylist->list[engine.indexlist.list[i]];
const size_t polyType = thePoly->type;
for (size_t j = 0; j < polyType; j++)
{
const GLushort vertIndex = thePoly->vertIndexes[j];
// While we're looping through our vertices, add each vertex index to
// a buffer. For GFX3D_QUADS and GFX3D_QUAD_STRIP, we also add additional
// vertices here to convert them to GL_TRIANGLES, which are much easier
// to work with and won't be deprecated in future OpenGL versions.
indexPtr[vertIndexCount++] = vertIndex;
if (thePoly->vtxFormat == GFX3D_QUADS || thePoly->vtxFormat == GFX3D_QUAD_STRIP)
{
if (j == 2)
{
indexPtr[vertIndexCount++] = vertIndex;
}
else if (j == 3)
{
indexPtr[vertIndexCount++] = thePoly->vertIndexes[0];
}
}
}
}
glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(VERT) * engine.vertlist->count, engine.vertlist);
return OGLERROR_NOERR;
}
Render3DError OpenGLRenderer_1_5::ReadBackPixels()
{
const size_t i = this->doubleBufferIndex;
@ -3044,6 +3086,9 @@ Render3DError OpenGLRenderer_2_0::InitFinalRenderStates(const std::set<std::stri
// Ignore our color buffer since we'll transfer the polygon alpha through a uniform.
OGLRef.color4fBuffer = NULL;
// VBOs are supported here, so just use the index buffer on the GPU.
OGLRef.vertIndexBuffer = NULL;
return OGLERROR_NOERR;
}
@ -3288,72 +3333,22 @@ Render3DError OpenGLRenderer_2_0::DestroyPostprocessingPrograms()
return OGLERROR_NOERR;
}
Render3DError OpenGLRenderer_2_0::SetupVertices(const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList, GLushort *outIndexBuffer, size_t *outIndexCount)
{
const size_t polyCount = polyList->count;
size_t vertIndexCount = 0;
for(size_t i = 0; i < polyCount; i++)
{
const POLY *poly = &polyList->list[indexList->list[i]];
const size_t polyType = poly->type;
for(size_t j = 0; j < polyType; j++)
{
const GLushort vertIndex = poly->vertIndexes[j];
// While we're looping through our vertices, add each vertex index to
// a buffer. For GFX3D_QUADS and GFX3D_QUAD_STRIP, we also add additional
// vertices here to convert them to GL_TRIANGLES, which are much easier
// to work with and won't be deprecated in future OpenGL versions.
outIndexBuffer[vertIndexCount++] = vertIndex;
if (poly->vtxFormat == GFX3D_QUADS || poly->vtxFormat == GFX3D_QUAD_STRIP)
{
if (j == 2)
{
outIndexBuffer[vertIndexCount++] = vertIndex;
}
else if (j == 3)
{
outIndexBuffer[vertIndexCount++] = poly->vertIndexes[0];
}
}
}
}
*outIndexCount = vertIndexCount;
return OGLERROR_NOERR;
}
Render3DError OpenGLRenderer_2_0::EnableVertexAttributes(const VERTLIST *vertList, const GLushort *indexBuffer, const size_t vertIndexCount)
Render3DError OpenGLRenderer_2_0::EnableVertexAttributes()
{
OGLRenderRef &OGLRef = *this->ref;
if (this->isVAOSupported)
{
glBindVertexArray(OGLRef.vaoGeometryStatesID);
glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboGeometryVtxID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, OGLRef.iboGeometryIndexID);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(VERT) * vertList->count, vertList);
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, vertIndexCount * sizeof(GLushort), indexBuffer);
}
else
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, OGLRef.iboGeometryIndexID);
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, vertIndexCount * sizeof(GLushort), indexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboGeometryVtxID);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(VERT) * vertList->count, vertList);
glEnableVertexAttribArray(OGLVertexAttributeID_Position);
glEnableVertexAttribArray(OGLVertexAttributeID_TexCoord0);
glEnableVertexAttribArray(OGLVertexAttributeID_Color);
glVertexAttribPointer(OGLVertexAttributeID_Position, 4, GL_FLOAT, GL_FALSE, sizeof(VERT), (const GLvoid *)offsetof(VERT, coord));
glVertexAttribPointer(OGLVertexAttributeID_TexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(VERT), (const GLvoid *)offsetof(VERT, texcoord));
glVertexAttribPointer(OGLVertexAttributeID_Color, 3, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(VERT), (const GLvoid *)offsetof(VERT, color));
glVertexAttribPointer(OGLVertexAttributeID_Position, 4, GL_FLOAT, GL_FALSE, sizeof(VERT), OGLRef.vtxPtrPosition);
glVertexAttribPointer(OGLVertexAttributeID_TexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(VERT), OGLRef.vtxPtrTexCoord);
glVertexAttribPointer(OGLVertexAttributeID_Color, 3, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(VERT), OGLRef.vtxPtrColor);
}
return OGLERROR_NOERR;
@ -3370,9 +3365,6 @@ Render3DError OpenGLRenderer_2_0::DisableVertexAttributes()
glDisableVertexAttribArray(OGLVertexAttributeID_Position);
glDisableVertexAttribArray(OGLVertexAttributeID_TexCoord0);
glDisableVertexAttribArray(OGLVertexAttributeID_Color);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
return OGLERROR_NOERR;
@ -3383,8 +3375,7 @@ Render3DError OpenGLRenderer_2_0::BeginRender(const GFX3D &engine)
OGLRenderRef &OGLRef = *this->ref;
this->doubleBufferIndex = (this->doubleBufferIndex + 1) & 0x01;
this->SelectRenderingFramebuffer();
// Setup render states
glUseProgram(OGLRef.programGeometryID);
glUniform1i(OGLRef.uniformStateToonShadingMode, engine.renderState.shading);
glUniform1i(OGLRef.uniformStateEnableAlphaTest, (engine.renderState.enableAlphaTest) ? GL_TRUE : GL_FALSE);
@ -3393,19 +3384,42 @@ Render3DError OpenGLRenderer_2_0::BeginRender(const GFX3D &engine)
glUniform1i(OGLRef.uniformStateUseWDepth, (engine.renderState.wbuffer) ? GL_TRUE : GL_FALSE);
glUniform1f(OGLRef.uniformStateAlphaTestRef, divide5bitBy31_LUT[engine.renderState.alphaTestRef]);
glEnable(GL_DEPTH_TEST);
glEnable(GL_STENCIL_TEST);
glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboGeometryVtxID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, OGLRef.iboGeometryIndexID);
if(engine.renderState.enableAlphaBlending)
size_t vertIndexCount = 0;
GLushort *indexPtr = (GLushort *)glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
for (size_t i = 0; i < engine.polylist->count; i++)
{
glEnable(GL_BLEND);
}
else
{
glDisable(GL_BLEND);
const POLY *thePoly = &engine.polylist->list[engine.indexlist.list[i]];
const size_t polyType = thePoly->type;
for (size_t j = 0; j < polyType; j++)
{
const GLushort vertIndex = thePoly->vertIndexes[j];
// While we're looping through our vertices, add each vertex index to
// a buffer. For GFX3D_QUADS and GFX3D_QUAD_STRIP, we also add additional
// vertices here to convert them to GL_TRIANGLES, which are much easier
// to work with and won't be deprecated in future OpenGL versions.
indexPtr[vertIndexCount++] = vertIndex;
if (thePoly->vtxFormat == GFX3D_QUADS || thePoly->vtxFormat == GFX3D_QUAD_STRIP)
{
if (j == 2)
{
indexPtr[vertIndexCount++] = vertIndex;
}
else if (j == 3)
{
indexPtr[vertIndexCount++] = thePoly->vertIndexes[0];
}
}
}
}
glDepthMask(GL_TRUE);
glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(VERT) * engine.vertlist->count, engine.vertlist);
return OGLERROR_NOERR;
}
@ -3574,12 +3588,6 @@ Render3DError OpenGLRenderer_2_0::SetupPolygon(const POLY &thePoly)
OGLRenderRef &OGLRef = *this->ref;
const PolygonAttributes attr = thePoly.getAttributes();
// Set up polygon attributes
glUniform1i(OGLRef.uniformPolyMode, attr.polygonMode);
glUniform1i(OGLRef.uniformPolyEnableFog, (attr.enableRenderFog) ? GL_TRUE : GL_FALSE);
glUniform1f(OGLRef.uniformPolyAlpha, (!attr.isWireframe && attr.isTranslucent) ? divide5bitBy31_LUT[attr.alpha] : 1.0f);
glUniform1i(OGLRef.uniformPolyID, attr.polygonID);
// Set up depth test mode
static const GLenum oglDepthFunc[2] = {GL_LESS, GL_EQUAL};
glDepthFunc(oglDepthFunc[attr.enableDepthTest]);
@ -3650,6 +3658,12 @@ Render3DError OpenGLRenderer_2_0::SetupPolygon(const POLY &thePoly)
}
glDepthMask(enableDepthWrite);
// Set up polygon attributes
glUniform1i(OGLRef.uniformPolyMode, attr.polygonMode);
glUniform1i(OGLRef.uniformPolyEnableFog, (attr.enableRenderFog) ? GL_TRUE : GL_FALSE);
glUniform1f(OGLRef.uniformPolyAlpha, (!attr.isWireframe && attr.isTranslucent) ? divide5bitBy31_LUT[attr.alpha] : 1.0f);
glUniform1i(OGLRef.uniformPolyID, attr.polygonID);
glUniform1i(OGLRef.uniformPolyEnableDepthWrite, enableDepthWrite);
glUniform1i(OGLRef.uniformPolySetNewDepthForTranslucent, (attr.enableAlphaDepthWrite) ? GL_TRUE : GL_FALSE);

View File

@ -280,7 +280,7 @@ EXTERNOGLEXT(PFNGLTEXBUFFERPROC, glTexBuffer) // Core in v3.1
#define OGLRENDER_MINIMUM_DRIVER_VERSION_REQUIRED_REVISION 0
#define OGLRENDER_MAX_MULTISAMPLES 16
#define OGLRENDER_VERT_INDEX_BUFFER_COUNT 131072
#define OGLRENDER_VERT_INDEX_BUFFER_COUNT (POLYLIST_SIZE * 6)
enum OGLVertexAttributeID
{
@ -477,7 +477,12 @@ struct OGLRenderRef
// Client-side Buffers
GLfloat *color4fBuffer;
CACHE_ALIGN GLushort vertIndexBuffer[OGLRENDER_VERT_INDEX_BUFFER_COUNT];
GLushort *vertIndexBuffer;
// Vertex Attributes Pointers
GLvoid *vtxPtrPosition;
GLvoid *vtxPtrTexCoord;
GLvoid *vtxPtrColor;
};
struct GFX3D_State;
@ -580,15 +585,12 @@ protected:
virtual Render3DError InitGeometryProgramShaderLocations() = 0;
virtual Render3DError CreateToonTable() = 0;
virtual Render3DError DestroyToonTable() = 0;
virtual Render3DError UploadToonTable(const u16 *toonTableBuffer) = 0;
virtual Render3DError UploadClearImage(const u16 *__restrict colorBuffer, const u32 *__restrict depthBuffer, const bool *__restrict fogBuffer, const u8 *__restrict polyIDBuffer) = 0;
virtual void GetExtensionSet(std::set<std::string> *oglExtensionSet) = 0;
virtual Render3DError ExpandFreeTextures() = 0;
virtual Render3DError SetupVertices(const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList, GLushort *outIndexBuffer, size_t *outIndexCount) = 0;
virtual Render3DError EnableVertexAttributes(const VERTLIST *vertList, const GLushort *indexBuffer, const size_t vertIndexCount) = 0;
virtual Render3DError EnableVertexAttributes() = 0;
virtual Render3DError DisableVertexAttributes() = 0;
virtual Render3DError SelectRenderingFramebuffer() = 0;
virtual Render3DError DownsampleFBO() = 0;
virtual Render3DError ReadBackPixels() = 0;
@ -641,15 +643,12 @@ protected:
virtual Render3DError CreateToonTable();
virtual Render3DError DestroyToonTable();
virtual Render3DError UploadToonTable(const u16 *toonTableBuffer);
virtual Render3DError UploadClearImage(const u16 *__restrict colorBuffer, const u32 *__restrict depthBuffer, const bool *__restrict fogBuffer, const u8 *__restrict polyIDBuffer);
virtual void GetExtensionSet(std::set<std::string> *oglExtensionSet);
virtual Render3DError ExpandFreeTextures();
virtual Render3DError SetupVertices(const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList, GLushort *outIndexBuffer, size_t *outIndexCount);
virtual Render3DError EnableVertexAttributes(const VERTLIST *vertList, const GLushort *indexBuffer, const size_t vertIndexCount);
virtual Render3DError EnableVertexAttributes();
virtual Render3DError DisableVertexAttributes();
virtual Render3DError SelectRenderingFramebuffer();
virtual Render3DError DownsampleFBO();
virtual Render3DError ReadBackPixels();
@ -681,8 +680,10 @@ public:
class OpenGLRenderer_1_3 : public OpenGLRenderer_1_2
{
protected:
virtual Render3DError UploadToonTable(const u16 *toonTableBuffer);
virtual Render3DError UploadClearImage(const u16 *__restrict colorBuffer, const u32 *__restrict depthBuffer, const bool *__restrict fogBuffer, const u8 *__restrict polyIDBuffer);
public:
virtual Render3DError UpdateToonTable(const u16 *toonTableBuffer);
};
class OpenGLRenderer_1_4 : public OpenGLRenderer_1_3
@ -700,8 +701,9 @@ protected:
virtual void DestroyPBOs();
virtual Render3DError CreateVAOs();
virtual Render3DError EnableVertexAttributes(const VERTLIST *vertList, const GLushort *indexBuffer, const size_t vertIndexCount);
virtual Render3DError EnableVertexAttributes();
virtual Render3DError DisableVertexAttributes();
virtual Render3DError BeginRender(const GFX3D &engine);
virtual Render3DError ReadBackPixels();
public:
@ -722,8 +724,7 @@ protected:
virtual Render3DError InitFogProgramShaderLocations();
virtual Render3DError DestroyPostprocessingPrograms();
virtual Render3DError SetupVertices(const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList, GLushort *outIndexBuffer, size_t *outIndexCount);
virtual Render3DError EnableVertexAttributes(const VERTLIST *vertList, const GLushort *indexBuffer, const size_t vertIndexCount);
virtual Render3DError EnableVertexAttributes();
virtual Render3DError DisableVertexAttributes();
virtual Render3DError BeginRender(const GFX3D &engine);

View File

@ -990,17 +990,9 @@ void OpenGLRenderer_3_2::GetExtensionSet(std::set<std::string> *oglExtensionSet)
}
}
Render3DError OpenGLRenderer_3_2::EnableVertexAttributes(const VERTLIST *vertList, const GLushort *indexBuffer, const size_t vertIndexCount)
Render3DError OpenGLRenderer_3_2::EnableVertexAttributes()
{
OGLRenderRef &OGLRef = *this->ref;
glBindVertexArray(OGLRef.vaoGeometryStatesID);
glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboGeometryVtxID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, OGLRef.iboGeometryIndexID);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(VERT) * vertList->count, vertList);
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, vertIndexCount * sizeof(GLushort), indexBuffer);
glBindVertexArray(this->ref->vaoGeometryStatesID);
return OGLERROR_NOERR;
}
@ -1010,17 +1002,6 @@ Render3DError OpenGLRenderer_3_2::DisableVertexAttributes()
return OGLERROR_NOERR;
}
Render3DError OpenGLRenderer_3_2::SelectRenderingFramebuffer()
{
OGLRenderRef &OGLRef = *this->ref;
OGLRef.selectedRenderingFBO = (CommonSettings.GFX3D_Renderer_Multisample) ? OGLRef.fboMSIntermediateRenderID : OGLRef.fboRenderID;
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.selectedRenderingFBO);
glDrawBuffers(4, RenderDrawList);
return OGLERROR_NOERR;
}
Render3DError OpenGLRenderer_3_2::DownsampleFBO()
{
OGLRenderRef &OGLRef = *this->ref;
@ -1141,13 +1122,19 @@ Render3DError OpenGLRenderer_3_2::BeginRender(const GFX3D &engine)
// Do per-poly setup
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_PolyStates);
glBindTexture(GL_TEXTURE_BUFFER, OGLRef.texPolyStatesID);
glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboGeometryVtxID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, OGLRef.iboGeometryIndexID);
glBindBuffer(GL_TEXTURE_BUFFER, OGLRef.tboPolyStatesID);
size_t vertIndexCount = 0;
GLushort *indexPtr = (GLushort *)glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, engine.polylist->count * 6 * sizeof(GLushort), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
OGLPolyStates *polyStates = (OGLPolyStates *)glMapBufferRange(GL_TEXTURE_BUFFER, 0, engine.polylist->count * sizeof(OGLPolyStates), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
for (size_t i = 0; i < engine.polylist->count; i++)
{
const POLY *thePoly = &engine.polylist->list[engine.indexlist.list[i]];
const size_t polyType = thePoly->type;
PolygonAttributes polyAttr = thePoly->getAttributes();
PolygonTexParams texParams = thePoly->getTexParams();
@ -1155,34 +1142,41 @@ Render3DError OpenGLRenderer_3_2::BeginRender(const GFX3D &engine)
polyStates[i].enableFog = (polyAttr.enableRenderFog) ? GL_TRUE : GL_FALSE;
polyStates[i].enableDepthWrite = ((!polyAttr.isTranslucent || polyAttr.enableAlphaDepthWrite) && !(polyAttr.polygonMode == 3 && polyAttr.polygonID == 0)) ? GL_TRUE : GL_FALSE;
polyStates[i].setNewDepthForTranslucent = (polyAttr.enableAlphaDepthWrite) ? GL_TRUE : GL_FALSE;
polyStates[i].polyAlpha = (!polyAttr.isWireframe && polyAttr.isTranslucent) ? polyAttr.alpha : 0x1F;
polyStates[i].polyMode = polyAttr.polygonMode;
polyStates[i].polyID = polyAttr.polygonID;
polyStates[i].texSizeS = texParams.sizeS;
polyStates[i].texSizeT = texParams.sizeT;
for (size_t j = 0; j < polyType; j++)
{
const GLushort vertIndex = thePoly->vertIndexes[j];
// While we're looping through our vertices, add each vertex index to
// a buffer. For GFX3D_QUADS and GFX3D_QUAD_STRIP, we also add additional
// vertices here to convert them to GL_TRIANGLES, which are much easier
// to work with and won't be deprecated in future OpenGL versions.
indexPtr[vertIndexCount++] = vertIndex;
if (thePoly->vtxFormat == GFX3D_QUADS || thePoly->vtxFormat == GFX3D_QUAD_STRIP)
{
if (j == 2)
{
indexPtr[vertIndexCount++] = vertIndex;
}
else if (j == 3)
{
indexPtr[vertIndexCount++] = thePoly->vertIndexes[0];
}
}
}
}
glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
glUnmapBuffer(GL_TEXTURE_BUFFER);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(VERT) * engine.vertlist->count, engine.vertlist);
// Set up remaining framebuffer states
this->SelectRenderingFramebuffer();
glUseProgram(OGLRef.programGeometryID);
glEnable(GL_DEPTH_TEST);
glEnable(GL_STENCIL_TEST);
if(engine.renderState.enableAlphaBlending)
{
glEnable(GL_BLEND);
}
else
{
glDisable(GL_BLEND);
}
glDepthMask(GL_TRUE);
return OGLERROR_NOERR;
}
@ -1253,16 +1247,12 @@ Render3DError OpenGLRenderer_3_2::ClearUsingImage(const u16 *__restrict colorBuf
this->UploadClearImage(colorBuffer, depthBuffer, fogBuffer, polyIDBuffer);
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);
// 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_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
// Blit the working depth buffer
glReadBuffer(GL_COLOR_ATTACHMENT1);
glDrawBuffer(GL_COLOR_ATTACHMENT1);
@ -1278,17 +1268,26 @@ Render3DError OpenGLRenderer_3_2::ClearUsingImage(const u16 *__restrict colorBuf
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);
// Reset framebuffer targets
// Blit the color buffer. Do this last so that color attachment 0 is set to the read FBO.
glReadBuffer(GL_COLOR_ATTACHMENT0);
glDrawBuffers(4, RenderDrawList);
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboMSIntermediateRenderID);
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);
}
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.selectedRenderingFBO);
glDrawBuffers(4, RenderDrawList);
return OGLERROR_NOERR;
}
Render3DError OpenGLRenderer_3_2::ClearUsingValues(const FragmentColor &clearColor, const FragmentAttributes &clearAttributes) const
{
OGLRenderRef &OGLRef = *this->ref;
OGLRef.selectedRenderingFBO = (CommonSettings.GFX3D_Renderer_Multisample) ? OGLRef.fboMSIntermediateRenderID : OGLRef.fboRenderID;
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.selectedRenderingFBO);
glDrawBuffers(4, RenderDrawList);
glDepthMask(GL_TRUE);
const GLfloat oglColor[4] = {divide5bitBy31_LUT[clearColor.r], divide5bitBy31_LUT[clearColor.g], divide5bitBy31_LUT[clearColor.b], divide5bitBy31_LUT[clearColor.a]};
const GLfloat oglDepth[4] = {(GLfloat)(clearAttributes.depth & 0x000000FF)/255.0f, (GLfloat)((clearAttributes.depth >> 8) & 0x000000FF)/255.0f, (GLfloat)((clearAttributes.depth >> 16) & 0x000000FF)/255.0f, 1.0};
const GLfloat oglPolyID[4] = {(GLfloat)clearAttributes.opaquePolyID/63.0f, 0.0, 0.0, 1.0};
@ -1309,10 +1308,8 @@ void OpenGLRenderer_3_2::SetPolygonIndex(const size_t index)
glUniform1i(this->ref->uniformPolyStateIndex, index);
}
Render3DError OpenGLRenderer_3_2::SetupPolygon(const POLY &thePoly)
{
//OGLRenderRef &OGLRef = *this->ref;
const PolygonAttributes attr = thePoly.getAttributes();
// Set up depth test mode

View File

@ -78,9 +78,8 @@ protected:
virtual void DestroyGeometryProgram();
virtual void GetExtensionSet(std::set<std::string> *oglExtensionSet);
virtual Render3DError EnableVertexAttributes(const VERTLIST *vertList, const GLushort *indexBuffer, const size_t vertIndexCount);
virtual Render3DError EnableVertexAttributes();
virtual Render3DError DisableVertexAttributes();
virtual Render3DError SelectRenderingFramebuffer();
virtual Render3DError DownsampleFBO();
virtual Render3DError BeginRender(const GFX3D &engine);
virtual Render3DError RenderEdgeMarking(const u16 *colorTable, const bool useAntialias);

View File

@ -485,7 +485,7 @@ struct POLY {
void load(EMUFILE* is);
};
#define POLYLIST_SIZE 100000
#define POLYLIST_SIZE 20000
struct POLYLIST {
POLY list[POLYLIST_SIZE];
int count;
@ -553,15 +553,15 @@ struct VERT {
void load(EMUFILE* is);
};
#define VERTLIST_SIZE 400000
//#define VERTLIST_SIZE 10000
#define VERTLIST_SIZE (POLYLIST_SIZE * 4)
struct VERTLIST {
VERT list[VERTLIST_SIZE];
int count;
};
#define INDEXLIST_SIZE (POLYLIST_SIZE * 4)
struct INDEXLIST {
int list[POLYLIST_SIZE];
int list[INDEXLIST_SIZE];
};

View File

@ -25,7 +25,7 @@
#include "MMU.h"
#include "texcache.h"
static CACHE_ALIGN u32 dsDepthToD24S8_LUT[32768] = {0};
static CACHE_ALIGN u32 dsDepthToD24_LUT[32768] = {0};
int cur3DCore = GPU3D_NULL;
GPU3DInterface gpu3DNull = {
@ -107,7 +107,7 @@ Render3D::Render3D()
{
for (size_t i = 0; i < 32768; i++)
{
dsDepthToD24S8_LUT[i] = (u32)DS_DEPTH15TO24(i) << 8;
dsDepthToD24_LUT[i] = (u32)DS_DEPTH15TO24(i);
}
needTableInit = false;
@ -195,7 +195,7 @@ Render3DError Render3D::ClearFramebuffer(const GFX3D_State &renderState)
//this is tested quite well in the sonic chronicles main map mode
//where depth values are used for trees etc you can walk behind
this->clearImageDepthBuffer[dd] = dsDepthToD24S8_LUT[clearDepthBuffer[adr] & 0x7FFF];
this->clearImageDepthBuffer[dd] = dsDepthToD24_LUT[clearDepthBuffer[adr] & 0x7FFF];
this->clearImageFogBuffer[dd] = BIT15(clearDepthBuffer[adr]);
this->clearImagePolyIDBuffer[dd] = clearFragment.opaquePolyID;