GFX3D: Rework polygon attributes and texture parameters using the latest coding style. Also improve the performance of SoftRasterizer while we’re at it.
This commit is contained in:
parent
e7d63e6cd2
commit
c6a5740665
|
@ -693,7 +693,7 @@ static void OGLGetDriverVersion(const char *oglVersionString,
|
|||
}
|
||||
}
|
||||
|
||||
OpenGLTexture::OpenGLTexture(u32 texAttributes, u32 palAttributes) : Render3DTexture(texAttributes, palAttributes)
|
||||
OpenGLTexture::OpenGLTexture(TEXIMAGE_PARAM texAttributes, u32 palAttributes) : Render3DTexture(texAttributes, palAttributes)
|
||||
{
|
||||
_cacheSize = GetUnpackSizeUsingFormat(TexFormat_32bpp);
|
||||
_invSizeS = 1.0f / (float)_sizeS;
|
||||
|
@ -1523,7 +1523,7 @@ OpenGLTexture* OpenGLRenderer::GetLoadedTextureFromPolygon(const POLY &thePoly,
|
|||
}
|
||||
|
||||
template <OGLPolyDrawMode DRAWMODE>
|
||||
size_t OpenGLRenderer::DrawPolygonsForIndexRange(const POLYLIST *polyList, const INDEXLIST *indexList, size_t firstIndex, size_t lastIndex, size_t &indexOffset, u32 &lastPolyAttr)
|
||||
size_t OpenGLRenderer::DrawPolygonsForIndexRange(const POLYLIST *polyList, const INDEXLIST *indexList, size_t firstIndex, size_t lastIndex, size_t &indexOffset, POLYGON_ATTR &lastPolyAttr)
|
||||
{
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
|
||||
|
@ -1550,7 +1550,7 @@ size_t OpenGLRenderer::DrawPolygonsForIndexRange(const POLYLIST *polyList, const
|
|||
|
||||
// Set up the initial polygon
|
||||
const POLY &initialPoly = polyList->list[indexList->list[firstIndex]];
|
||||
u32 lastTexParams = initialPoly.texParam;
|
||||
TEXIMAGE_PARAM lastTexParams = initialPoly.texParam;
|
||||
u32 lastTexPalette = initialPoly.texPalette;
|
||||
u32 lastViewport = initialPoly.viewport;
|
||||
|
||||
|
@ -1566,14 +1566,14 @@ size_t OpenGLRenderer::DrawPolygonsForIndexRange(const POLYLIST *polyList, const
|
|||
const POLY &thePoly = polyList->list[indexList->list[i]];
|
||||
|
||||
// Set up the polygon if it changed
|
||||
if (lastPolyAttr != thePoly.polyAttr)
|
||||
if (lastPolyAttr.value != thePoly.attribute.value)
|
||||
{
|
||||
lastPolyAttr = thePoly.polyAttr;
|
||||
lastPolyAttr = thePoly.attribute;
|
||||
this->SetupPolygon(thePoly, (DRAWMODE != OGLPolyDrawMode_DrawOpaquePolys), (DRAWMODE != OGLPolyDrawMode_ZeroAlphaPass));
|
||||
}
|
||||
|
||||
// Set up the texture if it changed
|
||||
if (lastTexParams != thePoly.texParam || lastTexPalette != thePoly.texPalette)
|
||||
if (lastTexParams.value != thePoly.texParam.value || lastTexPalette != thePoly.texPalette)
|
||||
{
|
||||
lastTexParams = thePoly.texParam;
|
||||
lastTexPalette = thePoly.texPalette;
|
||||
|
@ -1602,17 +1602,17 @@ size_t OpenGLRenderer::DrawPolygonsForIndexRange(const POLYLIST *polyList, const
|
|||
// the same and we're not drawing a line loop or line strip.
|
||||
if (i+1 <= lastIndex)
|
||||
{
|
||||
const POLY *nextPoly = &polyList->list[indexList->list[i+1]];
|
||||
const POLY &nextPoly = polyList->list[indexList->list[i+1]];
|
||||
|
||||
if (lastPolyAttr == nextPoly->polyAttr &&
|
||||
lastTexParams == nextPoly->texParam &&
|
||||
lastTexPalette == nextPoly->texPalette &&
|
||||
lastViewport == nextPoly->viewport &&
|
||||
polyPrimitive == oglPrimitiveType[nextPoly->vtxFormat] &&
|
||||
if (lastPolyAttr.value == nextPoly.attribute.value &&
|
||||
lastTexParams.value == nextPoly.texParam.value &&
|
||||
lastTexPalette == nextPoly.texPalette &&
|
||||
lastViewport == nextPoly.viewport &&
|
||||
polyPrimitive == oglPrimitiveType[nextPoly.vtxFormat] &&
|
||||
polyPrimitive != GL_LINE_LOOP &&
|
||||
polyPrimitive != GL_LINE_STRIP &&
|
||||
oglPrimitiveType[nextPoly->vtxFormat] != GL_LINE_LOOP &&
|
||||
oglPrimitiveType[nextPoly->vtxFormat] != GL_LINE_STRIP)
|
||||
oglPrimitiveType[nextPoly.vtxFormat] != GL_LINE_LOOP &&
|
||||
oglPrimitiveType[nextPoly.vtxFormat] != GL_LINE_STRIP)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -1621,22 +1621,22 @@ size_t OpenGLRenderer::DrawPolygonsForIndexRange(const POLYLIST *polyList, const
|
|||
// Render the polygons
|
||||
this->SetPolygonIndex(i);
|
||||
|
||||
if (thePoly.getAttributePolygonMode() == POLYGON_MODE_SHADOW)
|
||||
if (thePoly.attribute.Mode == POLYGON_MODE_SHADOW)
|
||||
{
|
||||
if (DRAWMODE != OGLPolyDrawMode_ZeroAlphaPass)
|
||||
{
|
||||
this->DrawShadowPolygon(polyPrimitive, vertIndexCount, indexBufferPtr, thePoly.getAttributeEnableAlphaDepthWrite(), thePoly.isTranslucent(), thePoly.getAttributePolygonID());
|
||||
this->DrawShadowPolygon(polyPrimitive, vertIndexCount, indexBufferPtr, thePoly.attribute.TranslucentDepthWrite_Enable, thePoly.isTranslucent(), thePoly.attribute.PolygonID);
|
||||
}
|
||||
}
|
||||
else if ( (thePoly.getTexParamTexFormat() == TEXMODE_A3I5) || (thePoly.getTexParamTexFormat() == TEXMODE_A5I3) )
|
||||
else if ( (thePoly.texParam.PackedFormat == TEXMODE_A3I5) || (thePoly.texParam.PackedFormat == TEXMODE_A5I3) )
|
||||
{
|
||||
if (DRAWMODE == OGLPolyDrawMode_ZeroAlphaPass)
|
||||
{
|
||||
this->DrawAlphaTexturePolygon<false>(polyPrimitive, vertIndexCount, indexBufferPtr, thePoly.getAttributeEnableAlphaDepthWrite(), thePoly.isTranslucent(), thePoly.isWireframe() || thePoly.isOpaque());
|
||||
this->DrawAlphaTexturePolygon<false>(polyPrimitive, vertIndexCount, indexBufferPtr, thePoly.attribute.TranslucentDepthWrite_Enable, thePoly.isTranslucent(), thePoly.isWireframe() || thePoly.isOpaque());
|
||||
}
|
||||
else
|
||||
{
|
||||
this->DrawAlphaTexturePolygon<true>(polyPrimitive, vertIndexCount, indexBufferPtr, thePoly.getAttributeEnableAlphaDepthWrite(), thePoly.isTranslucent(), thePoly.isWireframe() || thePoly.isOpaque());
|
||||
this->DrawAlphaTexturePolygon<true>(polyPrimitive, vertIndexCount, indexBufferPtr, thePoly.attribute.TranslucentDepthWrite_Enable, thePoly.isTranslucent(), thePoly.isWireframe() || thePoly.isOpaque());
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -3265,7 +3265,7 @@ Render3DError OpenGLRenderer_1_2::DisableVertexAttributes()
|
|||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_1_2::ZeroDstAlphaPass(const POLYLIST *polyList, const INDEXLIST *indexList, bool enableAlphaBlending, size_t indexOffset, u32 lastPolyAttr)
|
||||
Render3DError OpenGLRenderer_1_2::ZeroDstAlphaPass(const POLYLIST *polyList, const INDEXLIST *indexList, bool enableAlphaBlending, size_t indexOffset, POLYGON_ATTR lastPolyAttr)
|
||||
{
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
|
||||
|
@ -3618,7 +3618,7 @@ Render3DError OpenGLRenderer_1_2::BeginRender(const GFX3D &engine)
|
|||
}
|
||||
else
|
||||
{
|
||||
const GLfloat thePolyAlpha = (thePoly->isWireframe()) ? 1.0f : divide5bitBy31_LUT[thePoly->getAttributeAlpha()];
|
||||
const GLfloat thePolyAlpha = (thePoly->isWireframe()) ? 1.0f : divide5bitBy31_LUT[thePoly->attribute.Alpha];
|
||||
|
||||
for (size_t j = 0; j < polyType; j++)
|
||||
{
|
||||
|
@ -3692,7 +3692,7 @@ Render3DError OpenGLRenderer_1_2::RenderGeometry(const GFX3D_State &renderState,
|
|||
size_t indexOffset = 0;
|
||||
|
||||
const POLY &firstPoly = polyList->list[indexList->list[0]];
|
||||
u32 lastPolyAttr = firstPoly.polyAttr;
|
||||
POLYGON_ATTR lastPolyAttr = firstPoly.attribute;
|
||||
|
||||
if (polyList->opaqueCount > 0)
|
||||
{
|
||||
|
@ -3714,7 +3714,7 @@ Render3DError OpenGLRenderer_1_2::RenderGeometry(const GFX3D_State &renderState,
|
|||
if (polyList->opaqueCount > 0)
|
||||
{
|
||||
const POLY &lastOpaquePoly = polyList->list[indexList->list[polyList->opaqueCount - 1]];
|
||||
lastPolyAttr = lastOpaquePoly.polyAttr;
|
||||
lastPolyAttr = lastOpaquePoly.attribute;
|
||||
this->SetupPolygon(lastOpaquePoly, false, true);
|
||||
}
|
||||
}
|
||||
|
@ -4098,15 +4098,13 @@ void OpenGLRenderer_1_2::SetPolygonIndex(const size_t index)
|
|||
|
||||
Render3DError OpenGLRenderer_1_2::SetupPolygon(const POLY &thePoly, bool treatAsTranslucent, bool willChangeStencilBuffer)
|
||||
{
|
||||
const PolygonAttributes attr = thePoly.getAttributes();
|
||||
|
||||
// Set up depth test mode
|
||||
static const GLenum oglDepthFunc[2] = {GL_LESS, GL_EQUAL};
|
||||
glDepthFunc(oglDepthFunc[attr.enableDepthEqualTest]);
|
||||
glDepthFunc(oglDepthFunc[thePoly.attribute.DepthEqualTest_Enable]);
|
||||
|
||||
// Set up culling mode
|
||||
static const GLenum oglCullingMode[4] = {GL_FRONT_AND_BACK, GL_FRONT, GL_BACK, 0};
|
||||
GLenum cullingMode = oglCullingMode[attr.surfaceCullingMode];
|
||||
GLenum cullingMode = oglCullingMode[thePoly.attribute.SurfaceCullingMode];
|
||||
|
||||
if (cullingMode == 0)
|
||||
{
|
||||
|
@ -4121,13 +4119,13 @@ Render3DError OpenGLRenderer_1_2::SetupPolygon(const POLY &thePoly, bool treatAs
|
|||
if (willChangeStencilBuffer)
|
||||
{
|
||||
// Handle drawing states for the polygon
|
||||
if (attr.polygonMode == POLYGON_MODE_SHADOW)
|
||||
if (thePoly.attribute.Mode == POLYGON_MODE_SHADOW)
|
||||
{
|
||||
// Set up shadow polygon states.
|
||||
//
|
||||
// See comments in DrawShadowPolygon() for more information about
|
||||
// how this 4-pass process works in OpenGL.
|
||||
if (attr.polygonID == 0)
|
||||
if (thePoly.attribute.PolygonID == 0)
|
||||
{
|
||||
// 1st pass: Mark stencil buffer bits (0x40) with the shadow polygon volume.
|
||||
// Bits are only marked on depth-fail.
|
||||
|
@ -4140,7 +4138,7 @@ Render3DError OpenGLRenderer_1_2::SetupPolygon(const POLY &thePoly, bool treatAs
|
|||
// 2nd pass: Mark stencil buffer bits (0x80) with the result of the polygon ID
|
||||
// check. Bits are marked if the polygon ID of this polygon differs from the
|
||||
// one in the stencil buffer.
|
||||
glStencilFunc(GL_NOTEQUAL, 0x80 | attr.polygonID, 0x3F);
|
||||
glStencilFunc(GL_NOTEQUAL, 0x80 | thePoly.attribute.PolygonID, 0x3F);
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||
glStencilMask(0x80);
|
||||
}
|
||||
|
@ -4150,12 +4148,12 @@ Render3DError OpenGLRenderer_1_2::SetupPolygon(const POLY &thePoly, bool treatAs
|
|||
}
|
||||
else
|
||||
{
|
||||
glStencilFunc(GL_ALWAYS, attr.polygonID, 0x3F);
|
||||
glStencilFunc(GL_ALWAYS, thePoly.attribute.PolygonID, 0x3F);
|
||||
glStencilOp(GL_KEEP, GL_KEEP, (treatAsTranslucent) ? GL_KEEP : GL_REPLACE);
|
||||
glStencilMask(0xFF); // Drawing non-shadow polygons will implicitly reset the stencil buffer bits
|
||||
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
glDepthMask((!treatAsTranslucent || attr.enableAlphaDepthWrite) ? GL_TRUE : GL_FALSE);
|
||||
glDepthMask((!treatAsTranslucent || thePoly.attribute.TranslucentDepthWrite_Enable) ? GL_TRUE : GL_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4163,18 +4161,18 @@ Render3DError OpenGLRenderer_1_2::SetupPolygon(const POLY &thePoly, bool treatAs
|
|||
if (this->isShaderSupported)
|
||||
{
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
glUniform1i(OGLRef.uniformPolyMode, attr.polygonMode);
|
||||
glUniform1i(OGLRef.uniformPolyEnableFog, (attr.enableRenderFog) ? GL_TRUE : GL_FALSE);
|
||||
glUniform1f(OGLRef.uniformPolyAlpha, (attr.isWireframe) ? 1.0f : divide5bitBy31_LUT[attr.alpha]);
|
||||
glUniform1i(OGLRef.uniformPolyID, attr.polygonID);
|
||||
glUniform1i(OGLRef.uniformPolyIsWireframe, (attr.isWireframe) ? GL_TRUE : GL_FALSE);
|
||||
glUniform1i(OGLRef.uniformPolySetNewDepthForTranslucent, (attr.enableAlphaDepthWrite) ? GL_TRUE : GL_FALSE);
|
||||
glUniform1i(OGLRef.uniformPolyMode, thePoly.attribute.Mode);
|
||||
glUniform1i(OGLRef.uniformPolyEnableFog, (thePoly.attribute.Fog_Enable) ? GL_TRUE : GL_FALSE);
|
||||
glUniform1f(OGLRef.uniformPolyAlpha, (thePoly.isWireframe()) ? 1.0f : divide5bitBy31_LUT[thePoly.attribute.Alpha]);
|
||||
glUniform1i(OGLRef.uniformPolyID, thePoly.attribute.PolygonID);
|
||||
glUniform1i(OGLRef.uniformPolyIsWireframe, (thePoly.isWireframe()) ? GL_TRUE : GL_FALSE);
|
||||
glUniform1i(OGLRef.uniformPolySetNewDepthForTranslucent, (thePoly.attribute.TranslucentDepthWrite_Enable) ? 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]);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, oglTexBlendMode[thePoly.attribute.Mode]);
|
||||
}
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
|
@ -4202,8 +4200,6 @@ Render3DError OpenGLRenderer_1_2::SetupTexture(const POLY &thePoly, size_t polyR
|
|||
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
const PolygonTexParams texParams = thePoly.getTexParams();
|
||||
|
||||
// Enable textures if they weren't already enabled
|
||||
if (this->isShaderSupported)
|
||||
|
@ -4221,8 +4217,8 @@ Render3DError OpenGLRenderer_1_2::SetupTexture(const POLY &thePoly, size_t polyR
|
|||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, theTexture->GetID());
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (texParams.enableRepeatS ? (texParams.enableMirroredRepeatS ? OGLRef.stateTexMirroredRepeat : GL_REPEAT) : GL_CLAMP_TO_EDGE));
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (texParams.enableRepeatT ? (texParams.enableMirroredRepeatT ? OGLRef.stateTexMirroredRepeat : GL_REPEAT) : GL_CLAMP_TO_EDGE));
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, ((thePoly.texParam.RepeatS_Enable) ? ((thePoly.texParam.MirroredRepeatS_Enable) ? OGLRef.stateTexMirroredRepeat : GL_REPEAT) : GL_CLAMP_TO_EDGE));
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, ((thePoly.texParam.RepeatT_Enable) ? ((thePoly.texParam.MirroredRepeatT_Enable) ? OGLRef.stateTexMirroredRepeat : GL_REPEAT) : GL_CLAMP_TO_EDGE));
|
||||
|
||||
if (this->_textureSmooth)
|
||||
{
|
||||
|
@ -4687,14 +4683,12 @@ Render3DError OpenGLRenderer_2_0::SetupTexture(const POLY &thePoly, size_t polyR
|
|||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
const PolygonTexParams texParams = thePoly.getTexParams();
|
||||
|
||||
glUniform1i(OGLRef.uniformPolyEnableTexture, GL_TRUE);
|
||||
glUniform1i(OGLRef.uniformTexSingleBitAlpha, (packFormat != TEXMODE_A3I5 && packFormat != TEXMODE_A5I3) ? GL_TRUE : GL_FALSE);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, theTexture->GetID());
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (texParams.enableRepeatS ? (texParams.enableMirroredRepeatS ? GL_MIRRORED_REPEAT : GL_REPEAT) : GL_CLAMP_TO_EDGE));
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (texParams.enableRepeatT ? (texParams.enableMirroredRepeatT ? GL_MIRRORED_REPEAT : GL_REPEAT) : GL_CLAMP_TO_EDGE));
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, ((thePoly.texParam.RepeatS_Enable) ? ((thePoly.texParam.MirroredRepeatS_Enable) ? GL_MIRRORED_REPEAT : GL_REPEAT) : GL_CLAMP_TO_EDGE));
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, ((thePoly.texParam.RepeatT_Enable) ? ((thePoly.texParam.MirroredRepeatT_Enable) ? GL_MIRRORED_REPEAT : GL_REPEAT) : GL_CLAMP_TO_EDGE));
|
||||
|
||||
if (this->_textureSmooth)
|
||||
{
|
||||
|
@ -4748,6 +4742,6 @@ Render3DError OpenGLRenderer_2_1::RenderFlush(bool willFlushBuffer32, bool willF
|
|||
return RENDER3DERROR_NOERR;
|
||||
}
|
||||
|
||||
template size_t OpenGLRenderer::DrawPolygonsForIndexRange<OGLPolyDrawMode_DrawOpaquePolys>(const POLYLIST *polyList, const INDEXLIST *indexList, size_t firstIndex, size_t lastIndex, size_t &indexOffset, u32 &lastPolyAttr);
|
||||
template size_t OpenGLRenderer::DrawPolygonsForIndexRange<OGLPolyDrawMode_DrawTranslucentPolys>(const POLYLIST *polyList, const INDEXLIST *indexList, size_t firstIndex, size_t lastIndex, size_t &indexOffset, u32 &lastPolyAttr);
|
||||
template size_t OpenGLRenderer::DrawPolygonsForIndexRange<OGLPolyDrawMode_ZeroAlphaPass>(const POLYLIST *polyList, const INDEXLIST *indexList, size_t firstIndex, size_t lastIndex, size_t &indexOffset, u32 &lastPolyAttr);
|
||||
template size_t OpenGLRenderer::DrawPolygonsForIndexRange<OGLPolyDrawMode_DrawOpaquePolys>(const POLYLIST *polyList, const INDEXLIST *indexList, size_t firstIndex, size_t lastIndex, size_t &indexOffset, POLYGON_ATTR &lastPolyAttr);
|
||||
template size_t OpenGLRenderer::DrawPolygonsForIndexRange<OGLPolyDrawMode_DrawTranslucentPolys>(const POLYLIST *polyList, const INDEXLIST *indexList, size_t firstIndex, size_t lastIndex, size_t &indexOffset, POLYGON_ATTR &lastPolyAttr);
|
||||
template size_t OpenGLRenderer::DrawPolygonsForIndexRange<OGLPolyDrawMode_ZeroAlphaPass>(const POLYLIST *polyList, const INDEXLIST *indexList, size_t firstIndex, size_t lastIndex, size_t &indexOffset, POLYGON_ATTR &lastPolyAttr);
|
||||
|
|
|
@ -601,7 +601,7 @@ protected:
|
|||
u32 *_upscaleBuffer;
|
||||
|
||||
public:
|
||||
OpenGLTexture(u32 texAttributes, u32 palAttributes);
|
||||
OpenGLTexture(TEXIMAGE_PARAM texAttributes, u32 palAttributes);
|
||||
virtual ~OpenGLTexture();
|
||||
|
||||
virtual void Load(bool isNewTexture);
|
||||
|
@ -657,7 +657,7 @@ protected:
|
|||
|
||||
Render3DError FlushFramebuffer(const FragmentColor *__restrict srcFramebuffer, FragmentColor *__restrict dstFramebufferMain, u16 *__restrict dstFramebuffer16);
|
||||
OpenGLTexture* GetLoadedTextureFromPolygon(const POLY &thePoly, bool enableTexturing);
|
||||
template<OGLPolyDrawMode DRAWMODE> size_t DrawPolygonsForIndexRange(const POLYLIST *polyList, const INDEXLIST *indexList, size_t firstIndex, size_t lastIndex, size_t &indexOffset, u32 &lastPolyAttr);
|
||||
template<OGLPolyDrawMode DRAWMODE> size_t DrawPolygonsForIndexRange(const POLYLIST *polyList, const INDEXLIST *indexList, size_t firstIndex, size_t lastIndex, size_t &indexOffset, POLYGON_ATTR &lastPolyAttr);
|
||||
template<bool WILLUPDATESTENCILBUFFER> Render3DError DrawAlphaTexturePolygon(const GLenum polyPrimitive, const GLsizei vertIndexCount, const GLushort *indexBufferPtr, const bool enableAlphaDepthWrite, const bool isTranslucent, const bool canHaveOpaqueFragments);
|
||||
|
||||
// OpenGL-specific methods
|
||||
|
@ -773,7 +773,7 @@ protected:
|
|||
virtual void GetExtensionSet(std::set<std::string> *oglExtensionSet);
|
||||
virtual Render3DError EnableVertexAttributes();
|
||||
virtual Render3DError DisableVertexAttributes();
|
||||
virtual Render3DError ZeroDstAlphaPass(const POLYLIST *polyList, const INDEXLIST *indexList, bool enableAlphaBlending, size_t indexOffset, u32 lastPolyAttr);
|
||||
virtual Render3DError ZeroDstAlphaPass(const POLYLIST *polyList, const INDEXLIST *indexList, bool enableAlphaBlending, size_t indexOffset, POLYGON_ATTR lastPolyAttr);
|
||||
virtual Render3DError DownsampleFBO();
|
||||
virtual Render3DError ReadBackPixels();
|
||||
|
||||
|
|
|
@ -1350,7 +1350,7 @@ Render3DError OpenGLRenderer_3_2::DisableVertexAttributes()
|
|||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_3_2::ZeroDstAlphaPass(const POLYLIST *polyList, const INDEXLIST *indexList, bool enableAlphaBlending, size_t indexOffset, u32 lastPolyAttr)
|
||||
Render3DError OpenGLRenderer_3_2::ZeroDstAlphaPass(const POLYLIST *polyList, const INDEXLIST *indexList, bool enableAlphaBlending, size_t indexOffset, POLYGON_ATTR lastPolyAttr)
|
||||
{
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
|
||||
|
@ -1612,19 +1612,19 @@ Render3DError OpenGLRenderer_3_2::BeginRender(const GFX3D &engine)
|
|||
|
||||
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;
|
||||
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];
|
||||
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 (thePoly.vtxFormat == GFX3D_QUADS || thePoly.vtxFormat == GFX3D_QUAD_STRIP)
|
||||
{
|
||||
if (j == 2)
|
||||
{
|
||||
|
@ -1632,26 +1632,24 @@ Render3DError OpenGLRenderer_3_2::BeginRender(const GFX3D &engine)
|
|||
}
|
||||
else if (j == 3)
|
||||
{
|
||||
indexPtr[vertIndexCount++] = thePoly->vertIndexes[0];
|
||||
indexPtr[vertIndexCount++] = thePoly.vertIndexes[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this->_textureList[i] = this->GetLoadedTextureFromPolygon(*thePoly, engine.renderState.enableTexturing);
|
||||
this->_textureList[i] = this->GetLoadedTextureFromPolygon(thePoly, engine.renderState.enableTexturing);
|
||||
|
||||
const NDSTextureFormat packFormat = this->_textureList[i]->GetPackFormat();
|
||||
const PolygonAttributes polyAttr = thePoly->getAttributes();
|
||||
const PolygonTexParams texParams = thePoly->getTexParams();
|
||||
|
||||
polyStates[i].enableTexture = (this->_textureList[i]->IsSamplingEnabled()) ? GL_TRUE : GL_FALSE;
|
||||
polyStates[i].enableFog = (polyAttr.enableRenderFog) ? GL_TRUE : GL_FALSE;
|
||||
polyStates[i].isWireframe = (polyAttr.isWireframe) ? GL_TRUE : GL_FALSE;
|
||||
polyStates[i].setNewDepthForTranslucent = (polyAttr.enableAlphaDepthWrite) ? GL_TRUE : GL_FALSE;
|
||||
polyStates[i].polyAlpha = (polyAttr.isWireframe) ? 0x1F : polyAttr.alpha;
|
||||
polyStates[i].polyMode = polyAttr.polygonMode;
|
||||
polyStates[i].polyID = polyAttr.polygonID;
|
||||
polyStates[i].texSizeS = texParams.sizeS; // Note that we are using the packed version of sizeS
|
||||
polyStates[i].texSizeT = texParams.sizeT; // Note that we are using the packed version of sizeT
|
||||
polyStates[i].enableFog = (thePoly.attribute.Fog_Enable) ? GL_TRUE : GL_FALSE;
|
||||
polyStates[i].isWireframe = (thePoly.isWireframe()) ? GL_TRUE : GL_FALSE;
|
||||
polyStates[i].setNewDepthForTranslucent = (thePoly.attribute.TranslucentDepthWrite_Enable) ? GL_TRUE : GL_FALSE;
|
||||
polyStates[i].polyAlpha = (thePoly.isWireframe()) ? 0x1F : thePoly.attribute.Alpha;
|
||||
polyStates[i].polyMode = thePoly.attribute.Mode;
|
||||
polyStates[i].polyID = thePoly.attribute.PolygonID;
|
||||
polyStates[i].texSizeS = thePoly.texParam.SizeShiftS; // Note that we are using the preshifted size of S
|
||||
polyStates[i].texSizeT = thePoly.texParam.SizeShiftT; // Note that we are using the preshifted size of T
|
||||
polyStates[i].texSingleBitAlpha = (packFormat != TEXMODE_A3I5 && packFormat != TEXMODE_A5I3) ? GL_TRUE : GL_FALSE;
|
||||
}
|
||||
|
||||
|
@ -1860,15 +1858,13 @@ void OpenGLRenderer_3_2::SetPolygonIndex(const size_t index)
|
|||
|
||||
Render3DError OpenGLRenderer_3_2::SetupPolygon(const POLY &thePoly, bool treatAsTranslucent, bool willChangeStencilBuffer)
|
||||
{
|
||||
const PolygonAttributes attr = thePoly.getAttributes();
|
||||
|
||||
// Set up depth test mode
|
||||
static const GLenum oglDepthFunc[2] = {GL_LESS, GL_EQUAL};
|
||||
glDepthFunc(oglDepthFunc[attr.enableDepthEqualTest]);
|
||||
glDepthFunc(oglDepthFunc[thePoly.attribute.DepthEqualTest_Enable]);
|
||||
|
||||
// Set up culling mode
|
||||
static const GLenum oglCullingMode[4] = {GL_FRONT_AND_BACK, GL_FRONT, GL_BACK, 0};
|
||||
GLenum cullingMode = oglCullingMode[attr.surfaceCullingMode];
|
||||
GLenum cullingMode = oglCullingMode[thePoly.attribute.SurfaceCullingMode];
|
||||
|
||||
if (cullingMode == 0)
|
||||
{
|
||||
|
@ -1883,13 +1879,13 @@ Render3DError OpenGLRenderer_3_2::SetupPolygon(const POLY &thePoly, bool treatAs
|
|||
if (willChangeStencilBuffer)
|
||||
{
|
||||
// Handle drawing states for the polygon
|
||||
if (attr.polygonMode == POLYGON_MODE_SHADOW)
|
||||
if (thePoly.attribute.Mode == POLYGON_MODE_SHADOW)
|
||||
{
|
||||
// Set up shadow polygon states.
|
||||
//
|
||||
// See comments in DrawShadowPolygon() for more information about
|
||||
// how this 4-pass process works in OpenGL.
|
||||
if (attr.polygonID == 0)
|
||||
if (thePoly.attribute.PolygonID == 0)
|
||||
{
|
||||
// 1st pass: Mark stencil buffer bits (0x40) with the shadow polygon volume.
|
||||
// Bits are only marked on depth-fail.
|
||||
|
@ -1902,7 +1898,7 @@ Render3DError OpenGLRenderer_3_2::SetupPolygon(const POLY &thePoly, bool treatAs
|
|||
// 2nd pass: Mark stencil buffer bits (0x80) with the result of the polygon ID
|
||||
// check. Bits are marked if the polygon ID of this polygon differs from the
|
||||
// one in the stencil buffer.
|
||||
glStencilFunc(GL_NOTEQUAL, 0x80 | attr.polygonID, 0x3F);
|
||||
glStencilFunc(GL_NOTEQUAL, 0x80 | thePoly.attribute.PolygonID, 0x3F);
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||
glStencilMask(0x80);
|
||||
}
|
||||
|
@ -1912,12 +1908,12 @@ Render3DError OpenGLRenderer_3_2::SetupPolygon(const POLY &thePoly, bool treatAs
|
|||
}
|
||||
else
|
||||
{
|
||||
glStencilFunc(GL_ALWAYS, attr.polygonID, 0x3F);
|
||||
glStencilFunc(GL_ALWAYS, thePoly.attribute.PolygonID, 0x3F);
|
||||
glStencilOp(GL_KEEP, GL_KEEP, (treatAsTranslucent) ? GL_KEEP : GL_REPLACE);
|
||||
glStencilMask(0xFF); // Drawing non-shadow polygons will implicitly reset the stencil buffer bits
|
||||
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
glDepthMask((!treatAsTranslucent || attr.enableAlphaDepthWrite) ? GL_TRUE : GL_FALSE);
|
||||
glDepthMask((!treatAsTranslucent || thePoly.attribute.TranslucentDepthWrite_Enable) ? GL_TRUE : GL_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1934,11 +1930,9 @@ Render3DError OpenGLRenderer_3_2::SetupTexture(const POLY &thePoly, size_t polyR
|
|||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
PolygonTexParams texParams = thePoly.getTexParams();
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, theTexture->GetID());
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (texParams.enableRepeatS ? (texParams.enableMirroredRepeatS ? GL_MIRRORED_REPEAT : GL_REPEAT) : GL_CLAMP_TO_EDGE));
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (texParams.enableRepeatT ? (texParams.enableMirroredRepeatT ? GL_MIRRORED_REPEAT : GL_REPEAT) : GL_CLAMP_TO_EDGE));
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, ((thePoly.texParam.RepeatS_Enable) ? ((thePoly.texParam.MirroredRepeatS_Enable) ? GL_MIRRORED_REPEAT : GL_REPEAT) : GL_CLAMP_TO_EDGE));
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, ((thePoly.texParam.RepeatT_Enable) ? ((thePoly.texParam.MirroredRepeatT_Enable) ? GL_MIRRORED_REPEAT : GL_REPEAT) : GL_CLAMP_TO_EDGE));
|
||||
|
||||
if (this->_textureSmooth)
|
||||
{
|
||||
|
|
|
@ -85,7 +85,7 @@ protected:
|
|||
virtual void GetExtensionSet(std::set<std::string> *oglExtensionSet);
|
||||
virtual Render3DError EnableVertexAttributes();
|
||||
virtual Render3DError DisableVertexAttributes();
|
||||
virtual Render3DError ZeroDstAlphaPass(const POLYLIST *polyList, const INDEXLIST *indexList, bool enableAlphaBlending, size_t indexOffset, u32 lastPolyAttr);
|
||||
virtual Render3DError ZeroDstAlphaPass(const POLYLIST *polyList, const INDEXLIST *indexList, bool enableAlphaBlending, size_t indexOffset, POLYGON_ATTR lastPolyAttr);
|
||||
virtual Render3DError DownsampleFBO();
|
||||
virtual Render3DError ReadBackPixels();
|
||||
virtual Render3DError BeginRender(const GFX3D &engine);
|
||||
|
|
|
@ -334,7 +334,10 @@ static CACHE_ALIGN u16 BTcoords[6] = {0, 0, 0, 0, 0, 0};
|
|||
static CACHE_ALIGN float PTcoords[4] = {0.0, 0.0, 0.0, 1.0};
|
||||
|
||||
//raw ds format poly attributes
|
||||
static u32 polyAttr=0,textureFormat=0, texturePalette=0, polyAttrPending=0;
|
||||
static POLYGON_ATTR polyAttrInProcess;
|
||||
static POLYGON_ATTR currentPolyAttr;
|
||||
static TEXIMAGE_PARAM currentPolyTexParam;
|
||||
static u32 currentPolyTexPalette = 0;
|
||||
|
||||
//the current vertex color, 5bit values
|
||||
static u8 colorRGB[4] = { 31,31,31,31 };
|
||||
|
@ -351,11 +354,9 @@ static u8 shininessInd = 0;
|
|||
//-----------cached things:
|
||||
//these dont need to go into the savestate. they can be regenerated from HW registers
|
||||
//from polygonattr:
|
||||
static unsigned int cullingMask=0;
|
||||
static u32 envMode=0;
|
||||
static u32 lightMask=0;
|
||||
//other things:
|
||||
static int texCoordinateTransform = 0;
|
||||
static TextureTransformationMode texCoordTransformMode = TextureTransformationMode_None;
|
||||
static CACHE_ALIGN s32 cacheLightDirection[4][4];
|
||||
static CACHE_ALIGN s32 cacheHalfVector[4][4];
|
||||
//------------------
|
||||
|
@ -438,8 +439,8 @@ void POLY::save(EMUFILE &os)
|
|||
os.write_16LE(vertIndexes[1]);
|
||||
os.write_16LE(vertIndexes[2]);
|
||||
os.write_16LE(vertIndexes[3]);
|
||||
os.write_32LE(polyAttr);
|
||||
os.write_32LE(texParam);
|
||||
os.write_32LE(attribute.value);
|
||||
os.write_32LE(texParam.value);
|
||||
os.write_32LE(texPalette);
|
||||
os.write_32LE(viewport);
|
||||
os.write_floatLE(miny);
|
||||
|
@ -456,8 +457,8 @@ void POLY::load(EMUFILE &is)
|
|||
is.read_16LE(vertIndexes[1]);
|
||||
is.read_16LE(vertIndexes[2]);
|
||||
is.read_16LE(vertIndexes[3]);
|
||||
is.read_32LE(polyAttr);
|
||||
is.read_32LE(texParam);
|
||||
is.read_32LE(attribute.value);
|
||||
is.read_32LE(texParam.value);
|
||||
is.read_32LE(texPalette);
|
||||
is.read_32LE(viewport);
|
||||
is.read_floatLE(miny);
|
||||
|
@ -497,6 +498,10 @@ void VERT::load(EMUFILE &is)
|
|||
|
||||
void gfx3d_init()
|
||||
{
|
||||
polyAttrInProcess.value = 0;
|
||||
currentPolyAttr.value = 0;
|
||||
currentPolyTexParam.value = 0;
|
||||
|
||||
gxf_hardware.reset();
|
||||
//gxf_hardware.test();
|
||||
int zzz=9;
|
||||
|
@ -584,10 +589,10 @@ void gfx3d_reset()
|
|||
gfx3d.vertList = vertList;
|
||||
gfx3d.vertListCount = vertListCount[listTwiddle];
|
||||
|
||||
polyAttr = 0;
|
||||
textureFormat = 0;
|
||||
texturePalette = 0;
|
||||
polyAttrPending = 0;
|
||||
polyAttrInProcess.value = 0;
|
||||
currentPolyAttr.value = 0;
|
||||
currentPolyTexParam.value = 0;
|
||||
currentPolyTexPalette = 0;
|
||||
mode = MATRIXMODE_PROJECTION;
|
||||
s16coord[0] = s16coord[1] = s16coord[2] = s16coord[3] = 0;
|
||||
coordind = 0;
|
||||
|
@ -717,7 +722,7 @@ static void SetVertex()
|
|||
|
||||
DS_ALIGN(16) s32 coordTransformed[4] = { coord[0], coord[1], coord[2], (1<<12) };
|
||||
|
||||
if (texCoordinateTransform == 3)
|
||||
if (texCoordTransformMode == TextureTransformationMode_VertexSource)
|
||||
{
|
||||
//Tested by: Eledees The Adventures of Kai and Zero (E) [title screen and frontend menus]
|
||||
last_s = (s32)(((s64)s16coord[0] * mtxCurrent[3][0] +
|
||||
|
@ -869,7 +874,7 @@ static void SetVertex()
|
|||
|
||||
// Line segment detect
|
||||
// Tested" Castlevania POR - warp stone, trajectory of ricochet, "Eye of Decay"
|
||||
if (!(textureFormat & (7 << 26))) // no texture
|
||||
if (currentPolyTexParam.PackedFormat == TEXMODE_NONE)
|
||||
{
|
||||
bool duplicated = false;
|
||||
const VERT &vert0 = vertList[poly.vertIndexes[0]];
|
||||
|
@ -889,9 +894,9 @@ static void SetVertex()
|
|||
}
|
||||
}
|
||||
|
||||
poly.polyAttr = polyAttr;
|
||||
poly.texParam = textureFormat;
|
||||
poly.texPalette = texturePalette;
|
||||
poly.attribute = polyAttrInProcess;
|
||||
poly.texParam = currentPolyTexParam;
|
||||
poly.texPalette = currentPolyTexPalette;
|
||||
poly.viewport = viewport;
|
||||
polylist->count++;
|
||||
}
|
||||
|
@ -901,18 +906,12 @@ static void SetVertex()
|
|||
static void gfx3d_glPolygonAttrib_cache()
|
||||
{
|
||||
// Light enable/disable
|
||||
lightMask = (polyAttr&0xF);
|
||||
|
||||
// texture environment
|
||||
envMode = (polyAttr&0x30)>>4;
|
||||
|
||||
// back face culling
|
||||
cullingMask = (polyAttr>>6)&3;
|
||||
lightMask = polyAttrInProcess.LightMask;
|
||||
}
|
||||
|
||||
static void gfx3d_glTexImage_cache()
|
||||
{
|
||||
texCoordinateTransform = (textureFormat>>30);
|
||||
texCoordTransformMode = (TextureTransformationMode)currentPolyTexParam.TexCoordTransformMode;
|
||||
}
|
||||
|
||||
static void gfx3d_glLightDirection_cache(const size_t index)
|
||||
|
@ -1292,7 +1291,7 @@ static void gfx3d_glNormal(s32 v)
|
|||
|
||||
CACHE_ALIGN s32 normal[4] = { nx,ny,nz,(1<<12) };
|
||||
|
||||
if (texCoordinateTransform == 2)
|
||||
if (texCoordTransformMode == TextureTransformationMode_NormalSource)
|
||||
{
|
||||
//SM64 highlight rendered star in main menu tests this
|
||||
//also smackdown 2010 player textures tested this (needed cast on _s and _t)
|
||||
|
@ -1391,13 +1390,13 @@ static void gfx3d_glTexCoord(s32 val)
|
|||
_s = ((val<<16)>>16);
|
||||
_t = (val>>16);
|
||||
|
||||
if (texCoordinateTransform == 1)
|
||||
if (texCoordTransformMode == TextureTransformationMode_TexCoordSource)
|
||||
{
|
||||
//dragon quest 4 overworld will test this
|
||||
last_s = (s32) (( (s64)_s * mtxCurrent[3][0] + (s64)_t * mtxCurrent[3][4] + (s64)mtxCurrent[3][8] + (s64)mtxCurrent[3][12])>>12);
|
||||
last_t = (s32) (( (s64)_s * mtxCurrent[3][1] + (s64)_t * mtxCurrent[3][5] + (s64)mtxCurrent[3][9] + (s64)mtxCurrent[3][13])>>12);
|
||||
}
|
||||
else if(texCoordinateTransform == 0)
|
||||
else if (texCoordTransformMode == TextureTransformationMode_None)
|
||||
{
|
||||
last_s=_s;
|
||||
last_t=_t;
|
||||
|
@ -1469,20 +1468,20 @@ static void gfx3d_glPolygonAttrib (u32 val)
|
|||
//PROGINFO("Set polyattr in the middle of a begin/end pair.\n (This won't be activated until the next begin)\n");
|
||||
//TODO - we need some some similar checking for teximageparam etc.
|
||||
}
|
||||
polyAttrPending = val;
|
||||
currentPolyAttr.value = val;
|
||||
GFX_DELAY(1);
|
||||
}
|
||||
|
||||
static void gfx3d_glTexImage(u32 val)
|
||||
{
|
||||
textureFormat = val;
|
||||
currentPolyTexParam.value = val;
|
||||
gfx3d_glTexImage_cache();
|
||||
GFX_DELAY(1);
|
||||
}
|
||||
|
||||
static void gfx3d_glTexPalette(u32 val)
|
||||
{
|
||||
texturePalette = val;
|
||||
currentPolyTexPalette = val;
|
||||
GFX_DELAY(1);
|
||||
}
|
||||
|
||||
|
@ -1558,7 +1557,7 @@ static void gfx3d_glBegin(u32 v)
|
|||
triStripToggle = 0;
|
||||
tempVertInfo.count = 0;
|
||||
tempVertInfo.first = true;
|
||||
polyAttr = polyAttrPending;
|
||||
polyAttrInProcess = currentPolyAttr;
|
||||
gfx3d_glPolygonAttrib_cache();
|
||||
GFX_DELAY(1);
|
||||
}
|
||||
|
@ -2529,11 +2528,11 @@ void gfx3d_glGetLightColor(const size_t index, u32 &dst)
|
|||
|
||||
SFORMAT SF_GFX3D[]={
|
||||
{ "GCTL", 4, 1, &gfx3d.state.savedDISP3DCNT},
|
||||
{ "GPAT", 4, 1, &polyAttr},
|
||||
{ "GPAP", 4, 1, &polyAttrPending},
|
||||
{ "GPAT", 4, 1, &polyAttrInProcess.value},
|
||||
{ "GPAP", 4, 1, ¤tPolyAttr.value},
|
||||
{ "GINB", 4, 1, &inBegin},
|
||||
{ "GTFM", 4, 1, &textureFormat},
|
||||
{ "GTPA", 4, 1, &texturePalette},
|
||||
{ "GTFM", 4, 1, ¤tPolyTexParam.value},
|
||||
{ "GTPA", 4, 1, ¤tPolyTexPalette},
|
||||
{ "GMOD", 4, 1, &mode},
|
||||
{ "GMTM", 4,16, mtxTemporal},
|
||||
{ "GMCU", 4,64, mtxCurrent},
|
||||
|
|
|
@ -114,77 +114,6 @@ enum PolygonType
|
|||
POLYGON_TYPE_QUAD = 4
|
||||
};
|
||||
|
||||
// POLYGON ATTRIBUTES - BIT LOCATIONS
|
||||
enum
|
||||
{
|
||||
POLYGON_ATTR_ENABLE_LIGHT0_BIT = 0,
|
||||
POLYGON_ATTR_ENABLE_LIGHT1_BIT = 1,
|
||||
POLYGON_ATTR_ENABLE_LIGHT2_BIT = 2,
|
||||
POLYGON_ATTR_ENABLE_LIGHT3_BIT = 3,
|
||||
POLYGON_ATTR_MODE_BIT = 4, // Bits 4 - 5
|
||||
POLYGON_ATTR_ENABLE_BACK_SURFACE_BIT = 6,
|
||||
POLYGON_ATTR_ENABLE_FRONT_SURFACE_BIT = 7,
|
||||
// Bits 8 - 10 unused
|
||||
POLYGON_ATTR_ENABLE_ALPHA_DEPTH_WRITE_BIT = 11,
|
||||
POLYGON_ATTR_ENABLE_RENDER_ON_FAR_PLANE_INTERSECT_BIT = 12,
|
||||
POLYGON_ATTR_ENABLE_ONE_DOT_RENDER_BIT = 13,
|
||||
POLYGON_ATTR_ENABLE_DEPTH_EQUAL_TEST_BIT = 14,
|
||||
POLYGON_ATTR_ENABLE_FOG_BIT = 15,
|
||||
POLYGON_ATTR_ALPHA_BIT = 16, // Bits 16 - 20
|
||||
// Bits 21 - 23 unused
|
||||
POLYGON_ATTR_POLYGON_ID_BIT = 24 // Bits 24 - 29
|
||||
// Bits 30 - 31 unused
|
||||
};
|
||||
|
||||
// POLYGON ATTRIBUTES - BIT MASKS
|
||||
enum
|
||||
{
|
||||
POLYGON_ATTR_ENABLE_LIGHT0_MASK = 0x01 << POLYGON_ATTR_ENABLE_LIGHT0_BIT,
|
||||
POLYGON_ATTR_ENABLE_LIGHT1_MASK = 0x01 << POLYGON_ATTR_ENABLE_LIGHT1_BIT,
|
||||
POLYGON_ATTR_ENABLE_LIGHT2_MASK = 0x01 << POLYGON_ATTR_ENABLE_LIGHT2_BIT,
|
||||
POLYGON_ATTR_ENABLE_LIGHT3_MASK = 0x01 << POLYGON_ATTR_ENABLE_LIGHT3_BIT,
|
||||
POLYGON_ATTR_MODE_MASK = 0x03 << POLYGON_ATTR_MODE_BIT,
|
||||
POLYGON_ATTR_ENABLE_BACK_SURFACE_MASK = 0x01 << POLYGON_ATTR_ENABLE_BACK_SURFACE_BIT,
|
||||
POLYGON_ATTR_ENABLE_FRONT_SURFACE_MASK = 0x01 << POLYGON_ATTR_ENABLE_FRONT_SURFACE_BIT,
|
||||
POLYGON_ATTR_ENABLE_ALPHA_DEPTH_WRITE_MASK= 0x01 << POLYGON_ATTR_ENABLE_ALPHA_DEPTH_WRITE_BIT,
|
||||
POLYGON_ATTR_ENABLE_RENDER_ON_FAR_PLANE_INTERSECT_MASK = 0x01 << POLYGON_ATTR_ENABLE_RENDER_ON_FAR_PLANE_INTERSECT_BIT,
|
||||
POLYGON_ATTR_ENABLE_ONE_DOT_RENDER_MASK = 0x01 << POLYGON_ATTR_ENABLE_ONE_DOT_RENDER_BIT,
|
||||
POLYGON_ATTR_ENABLE_DEPTH_EQUAL_TEST_MASK = 0x01 << POLYGON_ATTR_ENABLE_DEPTH_EQUAL_TEST_BIT,
|
||||
POLYGON_ATTR_ENABLE_FOG_MASK = 0x01 << POLYGON_ATTR_ENABLE_FOG_BIT,
|
||||
POLYGON_ATTR_ALPHA_MASK = 0x1F << POLYGON_ATTR_ALPHA_BIT,
|
||||
POLYGON_ATTR_POLYGON_ID_MASK = 0x3F << POLYGON_ATTR_POLYGON_ID_BIT
|
||||
};
|
||||
|
||||
// TEXTURE PARAMETERS - BIT LOCATIONS
|
||||
enum
|
||||
{
|
||||
TEXTURE_PARAM_VRAM_OFFSET_BIT = 0, // Bits 0 - 15
|
||||
TEXTURE_PARAM_ENABLE_REPEAT_S_BIT = 16,
|
||||
TEXTURE_PARAM_ENABLE_REPEAT_T_BIT = 17,
|
||||
TEXTURE_PARAM_ENABLE_MIRRORED_REPEAT_S_BIT = 18,
|
||||
TEXTURE_PARAM_ENABLE_MIRRORED_REPEAT_T_BIT = 19,
|
||||
TEXTURE_PARAM_SIZE_S_BIT = 20, // Bits 20 - 22
|
||||
TEXTURE_PARAM_SIZE_T_BIT = 23, // Bits 23 - 25
|
||||
TEXTURE_PARAM_FORMAT_BIT = 26, // Bits 26 - 28
|
||||
TEXTURE_PARAM_ENABLE_TRANSPARENT_COLOR0_BIT = 29,
|
||||
TEXTURE_PARAM_COORD_TRANSFORM_MODE_BIT = 30 // Bits 30 - 31
|
||||
};
|
||||
|
||||
// TEXTURE PARAMETERS - BIT MASKS
|
||||
enum
|
||||
{
|
||||
TEXTURE_PARAM_VRAM_OFFSET_MASK = 0xFFFF << TEXTURE_PARAM_VRAM_OFFSET_BIT,
|
||||
TEXTURE_PARAM_ENABLE_REPEAT_S_MASK = 0x01 << TEXTURE_PARAM_ENABLE_REPEAT_S_BIT,
|
||||
TEXTURE_PARAM_ENABLE_REPEAT_T_MASK = 0x01 << TEXTURE_PARAM_ENABLE_REPEAT_T_BIT,
|
||||
TEXTURE_PARAM_ENABLE_MIRRORED_REPEAT_S_MASK = 0x01 << TEXTURE_PARAM_ENABLE_MIRRORED_REPEAT_S_BIT,
|
||||
TEXTURE_PARAM_ENABLE_MIRRORED_REPEAT_T_MASK = 0x01 << TEXTURE_PARAM_ENABLE_MIRRORED_REPEAT_T_BIT,
|
||||
TEXTURE_PARAM_SIZE_S_MASK = 0x07 << TEXTURE_PARAM_SIZE_S_BIT,
|
||||
TEXTURE_PARAM_SIZE_T_MASK = 0x07 << TEXTURE_PARAM_SIZE_T_BIT,
|
||||
TEXTURE_PARAM_FORMAT_MASK = 0x07 << TEXTURE_PARAM_FORMAT_BIT,
|
||||
TEXTURE_PARAM_ENABLE_TRANSPARENT_COLOR0_MASK = 0x01 << TEXTURE_PARAM_ENABLE_TRANSPARENT_COLOR0_BIT,
|
||||
TEXTURE_PARAM_COORD_TRANSFORM_MODE_MASK = 0x03 << TEXTURE_PARAM_COORD_TRANSFORM_MODE_BIT
|
||||
};
|
||||
|
||||
// TEXTURE PARAMETERS - FORMAT ID
|
||||
enum NDSTextureFormat
|
||||
{
|
||||
|
@ -198,6 +127,14 @@ enum NDSTextureFormat
|
|||
TEXMODE_16BPP = 7
|
||||
};
|
||||
|
||||
enum TextureTransformationMode
|
||||
{
|
||||
TextureTransformationMode_None = 0,
|
||||
TextureTransformationMode_TexCoordSource = 1,
|
||||
TextureTransformationMode_NormalSource = 2,
|
||||
TextureTransformationMode_VertexSource = 3
|
||||
};
|
||||
|
||||
enum PolygonShadingMode
|
||||
{
|
||||
PolygonShadingMode_Toon = 0,
|
||||
|
@ -208,48 +145,170 @@ void gfx3d_init();
|
|||
void gfx3d_deinit();
|
||||
void gfx3d_reset();
|
||||
|
||||
typedef struct
|
||||
typedef union
|
||||
{
|
||||
u8 enableLightFlags;
|
||||
bool enableLight0;
|
||||
bool enableLight1;
|
||||
bool enableLight2;
|
||||
bool enableLight3;
|
||||
PolygonMode polygonMode;
|
||||
u8 surfaceCullingMode;
|
||||
bool enableRenderBackSurface;
|
||||
bool enableRenderFrontSurface;
|
||||
bool enableAlphaDepthWrite;
|
||||
bool enableRenderOnFarPlaneIntersect;
|
||||
bool enableRenderOneDot;
|
||||
bool enableDepthEqualTest;
|
||||
bool enableRenderFog;
|
||||
bool isWireframe;
|
||||
bool isOpaque;
|
||||
bool isTranslucent;
|
||||
u8 alpha;
|
||||
u8 polygonID;
|
||||
} PolygonAttributes;
|
||||
u32 value;
|
||||
|
||||
struct
|
||||
{
|
||||
#ifndef MSB_FIRST
|
||||
u8 Light0:1; // 0: Light 0; 0=Disable, 1=Enable
|
||||
u8 Light1:1; // 1: Light 1; 0=Disable, 1=Enable
|
||||
u8 Light2:1; // 2: Light 2; 0=Disable, 1=Enable
|
||||
u8 Light3:1; // 3: Light 3; 0=Disable, 1=Enable
|
||||
u8 Mode:2; // 4- 5: Polygon mode;
|
||||
// 0=Low
|
||||
// 1=Medium
|
||||
// 2=High
|
||||
// 3=Maximum
|
||||
u8 BackSurface:1; // 6: Back surface; 0=Hide, 1=Render
|
||||
u8 FrontSurface:1; // 7: Front surface; 0=Hide, 1=Render
|
||||
|
||||
u8 :3; // 8-10: Unused bits
|
||||
u8 TranslucentDepthWrite_Enable:1; // 11: Translucent depth write; 0=Keep 1=Replace
|
||||
u8 FarPlaneIntersect_Enable:1; // 12: Far-plane intersecting polygons; 0=Hide, 1=Render/clipped
|
||||
u8 OneDotPolygons_Enable:1; // 13: One-dot polygons; 0=Hide, 1=Render
|
||||
u8 DepthEqualTest_Enable:1; // 14: Depth test mode; 0=Less, 1=Equal
|
||||
u8 Fog_Enable:1; // 15: Fog; 0=Disable, 1=Enable
|
||||
|
||||
u8 Alpha:5; // 16-20: Alpha value
|
||||
u8 :3; // 21-23: Unused bits
|
||||
|
||||
u8 PolygonID:6; // 24-29: Polygon ID
|
||||
u8 :2; // 30-31: Unused bits
|
||||
#else
|
||||
u8 FrontSurface:1; // 7: Front surface; 0=Hide, 1=Render
|
||||
u8 BackSurface:1; // 6: Back surface; 0=Hide, 1=Render
|
||||
u8 Mode:2; // 4- 5: Polygon mode;
|
||||
// 0=Low
|
||||
// 1=Medium
|
||||
// 2=High
|
||||
// 3=Maximum
|
||||
u8 Light3:1; // 3: Light 3; 0=Disable, 1=Enable
|
||||
u8 Light2:1; // 2: Light 2; 0=Disable, 1=Enable
|
||||
u8 Light1:1; // 1: Light 1; 0=Disable, 1=Enable
|
||||
u8 Light0:1; // 0: Light 0; 0=Disable, 1=Enable
|
||||
|
||||
u8 Fog_Enable:1; // 15: Fog; 0=Disable, 1=Enable
|
||||
u8 DepthEqualTest_Enable:1; // 14: Depth test mode; 0=Less, 1=Equal
|
||||
u8 OneDotPolygons_Enable:1; // 13: One-dot polygons; 0=Hide, 1=Render
|
||||
u8 FarPlaneIntersect_Enable:1; // 12: Far-plane intersecting polygons; 0=Hide, 1=Render/clipped
|
||||
u8 TranslucentDepthWrite_Enable:1; // 11: Translucent depth write; 0=Keep 1=Replace
|
||||
u8 :3; // 8-10: Unused bits
|
||||
|
||||
u8 :3; // 21-23: Unused bits
|
||||
u8 Alpha:5; // 16-20: Alpha value
|
||||
|
||||
u8 :2; // 30-31: Unused bits
|
||||
u8 PolygonID:6; // 24-29: Polygon ID
|
||||
#endif
|
||||
};
|
||||
|
||||
struct
|
||||
{
|
||||
#ifndef MSB_FIRST
|
||||
u8 LightMask:4; // 0- 3: Light enable mask
|
||||
u8 :2;
|
||||
u8 SurfaceCullingMode:2; // 6- 7: Surface culling mode;
|
||||
// 0=Cull front and back
|
||||
// 1=Cull front
|
||||
// 2=Cull back
|
||||
// 3=No culling
|
||||
u8 :8;
|
||||
u8 :8;
|
||||
u8 :8;
|
||||
#else
|
||||
u8 SurfaceCullingMode:2; // 6- 7: Surface culling mode;
|
||||
// 0=Cull front and back
|
||||
// 1=Cull front
|
||||
// 2=Cull back
|
||||
// 3=No culling
|
||||
u8 :2;
|
||||
u8 LightMask:4; // 0- 3: Light enable mask
|
||||
|
||||
u8 :8;
|
||||
u8 :8;
|
||||
u8 :8;
|
||||
#endif
|
||||
};
|
||||
} POLYGON_ATTR;
|
||||
|
||||
typedef struct
|
||||
typedef union
|
||||
{
|
||||
u16 VRAMOffset;
|
||||
bool enableRepeatS;
|
||||
bool enableRepeatT;
|
||||
bool enableMirroredRepeatS;
|
||||
bool enableMirroredRepeatT;
|
||||
u8 sizeS;
|
||||
u8 sizeT;
|
||||
u8 texFormat;
|
||||
bool enableTransparentColor0;
|
||||
u8 coordTransformMode;
|
||||
} PolygonTexParams;
|
||||
u32 value;
|
||||
|
||||
struct
|
||||
{
|
||||
u16 VRAMOffset:16; // 0-15: VRAM offset address
|
||||
|
||||
#ifndef MSB_FIRST
|
||||
u16 RepeatS_Enable:1; // 16: Repeat for S-coordinate; 0=Clamp 1=Repeat
|
||||
u16 RepeatT_Enable:1; // 17: Repeat for T-coordinate; 0=Clamp 1=Repeat
|
||||
u16 MirroredRepeatS_Enable:1; // 18: Mirrored repeat for S-coordinate, interacts with bit 16; 0=Disable 1=Enable
|
||||
u16 MirroredRepeatT_Enable:1; // 19: Mirrored repeat for T-coordinate, interacts with bit 17; 0=Disable 1=Enable
|
||||
u16 SizeShiftS:3; // 20-22: Texel size shift for S-coordinate; 0...7, where the actual texel size is (8 << N)
|
||||
u16 SizeShiftT:3; // 23-25: Texel size shift for T-coordinate; 0...7, where the actual texel size is (8 << N)
|
||||
u16 PackedFormat:3; // 26-28: Packed texture format;
|
||||
// 0=None
|
||||
// 1=A3I5, 5-bit indexed color with 3-bit alpha
|
||||
// 2=I2, 2-bit indexed color (4-color palette)
|
||||
// 3=I4, 4-bit indexed color (16-color palette)
|
||||
// 4=I8, 8-bit indexed color (256-color palette)
|
||||
// 5=4x4-texel compressed
|
||||
// 6=A5I3, 3-bit indexed color with 5-bit alpha
|
||||
// 7=Direct 16-bit color
|
||||
u16 KeyColor0_Enable:1; // 29: Use palette color 0 as transparent; 0=Displayed 1=Transparent
|
||||
u16 TexCoordTransformMode:2; // 30-31: Texture coordinate transformation mode;
|
||||
// 0=No transformation
|
||||
// 1=TexCoord source
|
||||
// 2=Normal source
|
||||
// 3=Vertex source
|
||||
#else
|
||||
u16 TexCoordTransformMode:2; // 30-31: Texture coordinate transformation mode;
|
||||
// 0=No transformation
|
||||
// 1=TexCoord source
|
||||
// 2=Normal source
|
||||
// 3=Vertex source
|
||||
u16 KeyColor0_Enable:1; // 29: Use palette color 0 as transparent; 0=Displayed 1=Transparent
|
||||
u16 PackedFormat:3; // 26-28: Packed texture format;
|
||||
// 0=None
|
||||
// 1=A3I5, 5-bit indexed color (32-color palette) with 3-bit alpha (0...7, where 0=Fully Transparent and 7=Opaque)
|
||||
// 2=I2, 2-bit indexed color (4-color palette)
|
||||
// 3=I4, 4-bit indexed color (16-color palette)
|
||||
// 4=I8, 8-bit indexed color (256-color palette)
|
||||
// 5=4x4-texel compressed
|
||||
// 6=A5I3, 3-bit indexed color (8-color palette) with 5-bit alpha (0...31, where 0=Fully Transparent and 31=Opaque)
|
||||
// 7=Direct 16-bit color
|
||||
u16 SizeShiftT:3; // 23-25: Texel size shift for T-coordinate; 0...7, where the actual texel size is (8 << N)
|
||||
u16 SizeShiftS:3; // 20-22: Texel size shift for S-coordinate; 0...7, where the actual texel size is (8 << N)
|
||||
u16 MirroredRepeatT_Enable:1; // 19: Mirrored repeat for T-coordinate, interacts with bit 17; 0=Disable 1=Enable
|
||||
u16 MirroredRepeatS_Enable:1; // 18: Mirrored repeat for S-coordinate, interacts with bit 16; 0=Disable 1=Enable
|
||||
u16 RepeatT_Enable:1; // 17: Repeat for T-coordinate; 0=Clamp 1=Repeat
|
||||
u16 RepeatS_Enable:1; // 16: Repeat for S-coordinate; 0=Clamp 1=Repeat
|
||||
#endif
|
||||
};
|
||||
|
||||
struct
|
||||
{
|
||||
u16 :16;
|
||||
|
||||
#ifndef MSB_FIRST
|
||||
u16 TextureWrapMode:4; // 16-19: Texture wrap mode for repeat and mirrored repeat
|
||||
u16 :12;
|
||||
#else
|
||||
u16 :12;
|
||||
u16 TextureWrapMode:4; // 16-19: Texture wrap mode for repeat and mirrored repeat
|
||||
#endif
|
||||
};
|
||||
} TEXIMAGE_PARAM;
|
||||
|
||||
struct POLY {
|
||||
PolygonType type; //tri or quad
|
||||
PolygonPrimitiveType vtxFormat;
|
||||
u16 vertIndexes[4]; //up to four verts can be referenced by this poly
|
||||
u32 polyAttr, texParam, texPalette; //the hardware rendering params
|
||||
POLYGON_ATTR attribute;
|
||||
TEXIMAGE_PARAM texParam;
|
||||
u32 texPalette; //the hardware rendering params
|
||||
u32 viewport;
|
||||
float miny, maxy;
|
||||
|
||||
|
@ -262,193 +321,14 @@ struct POLY {
|
|||
else type = POLYGON_TYPE_TRIANGLE;
|
||||
}
|
||||
|
||||
u8 getAttributeEnableLightFlags() const
|
||||
{
|
||||
return ((polyAttr & (POLYGON_ATTR_ENABLE_LIGHT0_MASK |
|
||||
POLYGON_ATTR_ENABLE_LIGHT1_MASK |
|
||||
POLYGON_ATTR_ENABLE_LIGHT2_MASK |
|
||||
POLYGON_ATTR_ENABLE_LIGHT3_MASK)) >> POLYGON_ATTR_ENABLE_LIGHT0_BIT);
|
||||
}
|
||||
|
||||
bool getAttributeEnableLight0() const
|
||||
{
|
||||
return ((polyAttr & POLYGON_ATTR_ENABLE_LIGHT0_MASK) > 0);
|
||||
}
|
||||
|
||||
bool getAttributeEnableLight1() const
|
||||
{
|
||||
return ((polyAttr & POLYGON_ATTR_ENABLE_LIGHT1_MASK) > 0);
|
||||
}
|
||||
|
||||
bool getAttributeEnableLight2() const
|
||||
{
|
||||
return ((polyAttr & POLYGON_ATTR_ENABLE_LIGHT2_MASK) > 0);
|
||||
}
|
||||
|
||||
bool getAttributeEnableLight3() const
|
||||
{
|
||||
return ((polyAttr & POLYGON_ATTR_ENABLE_LIGHT3_MASK) > 0);
|
||||
}
|
||||
|
||||
PolygonMode getAttributePolygonMode() const
|
||||
{
|
||||
return (PolygonMode)((polyAttr & POLYGON_ATTR_MODE_MASK) >> POLYGON_ATTR_MODE_BIT);
|
||||
}
|
||||
|
||||
u8 getAttributeEnableFaceCullingFlags() const
|
||||
{
|
||||
return ((polyAttr & (POLYGON_ATTR_ENABLE_BACK_SURFACE_MASK |
|
||||
POLYGON_ATTR_ENABLE_FRONT_SURFACE_MASK)) >> POLYGON_ATTR_ENABLE_BACK_SURFACE_BIT);
|
||||
}
|
||||
|
||||
bool getAttributeEnableBackSurface() const
|
||||
{
|
||||
return ((polyAttr & POLYGON_ATTR_ENABLE_BACK_SURFACE_MASK) > 0);
|
||||
}
|
||||
|
||||
bool getAttributeEnableFrontSurface() const
|
||||
{
|
||||
return ((polyAttr & POLYGON_ATTR_ENABLE_FRONT_SURFACE_MASK) > 0);
|
||||
}
|
||||
|
||||
bool getAttributeEnableAlphaDepthWrite() const
|
||||
{
|
||||
return ((polyAttr & POLYGON_ATTR_ENABLE_ALPHA_DEPTH_WRITE_MASK) > 0);
|
||||
}
|
||||
|
||||
bool getAttributeEnableRenderOnFarPlaneIntersect() const
|
||||
{
|
||||
return ((polyAttr & POLYGON_ATTR_ENABLE_RENDER_ON_FAR_PLANE_INTERSECT_MASK) > 0);
|
||||
}
|
||||
|
||||
bool getAttributeEnableOneDotRender() const
|
||||
{
|
||||
return ((polyAttr & POLYGON_ATTR_ENABLE_ONE_DOT_RENDER_MASK) > 0);
|
||||
}
|
||||
|
||||
bool getAttributeEnableDepthEqualTest() const
|
||||
{
|
||||
return ((polyAttr & POLYGON_ATTR_ENABLE_DEPTH_EQUAL_TEST_MASK) > 0);
|
||||
}
|
||||
|
||||
bool getAttributeEnableFog() const
|
||||
{
|
||||
return ((polyAttr & POLYGON_ATTR_ENABLE_FOG_MASK) > 0);
|
||||
}
|
||||
|
||||
u8 getAttributeAlpha() const
|
||||
{
|
||||
return ((polyAttr & POLYGON_ATTR_ALPHA_MASK) >> POLYGON_ATTR_ALPHA_BIT);
|
||||
}
|
||||
|
||||
u8 getAttributePolygonID() const
|
||||
{
|
||||
return ((polyAttr & POLYGON_ATTR_POLYGON_ID_MASK) >> POLYGON_ATTR_POLYGON_ID_BIT);
|
||||
}
|
||||
|
||||
PolygonAttributes getAttributes() const
|
||||
{
|
||||
PolygonAttributes theAttr;
|
||||
|
||||
theAttr.enableLightFlags = this->getAttributeEnableLightFlags();
|
||||
theAttr.enableLight0 = this->getAttributeEnableLight0();
|
||||
theAttr.enableLight1 = this->getAttributeEnableLight1();
|
||||
theAttr.enableLight2 = this->getAttributeEnableLight2();
|
||||
theAttr.enableLight3 = this->getAttributeEnableLight3();
|
||||
theAttr.polygonMode = this->getAttributePolygonMode();
|
||||
theAttr.surfaceCullingMode = this->getAttributeEnableFaceCullingFlags();
|
||||
theAttr.enableRenderBackSurface = this->getAttributeEnableBackSurface();
|
||||
theAttr.enableRenderFrontSurface = this->getAttributeEnableFrontSurface();
|
||||
theAttr.enableAlphaDepthWrite = this->getAttributeEnableAlphaDepthWrite();
|
||||
theAttr.enableRenderOnFarPlaneIntersect = this->getAttributeEnableRenderOnFarPlaneIntersect();
|
||||
theAttr.enableRenderOneDot = this->getAttributeEnableOneDotRender();
|
||||
theAttr.enableDepthEqualTest = this->getAttributeEnableDepthEqualTest();
|
||||
theAttr.enableRenderFog = this->getAttributeEnableFog();
|
||||
theAttr.alpha = this->getAttributeAlpha();
|
||||
theAttr.isWireframe = this->isWireframe();
|
||||
theAttr.isOpaque = this->isOpaque();
|
||||
theAttr.isTranslucent = this->isTranslucent();
|
||||
theAttr.polygonID = this->getAttributePolygonID();
|
||||
|
||||
return theAttr;
|
||||
}
|
||||
|
||||
u16 getTexParamVRAMOffset() const
|
||||
{
|
||||
return ((texParam & TEXTURE_PARAM_VRAM_OFFSET_MASK) >> TEXTURE_PARAM_VRAM_OFFSET_BIT);
|
||||
}
|
||||
|
||||
bool getTexParamEnableRepeatS() const
|
||||
{
|
||||
return ((texParam & TEXTURE_PARAM_ENABLE_REPEAT_S_MASK) > 0);
|
||||
}
|
||||
|
||||
bool getTexParamEnableRepeatT() const
|
||||
{
|
||||
return ((texParam & TEXTURE_PARAM_ENABLE_REPEAT_T_MASK) > 0);
|
||||
}
|
||||
|
||||
bool getTexParamEnableMirroredRepeatS() const
|
||||
{
|
||||
return ((texParam & TEXTURE_PARAM_ENABLE_MIRRORED_REPEAT_S_MASK) > 0);
|
||||
}
|
||||
|
||||
bool getTexParamEnableMirroredRepeatT() const
|
||||
{
|
||||
return ((texParam & TEXTURE_PARAM_ENABLE_MIRRORED_REPEAT_T_MASK) > 0);
|
||||
}
|
||||
|
||||
u8 getTexParamSizeS() const
|
||||
{
|
||||
return ((texParam & TEXTURE_PARAM_SIZE_S_MASK) >> TEXTURE_PARAM_SIZE_S_BIT);
|
||||
}
|
||||
|
||||
u8 getTexParamSizeT() const
|
||||
{
|
||||
return ((texParam & TEXTURE_PARAM_SIZE_T_MASK) >> TEXTURE_PARAM_SIZE_T_BIT);
|
||||
}
|
||||
|
||||
u8 getTexParamTexFormat() const
|
||||
{
|
||||
return ((texParam & TEXTURE_PARAM_FORMAT_MASK) >> TEXTURE_PARAM_FORMAT_BIT);
|
||||
}
|
||||
|
||||
bool getTexParamEnableTransparentColor0() const
|
||||
{
|
||||
return ((texParam & TEXTURE_PARAM_ENABLE_TRANSPARENT_COLOR0_MASK) > 0);
|
||||
}
|
||||
|
||||
u8 getTexParamCoordTransformMode() const
|
||||
{
|
||||
return ((texParam & TEXTURE_PARAM_COORD_TRANSFORM_MODE_MASK) >> TEXTURE_PARAM_COORD_TRANSFORM_MODE_BIT);
|
||||
}
|
||||
|
||||
PolygonTexParams getTexParams() const
|
||||
{
|
||||
PolygonTexParams theTexParams;
|
||||
|
||||
theTexParams.VRAMOffset = this->getTexParamVRAMOffset();
|
||||
theTexParams.enableRepeatS = this->getTexParamEnableRepeatS();
|
||||
theTexParams.enableRepeatT = this->getTexParamEnableRepeatT();
|
||||
theTexParams.enableMirroredRepeatS = this->getTexParamEnableMirroredRepeatS();
|
||||
theTexParams.enableMirroredRepeatT = this->getTexParamEnableMirroredRepeatT();
|
||||
theTexParams.sizeS = this->getTexParamSizeS();
|
||||
theTexParams.sizeT = this->getTexParamSizeT();
|
||||
theTexParams.texFormat = this->getTexParamTexFormat();
|
||||
theTexParams.enableTransparentColor0 = this->getTexParamEnableTransparentColor0();
|
||||
theTexParams.coordTransformMode = this->getTexParamCoordTransformMode();
|
||||
|
||||
return theTexParams;
|
||||
}
|
||||
|
||||
bool isWireframe() const
|
||||
{
|
||||
return (this->getAttributeAlpha() == 0);
|
||||
return (this->attribute.Alpha == 0);
|
||||
}
|
||||
|
||||
bool isOpaque() const
|
||||
{
|
||||
return (this->getAttributeAlpha() == 31);
|
||||
return (this->attribute.Alpha == 31);
|
||||
}
|
||||
|
||||
bool isTranslucent() const
|
||||
|
@ -461,8 +341,8 @@ struct POLY {
|
|||
}
|
||||
|
||||
// Also check for translucent texture format.
|
||||
const u8 texFormat = this->getTexParamTexFormat();
|
||||
const PolygonMode mode = this->getAttributePolygonMode();
|
||||
const NDSTextureFormat texFormat = (NDSTextureFormat)this->texParam.PackedFormat;
|
||||
const PolygonMode mode = (PolygonMode)this->attribute.Mode;
|
||||
|
||||
//a5i3 or a3i5 -> translucent
|
||||
if ( (texFormat == TEXMODE_A3I5 || texFormat == TEXMODE_A5I3) && (mode != POLYGON_MODE_DECAL && mode != POLYGON_MODE_SHADOW) )
|
||||
|
|
|
@ -380,7 +380,7 @@ public:
|
|||
return RENDER3DERROR_NOERR;
|
||||
}
|
||||
|
||||
this->_textureWrapMode = (thePoly.texParam >> 16) & 0x0F;
|
||||
this->_textureWrapMode = thePoly.texParam.TextureWrapMode;
|
||||
|
||||
theTexture->ResetCacheAge();
|
||||
theTexture->IncreaseCacheUsageCount(1);
|
||||
|
@ -508,7 +508,7 @@ public:
|
|||
}
|
||||
|
||||
template<bool ISSHADOWPOLYGON>
|
||||
FORCEINLINE void pixel(const PolygonAttributes &polyAttr, const size_t fragmentIndex, FragmentColor &dstColor, float r, float g, float b, float invu, float invv, float w, float z)
|
||||
FORCEINLINE void pixel(const POLYGON_ATTR polyAttr, const bool isTranslucent, const size_t fragmentIndex, FragmentColor &dstColor, float r, float g, float b, float invu, float invv, float w, float z)
|
||||
{
|
||||
FragmentColor srcColor;
|
||||
FragmentColor shaderOutput;
|
||||
|
@ -530,7 +530,7 @@ public:
|
|||
|
||||
// run the depth test
|
||||
bool depthFail = false;
|
||||
if (polyAttr.enableDepthEqualTest)
|
||||
if (polyAttr.DepthEqualTest_Enable)
|
||||
{
|
||||
const u32 minDepth = max<u32>(0x00000000, dstAttributeDepth - SOFTRASTERIZER_DEPTH_EQUAL_TEST_TOLERANCE);
|
||||
const u32 maxDepth = min<u32>(0x00FFFFFF, dstAttributeDepth + SOFTRASTERIZER_DEPTH_EQUAL_TEST_TOLERANCE);
|
||||
|
@ -548,10 +548,10 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
if(depthFail)
|
||||
if (depthFail)
|
||||
{
|
||||
//shadow mask polygons set stencil bit here
|
||||
if (ISSHADOWPOLYGON && polyAttr.polygonID == 0)
|
||||
if (ISSHADOWPOLYGON && polyAttr.PolygonID == 0)
|
||||
dstAttributeStencil=1;
|
||||
return;
|
||||
}
|
||||
|
@ -559,7 +559,7 @@ public:
|
|||
//handle shadow polys
|
||||
if (ISSHADOWPOLYGON)
|
||||
{
|
||||
if (polyAttr.polygonID == 0)
|
||||
if (polyAttr.PolygonID == 0)
|
||||
{
|
||||
//shadow mask polygons only affect the stencil buffer, and then only when they fail depth test
|
||||
//if we made it here, the shadow mask polygon fragment needs to be trashed
|
||||
|
@ -573,7 +573,7 @@ public:
|
|||
//draw only where stencil bit is set
|
||||
return;
|
||||
}
|
||||
if (dstAttributeOpaquePolyID == polyAttr.polygonID)
|
||||
if (dstAttributeOpaquePolyID == polyAttr.PolygonID)
|
||||
{
|
||||
//draw only when polygon ID differs
|
||||
//TODO: are we using the right dst polyID?
|
||||
|
@ -596,10 +596,10 @@ public:
|
|||
srcColor = MakeFragmentColor(max<u8>(0x00, min<u32>(0x3F,u32floor(r))),
|
||||
max<u8>(0x00, min<u32>(0x3F,u32floor(g))),
|
||||
max<u8>(0x00, min<u32>(0x3F,u32floor(b))),
|
||||
polyAttr.alpha);
|
||||
polyAttr.Alpha);
|
||||
|
||||
//pixel shader
|
||||
shade(polyAttr.polygonMode, srcColor, shaderOutput, invu * w, invv * w);
|
||||
shade((PolygonMode)polyAttr.Mode, srcColor, shaderOutput, invu * w, invv * w);
|
||||
|
||||
// handle alpha test
|
||||
if ( shaderOutput.a == 0 ||
|
||||
|
@ -612,42 +612,42 @@ public:
|
|||
isOpaquePixel = (shaderOutput.a == 0x1F);
|
||||
if (isOpaquePixel)
|
||||
{
|
||||
dstAttributeOpaquePolyID = polyAttr.polygonID;
|
||||
dstAttributeIsTranslucentPoly = polyAttr.isTranslucent;
|
||||
dstAttributeIsFogged = polyAttr.enableRenderFog;
|
||||
dstAttributeOpaquePolyID = polyAttr.PolygonID;
|
||||
dstAttributeIsTranslucentPoly = isTranslucent;
|
||||
dstAttributeIsFogged = polyAttr.Fog_Enable;
|
||||
dstColor = shaderOutput;
|
||||
}
|
||||
else
|
||||
{
|
||||
//dont overwrite pixels on translucent polys with the same polyids
|
||||
if (dstAttributeTranslucentPolyID == polyAttr.polygonID)
|
||||
if (dstAttributeTranslucentPolyID == polyAttr.PolygonID)
|
||||
return;
|
||||
|
||||
//originally we were using a test case of shadows-behind-trees in sm64ds
|
||||
//but, it looks bad in that game. this is actually correct
|
||||
//if this isnt correct, then complex shape cart shadows in mario kart don't work right
|
||||
dstAttributeTranslucentPolyID = polyAttr.polygonID;
|
||||
dstAttributeTranslucentPolyID = polyAttr.PolygonID;
|
||||
|
||||
//alpha blending and write color
|
||||
alphaBlend(dstColor, shaderOutput);
|
||||
|
||||
dstAttributeIsFogged = (dstAttributeIsFogged && polyAttr.enableRenderFog);
|
||||
dstAttributeIsFogged = (dstAttributeIsFogged && polyAttr.Fog_Enable);
|
||||
}
|
||||
|
||||
//depth writing
|
||||
if (isOpaquePixel || polyAttr.enableAlphaDepthWrite)
|
||||
if (isOpaquePixel || polyAttr.TranslucentDepthWrite_Enable)
|
||||
dstAttributeDepth = newDepth;
|
||||
}
|
||||
|
||||
//draws a single scanline
|
||||
template <bool ISSHADOWPOLYGON>
|
||||
FORCEINLINE void drawscanline(const PolygonAttributes &polyAttr, FragmentColor *dstColor, const size_t framebufferWidth, const size_t framebufferHeight, edge_fx_fl *pLeft, edge_fx_fl *pRight, bool lineHack)
|
||||
template <bool ISSHADOWPOLYGON, bool USELINEHACK>
|
||||
FORCEINLINE void drawscanline(const POLYGON_ATTR polyAttr, const bool isTranslucent, FragmentColor *dstColor, const size_t framebufferWidth, const size_t framebufferHeight, edge_fx_fl *pLeft, edge_fx_fl *pRight)
|
||||
{
|
||||
int XStart = pLeft->X;
|
||||
int width = pRight->X - XStart;
|
||||
|
||||
// HACK: workaround for vertical/slant line poly
|
||||
if (lineHack && width == 0)
|
||||
if (USELINEHACK && width == 0)
|
||||
{
|
||||
int leftWidth = pLeft->XStep;
|
||||
if (pLeft->ErrorTerm + pLeft->Numerator >= pLeft->Denominator)
|
||||
|
@ -699,7 +699,7 @@ public:
|
|||
|
||||
if (x < 0)
|
||||
{
|
||||
if (RENDERER && !lineHack)
|
||||
if (RENDERER && !USELINEHACK)
|
||||
{
|
||||
printf("rasterizer rendering at x=%d! oops!\n",x);
|
||||
return;
|
||||
|
@ -717,7 +717,7 @@ public:
|
|||
}
|
||||
if (x+width > framebufferWidth)
|
||||
{
|
||||
if (RENDERER && !lineHack && framebufferWidth == GPU_FRAMEBUFFER_NATIVE_WIDTH)
|
||||
if (RENDERER && !USELINEHACK && framebufferWidth == GPU_FRAMEBUFFER_NATIVE_WIDTH)
|
||||
{
|
||||
printf("rasterizer rendering at x=%d! oops!\n",x+width-1);
|
||||
return;
|
||||
|
@ -727,7 +727,7 @@ public:
|
|||
|
||||
while (width-- > 0)
|
||||
{
|
||||
pixel<ISSHADOWPOLYGON>(polyAttr, adr, dstColor[adr], color[0], color[1], color[2], u, v, 1.0f/invw, z);
|
||||
pixel<ISSHADOWPOLYGON>(polyAttr, isTranslucent, adr, dstColor[adr], color[0], color[1], color[2], u, v, 1.0f/invw, z);
|
||||
adr++;
|
||||
x++;
|
||||
|
||||
|
@ -742,44 +742,44 @@ public:
|
|||
}
|
||||
|
||||
//runs several scanlines, until an edge is finished
|
||||
template<bool SLI, bool ISSHADOWPOLYGON>
|
||||
void runscanlines(const PolygonAttributes &polyAttr, FragmentColor *dstColor, const size_t framebufferWidth, const size_t framebufferHeight, edge_fx_fl *left, edge_fx_fl *right, bool horizontal, bool lineHack)
|
||||
template <bool SLI, bool ISSHADOWPOLYGON, bool USELINEHACK, bool ISHORIZONTAL>
|
||||
void runscanlines(const POLYGON_ATTR polyAttr, const bool isTranslucent, FragmentColor *dstColor, const size_t framebufferWidth, const size_t framebufferHeight, edge_fx_fl *left, edge_fx_fl *right)
|
||||
{
|
||||
//oh lord, hack city for edge drawing
|
||||
|
||||
//do not overstep either of the edges
|
||||
int Height = min(left->Height,right->Height);
|
||||
bool first=true;
|
||||
bool first = true;
|
||||
|
||||
//HACK: special handling for horizontal line poly
|
||||
if (lineHack && left->Height == 0 && right->Height == 0 && left->Y<framebufferHeight && left->Y>=0)
|
||||
if (USELINEHACK && left->Height == 0 && right->Height == 0 && left->Y<framebufferHeight && left->Y>=0)
|
||||
{
|
||||
bool draw = (!SLI || (left->Y & SLI_MASK) == SLI_VALUE);
|
||||
if(draw) drawscanline<ISSHADOWPOLYGON>(polyAttr, dstColor, framebufferWidth, framebufferHeight, left,right,lineHack);
|
||||
if (draw) drawscanline<ISSHADOWPOLYGON, USELINEHACK>(polyAttr, isTranslucent, dstColor, framebufferWidth, framebufferHeight, left, right);
|
||||
}
|
||||
|
||||
while(Height--)
|
||||
while (Height--)
|
||||
{
|
||||
bool draw = (!SLI || (left->Y & SLI_MASK) == SLI_VALUE);
|
||||
if(draw) drawscanline<ISSHADOWPOLYGON>(polyAttr, dstColor, framebufferWidth, framebufferHeight, left,right,lineHack);
|
||||
if (draw) drawscanline<ISSHADOWPOLYGON, USELINEHACK>(polyAttr, isTranslucent, dstColor, framebufferWidth, framebufferHeight, left, right);
|
||||
const int xl = left->X;
|
||||
const int xr = right->X;
|
||||
const int y = left->Y;
|
||||
left->Step();
|
||||
right->Step();
|
||||
|
||||
if(!RENDERER && _debug_thisPoly)
|
||||
if (!RENDERER && _debug_thisPoly)
|
||||
{
|
||||
//debug drawing
|
||||
bool top = (horizontal&&first);
|
||||
bool bottom = (!Height&&horizontal);
|
||||
if(Height || top || bottom)
|
||||
bool top = (ISHORIZONTAL && first);
|
||||
bool bottom = (!Height && ISHORIZONTAL);
|
||||
if (Height || top || bottom)
|
||||
{
|
||||
if(draw)
|
||||
if (draw)
|
||||
{
|
||||
int nxl = left->X;
|
||||
int nxr = right->X;
|
||||
if(top)
|
||||
if (top)
|
||||
{
|
||||
int xs = min(xl,xr);
|
||||
int xe = max(xl,xr);
|
||||
|
@ -791,7 +791,7 @@ public:
|
|||
dstColor[adr].b = 0;
|
||||
}
|
||||
}
|
||||
else if(bottom)
|
||||
else if (bottom)
|
||||
{
|
||||
int xs = min(xl,xr);
|
||||
int xe = max(xl,xr);
|
||||
|
@ -844,11 +844,11 @@ public:
|
|||
|
||||
//rotate verts until vert0.y is minimum, and then vert0.x is minimum in case of ties
|
||||
//this is a necessary precondition for our shape engine
|
||||
template<int TYPE>
|
||||
void sort_verts(bool backwards)
|
||||
template<bool ISBACKWARDS, int TYPE>
|
||||
void sort_verts()
|
||||
{
|
||||
//if the verts are backwards, reorder them first
|
||||
if (backwards)
|
||||
if (ISBACKWARDS)
|
||||
for (size_t i = 0; i < TYPE/2; i++)
|
||||
swap(verts[i],verts[TYPE-i-1]);
|
||||
|
||||
|
@ -881,22 +881,22 @@ public:
|
|||
//verts must be clockwise.
|
||||
//I didnt reference anything for this algorithm but it seems like I've seen it somewhere before.
|
||||
//Maybe it is like crow's algorithm
|
||||
template<bool SLI, bool ISSHADOWPOLYGON>
|
||||
void shape_engine(const PolygonAttributes &polyAttr, FragmentColor *dstColor, const size_t framebufferWidth, const size_t framebufferHeight, int type, const bool backwards, bool lineHack)
|
||||
template <bool SLI, bool ISBACKWARDS, bool ISSHADOWPOLYGON, bool USELINEHACK>
|
||||
void shape_engine(const POLYGON_ATTR polyAttr, const bool isTranslucent, FragmentColor *dstColor, const size_t framebufferWidth, const size_t framebufferHeight, int type)
|
||||
{
|
||||
bool failure = false;
|
||||
|
||||
switch(type)
|
||||
switch (type)
|
||||
{
|
||||
case 3: sort_verts<3>(backwards); break;
|
||||
case 4: sort_verts<4>(backwards); break;
|
||||
case 5: sort_verts<5>(backwards); break;
|
||||
case 6: sort_verts<6>(backwards); break;
|
||||
case 7: sort_verts<7>(backwards); break;
|
||||
case 8: sort_verts<8>(backwards); break;
|
||||
case 9: sort_verts<9>(backwards); break;
|
||||
case 10: sort_verts<10>(backwards); break;
|
||||
default: printf("skipping type %d\n",type); return;
|
||||
case 3: sort_verts<ISBACKWARDS, 3>(); break;
|
||||
case 4: sort_verts<ISBACKWARDS, 4>(); break;
|
||||
case 5: sort_verts<ISBACKWARDS, 5>(); break;
|
||||
case 6: sort_verts<ISBACKWARDS, 6>(); break;
|
||||
case 7: sort_verts<ISBACKWARDS, 7>(); break;
|
||||
case 8: sort_verts<ISBACKWARDS, 8>(); break;
|
||||
case 9: sort_verts<ISBACKWARDS, 9>(); break;
|
||||
case 10: sort_verts<ISBACKWARDS, 10>(); break;
|
||||
default: printf("skipping type %d\n", type); return;
|
||||
}
|
||||
|
||||
//we are going to step around the polygon in both directions starting from vert 0.
|
||||
|
@ -912,18 +912,25 @@ public:
|
|||
//generate new edges if necessary. we must avoid regenerating edges when they are incomplete
|
||||
//so that they can be continued on down the shape
|
||||
assert(rv != type);
|
||||
int _lv = lv==type?0:lv; //make sure that we ask for vert 0 when the variable contains the starting value
|
||||
int _lv = (lv == type) ? 0 : lv; //make sure that we ask for vert 0 when the variable contains the starting value
|
||||
if (step_left) left = edge_fx_fl(_lv,lv-1,(VERT**)&verts, failure);
|
||||
if (step_right) right = edge_fx_fl(rv,rv+1,(VERT**)&verts, failure);
|
||||
step_left = step_right = false;
|
||||
|
||||
//handle a failure in the edge setup due to nutty polys
|
||||
if(failure)
|
||||
if (failure)
|
||||
return;
|
||||
|
||||
bool horizontal = left.Y == right.Y;
|
||||
runscanlines<SLI, ISSHADOWPOLYGON>(polyAttr, dstColor, framebufferWidth, framebufferHeight, &left, &right, horizontal, lineHack);
|
||||
|
||||
const bool horizontal = (left.Y == right.Y);
|
||||
if (horizontal)
|
||||
{
|
||||
runscanlines<SLI, ISSHADOWPOLYGON, USELINEHACK, true>(polyAttr, isTranslucent, dstColor, framebufferWidth, framebufferHeight, &left, &right);
|
||||
}
|
||||
else
|
||||
{
|
||||
runscanlines<SLI, ISSHADOWPOLYGON, USELINEHACK, false>(polyAttr, isTranslucent, dstColor, framebufferWidth, framebufferHeight, &left, &right);
|
||||
}
|
||||
|
||||
//if we ran out of an edge, step to the next one
|
||||
if (right.Height == 0)
|
||||
{
|
||||
|
@ -937,11 +944,11 @@ public:
|
|||
}
|
||||
|
||||
//this is our completion condition: when our stepped edges meet in the middle
|
||||
if (lv<=rv+1) break;
|
||||
if (lv <= rv+1) break;
|
||||
}
|
||||
}
|
||||
|
||||
template<bool SLI>
|
||||
template<bool SLI, bool USELINEHACK>
|
||||
FORCEINLINE void mainLoop()
|
||||
{
|
||||
const size_t polyCount = this->_softRender->_clippedPolyCount;
|
||||
|
@ -956,9 +963,8 @@ public:
|
|||
|
||||
const GFX3D_Clipper::TClippedPoly &firstClippedPoly = this->_softRender->clippedPolys[0];
|
||||
const POLY &firstPoly = *firstClippedPoly.poly;
|
||||
PolygonAttributes polyAttr = firstPoly.getAttributes();
|
||||
u32 lastPolyAttr = firstPoly.polyAttr;
|
||||
u32 lastTexParams = firstPoly.texParam;
|
||||
POLYGON_ATTR polyAttr = firstPoly.attribute;
|
||||
TEXIMAGE_PARAM lastTexParams = firstPoly.texParam;
|
||||
u32 lastTexPalette = firstPoly.texPalette;
|
||||
|
||||
this->SetupTexture(firstPoly, 0);
|
||||
|
@ -972,38 +978,78 @@ public:
|
|||
|
||||
GFX3D_Clipper::TClippedPoly &clippedPoly = this->_softRender->clippedPolys[i];
|
||||
const POLY &thePoly = *clippedPoly.poly;
|
||||
const PolygonType type = clippedPoly.type;
|
||||
const int vertCount = clippedPoly.type;
|
||||
const bool useLineHack = USELINEHACK && (thePoly.vtxFormat & 4);
|
||||
|
||||
if (lastPolyAttr != thePoly.polyAttr)
|
||||
{
|
||||
polyAttr = thePoly.getAttributes();
|
||||
lastPolyAttr = thePoly.polyAttr;
|
||||
}
|
||||
polyAttr = thePoly.attribute;
|
||||
const bool isTranslucent = thePoly.isTranslucent();
|
||||
|
||||
if (lastTexParams != thePoly.texParam || lastTexPalette != thePoly.texPalette)
|
||||
if (lastTexParams.value != thePoly.texParam.value || lastTexPalette != thePoly.texPalette)
|
||||
{
|
||||
lastTexParams = thePoly.texParam;
|
||||
lastTexPalette = thePoly.texPalette;
|
||||
this->SetupTexture(thePoly, i);
|
||||
}
|
||||
|
||||
for (int j = 0; j < type; j++)
|
||||
for (int j = 0; j < vertCount; j++)
|
||||
this->verts[j] = &clippedPoly.clipVerts[j];
|
||||
for (int j = type; j < MAX_CLIPPED_VERTS; j++)
|
||||
for (int j = vertCount; j < MAX_CLIPPED_VERTS; j++)
|
||||
this->verts[j] = NULL;
|
||||
|
||||
if (polyAttr.polygonMode == POLYGON_MODE_SHADOW)
|
||||
if (!this->_softRender->polyBackfacing[i])
|
||||
{
|
||||
shape_engine<SLI, true>(polyAttr, dstColor, dstWidth, dstHeight, type, !this->_softRender->polyBackfacing[i], (thePoly.vtxFormat & 4) && CommonSettings.GFX3D_LineHack);
|
||||
if (polyAttr.Mode == POLYGON_MODE_SHADOW)
|
||||
{
|
||||
if (useLineHack)
|
||||
{
|
||||
shape_engine<SLI, true, true, true>(polyAttr, isTranslucent, dstColor, dstWidth, dstHeight, vertCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
shape_engine<SLI, true, true, false>(polyAttr, isTranslucent, dstColor, dstWidth, dstHeight, vertCount);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (useLineHack)
|
||||
{
|
||||
shape_engine<SLI, true, false, true>(polyAttr, isTranslucent, dstColor, dstWidth, dstHeight, vertCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
shape_engine<SLI, true, false, false>(polyAttr, isTranslucent, dstColor, dstWidth, dstHeight, vertCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
shape_engine<SLI, false>(polyAttr, dstColor, dstWidth, dstHeight, type, !this->_softRender->polyBackfacing[i], (thePoly.vtxFormat & 4) && CommonSettings.GFX3D_LineHack);
|
||||
if (polyAttr.Mode == POLYGON_MODE_SHADOW)
|
||||
{
|
||||
if (useLineHack)
|
||||
{
|
||||
shape_engine<SLI, false, true, true>(polyAttr, isTranslucent, dstColor, dstWidth, dstHeight, vertCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
shape_engine<SLI, false, true, false>(polyAttr, isTranslucent, dstColor, dstWidth, dstHeight, vertCount);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (useLineHack)
|
||||
{
|
||||
shape_engine<SLI, false, false, true>(polyAttr, isTranslucent, dstColor, dstWidth, dstHeight, vertCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
shape_engine<SLI, false, false, false>(polyAttr, isTranslucent, dstColor, dstWidth, dstHeight, vertCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}; //rasterizerUnit
|
||||
|
||||
#define _MAX_CORES 16
|
||||
|
@ -1016,7 +1062,16 @@ static bool rasterizerUnitTasksInited = false;
|
|||
static void* execRasterizerUnit(void *arg)
|
||||
{
|
||||
intptr_t which = (intptr_t)arg;
|
||||
rasterizerUnit[which].mainLoop<true>();
|
||||
|
||||
if (CommonSettings.GFX3D_LineHack)
|
||||
{
|
||||
rasterizerUnit[which].mainLoop<true, true>();
|
||||
}
|
||||
else
|
||||
{
|
||||
rasterizerUnit[which].mainLoop<true, false>();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1066,7 +1121,14 @@ static void* SoftRasterizer_RunRenderEdgeMarkAndFog(void *arg)
|
|||
|
||||
void _HACK_Viewer_ExecUnit()
|
||||
{
|
||||
_HACK_viewer_rasterizerUnit.mainLoop<false>();
|
||||
if (CommonSettings.GFX3D_LineHack)
|
||||
{
|
||||
_HACK_viewer_rasterizerUnit.mainLoop<false, true>();
|
||||
}
|
||||
else
|
||||
{
|
||||
_HACK_viewer_rasterizerUnit.mainLoop<false, false>();
|
||||
}
|
||||
}
|
||||
|
||||
static Render3D* SoftRasterizerRendererCreate()
|
||||
|
@ -1092,7 +1154,7 @@ static void SoftRasterizerRendererDestroy()
|
|||
}
|
||||
}
|
||||
|
||||
SoftRasterizerTexture::SoftRasterizerTexture(u32 texAttributes, u32 palAttributes) : Render3DTexture(texAttributes, palAttributes)
|
||||
SoftRasterizerTexture::SoftRasterizerTexture(TEXIMAGE_PARAM texAttributes, u32 palAttributes) : Render3DTexture(texAttributes, palAttributes)
|
||||
{
|
||||
_cacheSize = GetUnpackSizeUsingFormat(TexFormat_15bpp);
|
||||
_unpackData = (u32 *)malloc_alignedCacheLine(_cacheSize);
|
||||
|
@ -1599,7 +1661,7 @@ void SoftRasterizerRenderer::performBackfaceTests()
|
|||
const POLY &thePoly = *clippedPoly.poly;
|
||||
const PolygonType type = clippedPoly.type;
|
||||
const VERT *verts = &clippedPoly.clipVerts[0];
|
||||
const u8 cullingMode = thePoly.getAttributeEnableFaceCullingFlags();
|
||||
const u8 cullingMode = thePoly.attribute.SurfaceCullingMode;
|
||||
|
||||
//HACK: backface culling
|
||||
//this should be moved to gfx3d, but first we need to redo the way the lists are built
|
||||
|
@ -1714,7 +1776,15 @@ Render3DError SoftRasterizerRenderer::RenderGeometry(const GFX3D_State &renderSt
|
|||
}
|
||||
else
|
||||
{
|
||||
rasterizerUnit[0].mainLoop<false>();
|
||||
if (CommonSettings.GFX3D_LineHack)
|
||||
{
|
||||
rasterizerUnit[0].mainLoop<false, true>();
|
||||
}
|
||||
else
|
||||
{
|
||||
rasterizerUnit[0].mainLoop<false, false>();
|
||||
}
|
||||
|
||||
this->_renderGeometryNeedsFinish = false;
|
||||
texCache.Evict(); // Since we're finishing geometry rendering here and now, also check the texture cache now.
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ protected:
|
|||
u32 _renderWidthShift;
|
||||
|
||||
public:
|
||||
SoftRasterizerTexture(u32 texAttributes, u32 palAttributes);
|
||||
SoftRasterizerTexture(TEXIMAGE_PARAM texAttributes, u32 palAttributes);
|
||||
virtual ~SoftRasterizerTexture();
|
||||
|
||||
virtual void Load();
|
||||
|
|
|
@ -193,7 +193,7 @@ void FragmentAttributesBuffer::SetAll(const FragmentAttributes &attr)
|
|||
}
|
||||
}
|
||||
|
||||
Render3DTexture::Render3DTexture(u32 texAttributes, u32 palAttributes) : TextureStore(texAttributes, palAttributes)
|
||||
Render3DTexture::Render3DTexture(TEXIMAGE_PARAM texAttributes, u32 palAttributes) : TextureStore(texAttributes, palAttributes)
|
||||
{
|
||||
_isSamplingEnabled = true;
|
||||
_useDeposterize = false;
|
||||
|
|
|
@ -126,7 +126,7 @@ protected:
|
|||
template<size_t SCALEFACTOR> void _Upscale(const u32 *__restrict src, u32 *__restrict dst);
|
||||
|
||||
public:
|
||||
Render3DTexture(u32 texAttributes, u32 palAttributes);
|
||||
Render3DTexture(TEXIMAGE_PARAM texAttributes, u32 palAttributes);
|
||||
|
||||
bool IsSamplingEnabled() const;
|
||||
void SetSamplingEnabled(bool isEnabled);
|
||||
|
|
|
@ -321,7 +321,7 @@ void TextureCache::ForceReloadAllTextures()
|
|||
}
|
||||
}
|
||||
|
||||
TextureStore* TextureCache::GetTexture(u32 texAttributes, u32 palAttributes)
|
||||
TextureStore* TextureCache::GetTexture(TEXIMAGE_PARAM texAttributes, u32 palAttributes)
|
||||
{
|
||||
TextureStore *theTexture = NULL;
|
||||
const TextureCacheKey key = TextureCache::GenerateKey(texAttributes, palAttributes);
|
||||
|
@ -364,16 +364,16 @@ void TextureCache::Remove(TextureStore *texItem)
|
|||
this->_actualCacheSize -= texItem->GetCacheSize();
|
||||
}
|
||||
|
||||
TextureCacheKey TextureCache::GenerateKey(const u32 texAttributes, const u32 palAttributes)
|
||||
TextureCacheKey TextureCache::GenerateKey(const TEXIMAGE_PARAM texAttributes, const u32 palAttributes)
|
||||
{
|
||||
// Since the repeat, flip, and coordinate transformation modes are render settings
|
||||
// and not data settings, we can mask out those bits to help reduce duplicate entries.
|
||||
return (TextureCacheKey)( ((u64)palAttributes << 32) | (u64)(texAttributes & 0x3FF0FFFF) );
|
||||
return (TextureCacheKey)( ((u64)palAttributes << 32) | (u64)(texAttributes.value & 0x3FF0FFFF) );
|
||||
}
|
||||
|
||||
TextureStore::TextureStore()
|
||||
{
|
||||
_textureAttributes = 0;
|
||||
_textureAttributes.value = 0;
|
||||
_paletteAttributes = 0;
|
||||
_cacheKey = 0;
|
||||
|
||||
|
@ -406,7 +406,7 @@ TextureStore::TextureStore()
|
|||
_cacheUsageCount = 0;
|
||||
}
|
||||
|
||||
TextureStore::TextureStore(const u32 texAttributes, const u32 palAttributes)
|
||||
TextureStore::TextureStore(const TEXIMAGE_PARAM texAttributes, const u32 palAttributes)
|
||||
{
|
||||
//for each texformat, multiplier from numtexels to numbytes (fixed point 30.2)
|
||||
static const u32 texSizes[] = {0, 4, 1, 2, 4, 1, 4, 8};
|
||||
|
@ -418,16 +418,16 @@ TextureStore::TextureStore(const u32 texAttributes, const u32 palAttributes)
|
|||
_paletteAttributes = palAttributes;
|
||||
_cacheKey = TextureCache::GenerateKey(texAttributes, palAttributes);
|
||||
|
||||
_sizeS = (8 << ((texAttributes >> 20) & 0x07));
|
||||
_sizeT = (8 << ((texAttributes >> 23) & 0x07));
|
||||
_sizeS = (8 << texAttributes.SizeShiftS);
|
||||
_sizeT = (8 << texAttributes.SizeShiftT);
|
||||
|
||||
_packFormat = (NDSTextureFormat)((texAttributes >> 26) & 0x07);
|
||||
_packAddress = (texAttributes & 0xFFFF) << 3;
|
||||
_packFormat = (NDSTextureFormat)(texAttributes.PackedFormat);
|
||||
_packAddress = texAttributes.VRAMOffset << 3;
|
||||
_packSize = (_sizeS * _sizeT * texSizes[_packFormat]) >> 2; //shifted because the texSizes multiplier is fixed point
|
||||
|
||||
if ( (_packFormat == TEXMODE_I2) || (_packFormat == TEXMODE_I4) || (_packFormat == TEXMODE_I8) )
|
||||
{
|
||||
_isPalZeroTransparent = ( ((texAttributes >> 29) & 1) != 0 );
|
||||
_isPalZeroTransparent = (texAttributes.KeyColor0_Enable != 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -439,8 +439,8 @@ TextureStore::TextureStore(const u32 texAttributes, const u32 palAttributes)
|
|||
|
||||
if (_packFormat == TEXMODE_4X4)
|
||||
{
|
||||
const u32 indexBase = ((texAttributes & 0xC000) == 0x8000) ? 0x30000 : 0x20000;
|
||||
const u32 indexOffset = (texAttributes & 0x3FFF) << 2;
|
||||
const u32 indexBase = ((texAttributes.VRAMOffset & 0xC000) == 0x8000) ? 0x30000 : 0x20000;
|
||||
const u32 indexOffset = (texAttributes.VRAMOffset & 0x3FFF) << 2;
|
||||
_packIndexAddress = indexBase + indexOffset;
|
||||
_packIndexSize = (_sizeS * _sizeT) >> 3;
|
||||
|
||||
|
@ -502,7 +502,7 @@ TextureStore::~TextureStore()
|
|||
free_aligned(this->_packData);
|
||||
}
|
||||
|
||||
u32 TextureStore::GetTextureAttributes() const
|
||||
TEXIMAGE_PARAM TextureStore::GetTextureAttributes() const
|
||||
{
|
||||
return this->_textureAttributes;
|
||||
}
|
||||
|
@ -647,7 +647,7 @@ void TextureStore::Unpack(u32 *unpackBuffer)
|
|||
PROGINFO("Your 4x4 texture has overrun its texture slot.\n");
|
||||
}
|
||||
|
||||
NDSTextureUnpack4x4<TEXCACHEFORMAT>(this->_packSizeFirstSlot, (u32 *)this->_packData, (u16 *)this->_packIndexData, this->_paletteAddress, this->_textureAttributes, this->_sizeS, this->_sizeT, unpackBuffer);
|
||||
NDSTextureUnpack4x4<TEXCACHEFORMAT>(this->_packSizeFirstSlot, (u32 *)this->_packData, (u16 *)this->_packIndexData, this->_paletteAddress, this->_sizeS, this->_sizeT, unpackBuffer);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1164,7 +1164,7 @@ void NDSTextureUnpackA5I3(const size_t srcSize, const u8 *__restrict srcData, co
|
|||
#define PAL4X4(offset) ( LE_TO_LOCAL_16( *(u16*)( MMU.texInfo.texPalSlot[((palAddress + (offset)*2)>>14)&0x7] + ((palAddress + (offset)*2)&0x3FFF) ) ) & 0x7FFF )
|
||||
|
||||
template <TextureStoreUnpackFormat TEXCACHEFORMAT>
|
||||
void NDSTextureUnpack4x4(const size_t srcSize, const u32 *__restrict srcData, const u16 *__restrict srcIndex, const u32 palAddress, const u32 texAttributes, const u32 sizeX, const u32 sizeY, u32 *__restrict dstBuffer)
|
||||
void NDSTextureUnpack4x4(const size_t srcSize, const u32 *__restrict srcData, const u16 *__restrict srcIndex, const u32 palAddress, const u32 sizeX, const u32 sizeY, u32 *__restrict dstBuffer)
|
||||
{
|
||||
const u32 limit = srcSize * sizeof(u32);
|
||||
const u16 xTmpSize = sizeX >> 2;
|
||||
|
|
|
@ -76,18 +76,18 @@ public:
|
|||
void Reset();
|
||||
void ForceReloadAllTextures();
|
||||
|
||||
TextureStore* GetTexture(u32 texAttributes, u32 palAttributes);
|
||||
TextureStore* GetTexture(TEXIMAGE_PARAM texAttributes, u32 palAttributes);
|
||||
|
||||
void Add(TextureStore *texItem);
|
||||
void Remove(TextureStore *texItem);
|
||||
|
||||
static TextureCacheKey GenerateKey(const u32 texAttributes, const u32 palAttributes);
|
||||
static TextureCacheKey GenerateKey(const TEXIMAGE_PARAM texAttributes, const u32 palAttributes);
|
||||
};
|
||||
|
||||
class TextureStore
|
||||
{
|
||||
protected:
|
||||
u32 _textureAttributes;
|
||||
TEXIMAGE_PARAM _textureAttributes;
|
||||
u32 _paletteAttributes;
|
||||
|
||||
u32 _sizeS;
|
||||
|
@ -123,10 +123,10 @@ protected:
|
|||
|
||||
public:
|
||||
TextureStore();
|
||||
TextureStore(const u32 texAttributes, const u32 palAttributes);
|
||||
TextureStore(const TEXIMAGE_PARAM texAttributes, const u32 palAttributes);
|
||||
virtual ~TextureStore();
|
||||
|
||||
u32 GetTextureAttributes() const;
|
||||
TEXIMAGE_PARAM GetTextureAttributes() const;
|
||||
u32 GetPaletteAttributes() const;
|
||||
|
||||
u32 GetWidth() const;
|
||||
|
@ -187,7 +187,7 @@ template<TextureStoreUnpackFormat TEXCACHEFORMAT> void NDSTextureUnpackI4(const
|
|||
template<TextureStoreUnpackFormat TEXCACHEFORMAT> void NDSTextureUnpackI8(const size_t srcSize, const u8 *__restrict srcData, const u16 *__restrict srcPal, const bool isPalZeroTransparent, u32 *__restrict dstBuffer);
|
||||
template<TextureStoreUnpackFormat TEXCACHEFORMAT> void NDSTextureUnpackA3I5(const size_t srcSize, const u8 *__restrict srcData, const u16 *__restrict srcPal, u32 *__restrict dstBuffer);
|
||||
template<TextureStoreUnpackFormat TEXCACHEFORMAT> void NDSTextureUnpackA5I3(const size_t srcSize, const u8 *__restrict srcData, const u16 *__restrict srcPal, u32 *__restrict dstBuffer);
|
||||
template<TextureStoreUnpackFormat TEXCACHEFORMAT> void NDSTextureUnpack4x4(const size_t srcSize, const u32 *__restrict srcData, const u16 *__restrict srcIndex, const u32 palAddress, const u32 texAttributes, const u32 sizeX, const u32 sizeY, u32 *__restrict dstBuffer);
|
||||
template<TextureStoreUnpackFormat TEXCACHEFORMAT> void NDSTextureUnpack4x4(const size_t srcSize, const u32 *__restrict srcData, const u16 *__restrict srcIndex, const u32 palAddress, const u32 sizeX, const u32 sizeY, u32 *__restrict dstBuffer);
|
||||
template<TextureStoreUnpackFormat TEXCACHEFORMAT> void NDSTextureUnpackDirect16Bit(const size_t srcSize, const u16 *__restrict srcData, u32 *__restrict dstBuffer);
|
||||
|
||||
extern TextureCache texCache;
|
||||
|
|
Loading…
Reference in New Issue