OpenGL Renderer:
- Texture sampling now works with bilinear filtering, mipmapping, and anisotropic filtering! These texture smoothing features can be used by enabling the new CommonSettings.GFX3D_Renderer_TextureSmoothing flag.
This commit is contained in:
parent
ce5765006f
commit
9a9f006397
|
@ -483,8 +483,9 @@ extern struct TCommonSettings {
|
|||
, GFX3D_LineHack(true)
|
||||
, GFX3D_Zelda_Shadow_Depth_Hack(0)
|
||||
, GFX3D_Renderer_Multisample(false)
|
||||
, GFX3D_Renderer_TextureDeposterize(false)
|
||||
, GFX3D_Renderer_TextureScalingFactor(1) // Possible values: 1, 2, 4
|
||||
, GFX3D_Renderer_TextureDeposterize(false)
|
||||
, GFX3D_Renderer_TextureSmoothing(false)
|
||||
, GFX3D_TXTHack(false)
|
||||
, GFX3D_PrescaleHD(1)
|
||||
, jit_max_block_size(100)
|
||||
|
@ -545,8 +546,9 @@ extern struct TCommonSettings {
|
|||
bool GFX3D_LineHack;
|
||||
int GFX3D_Zelda_Shadow_Depth_Hack;
|
||||
bool GFX3D_Renderer_Multisample;
|
||||
bool GFX3D_Renderer_TextureDeposterize;
|
||||
int GFX3D_Renderer_TextureScalingFactor;
|
||||
bool GFX3D_Renderer_TextureDeposterize;
|
||||
bool GFX3D_Renderer_TextureSmoothing;
|
||||
bool GFX3D_TXTHack;
|
||||
|
||||
//may not want this on OSX port
|
||||
|
|
|
@ -293,10 +293,11 @@ static const char *fragmentShader_100 = {"\
|
|||
uniform int polyMode; \n\
|
||||
uniform bool polyEnableDepthWrite;\n\
|
||||
uniform bool polySetNewDepthForTranslucent;\n\
|
||||
uniform int polyID; \n\
|
||||
uniform int polyID;\n\
|
||||
\n\
|
||||
uniform bool polyEnableTexture; \n\
|
||||
uniform bool polyEnableTexture;\n\
|
||||
uniform bool polyEnableFog;\n\
|
||||
uniform bool texSingleBitAlpha;\n\
|
||||
\n\
|
||||
vec3 packVec3FromFloat(const float value)\n\
|
||||
{\n\
|
||||
|
@ -308,6 +309,20 @@ static const char *fragmentShader_100 = {"\
|
|||
void main() \n\
|
||||
{ \n\
|
||||
vec4 mainTexColor = (polyEnableTexture) ? texture2D(texRenderObject, vtxTexCoord) : vec4(1.0, 1.0, 1.0, 1.0); \n\
|
||||
\n\
|
||||
if (texSingleBitAlpha)\n\
|
||||
{\n\
|
||||
if (mainTexColor.a < 0.500)\n\
|
||||
{\n\
|
||||
mainTexColor.a = 0.0;\n\
|
||||
}\n\
|
||||
else\n\
|
||||
{\n\
|
||||
mainTexColor.rgb = mainTexColor.rgb / mainTexColor.a;\n\
|
||||
mainTexColor.a = 1.0;\n\
|
||||
}\n\
|
||||
}\n\
|
||||
\n\
|
||||
vec4 newFragColor = mainTexColor * vtxColor; \n\
|
||||
\n\
|
||||
if(polyMode == 1) \n\
|
||||
|
@ -328,7 +343,7 @@ static const char *fragmentShader_100 = {"\
|
|||
} \n\
|
||||
} \n\
|
||||
\n\
|
||||
if (newFragColor.a == 0.0 || (stateEnableAlphaTest && newFragColor.a < stateAlphaTestRef)) \n\
|
||||
if (newFragColor.a < 0.001 || (stateEnableAlphaTest && newFragColor.a < stateAlphaTestRef)) \n\
|
||||
{ \n\
|
||||
discard; \n\
|
||||
} \n\
|
||||
|
@ -902,8 +917,15 @@ GPU3DInterface gpu3Dgl_3_2 = {
|
|||
|
||||
OpenGLRenderer::OpenGLRenderer()
|
||||
{
|
||||
_renderID = RENDERID_OPENGL_AUTO;
|
||||
_renderName = "OpenGL";
|
||||
_deviceInfo.renderID = RENDERID_OPENGL_AUTO;
|
||||
_deviceInfo.renderName = "OpenGL";
|
||||
_deviceInfo.isTexturingSupported = true;
|
||||
_deviceInfo.isEdgeMarkSupported = true;
|
||||
_deviceInfo.isFogSupported = true;
|
||||
_deviceInfo.isTextureSmoothingSupported = true;
|
||||
_deviceInfo.maxAnisotropy = 1.0f;
|
||||
_deviceInfo.maxSamples = 0;
|
||||
|
||||
_internalRenderingFormat = NDSColorFormat_BGR888_Rev;
|
||||
|
||||
versionMajor = 0;
|
||||
|
@ -1361,6 +1383,15 @@ Render3DError OpenGLRenderer_1_2::InitExtensions()
|
|||
std::set<std::string> oglExtensionSet;
|
||||
this->GetExtensionSet(&oglExtensionSet);
|
||||
|
||||
// Get host GPU device properties
|
||||
GLfloat maxAnisotropyOGL = 1.0f;
|
||||
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropyOGL);
|
||||
this->_deviceInfo.maxAnisotropy = maxAnisotropyOGL;
|
||||
|
||||
GLint maxSamplesOGL = 0;
|
||||
glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSamplesOGL);
|
||||
this->_deviceInfo.maxSamples = (u8)maxSamplesOGL;
|
||||
|
||||
// Initialize OpenGL
|
||||
this->InitTables();
|
||||
|
||||
|
@ -1395,21 +1426,32 @@ Render3DError OpenGLRenderer_1_2::InitExtensions()
|
|||
framebufferOutputRGBA8888FragShaderString);
|
||||
if (error != OGLERROR_NOERR)
|
||||
{
|
||||
this->_deviceInfo.isEdgeMarkSupported = false;
|
||||
this->_deviceInfo.isFogSupported = false;
|
||||
INFO("OpenGL: Edge mark and fog require OpenGL v2.0 or later. These features will be disabled.\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this->_deviceInfo.isEdgeMarkSupported = false;
|
||||
this->_deviceInfo.isFogSupported = false;
|
||||
this->_deviceInfo.isTextureSmoothingSupported = false;
|
||||
this->isShaderSupported = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this->_deviceInfo.isEdgeMarkSupported = false;
|
||||
this->_deviceInfo.isFogSupported = false;
|
||||
this->_deviceInfo.isTextureSmoothingSupported = false;
|
||||
this->isShaderSupported = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this->_deviceInfo.isEdgeMarkSupported = false;
|
||||
this->_deviceInfo.isFogSupported = false;
|
||||
this->_deviceInfo.isTextureSmoothingSupported = false;
|
||||
INFO("OpenGL: Shaders are unsupported. Disabling shaders and using fixed-function pipeline. Some emulation features will be disabled.\n");
|
||||
}
|
||||
|
||||
|
@ -1600,6 +1642,7 @@ Render3DError OpenGLRenderer_1_2::InitGeometryProgramShaderLocations()
|
|||
|
||||
OGLRef.uniformPolyEnableTexture = glGetUniformLocation(OGLRef.programGeometryID, "polyEnableTexture");
|
||||
OGLRef.uniformPolyEnableFog = glGetUniformLocation(OGLRef.programGeometryID, "polyEnableFog");
|
||||
OGLRef.uniformTexSingleBitAlpha = glGetUniformLocation(OGLRef.programGeometryID, "texSingleBitAlpha");
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
@ -2058,8 +2101,7 @@ Render3DError OpenGLRenderer_1_2::CreateMultisampledFBO()
|
|||
// Check the maximum number of samples that the driver supports and use that.
|
||||
// Since our target resolution is only 256x192 pixels, using the most samples
|
||||
// possible is the best thing to do.
|
||||
GLint maxSamples = 0;
|
||||
glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSamples);
|
||||
GLint maxSamples = (GLint)this->_deviceInfo.maxSamples;
|
||||
|
||||
if (maxSamples < 2)
|
||||
{
|
||||
|
@ -3071,6 +3113,7 @@ Render3DError OpenGLRenderer_1_2::SetupTexture(const POLY &thePoly, bool enableT
|
|||
if (this->isShaderSupported)
|
||||
{
|
||||
glUniform1i(OGLRef.uniformPolyEnableTexture, GL_FALSE);
|
||||
glUniform1i(OGLRef.uniformTexSingleBitAlpha, GL_FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3084,6 +3127,7 @@ Render3DError OpenGLRenderer_1_2::SetupTexture(const POLY &thePoly, bool enableT
|
|||
if (this->isShaderSupported)
|
||||
{
|
||||
glUniform1i(OGLRef.uniformPolyEnableTexture, GL_TRUE);
|
||||
glUniform1i(OGLRef.uniformTexSingleBitAlpha, (params.texFormat != TEXMODE_A3I5 && params.texFormat != TEXMODE_A5I3) ? GL_TRUE : GL_FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3108,8 +3152,6 @@ Render3DError OpenGLRenderer_1_2::SetupTexture(const POLY &thePoly, bool enableT
|
|||
OGLRef.freeTextureIDs.pop();
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, (GLuint)this->currTexture->texid);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (params.enableRepeatS ? (params.enableMirroredRepeatS ? OGLRef.stateTexMirroredRepeat : GL_REPEAT) : GL_CLAMP_TO_EDGE));
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (params.enableRepeatT ? (params.enableMirroredRepeatT ? OGLRef.stateTexMirroredRepeat : GL_REPEAT) : GL_CLAMP_TO_EDGE));
|
||||
|
||||
|
@ -3125,25 +3167,81 @@ Render3DError OpenGLRenderer_1_2::SetupTexture(const POLY &thePoly, bool enableT
|
|||
|
||||
switch (this->_textureScalingFactor)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (this->_textureSmooth) ? GL_LINEAR : GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (this->_textureSmooth) ? GL_LINEAR : GL_NEAREST);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (this->_textureSmooth) ? this->_deviceInfo.maxAnisotropy : 1.0f);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureSrc);
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
if (this->_textureSmooth)
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, this->_deviceInfo.maxAnisotropy);
|
||||
|
||||
this->TextureUpscale<2>(textureSrc, texWidth, texHeight);
|
||||
textureSrc = this->_textureUpscaleBuffer;
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, this->_textureUpscaleBuffer);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, currTexture->sizeX, currTexture->sizeY, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureSrc);
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f);
|
||||
|
||||
this->TextureUpscale<2>(textureSrc, texWidth, texHeight);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, this->_textureUpscaleBuffer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 4:
|
||||
{
|
||||
if (this->_textureSmooth)
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, this->_deviceInfo.maxAnisotropy);
|
||||
|
||||
this->TextureUpscale<4>(textureSrc, texWidth, texHeight);
|
||||
textureSrc = this->_textureUpscaleBuffer;
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, this->_textureUpscaleBuffer);
|
||||
|
||||
texWidth = currTexture->sizeX;
|
||||
texHeight = currTexture->sizeY;
|
||||
this->TextureUpscale<2>(textureSrc, texWidth, texHeight);
|
||||
glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, this->_textureUpscaleBuffer);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, currTexture->sizeX, currTexture->sizeY, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureSrc);
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f);
|
||||
|
||||
this->TextureUpscale<4>(textureSrc, texWidth, texHeight);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, this->_textureUpscaleBuffer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureSrc);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3313,8 +3411,7 @@ Render3DError OpenGLRenderer_1_2::SetFramebufferSize(size_t w, size_t h)
|
|||
|
||||
if (this->isMultisampledFBOSupported)
|
||||
{
|
||||
GLint maxSamples = 0;
|
||||
glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSamples);
|
||||
GLint maxSamples = (GLint)this->_deviceInfo.maxSamples;
|
||||
|
||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, OGLRef.rboMSGColorID);
|
||||
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, maxSamples, GL_RGBA, w, h);
|
||||
|
@ -3493,8 +3590,7 @@ Render3DError OpenGLRenderer_1_3::SetFramebufferSize(size_t w, size_t h)
|
|||
|
||||
if (this->isMultisampledFBOSupported)
|
||||
{
|
||||
GLint maxSamples = 0;
|
||||
glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSamples);
|
||||
GLint maxSamples = (GLint)this->_deviceInfo.maxSamples;
|
||||
|
||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, OGLRef.rboMSGColorID);
|
||||
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, maxSamples, GL_RGBA, w, h);
|
||||
|
@ -3819,6 +3915,15 @@ Render3DError OpenGLRenderer_2_0::InitExtensions()
|
|||
std::set<std::string> oglExtensionSet;
|
||||
this->GetExtensionSet(&oglExtensionSet);
|
||||
|
||||
// Get host GPU device properties
|
||||
GLfloat maxAnisotropyOGL = 1.0f;
|
||||
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropyOGL);
|
||||
this->_deviceInfo.maxAnisotropy = maxAnisotropyOGL;
|
||||
|
||||
GLint maxSamplesOGL = 0;
|
||||
glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSamplesOGL);
|
||||
this->_deviceInfo.maxSamples = (u8)maxSamplesOGL;
|
||||
|
||||
// Initialize OpenGL
|
||||
this->InitTables();
|
||||
|
||||
|
@ -3859,6 +3964,8 @@ Render3DError OpenGLRenderer_2_0::InitExtensions()
|
|||
{
|
||||
this->DestroyGeometryProgram();
|
||||
this->isShaderSupported = false;
|
||||
this->_deviceInfo.isEdgeMarkSupported = false;
|
||||
this->_deviceInfo.isFogSupported = false;
|
||||
}
|
||||
|
||||
this->isVBOSupported = true;
|
||||
|
@ -4694,10 +4801,12 @@ Render3DError OpenGLRenderer_2_0::SetupTexture(const POLY &thePoly, bool enableT
|
|||
if (params.texFormat == TEXMODE_NONE || !enableTexturing)
|
||||
{
|
||||
glUniform1i(OGLRef.uniformPolyEnableTexture, GL_FALSE);
|
||||
glUniform1i(OGLRef.uniformTexSingleBitAlpha, GL_FALSE);
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
glUniform1i(OGLRef.uniformPolyEnableTexture, GL_TRUE);
|
||||
glUniform1i(OGLRef.uniformTexSingleBitAlpha, (params.texFormat != TEXMODE_A3I5 && params.texFormat != TEXMODE_A5I3) ? GL_TRUE : GL_FALSE);
|
||||
|
||||
TexCacheItem *newTexture = TexCache_SetTexture(TexFormat_32bpp, thePoly.texParam, thePoly.texPalette);
|
||||
if(newTexture != this->currTexture)
|
||||
|
@ -4717,8 +4826,6 @@ Render3DError OpenGLRenderer_2_0::SetupTexture(const POLY &thePoly, bool enableT
|
|||
OGLRef.freeTextureIDs.pop();
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, (GLuint)this->currTexture->texid);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (params.enableRepeatS ? (params.enableMirroredRepeatS ? GL_MIRRORED_REPEAT : GL_REPEAT) : GL_CLAMP_TO_EDGE));
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (params.enableRepeatT ? (params.enableMirroredRepeatT ? GL_MIRRORED_REPEAT : GL_REPEAT) : GL_CLAMP_TO_EDGE));
|
||||
|
||||
|
@ -4734,25 +4841,81 @@ Render3DError OpenGLRenderer_2_0::SetupTexture(const POLY &thePoly, bool enableT
|
|||
|
||||
switch (this->_textureScalingFactor)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (this->_textureSmooth) ? GL_LINEAR : GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (this->_textureSmooth) ? GL_LINEAR : GL_NEAREST);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (this->_textureSmooth) ? this->_deviceInfo.maxAnisotropy : 1.0f);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureSrc);
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
if (this->_textureSmooth)
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, this->_deviceInfo.maxAnisotropy);
|
||||
|
||||
this->TextureUpscale<2>(textureSrc, texWidth, texHeight);
|
||||
textureSrc = this->_textureUpscaleBuffer;
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, this->_textureUpscaleBuffer);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, currTexture->sizeX, currTexture->sizeY, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureSrc);
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f);
|
||||
|
||||
this->TextureUpscale<2>(textureSrc, texWidth, texHeight);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, this->_textureUpscaleBuffer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 4:
|
||||
{
|
||||
if (this->_textureSmooth)
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, this->_deviceInfo.maxAnisotropy);
|
||||
|
||||
this->TextureUpscale<4>(textureSrc, texWidth, texHeight);
|
||||
textureSrc = this->_textureUpscaleBuffer;
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, this->_textureUpscaleBuffer);
|
||||
|
||||
texWidth = currTexture->sizeX;
|
||||
texHeight = currTexture->sizeY;
|
||||
this->TextureUpscale<2>(textureSrc, texWidth, texHeight);
|
||||
glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, this->_textureUpscaleBuffer);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, currTexture->sizeX, currTexture->sizeY, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureSrc);
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f);
|
||||
|
||||
this->TextureUpscale<4>(textureSrc, texWidth, texHeight);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, this->_textureUpscaleBuffer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureSrc);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -389,7 +389,7 @@ struct OGLPolyStates
|
|||
|
||||
union
|
||||
{
|
||||
struct { GLubyte texSizeS, texSizeT, texParamPad[2]; };
|
||||
struct { GLubyte texSizeS, texSizeT, texSingleBitAlpha, texParamPad[1]; };
|
||||
GLubyte texParam[4];
|
||||
};
|
||||
};
|
||||
|
@ -481,6 +481,7 @@ struct OGLRenderRef
|
|||
|
||||
GLint uniformPolyEnableTexture;
|
||||
GLint uniformPolyEnableFog;
|
||||
GLint uniformTexSingleBitAlpha;
|
||||
|
||||
GLint uniformPolyStateIndex;
|
||||
|
||||
|
|
|
@ -122,6 +122,7 @@ static const char *GeometryVtxShader_150 = {"\
|
|||
flat out uint polySetNewDepthForTranslucent;\n\
|
||||
flat out uint polyMode;\n\
|
||||
flat out uint polyID;\n\
|
||||
flat out uint texSingleBitAlpha;\n\
|
||||
\n\
|
||||
void main() \n\
|
||||
{ \n\
|
||||
|
@ -138,6 +139,7 @@ static const char *GeometryVtxShader_150 = {"\
|
|||
polySetNewDepthForTranslucent = polyStateFlags[3];\n\
|
||||
polyMode = polyStateValues[1];\n\
|
||||
polyID = polyStateValues[2];\n\
|
||||
texSingleBitAlpha = polyStateTexParams[2];\n\
|
||||
\n\
|
||||
mat2 texScaleMtx = mat2( vec2(polyTexScale.x, 0.0), \n\
|
||||
vec2( 0.0, polyTexScale.y)); \n\
|
||||
|
@ -163,6 +165,7 @@ static const char *GeometryFragShader_150 = {"\
|
|||
flat in uint polySetNewDepthForTranslucent;\n\
|
||||
flat in uint polyMode;\n\
|
||||
flat in uint polyID;\n\
|
||||
flat in uint texSingleBitAlpha;\n\
|
||||
\n\
|
||||
layout (std140) uniform RenderStates\n\
|
||||
{\n\
|
||||
|
@ -202,6 +205,20 @@ static const char *GeometryFragShader_150 = {"\
|
|||
void main() \n\
|
||||
{ \n\
|
||||
vec4 mainTexColor = bool(polyEnableTexture) ? texture(texRenderObject, vtxTexCoord) : vec4(1.0, 1.0, 1.0, 1.0);\n\
|
||||
\n\
|
||||
if (bool(texSingleBitAlpha))\n\
|
||||
{\n\
|
||||
if (mainTexColor.a < 0.500)\n\
|
||||
{\n\
|
||||
mainTexColor.a = 0.0;\n\
|
||||
}\n\
|
||||
else\n\
|
||||
{\n\
|
||||
mainTexColor.rgb = mainTexColor.rgb / mainTexColor.a;\n\
|
||||
mainTexColor.a = 1.0;\n\
|
||||
}\n\
|
||||
}\n\
|
||||
\n\
|
||||
vec4 newFragColor = mainTexColor * vtxColor; \n\
|
||||
\n\
|
||||
if (polyMode == 1u) \n\
|
||||
|
@ -222,10 +239,10 @@ static const char *GeometryFragShader_150 = {"\
|
|||
} \n\
|
||||
} \n\
|
||||
\n\
|
||||
if (newFragColor.a == 0.0 || (state.enableAlphaTest && newFragColor.a < state.alphaTestRef)) \n\
|
||||
{ \n\
|
||||
discard; \n\
|
||||
} \n\
|
||||
if (newFragColor.a < 0.001 || (state.enableAlphaTest && newFragColor.a < state.alphaTestRef))\n\
|
||||
{\n\
|
||||
discard;\n\
|
||||
}\n\
|
||||
\n\
|
||||
float vertW = (vtxPosition.w == 0.0) ? 0.00000001 : vtxPosition.w; \n\
|
||||
// hack: when using z-depth, drop some LSBs so that the overworld map in Dragon Quest IV shows up correctly\n\
|
||||
|
@ -502,6 +519,18 @@ Render3DError OpenGLRenderer_3_2::InitExtensions()
|
|||
std::set<std::string> oglExtensionSet;
|
||||
this->GetExtensionSet(&oglExtensionSet);
|
||||
|
||||
// Get host GPU device properties
|
||||
GLfloat maxAnisotropyOGL = 1.0f;
|
||||
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropyOGL);
|
||||
this->_deviceInfo.maxAnisotropy = (float)maxAnisotropyOGL;
|
||||
|
||||
GLint maxSamplesOGL = 0;
|
||||
glGetIntegerv(GL_MAX_SAMPLES, &maxSamplesOGL);
|
||||
this->_deviceInfo.maxSamples = (u8)maxSamplesOGL;
|
||||
|
||||
_deviceInfo.isEdgeMarkSupported = true;
|
||||
_deviceInfo.isFogSupported = true;
|
||||
|
||||
// Initialize OpenGL
|
||||
this->InitTables();
|
||||
|
||||
|
@ -955,8 +984,7 @@ Render3DError OpenGLRenderer_3_2::CreateMultisampledFBO()
|
|||
// Check the maximum number of samples that the GPU supports and use that.
|
||||
// Since our target resolution is only 256x192 pixels, using the most samples
|
||||
// possible is the best thing to do.
|
||||
GLint maxSamples = 0;
|
||||
glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
|
||||
GLint maxSamples = (GLint)this->_deviceInfo.maxSamples;
|
||||
|
||||
if (maxSamples < 2)
|
||||
{
|
||||
|
@ -1387,6 +1415,7 @@ Render3DError OpenGLRenderer_3_2::BeginRender(const GFX3D &engine)
|
|||
polyStates[i].polyID = polyAttr.polygonID;
|
||||
polyStates[i].texSizeS = texParams.sizeS;
|
||||
polyStates[i].texSizeT = texParams.sizeT;
|
||||
polyStates[i].texSingleBitAlpha = (texParams.texFormat != TEXMODE_A3I5 && texParams.texFormat != TEXMODE_A5I3) ? GL_TRUE : GL_FALSE;
|
||||
|
||||
for (size_t j = 0; j < polyType; j++)
|
||||
{
|
||||
|
@ -1684,8 +1713,6 @@ Render3DError OpenGLRenderer_3_2::SetupTexture(const POLY &thePoly, bool enableT
|
|||
OGLRef.freeTextureIDs.pop();
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, (GLuint)this->currTexture->texid);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (params.enableRepeatS ? (params.enableMirroredRepeatS ? GL_MIRRORED_REPEAT : GL_REPEAT) : GL_CLAMP_TO_EDGE));
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (params.enableRepeatT ? (params.enableMirroredRepeatT ? GL_MIRRORED_REPEAT : GL_REPEAT) : GL_CLAMP_TO_EDGE));
|
||||
|
||||
|
@ -1701,25 +1728,81 @@ Render3DError OpenGLRenderer_3_2::SetupTexture(const POLY &thePoly, bool enableT
|
|||
|
||||
switch (this->_textureScalingFactor)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (this->_textureSmooth) ? GL_LINEAR : GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (this->_textureSmooth) ? GL_LINEAR : GL_NEAREST);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (this->_textureSmooth) ? this->_deviceInfo.maxAnisotropy : 1.0f);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureSrc);
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
if (this->_textureSmooth)
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, this->_deviceInfo.maxAnisotropy);
|
||||
|
||||
this->TextureUpscale<2>(textureSrc, texWidth, texHeight);
|
||||
textureSrc = this->_textureUpscaleBuffer;
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, this->_textureUpscaleBuffer);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, currTexture->sizeX, currTexture->sizeY, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureSrc);
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f);
|
||||
|
||||
this->TextureUpscale<2>(textureSrc, texWidth, texHeight);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, this->_textureUpscaleBuffer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 4:
|
||||
{
|
||||
if (this->_textureSmooth)
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, this->_deviceInfo.maxAnisotropy);
|
||||
|
||||
this->TextureUpscale<4>(textureSrc, texWidth, texHeight);
|
||||
textureSrc = this->_textureUpscaleBuffer;
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, this->_textureUpscaleBuffer);
|
||||
|
||||
texWidth = currTexture->sizeX;
|
||||
texHeight = currTexture->sizeY;
|
||||
this->TextureUpscale<2>(textureSrc, texWidth, texHeight);
|
||||
glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, this->_textureUpscaleBuffer);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, currTexture->sizeX, currTexture->sizeY, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureSrc);
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f);
|
||||
|
||||
this->TextureUpscale<4>(textureSrc, texWidth, texHeight);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, this->_textureUpscaleBuffer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureSrc);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1779,8 +1862,7 @@ Render3DError OpenGLRenderer_3_2::SetFramebufferSize(size_t w, size_t h)
|
|||
|
||||
if (this->isMultisampledFBOSupported)
|
||||
{
|
||||
GLint maxSamples = 0;
|
||||
glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
|
||||
GLint maxSamples = (GLint)this->_deviceInfo.maxSamples;
|
||||
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, OGLRef.rboMSGColorID);
|
||||
glRenderbufferStorageMultisample(GL_RENDERBUFFER, maxSamples, GL_RGBA, w, h);
|
||||
|
|
|
@ -2336,7 +2336,9 @@ void gfx3d_VBlankEndSignal(bool skipFrame)
|
|||
if (CommonSettings.showGpu.main)
|
||||
{
|
||||
CurrentRenderer->SetRenderNeedsFinish(true);
|
||||
CurrentRenderer->SetTextureProcessingProperties(CommonSettings.GFX3D_Renderer_TextureDeposterize, CommonSettings.GFX3D_Renderer_TextureScalingFactor);
|
||||
CurrentRenderer->SetTextureProcessingProperties(CommonSettings.GFX3D_Renderer_TextureScalingFactor,
|
||||
CommonSettings.GFX3D_Renderer_TextureDeposterize,
|
||||
CommonSettings.GFX3D_Renderer_TextureSmoothing);
|
||||
CurrentRenderer->Render(gfx3d);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -1165,8 +1165,14 @@ GPU3DInterface gpu3DRasterize = {
|
|||
|
||||
SoftRasterizerRenderer::SoftRasterizerRenderer()
|
||||
{
|
||||
_renderID = RENDERID_SOFTRASTERIZER;
|
||||
_renderName = "SoftRasterizer";
|
||||
_deviceInfo.renderID = RENDERID_SOFTRASTERIZER;
|
||||
_deviceInfo.renderName = "SoftRasterizer";
|
||||
_deviceInfo.isTexturingSupported = true;
|
||||
_deviceInfo.isEdgeMarkSupported = true;
|
||||
_deviceInfo.isFogSupported = true;
|
||||
_deviceInfo.isTextureSmoothingSupported = false;
|
||||
_deviceInfo.maxAnisotropy = 1.0f;
|
||||
_deviceInfo.maxSamples = 0;
|
||||
|
||||
_debug_drawClippedUserPoly = -1;
|
||||
clippedPolys = clipper.clippedPolys = new GFX3D_Clipper::TClippedPoly[POLYLIST_SIZE*2];
|
||||
|
|
|
@ -265,8 +265,14 @@ void Render3D::operator delete(void *ptr)
|
|||
|
||||
Render3D::Render3D()
|
||||
{
|
||||
_renderID = RENDERID_NULL;
|
||||
_renderName = "None";
|
||||
_deviceInfo.renderID = RENDERID_NULL;
|
||||
_deviceInfo.renderName = "None";
|
||||
_deviceInfo.isTexturingSupported = false;
|
||||
_deviceInfo.isEdgeMarkSupported = false;
|
||||
_deviceInfo.isFogSupported = false;
|
||||
_deviceInfo.isTextureSmoothingSupported = false;
|
||||
_deviceInfo.maxAnisotropy = 1.0f;
|
||||
_deviceInfo.maxSamples = 0;
|
||||
|
||||
static bool needTableInit = true;
|
||||
|
||||
|
@ -292,6 +298,7 @@ Render3D::Render3D()
|
|||
_willFlushFramebufferRGBA5551 = true;
|
||||
|
||||
_textureScalingFactor = 1;
|
||||
_textureSmooth = false;
|
||||
_textureDeposterizeBuffer = NULL;
|
||||
_textureUpscaleBuffer = NULL;
|
||||
|
||||
|
@ -303,14 +310,19 @@ Render3D::~Render3D()
|
|||
// Do nothing.
|
||||
}
|
||||
|
||||
const Render3DDeviceInfo& Render3D::GetDeviceInfo()
|
||||
{
|
||||
return this->_deviceInfo;
|
||||
}
|
||||
|
||||
RendererID Render3D::GetRenderID()
|
||||
{
|
||||
return this->_renderID;
|
||||
return this->_deviceInfo.renderID;
|
||||
}
|
||||
|
||||
std::string Render3D::GetName()
|
||||
{
|
||||
return this->_renderName;
|
||||
return this->_deviceInfo.renderName;
|
||||
}
|
||||
|
||||
FragmentColor* Render3D::GetFramebuffer()
|
||||
|
@ -381,7 +393,7 @@ void Render3D::SetRenderNeedsFinish(const bool renderNeedsFinish)
|
|||
this->_renderNeedsFinish = renderNeedsFinish;
|
||||
}
|
||||
|
||||
void Render3D::SetTextureProcessingProperties(bool willDeposterize, size_t scalingFactor)
|
||||
void Render3D::SetTextureProcessingProperties(size_t scalingFactor, bool willDeposterize, bool willSmooth)
|
||||
{
|
||||
const bool isScaleValid = ( (scalingFactor == 2) || (scalingFactor == 4) );
|
||||
const size_t newScalingFactor = (isScaleValid) ? scalingFactor : 1;
|
||||
|
@ -416,6 +428,13 @@ void Render3D::SetTextureProcessingProperties(bool willDeposterize, size_t scali
|
|||
needTexCacheReset = true;
|
||||
}
|
||||
|
||||
if (willSmooth != this->_textureSmooth)
|
||||
{
|
||||
this->_textureSmooth = willSmooth;
|
||||
|
||||
needTexCacheReset = true;
|
||||
}
|
||||
|
||||
if (needTexCacheReset)
|
||||
{
|
||||
TexCache_Reset();
|
||||
|
|
|
@ -98,11 +98,24 @@ struct FragmentAttributesBuffer
|
|||
void SetAll(const FragmentAttributes &attr);
|
||||
};
|
||||
|
||||
struct Render3DDeviceInfo
|
||||
{
|
||||
RendererID renderID;
|
||||
std::string renderName;
|
||||
|
||||
bool isTexturingSupported;
|
||||
bool isEdgeMarkSupported;
|
||||
bool isFogSupported;
|
||||
bool isTextureSmoothingSupported;
|
||||
|
||||
float maxAnisotropy;
|
||||
u8 maxSamples;
|
||||
};
|
||||
|
||||
class Render3D
|
||||
{
|
||||
protected:
|
||||
RendererID _renderID;
|
||||
std::string _renderName;
|
||||
Render3DDeviceInfo _deviceInfo;
|
||||
|
||||
size_t _framebufferWidth;
|
||||
size_t _framebufferHeight;
|
||||
|
@ -116,6 +129,7 @@ protected:
|
|||
bool _willFlushFramebufferRGBA5551;
|
||||
|
||||
size_t _textureScalingFactor;
|
||||
bool _textureSmooth;
|
||||
u32 *_textureDeposterizeBuffer;
|
||||
u32 *_textureUpscaleBuffer;
|
||||
|
||||
|
@ -147,6 +161,7 @@ public:
|
|||
Render3D();
|
||||
~Render3D();
|
||||
|
||||
const Render3DDeviceInfo& GetDeviceInfo();
|
||||
RendererID GetRenderID();
|
||||
std::string GetName();
|
||||
|
||||
|
@ -179,7 +194,7 @@ public:
|
|||
bool GetRenderNeedsFinish() const;
|
||||
void SetRenderNeedsFinish(const bool renderNeedsFinish);
|
||||
|
||||
void SetTextureProcessingProperties(bool willDeposterize, size_t scalingFactor);
|
||||
void SetTextureProcessingProperties(size_t scalingFactor, bool willDeposterize, bool willSmooth);
|
||||
};
|
||||
|
||||
#ifdef ENABLE_SSE2
|
||||
|
|
|
@ -399,6 +399,10 @@ public:
|
|||
//Texture conversion
|
||||
//============================================================================
|
||||
|
||||
// Whenever a 1-bit alpha or no-alpha texture is unpacked (this means any texture
|
||||
// format that is not A3I5 or A5I3), set all transparent pixels to 0 so that 3D
|
||||
// renderers can assume that the transparent color is 0 during texture sampling.
|
||||
|
||||
const u8 opaqueColor = (TEXFORMAT == TexFormat_32bpp) ? 0xFF : 0x1F;
|
||||
const u8 palZeroTransparent = ( 1 - ((format>>29) & 1) ) * opaqueColor;
|
||||
|
||||
|
@ -406,7 +410,8 @@ public:
|
|||
{
|
||||
case TEXMODE_A3I5:
|
||||
{
|
||||
for(int j=0;j<ms.numItems;j++) {
|
||||
for(int j=0;j<ms.numItems;j++)
|
||||
{
|
||||
adr = ms.items[j].ptr;
|
||||
for(u32 x = 0; x < ms.items[j].len; x++)
|
||||
{
|
||||
|
@ -424,7 +429,10 @@ public:
|
|||
|
||||
case TEXMODE_I2:
|
||||
{
|
||||
for(int j=0;j<ms.numItems;j++) {
|
||||
if (palZeroTransparent == 0)
|
||||
{
|
||||
for(int j=0;j<ms.numItems;j++)
|
||||
{
|
||||
adr = ms.items[j].ptr;
|
||||
for(u32 x = 0; x < ms.items[j].len; x++)
|
||||
{
|
||||
|
@ -433,28 +441,63 @@ public:
|
|||
|
||||
bits = (*adr)&0x3;
|
||||
c = pal[bits];
|
||||
*dwdst++ = CONVERT(c,(bits == 0) ? palZeroTransparent : opaqueColor);
|
||||
*dwdst++ = (bits == 0) ? 0 : CONVERT(c,opaqueColor);
|
||||
|
||||
bits = ((*adr)>>2)&0x3;
|
||||
c = pal[bits];
|
||||
*dwdst++ = CONVERT(c,(bits == 0) ? palZeroTransparent : opaqueColor);
|
||||
*dwdst++ = (bits == 0) ? 0 : CONVERT(c,opaqueColor);
|
||||
|
||||
bits = ((*adr)>>4)&0x3;
|
||||
c = pal[bits];
|
||||
*dwdst++ = CONVERT(c,(bits == 0) ? palZeroTransparent : opaqueColor);
|
||||
*dwdst++ = (bits == 0) ? 0 : CONVERT(c,opaqueColor);
|
||||
|
||||
bits = ((*adr)>>6)&0x3;
|
||||
c = pal[bits];
|
||||
*dwdst++ = CONVERT(c,(bits == 0) ? palZeroTransparent : opaqueColor);
|
||||
*dwdst++ = (bits == 0) ? 0 : CONVERT(c,opaqueColor);
|
||||
|
||||
adr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int j=0;j<ms.numItems;j++)
|
||||
{
|
||||
adr = ms.items[j].ptr;
|
||||
for(u32 x = 0; x < ms.items[j].len; x++)
|
||||
{
|
||||
u8 bits;
|
||||
u16 c;
|
||||
|
||||
bits = (*adr)&0x3;
|
||||
c = pal[bits];
|
||||
*dwdst++ = CONVERT(c,opaqueColor);
|
||||
|
||||
bits = ((*adr)>>2)&0x3;
|
||||
c = pal[bits];
|
||||
*dwdst++ = CONVERT(c,opaqueColor);
|
||||
|
||||
bits = ((*adr)>>4)&0x3;
|
||||
c = pal[bits];
|
||||
*dwdst++ = CONVERT(c,opaqueColor);
|
||||
|
||||
bits = ((*adr)>>6)&0x3;
|
||||
c = pal[bits];
|
||||
*dwdst++ = CONVERT(c,opaqueColor);
|
||||
|
||||
adr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TEXMODE_I4:
|
||||
{
|
||||
for(int j=0;j<ms.numItems;j++) {
|
||||
if (palZeroTransparent == 0)
|
||||
{
|
||||
for(int j=0;j<ms.numItems;j++)
|
||||
{
|
||||
adr = ms.items[j].ptr;
|
||||
for(u32 x = 0; x < ms.items[j].len; x++)
|
||||
{
|
||||
|
@ -463,29 +506,70 @@ public:
|
|||
|
||||
bits = (*adr)&0xF;
|
||||
c = pal[bits];
|
||||
*dwdst++ = CONVERT(c,(bits == 0) ? palZeroTransparent : opaqueColor);
|
||||
*dwdst++ = (bits == 0) ? 0 : CONVERT(c,opaqueColor);
|
||||
|
||||
bits = ((*adr)>>4);
|
||||
c = pal[bits];
|
||||
*dwdst++ = CONVERT(c,(bits == 0) ? palZeroTransparent : opaqueColor);
|
||||
*dwdst++ = (bits == 0) ? 0 : CONVERT(c,opaqueColor);
|
||||
adr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int j=0;j<ms.numItems;j++)
|
||||
{
|
||||
adr = ms.items[j].ptr;
|
||||
for(u32 x = 0; x < ms.items[j].len; x++)
|
||||
{
|
||||
u8 bits;
|
||||
u16 c;
|
||||
|
||||
bits = (*adr)&0xF;
|
||||
c = pal[bits];
|
||||
*dwdst++ = CONVERT(c,opaqueColor);
|
||||
|
||||
bits = ((*adr)>>4);
|
||||
c = pal[bits];
|
||||
*dwdst++ = CONVERT(c,opaqueColor);
|
||||
adr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TEXMODE_I8:
|
||||
{
|
||||
for(int j=0;j<ms.numItems;j++) {
|
||||
if (palZeroTransparent == 0)
|
||||
{
|
||||
for(int j=0;j<ms.numItems;j++)
|
||||
{
|
||||
adr = ms.items[j].ptr;
|
||||
for(u32 x = 0; x < ms.items[j].len; ++x)
|
||||
{
|
||||
u16 c = pal[*adr];
|
||||
*dwdst++ = CONVERT(c,(*adr == 0) ? palZeroTransparent : opaqueColor);
|
||||
*dwdst++ = (*adr == 0) ? 0 : CONVERT(c,opaqueColor);
|
||||
adr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int j=0;j<ms.numItems;j++)
|
||||
{
|
||||
adr = ms.items[j].ptr;
|
||||
for(u32 x = 0; x < ms.items[j].len; ++x)
|
||||
{
|
||||
u16 c = pal[*adr];
|
||||
*dwdst++ = CONVERT(c,opaqueColor);
|
||||
adr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TEXMODE_4X4:
|
||||
{
|
||||
if(ms.numItems != 1) {
|
||||
|
@ -544,7 +628,7 @@ public:
|
|||
{
|
||||
case 0:
|
||||
tmp_col[2] = RGB15TO32( PAL4X4(pal1offset+2), 0xFF );
|
||||
tmp_col[3] = RGB15TO32(0x7FFF, 0x00);
|
||||
tmp_col[3] = 0x00000000;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
|
@ -553,12 +637,12 @@ public:
|
|||
( (((tmp_col[0] & 0x00FF0000) + (tmp_col[1] & 0x00FF0000)) >> 1) & 0x00FF0000 ) |
|
||||
( (((tmp_col[0] & 0x0000FF00) + (tmp_col[1] & 0x0000FF00)) >> 1) & 0x0000FF00 ) |
|
||||
0x000000FF;
|
||||
tmp_col[3] = 0xFFFFFF00;
|
||||
tmp_col[3] = 0x00000000;
|
||||
#else
|
||||
tmp_col[2] = ( (((tmp_col[0] & 0x00FF00FF) + (tmp_col[1] & 0x00FF00FF)) >> 1) & 0x00FF00FF ) |
|
||||
( (((tmp_col[0] & 0x0000FF00) + (tmp_col[1] & 0x0000FF00)) >> 1) & 0x0000FF00 ) |
|
||||
0xFF000000;
|
||||
tmp_col[3] = 0x00FFFFFF;
|
||||
tmp_col[3] = 0x00000000;
|
||||
#endif
|
||||
break;
|
||||
|
||||
|
@ -634,9 +718,11 @@ public:
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TEXMODE_A5I3:
|
||||
{
|
||||
for(int j=0;j<ms.numItems;j++) {
|
||||
for(int j=0;j<ms.numItems;j++)
|
||||
{
|
||||
adr = ms.items[j].ptr;
|
||||
for(u32 x = 0; x < ms.items[j].len; ++x)
|
||||
{
|
||||
|
@ -651,16 +737,18 @@ public:
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TEXMODE_16BPP:
|
||||
{
|
||||
for(int j=0;j<ms.numItems;j++) {
|
||||
for(int j=0;j<ms.numItems;j++)
|
||||
{
|
||||
u16* map = (u16*)ms.items[j].ptr;
|
||||
int len = ms.items[j].len>>1;
|
||||
|
||||
for(int x = 0; x < len; ++x)
|
||||
{
|
||||
u16 c = map[x];
|
||||
int alpha = ((c&0x8000)?opaqueColor:0);
|
||||
*dwdst++ = CONVERT(c&0x7FFF,alpha);
|
||||
*dwdst++ = (c & 0x8000) ? CONVERT(c&0x7FFF,opaqueColor) : 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue