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:
parent
7dd90c9948
commit
d5bb6fd79e
|
@ -963,6 +963,9 @@ OpenGLRenderer_1_2::~OpenGLRenderer_1_2()
|
||||||
delete[] ref->color4fBuffer;
|
delete[] ref->color4fBuffer;
|
||||||
ref->color4fBuffer = NULL;
|
ref->color4fBuffer = NULL;
|
||||||
|
|
||||||
|
delete[] ref->vertIndexBuffer;
|
||||||
|
ref->vertIndexBuffer = NULL;
|
||||||
|
|
||||||
DestroyGeometryProgram();
|
DestroyGeometryProgram();
|
||||||
DestroyPostprocessingPrograms();
|
DestroyPostprocessingPrograms();
|
||||||
DestroyVAOs();
|
DestroyVAOs();
|
||||||
|
@ -1014,19 +1017,20 @@ Render3DError OpenGLRenderer_1_2::InitExtensions()
|
||||||
if (error == OGLERROR_NOERR)
|
if (error == OGLERROR_NOERR)
|
||||||
{
|
{
|
||||||
error = this->InitGeometryProgram(vertexShaderProgram, fragmentShaderProgram);
|
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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
this->DestroyGeometryProgram();
|
|
||||||
this->isShaderSupported = false;
|
this->isShaderSupported = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1046,7 +1050,7 @@ Render3DError OpenGLRenderer_1_2::InitExtensions()
|
||||||
this->CreateVBOs();
|
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_ARB_pixel_buffer_object") ||
|
||||||
this->IsExtensionPresent(&oglExtensionSet, "GL_EXT_pixel_buffer_object"));
|
this->IsExtensionPresent(&oglExtensionSet, "GL_EXT_pixel_buffer_object"));
|
||||||
if (this->isPBOSupported)
|
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
|
// 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
|
// 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.)
|
// 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;
|
return OGLERROR_NOERR;
|
||||||
}
|
}
|
||||||
|
@ -1731,34 +1739,26 @@ Render3DError OpenGLRenderer_1_2::DestroyToonTable()
|
||||||
return OGLERROR_NOERR;
|
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)
|
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;
|
OGLRenderRef &OGLRef = *this->ref;
|
||||||
|
|
||||||
static GLuint depth[GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT];
|
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 fogAttributes[GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT];
|
||||||
static GLuint polyID[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++)
|
for (size_t i = 0; i < GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT; i++)
|
||||||
{
|
{
|
||||||
depth[i] = depthBuffer[i] | 0xFF000000;
|
depth[i] = depthBuffer[i] | 0xFF000000;
|
||||||
|
depthStencil[i] = depthBuffer[i] << 8;
|
||||||
fogAttributes[i] = (fogBuffer[i]) ? 0xFF0000FF : 0xFF000000;
|
fogAttributes[i] = (fogBuffer[i]) ? 0xFF0000FF : 0xFF000000;
|
||||||
polyID[i] = (GLuint)polyIDBuffer[i] | 0xFF000000;
|
polyID[i] = (GLuint)polyIDBuffer[i] | 0xFF000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
glActiveTextureARB(GL_TEXTURE0_ARB + OGLTextureUnitID_GColor);
|
glActiveTextureARB(GL_TEXTURE0_ARB + OGLTextureUnitID_GColor);
|
||||||
glBindTexture(GL_TEXTURE_2D, OGLRef.texGDepthStencilID);
|
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);
|
glBindTexture(GL_TEXTURE_2D, OGLRef.texGColorID);
|
||||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, colorBuffer);
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 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;
|
return OGLERROR_NOERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
Render3DError OpenGLRenderer_1_2::SetupVertices(const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList, GLushort *outIndexBuffer, size_t *outIndexCount)
|
Render3DError OpenGLRenderer_1_2::EnableVertexAttributes()
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
OGLRenderRef &OGLRef = *this->ref;
|
OGLRenderRef &OGLRef = *this->ref;
|
||||||
|
|
||||||
if (this->isVAOSupported)
|
if (this->isVAOSupported)
|
||||||
{
|
{
|
||||||
glBindVertexArray(OGLRef.vaoGeometryStatesID);
|
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -1912,24 +1830,9 @@ Render3DError OpenGLRenderer_1_2::EnableVertexAttributes(const VERTLIST *vertLis
|
||||||
glEnableVertexAttribArray(OGLVertexAttributeID_Position);
|
glEnableVertexAttribArray(OGLVertexAttributeID_Position);
|
||||||
glEnableVertexAttribArray(OGLVertexAttributeID_TexCoord0);
|
glEnableVertexAttribArray(OGLVertexAttributeID_TexCoord0);
|
||||||
glEnableVertexAttribArray(OGLVertexAttributeID_Color);
|
glEnableVertexAttribArray(OGLVertexAttributeID_Color);
|
||||||
|
glVertexAttribPointer(OGLVertexAttributeID_Position, 4, GL_FLOAT, GL_FALSE, sizeof(VERT), OGLRef.vtxPtrPosition);
|
||||||
if (this->isVBOSupported)
|
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);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1939,23 +1842,17 @@ Render3DError OpenGLRenderer_1_2::EnableVertexAttributes(const VERTLIST *vertLis
|
||||||
|
|
||||||
if (this->isVBOSupported)
|
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);
|
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);
|
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
|
else
|
||||||
{
|
{
|
||||||
glVertexPointer(4, GL_FLOAT, sizeof(VERT), &vertList->list[0].coord);
|
glColorPointer(4, GL_FLOAT, 0, OGLRef.vtxPtrColor);
|
||||||
glTexCoordPointer(2, GL_FLOAT, sizeof(VERT), &vertList->list[0].texcoord);
|
|
||||||
glColorPointer(4, GL_FLOAT, 0, OGLRef.color4fBuffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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_COLOR_ARRAY);
|
||||||
glDisableClientState(GL_TEXTURE_COORD_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;
|
return OGLERROR_NOERR;
|
||||||
|
@ -2076,8 +1954,6 @@ Render3DError OpenGLRenderer_1_2::BeginRender(const GFX3D &engine)
|
||||||
OGLRenderRef &OGLRef = *this->ref;
|
OGLRenderRef &OGLRef = *this->ref;
|
||||||
this->doubleBufferIndex = (this->doubleBufferIndex + 1) & 0x01;
|
this->doubleBufferIndex = (this->doubleBufferIndex + 1) & 0x01;
|
||||||
|
|
||||||
this->SelectRenderingFramebuffer();
|
|
||||||
|
|
||||||
if (this->isShaderSupported)
|
if (this->isShaderSupported)
|
||||||
{
|
{
|
||||||
glUseProgram(OGLRef.programGeometryID);
|
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.uniformStateEnableEdgeMarking, (engine.renderState.enableEdgeMarking) ? GL_TRUE : GL_FALSE);
|
||||||
glUniform1i(OGLRef.uniformStateUseWDepth, (engine.renderState.wbuffer) ? GL_TRUE : GL_FALSE);
|
glUniform1i(OGLRef.uniformStateUseWDepth, (engine.renderState.wbuffer) ? GL_TRUE : GL_FALSE);
|
||||||
glUniform1f(OGLRef.uniformStateAlphaTestRef, divide5bitBy31_LUT[engine.renderState.alphaTestRef]);
|
glUniform1f(OGLRef.uniformStateAlphaTestRef, divide5bitBy31_LUT[engine.renderState.alphaTestRef]);
|
||||||
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
|
||||||
glEnable(GL_STENCIL_TEST);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2106,16 +1979,96 @@ Render3DError OpenGLRenderer_1_2::BeginRender(const GFX3D &engine)
|
||||||
glLoadIdentity();
|
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
|
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;
|
return OGLERROR_NOERR;
|
||||||
}
|
}
|
||||||
|
@ -2138,9 +2091,19 @@ Render3DError OpenGLRenderer_1_2::RenderGeometry(const GFX3D_State &renderState,
|
||||||
|
|
||||||
if (polyCount > 0)
|
if (polyCount > 0)
|
||||||
{
|
{
|
||||||
size_t vertIndexBufferCount = 0;
|
glEnable(GL_DEPTH_TEST);
|
||||||
this->SetupVertices(vertList, polyList, indexList, OGLRef.vertIndexBuffer, &vertIndexBufferCount);
|
glEnable(GL_STENCIL_TEST);
|
||||||
this->EnableVertexAttributes(vertList, OGLRef.vertIndexBuffer, vertIndexBufferCount);
|
|
||||||
|
if(renderState.enableAlphaBlending)
|
||||||
|
{
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glDisable(GL_BLEND);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->EnableVertexAttributes();
|
||||||
|
|
||||||
const POLY &firstPoly = polyList->list[indexList->list[0]];
|
const POLY &firstPoly = polyList->list[indexList->list[0]];
|
||||||
u32 lastPolyAttr = firstPoly.polyAttr;
|
u32 lastPolyAttr = firstPoly.polyAttr;
|
||||||
|
@ -2153,7 +2116,7 @@ Render3DError OpenGLRenderer_1_2::RenderGeometry(const GFX3D_State &renderState,
|
||||||
this->SetupViewport(lastViewport);
|
this->SetupViewport(lastViewport);
|
||||||
|
|
||||||
GLsizei vertIndexCount = 0;
|
GLsizei vertIndexCount = 0;
|
||||||
GLushort *indexBufferPtr = (this->isVBOSupported) ? 0 : OGLRef.vertIndexBuffer;
|
GLushort *indexBufferPtr = OGLRef.vertIndexBuffer;
|
||||||
|
|
||||||
// Enumerate through all polygons and render
|
// Enumerate through all polygons and render
|
||||||
for (size_t i = 0; i < polyCount; i++)
|
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)
|
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;
|
return OGLERROR_NOERR;
|
||||||
}
|
}
|
||||||
|
@ -2256,44 +2222,46 @@ Render3DError OpenGLRenderer_1_2::ClearUsingImage(const u16 *__restrict colorBuf
|
||||||
|
|
||||||
this->UploadClearImage(colorBuffer, depthBuffer, fogBuffer, polyIDBuffer);
|
this->UploadClearImage(colorBuffer, depthBuffer, fogBuffer, polyIDBuffer);
|
||||||
|
|
||||||
if (this->isMultisampledFBOSupported && OGLRef.selectedRenderingFBO == OGLRef.fboMSIntermediateRenderID)
|
if (this->isMultisampledFBOSupported)
|
||||||
{
|
{
|
||||||
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, OGLRef.fboRenderID);
|
OGLRef.selectedRenderingFBO = (CommonSettings.GFX3D_Renderer_Multisample) ? OGLRef.fboMSIntermediateRenderID : OGLRef.fboRenderID;
|
||||||
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, OGLRef.fboMSIntermediateRenderID);
|
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
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.selectedRenderingFBO);
|
||||||
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);
|
|
||||||
glDrawBuffers(4, RenderDrawList);
|
glDrawBuffers(4, RenderDrawList);
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboMSIntermediateRenderID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return OGLERROR_NOERR;
|
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
|
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)
|
if (this->isShaderSupported && this->isFBOSupported)
|
||||||
{
|
{
|
||||||
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); // texGColorID
|
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); // texGColorID
|
||||||
|
@ -2344,21 +2322,6 @@ Render3DError OpenGLRenderer_1_2::SetupPolygon(const POLY &thePoly)
|
||||||
OGLRenderRef &OGLRef = *this->ref;
|
OGLRenderRef &OGLRef = *this->ref;
|
||||||
const PolygonAttributes attr = thePoly.getAttributes();
|
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
|
// Set up depth test mode
|
||||||
static const GLenum oglDepthFunc[2] = {GL_LESS, GL_EQUAL};
|
static const GLenum oglDepthFunc[2] = {GL_LESS, GL_EQUAL};
|
||||||
glDepthFunc(oglDepthFunc[attr.enableDepthTest]);
|
glDepthFunc(oglDepthFunc[attr.enableDepthTest]);
|
||||||
|
@ -2430,11 +2393,22 @@ Render3DError OpenGLRenderer_1_2::SetupPolygon(const POLY &thePoly)
|
||||||
|
|
||||||
glDepthMask(enableDepthWrite);
|
glDepthMask(enableDepthWrite);
|
||||||
|
|
||||||
|
// Set up polygon attributes
|
||||||
if (this->isShaderSupported)
|
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.uniformPolyEnableDepthWrite, enableDepthWrite);
|
||||||
glUniform1i(OGLRef.uniformPolySetNewDepthForTranslucent, (attr.enableAlphaDepthWrite) ? GL_TRUE : GL_FALSE);
|
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;
|
return OGLERROR_NOERR;
|
||||||
}
|
}
|
||||||
|
@ -2542,7 +2516,7 @@ Render3DError OpenGLRenderer_1_2::Reset()
|
||||||
memset(this->GPU_screen3D[i], 0, sizeof(this->GPU_screen3D[i]));
|
memset(this->GPU_screen3D[i], 0, sizeof(this->GPU_screen3D[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!this->isShaderSupported)
|
if (!this->isShaderSupported)
|
||||||
{
|
{
|
||||||
glEnable(GL_NORMALIZE);
|
glEnable(GL_NORMALIZE);
|
||||||
glEnable(GL_TEXTURE_1D);
|
glEnable(GL_TEXTURE_1D);
|
||||||
|
@ -2550,15 +2524,26 @@ Render3DError OpenGLRenderer_1_2::Reset()
|
||||||
glAlphaFunc(GL_GREATER, 0);
|
glAlphaFunc(GL_GREATER, 0);
|
||||||
glEnable(GL_ALPHA_TEST);
|
glEnable(GL_ALPHA_TEST);
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OGLRef.color4fBuffer != NULL)
|
||||||
|
{
|
||||||
memset(OGLRef.color4fBuffer, 0, VERTLIST_SIZE * 4 * sizeof(GLfloat));
|
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->currTexture = NULL;
|
||||||
this->doubleBufferIndex = 0;
|
this->doubleBufferIndex = 0;
|
||||||
this->_currentPolyIndex = 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;
|
return OGLERROR_NOERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2598,7 +2583,7 @@ Render3DError OpenGLRenderer_1_2::RenderFinish()
|
||||||
return OGLERROR_NOERR;
|
return OGLERROR_NOERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
Render3DError OpenGLRenderer_1_3::UploadToonTable(const u16 *toonTableBuffer)
|
Render3DError OpenGLRenderer_1_3::UpdateToonTable(const u16 *toonTableBuffer)
|
||||||
{
|
{
|
||||||
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_ToonTable);
|
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_ToonTable);
|
||||||
glBindTexture(GL_TEXTURE_1D, this->ref->texToonTableID);
|
glBindTexture(GL_TEXTURE_1D, this->ref->texToonTableID);
|
||||||
|
@ -2613,19 +2598,21 @@ Render3DError OpenGLRenderer_1_3::UploadClearImage(const u16 *__restrict colorBu
|
||||||
OGLRenderRef &OGLRef = *this->ref;
|
OGLRenderRef &OGLRef = *this->ref;
|
||||||
|
|
||||||
static GLuint depth[GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT];
|
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 fogAttributes[GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT];
|
||||||
static GLuint polyID[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++)
|
for (size_t i = 0; i < GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT; i++)
|
||||||
{
|
{
|
||||||
depth[i] = depthBuffer[i] | 0xFF000000;
|
depth[i] = depthBuffer[i] | 0xFF000000;
|
||||||
|
depthStencil[i] = depthBuffer[i] << 8;
|
||||||
fogAttributes[i] = (fogBuffer[i]) ? 0xFF0000FF : 0xFF000000;
|
fogAttributes[i] = (fogBuffer[i]) ? 0xFF0000FF : 0xFF000000;
|
||||||
polyID[i] = (GLuint)polyIDBuffer[i] | 0xFF000000;
|
polyID[i] = (GLuint)polyIDBuffer[i] | 0xFF000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_GColor);
|
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_GColor);
|
||||||
glBindTexture(GL_TEXTURE_2D, OGLRef.texGDepthStencilID);
|
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);
|
glBindTexture(GL_TEXTURE_2D, OGLRef.texGColorID);
|
||||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, colorBuffer);
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 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
|
// 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
|
// 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.)
|
// 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;
|
return OGLERROR_NOERR;
|
||||||
}
|
}
|
||||||
|
@ -2794,36 +2785,24 @@ Render3DError OpenGLRenderer_1_5::CreateVAOs()
|
||||||
return OGLERROR_NOERR;
|
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;
|
OGLRenderRef &OGLRef = *this->ref;
|
||||||
|
|
||||||
if (this->isVAOSupported)
|
if (this->isVAOSupported)
|
||||||
{
|
{
|
||||||
glBindVertexArray(OGLRef.vaoGeometryStatesID);
|
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
|
else
|
||||||
{
|
{
|
||||||
if (this->isShaderSupported)
|
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_Position);
|
||||||
glEnableVertexAttribArray(OGLVertexAttributeID_TexCoord0);
|
glEnableVertexAttribArray(OGLVertexAttributeID_TexCoord0);
|
||||||
glEnableVertexAttribArray(OGLVertexAttributeID_Color);
|
glEnableVertexAttribArray(OGLVertexAttributeID_Color);
|
||||||
|
glVertexAttribPointer(OGLVertexAttributeID_Position, 4, GL_FLOAT, GL_FALSE, sizeof(VERT), OGLRef.vtxPtrPosition);
|
||||||
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), OGLRef.vtxPtrTexCoord);
|
||||||
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), OGLRef.vtxPtrColor);
|
||||||
glVertexAttribPointer(OGLVertexAttributeID_Color, 3, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(VERT), (const GLvoid *)offsetof(VERT, color));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2831,16 +2810,12 @@ Render3DError OpenGLRenderer_1_5::EnableVertexAttributes(const VERTLIST *vertLis
|
||||||
glEnableClientState(GL_COLOR_ARRAY);
|
glEnableClientState(GL_COLOR_ARRAY);
|
||||||
glEnableClientState(GL_VERTEX_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);
|
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);
|
glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboGeometryVtxID);
|
||||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(VERT) * vertList->count, vertList);
|
glVertexPointer(4, GL_FLOAT, sizeof(VERT), OGLRef.vtxPtrPosition);
|
||||||
glVertexPointer(4, GL_FLOAT, sizeof(VERT), (const GLvoid *)offsetof(VERT, coord));
|
glTexCoordPointer(2, GL_FLOAT, sizeof(VERT), OGLRef.vtxPtrTexCoord);
|
||||||
glTexCoordPointer(2, GL_FLOAT, sizeof(VERT), (const GLvoid *)offsetof(VERT, texcoord));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2867,14 +2842,81 @@ Render3DError OpenGLRenderer_1_5::DisableVertexAttributes()
|
||||||
glDisableClientState(GL_COLOR_ARRAY);
|
glDisableClientState(GL_COLOR_ARRAY);
|
||||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return OGLERROR_NOERR;
|
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()
|
Render3DError OpenGLRenderer_1_5::ReadBackPixels()
|
||||||
{
|
{
|
||||||
const size_t i = this->doubleBufferIndex;
|
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.
|
// Ignore our color buffer since we'll transfer the polygon alpha through a uniform.
|
||||||
OGLRef.color4fBuffer = NULL;
|
OGLRef.color4fBuffer = NULL;
|
||||||
|
|
||||||
|
// VBOs are supported here, so just use the index buffer on the GPU.
|
||||||
|
OGLRef.vertIndexBuffer = NULL;
|
||||||
|
|
||||||
return OGLERROR_NOERR;
|
return OGLERROR_NOERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3288,72 +3333,22 @@ Render3DError OpenGLRenderer_2_0::DestroyPostprocessingPrograms()
|
||||||
return OGLERROR_NOERR;
|
return OGLERROR_NOERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
Render3DError OpenGLRenderer_2_0::SetupVertices(const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList, GLushort *outIndexBuffer, size_t *outIndexCount)
|
Render3DError OpenGLRenderer_2_0::EnableVertexAttributes()
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
OGLRenderRef &OGLRef = *this->ref;
|
OGLRenderRef &OGLRef = *this->ref;
|
||||||
|
|
||||||
if (this->isVAOSupported)
|
if (this->isVAOSupported)
|
||||||
{
|
{
|
||||||
glBindVertexArray(OGLRef.vaoGeometryStatesID);
|
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
|
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_Position);
|
||||||
glEnableVertexAttribArray(OGLVertexAttributeID_TexCoord0);
|
glEnableVertexAttribArray(OGLVertexAttributeID_TexCoord0);
|
||||||
glEnableVertexAttribArray(OGLVertexAttributeID_Color);
|
glEnableVertexAttribArray(OGLVertexAttributeID_Color);
|
||||||
|
glVertexAttribPointer(OGLVertexAttributeID_Position, 4, GL_FLOAT, GL_FALSE, sizeof(VERT), OGLRef.vtxPtrPosition);
|
||||||
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), OGLRef.vtxPtrTexCoord);
|
||||||
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), OGLRef.vtxPtrColor);
|
||||||
glVertexAttribPointer(OGLVertexAttributeID_Color, 3, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(VERT), (const GLvoid *)offsetof(VERT, color));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return OGLERROR_NOERR;
|
return OGLERROR_NOERR;
|
||||||
|
@ -3370,9 +3365,6 @@ Render3DError OpenGLRenderer_2_0::DisableVertexAttributes()
|
||||||
glDisableVertexAttribArray(OGLVertexAttributeID_Position);
|
glDisableVertexAttribArray(OGLVertexAttributeID_Position);
|
||||||
glDisableVertexAttribArray(OGLVertexAttributeID_TexCoord0);
|
glDisableVertexAttribArray(OGLVertexAttributeID_TexCoord0);
|
||||||
glDisableVertexAttribArray(OGLVertexAttributeID_Color);
|
glDisableVertexAttribArray(OGLVertexAttributeID_Color);
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return OGLERROR_NOERR;
|
return OGLERROR_NOERR;
|
||||||
|
@ -3383,8 +3375,7 @@ Render3DError OpenGLRenderer_2_0::BeginRender(const GFX3D &engine)
|
||||||
OGLRenderRef &OGLRef = *this->ref;
|
OGLRenderRef &OGLRef = *this->ref;
|
||||||
this->doubleBufferIndex = (this->doubleBufferIndex + 1) & 0x01;
|
this->doubleBufferIndex = (this->doubleBufferIndex + 1) & 0x01;
|
||||||
|
|
||||||
this->SelectRenderingFramebuffer();
|
// Setup render states
|
||||||
|
|
||||||
glUseProgram(OGLRef.programGeometryID);
|
glUseProgram(OGLRef.programGeometryID);
|
||||||
glUniform1i(OGLRef.uniformStateToonShadingMode, engine.renderState.shading);
|
glUniform1i(OGLRef.uniformStateToonShadingMode, engine.renderState.shading);
|
||||||
glUniform1i(OGLRef.uniformStateEnableAlphaTest, (engine.renderState.enableAlphaTest) ? GL_TRUE : GL_FALSE);
|
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);
|
glUniform1i(OGLRef.uniformStateUseWDepth, (engine.renderState.wbuffer) ? GL_TRUE : GL_FALSE);
|
||||||
glUniform1f(OGLRef.uniformStateAlphaTestRef, divide5bitBy31_LUT[engine.renderState.alphaTestRef]);
|
glUniform1f(OGLRef.uniformStateAlphaTestRef, divide5bitBy31_LUT[engine.renderState.alphaTestRef]);
|
||||||
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboGeometryVtxID);
|
||||||
glEnable(GL_STENCIL_TEST);
|
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);
|
const POLY *thePoly = &engine.polylist->list[engine.indexlist.list[i]];
|
||||||
}
|
const size_t polyType = thePoly->type;
|
||||||
else
|
|
||||||
{
|
for (size_t j = 0; j < polyType; j++)
|
||||||
glDisable(GL_BLEND);
|
{
|
||||||
|
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;
|
return OGLERROR_NOERR;
|
||||||
}
|
}
|
||||||
|
@ -3574,12 +3588,6 @@ Render3DError OpenGLRenderer_2_0::SetupPolygon(const POLY &thePoly)
|
||||||
OGLRenderRef &OGLRef = *this->ref;
|
OGLRenderRef &OGLRef = *this->ref;
|
||||||
const PolygonAttributes attr = thePoly.getAttributes();
|
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
|
// Set up depth test mode
|
||||||
static const GLenum oglDepthFunc[2] = {GL_LESS, GL_EQUAL};
|
static const GLenum oglDepthFunc[2] = {GL_LESS, GL_EQUAL};
|
||||||
glDepthFunc(oglDepthFunc[attr.enableDepthTest]);
|
glDepthFunc(oglDepthFunc[attr.enableDepthTest]);
|
||||||
|
@ -3650,6 +3658,12 @@ Render3DError OpenGLRenderer_2_0::SetupPolygon(const POLY &thePoly)
|
||||||
}
|
}
|
||||||
|
|
||||||
glDepthMask(enableDepthWrite);
|
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.uniformPolyEnableDepthWrite, enableDepthWrite);
|
||||||
glUniform1i(OGLRef.uniformPolySetNewDepthForTranslucent, (attr.enableAlphaDepthWrite) ? GL_TRUE : GL_FALSE);
|
glUniform1i(OGLRef.uniformPolySetNewDepthForTranslucent, (attr.enableAlphaDepthWrite) ? GL_TRUE : GL_FALSE);
|
||||||
|
|
||||||
|
|
|
@ -280,7 +280,7 @@ EXTERNOGLEXT(PFNGLTEXBUFFERPROC, glTexBuffer) // Core in v3.1
|
||||||
#define OGLRENDER_MINIMUM_DRIVER_VERSION_REQUIRED_REVISION 0
|
#define OGLRENDER_MINIMUM_DRIVER_VERSION_REQUIRED_REVISION 0
|
||||||
|
|
||||||
#define OGLRENDER_MAX_MULTISAMPLES 16
|
#define OGLRENDER_MAX_MULTISAMPLES 16
|
||||||
#define OGLRENDER_VERT_INDEX_BUFFER_COUNT 131072
|
#define OGLRENDER_VERT_INDEX_BUFFER_COUNT (POLYLIST_SIZE * 6)
|
||||||
|
|
||||||
enum OGLVertexAttributeID
|
enum OGLVertexAttributeID
|
||||||
{
|
{
|
||||||
|
@ -477,7 +477,12 @@ struct OGLRenderRef
|
||||||
|
|
||||||
// Client-side Buffers
|
// Client-side Buffers
|
||||||
GLfloat *color4fBuffer;
|
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;
|
struct GFX3D_State;
|
||||||
|
@ -580,15 +585,12 @@ protected:
|
||||||
virtual Render3DError InitGeometryProgramShaderLocations() = 0;
|
virtual Render3DError InitGeometryProgramShaderLocations() = 0;
|
||||||
virtual Render3DError CreateToonTable() = 0;
|
virtual Render3DError CreateToonTable() = 0;
|
||||||
virtual Render3DError DestroyToonTable() = 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 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 void GetExtensionSet(std::set<std::string> *oglExtensionSet) = 0;
|
||||||
virtual Render3DError ExpandFreeTextures() = 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() = 0;
|
||||||
virtual Render3DError EnableVertexAttributes(const VERTLIST *vertList, const GLushort *indexBuffer, const size_t vertIndexCount) = 0;
|
|
||||||
virtual Render3DError DisableVertexAttributes() = 0;
|
virtual Render3DError DisableVertexAttributes() = 0;
|
||||||
virtual Render3DError SelectRenderingFramebuffer() = 0;
|
|
||||||
virtual Render3DError DownsampleFBO() = 0;
|
virtual Render3DError DownsampleFBO() = 0;
|
||||||
virtual Render3DError ReadBackPixels() = 0;
|
virtual Render3DError ReadBackPixels() = 0;
|
||||||
|
|
||||||
|
@ -641,15 +643,12 @@ protected:
|
||||||
|
|
||||||
virtual Render3DError CreateToonTable();
|
virtual Render3DError CreateToonTable();
|
||||||
virtual Render3DError DestroyToonTable();
|
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 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 void GetExtensionSet(std::set<std::string> *oglExtensionSet);
|
||||||
virtual Render3DError ExpandFreeTextures();
|
virtual Render3DError ExpandFreeTextures();
|
||||||
virtual Render3DError SetupVertices(const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList, GLushort *outIndexBuffer, size_t *outIndexCount);
|
virtual Render3DError EnableVertexAttributes();
|
||||||
virtual Render3DError EnableVertexAttributes(const VERTLIST *vertList, const GLushort *indexBuffer, const size_t vertIndexCount);
|
|
||||||
virtual Render3DError DisableVertexAttributes();
|
virtual Render3DError DisableVertexAttributes();
|
||||||
virtual Render3DError SelectRenderingFramebuffer();
|
|
||||||
virtual Render3DError DownsampleFBO();
|
virtual Render3DError DownsampleFBO();
|
||||||
virtual Render3DError ReadBackPixels();
|
virtual Render3DError ReadBackPixels();
|
||||||
|
|
||||||
|
@ -681,8 +680,10 @@ public:
|
||||||
class OpenGLRenderer_1_3 : public OpenGLRenderer_1_2
|
class OpenGLRenderer_1_3 : public OpenGLRenderer_1_2
|
||||||
{
|
{
|
||||||
protected:
|
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);
|
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
|
class OpenGLRenderer_1_4 : public OpenGLRenderer_1_3
|
||||||
|
@ -700,8 +701,9 @@ protected:
|
||||||
virtual void DestroyPBOs();
|
virtual void DestroyPBOs();
|
||||||
virtual Render3DError CreateVAOs();
|
virtual Render3DError CreateVAOs();
|
||||||
|
|
||||||
virtual Render3DError EnableVertexAttributes(const VERTLIST *vertList, const GLushort *indexBuffer, const size_t vertIndexCount);
|
virtual Render3DError EnableVertexAttributes();
|
||||||
virtual Render3DError DisableVertexAttributes();
|
virtual Render3DError DisableVertexAttributes();
|
||||||
|
virtual Render3DError BeginRender(const GFX3D &engine);
|
||||||
virtual Render3DError ReadBackPixels();
|
virtual Render3DError ReadBackPixels();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -722,8 +724,7 @@ protected:
|
||||||
virtual Render3DError InitFogProgramShaderLocations();
|
virtual Render3DError InitFogProgramShaderLocations();
|
||||||
virtual Render3DError DestroyPostprocessingPrograms();
|
virtual Render3DError DestroyPostprocessingPrograms();
|
||||||
|
|
||||||
virtual Render3DError SetupVertices(const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList, GLushort *outIndexBuffer, size_t *outIndexCount);
|
virtual Render3DError EnableVertexAttributes();
|
||||||
virtual Render3DError EnableVertexAttributes(const VERTLIST *vertList, const GLushort *indexBuffer, const size_t vertIndexCount);
|
|
||||||
virtual Render3DError DisableVertexAttributes();
|
virtual Render3DError DisableVertexAttributes();
|
||||||
|
|
||||||
virtual Render3DError BeginRender(const GFX3D &engine);
|
virtual Render3DError BeginRender(const GFX3D &engine);
|
||||||
|
|
|
@ -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(this->ref->vaoGeometryStatesID);
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
return OGLERROR_NOERR;
|
return OGLERROR_NOERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1010,17 +1002,6 @@ Render3DError OpenGLRenderer_3_2::DisableVertexAttributes()
|
||||||
return OGLERROR_NOERR;
|
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()
|
Render3DError OpenGLRenderer_3_2::DownsampleFBO()
|
||||||
{
|
{
|
||||||
OGLRenderRef &OGLRef = *this->ref;
|
OGLRenderRef &OGLRef = *this->ref;
|
||||||
|
@ -1141,13 +1122,19 @@ Render3DError OpenGLRenderer_3_2::BeginRender(const GFX3D &engine)
|
||||||
// Do per-poly setup
|
// Do per-poly setup
|
||||||
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_PolyStates);
|
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_PolyStates);
|
||||||
glBindTexture(GL_TEXTURE_BUFFER, OGLRef.texPolyStatesID);
|
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);
|
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);
|
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++)
|
for (size_t i = 0; i < engine.polylist->count; i++)
|
||||||
{
|
{
|
||||||
const POLY *thePoly = &engine.polylist->list[engine.indexlist.list[i]];
|
const POLY *thePoly = &engine.polylist->list[engine.indexlist.list[i]];
|
||||||
|
const size_t polyType = thePoly->type;
|
||||||
PolygonAttributes polyAttr = thePoly->getAttributes();
|
PolygonAttributes polyAttr = thePoly->getAttributes();
|
||||||
PolygonTexParams texParams = thePoly->getTexParams();
|
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].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].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].setNewDepthForTranslucent = (polyAttr.enableAlphaDepthWrite) ? GL_TRUE : GL_FALSE;
|
||||||
|
|
||||||
polyStates[i].polyAlpha = (!polyAttr.isWireframe && polyAttr.isTranslucent) ? polyAttr.alpha : 0x1F;
|
polyStates[i].polyAlpha = (!polyAttr.isWireframe && polyAttr.isTranslucent) ? polyAttr.alpha : 0x1F;
|
||||||
polyStates[i].polyMode = polyAttr.polygonMode;
|
polyStates[i].polyMode = polyAttr.polygonMode;
|
||||||
polyStates[i].polyID = polyAttr.polygonID;
|
polyStates[i].polyID = polyAttr.polygonID;
|
||||||
polyStates[i].texSizeS = texParams.sizeS;
|
polyStates[i].texSizeS = texParams.sizeS;
|
||||||
polyStates[i].texSizeT = texParams.sizeT;
|
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);
|
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);
|
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;
|
return OGLERROR_NOERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1253,16 +1247,12 @@ Render3DError OpenGLRenderer_3_2::ClearUsingImage(const u16 *__restrict colorBuf
|
||||||
|
|
||||||
this->UploadClearImage(colorBuffer, depthBuffer, fogBuffer, polyIDBuffer);
|
this->UploadClearImage(colorBuffer, depthBuffer, fogBuffer, polyIDBuffer);
|
||||||
|
|
||||||
|
OGLRef.selectedRenderingFBO = (CommonSettings.GFX3D_Renderer_Multisample) ? OGLRef.fboMSIntermediateRenderID : OGLRef.fboRenderID;
|
||||||
if (OGLRef.selectedRenderingFBO == OGLRef.fboMSIntermediateRenderID)
|
if (OGLRef.selectedRenderingFBO == OGLRef.fboMSIntermediateRenderID)
|
||||||
{
|
{
|
||||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, OGLRef.fboRenderID);
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, OGLRef.fboRenderID);
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, OGLRef.fboMSIntermediateRenderID);
|
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
|
// Blit the working depth buffer
|
||||||
glReadBuffer(GL_COLOR_ATTACHMENT1);
|
glReadBuffer(GL_COLOR_ATTACHMENT1);
|
||||||
glDrawBuffer(GL_COLOR_ATTACHMENT1);
|
glDrawBuffer(GL_COLOR_ATTACHMENT1);
|
||||||
|
@ -1278,17 +1268,26 @@ Render3DError OpenGLRenderer_3_2::ClearUsingImage(const u16 *__restrict colorBuf
|
||||||
glDrawBuffer(GL_COLOR_ATTACHMENT3);
|
glDrawBuffer(GL_COLOR_ATTACHMENT3);
|
||||||
glBlitFramebuffer(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
glBlitFramebuffer(0, 0, 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);
|
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
||||||
glDrawBuffers(4, RenderDrawList);
|
glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboMSIntermediateRenderID);
|
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;
|
return OGLERROR_NOERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
Render3DError OpenGLRenderer_3_2::ClearUsingValues(const FragmentColor &clearColor, const FragmentAttributes &clearAttributes) const
|
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 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 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};
|
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);
|
glUniform1i(this->ref->uniformPolyStateIndex, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Render3DError OpenGLRenderer_3_2::SetupPolygon(const POLY &thePoly)
|
Render3DError OpenGLRenderer_3_2::SetupPolygon(const POLY &thePoly)
|
||||||
{
|
{
|
||||||
//OGLRenderRef &OGLRef = *this->ref;
|
|
||||||
const PolygonAttributes attr = thePoly.getAttributes();
|
const PolygonAttributes attr = thePoly.getAttributes();
|
||||||
|
|
||||||
// Set up depth test mode
|
// Set up depth test mode
|
||||||
|
|
|
@ -78,9 +78,8 @@ protected:
|
||||||
virtual void DestroyGeometryProgram();
|
virtual void DestroyGeometryProgram();
|
||||||
|
|
||||||
virtual void GetExtensionSet(std::set<std::string> *oglExtensionSet);
|
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 DisableVertexAttributes();
|
||||||
virtual Render3DError SelectRenderingFramebuffer();
|
|
||||||
virtual Render3DError DownsampleFBO();
|
virtual Render3DError DownsampleFBO();
|
||||||
virtual Render3DError BeginRender(const GFX3D &engine);
|
virtual Render3DError BeginRender(const GFX3D &engine);
|
||||||
virtual Render3DError RenderEdgeMarking(const u16 *colorTable, const bool useAntialias);
|
virtual Render3DError RenderEdgeMarking(const u16 *colorTable, const bool useAntialias);
|
||||||
|
|
|
@ -485,7 +485,7 @@ struct POLY {
|
||||||
void load(EMUFILE* is);
|
void load(EMUFILE* is);
|
||||||
};
|
};
|
||||||
|
|
||||||
#define POLYLIST_SIZE 100000
|
#define POLYLIST_SIZE 20000
|
||||||
struct POLYLIST {
|
struct POLYLIST {
|
||||||
POLY list[POLYLIST_SIZE];
|
POLY list[POLYLIST_SIZE];
|
||||||
int count;
|
int count;
|
||||||
|
@ -553,15 +553,15 @@ struct VERT {
|
||||||
void load(EMUFILE* is);
|
void load(EMUFILE* is);
|
||||||
};
|
};
|
||||||
|
|
||||||
#define VERTLIST_SIZE 400000
|
#define VERTLIST_SIZE (POLYLIST_SIZE * 4)
|
||||||
//#define VERTLIST_SIZE 10000
|
|
||||||
struct VERTLIST {
|
struct VERTLIST {
|
||||||
VERT list[VERTLIST_SIZE];
|
VERT list[VERTLIST_SIZE];
|
||||||
int count;
|
int count;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define INDEXLIST_SIZE (POLYLIST_SIZE * 4)
|
||||||
struct INDEXLIST {
|
struct INDEXLIST {
|
||||||
int list[POLYLIST_SIZE];
|
int list[INDEXLIST_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
#include "MMU.h"
|
#include "MMU.h"
|
||||||
#include "texcache.h"
|
#include "texcache.h"
|
||||||
|
|
||||||
static CACHE_ALIGN u32 dsDepthToD24S8_LUT[32768] = {0};
|
static CACHE_ALIGN u32 dsDepthToD24_LUT[32768] = {0};
|
||||||
int cur3DCore = GPU3D_NULL;
|
int cur3DCore = GPU3D_NULL;
|
||||||
|
|
||||||
GPU3DInterface gpu3DNull = {
|
GPU3DInterface gpu3DNull = {
|
||||||
|
@ -107,7 +107,7 @@ Render3D::Render3D()
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < 32768; i++)
|
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;
|
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
|
//this is tested quite well in the sonic chronicles main map mode
|
||||||
//where depth values are used for trees etc you can walk behind
|
//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->clearImageFogBuffer[dd] = BIT15(clearDepthBuffer[adr]);
|
||||||
this->clearImagePolyIDBuffer[dd] = clearFragment.opaquePolyID;
|
this->clearImagePolyIDBuffer[dd] = clearFragment.opaquePolyID;
|
||||||
|
|
Loading…
Reference in New Issue