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_LineHack(true)
|
||||||
, GFX3D_Zelda_Shadow_Depth_Hack(0)
|
, GFX3D_Zelda_Shadow_Depth_Hack(0)
|
||||||
, GFX3D_Renderer_Multisample(false)
|
, GFX3D_Renderer_Multisample(false)
|
||||||
, GFX3D_Renderer_TextureDeposterize(false)
|
|
||||||
, GFX3D_Renderer_TextureScalingFactor(1) // Possible values: 1, 2, 4
|
, GFX3D_Renderer_TextureScalingFactor(1) // Possible values: 1, 2, 4
|
||||||
|
, GFX3D_Renderer_TextureDeposterize(false)
|
||||||
|
, GFX3D_Renderer_TextureSmoothing(false)
|
||||||
, GFX3D_TXTHack(false)
|
, GFX3D_TXTHack(false)
|
||||||
, GFX3D_PrescaleHD(1)
|
, GFX3D_PrescaleHD(1)
|
||||||
, jit_max_block_size(100)
|
, jit_max_block_size(100)
|
||||||
|
@ -545,8 +546,9 @@ extern struct TCommonSettings {
|
||||||
bool GFX3D_LineHack;
|
bool GFX3D_LineHack;
|
||||||
int GFX3D_Zelda_Shadow_Depth_Hack;
|
int GFX3D_Zelda_Shadow_Depth_Hack;
|
||||||
bool GFX3D_Renderer_Multisample;
|
bool GFX3D_Renderer_Multisample;
|
||||||
bool GFX3D_Renderer_TextureDeposterize;
|
|
||||||
int GFX3D_Renderer_TextureScalingFactor;
|
int GFX3D_Renderer_TextureScalingFactor;
|
||||||
|
bool GFX3D_Renderer_TextureDeposterize;
|
||||||
|
bool GFX3D_Renderer_TextureSmoothing;
|
||||||
bool GFX3D_TXTHack;
|
bool GFX3D_TXTHack;
|
||||||
|
|
||||||
//may not want this on OSX port
|
//may not want this on OSX port
|
||||||
|
|
|
@ -293,10 +293,11 @@ static const char *fragmentShader_100 = {"\
|
||||||
uniform int polyMode; \n\
|
uniform int polyMode; \n\
|
||||||
uniform bool polyEnableDepthWrite;\n\
|
uniform bool polyEnableDepthWrite;\n\
|
||||||
uniform bool polySetNewDepthForTranslucent;\n\
|
uniform bool polySetNewDepthForTranslucent;\n\
|
||||||
uniform int polyID; \n\
|
uniform int polyID;\n\
|
||||||
\n\
|
\n\
|
||||||
uniform bool polyEnableTexture; \n\
|
uniform bool polyEnableTexture;\n\
|
||||||
uniform bool polyEnableFog;\n\
|
uniform bool polyEnableFog;\n\
|
||||||
|
uniform bool texSingleBitAlpha;\n\
|
||||||
\n\
|
\n\
|
||||||
vec3 packVec3FromFloat(const float value)\n\
|
vec3 packVec3FromFloat(const float value)\n\
|
||||||
{\n\
|
{\n\
|
||||||
|
@ -308,6 +309,20 @@ static const char *fragmentShader_100 = {"\
|
||||||
void main() \n\
|
void main() \n\
|
||||||
{ \n\
|
{ \n\
|
||||||
vec4 mainTexColor = (polyEnableTexture) ? texture2D(texRenderObject, vtxTexCoord) : vec4(1.0, 1.0, 1.0, 1.0); \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\
|
vec4 newFragColor = mainTexColor * vtxColor; \n\
|
||||||
\n\
|
\n\
|
||||||
if(polyMode == 1) \n\
|
if(polyMode == 1) \n\
|
||||||
|
@ -328,7 +343,7 @@ static const char *fragmentShader_100 = {"\
|
||||||
} \n\
|
} \n\
|
||||||
} \n\
|
} \n\
|
||||||
\n\
|
\n\
|
||||||
if (newFragColor.a == 0.0 || (stateEnableAlphaTest && newFragColor.a < stateAlphaTestRef)) \n\
|
if (newFragColor.a < 0.001 || (stateEnableAlphaTest && newFragColor.a < stateAlphaTestRef)) \n\
|
||||||
{ \n\
|
{ \n\
|
||||||
discard; \n\
|
discard; \n\
|
||||||
} \n\
|
} \n\
|
||||||
|
@ -902,8 +917,15 @@ GPU3DInterface gpu3Dgl_3_2 = {
|
||||||
|
|
||||||
OpenGLRenderer::OpenGLRenderer()
|
OpenGLRenderer::OpenGLRenderer()
|
||||||
{
|
{
|
||||||
_renderID = RENDERID_OPENGL_AUTO;
|
_deviceInfo.renderID = RENDERID_OPENGL_AUTO;
|
||||||
_renderName = "OpenGL";
|
_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;
|
_internalRenderingFormat = NDSColorFormat_BGR888_Rev;
|
||||||
|
|
||||||
versionMajor = 0;
|
versionMajor = 0;
|
||||||
|
@ -1361,6 +1383,15 @@ Render3DError OpenGLRenderer_1_2::InitExtensions()
|
||||||
std::set<std::string> oglExtensionSet;
|
std::set<std::string> oglExtensionSet;
|
||||||
this->GetExtensionSet(&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
|
// Initialize OpenGL
|
||||||
this->InitTables();
|
this->InitTables();
|
||||||
|
|
||||||
|
@ -1395,21 +1426,32 @@ Render3DError OpenGLRenderer_1_2::InitExtensions()
|
||||||
framebufferOutputRGBA8888FragShaderString);
|
framebufferOutputRGBA8888FragShaderString);
|
||||||
if (error != OGLERROR_NOERR)
|
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");
|
INFO("OpenGL: Edge mark and fog require OpenGL v2.0 or later. These features will be disabled.\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
this->_deviceInfo.isEdgeMarkSupported = false;
|
||||||
|
this->_deviceInfo.isFogSupported = false;
|
||||||
|
this->_deviceInfo.isTextureSmoothingSupported = false;
|
||||||
this->isShaderSupported = false;
|
this->isShaderSupported = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
this->_deviceInfo.isEdgeMarkSupported = false;
|
||||||
|
this->_deviceInfo.isFogSupported = false;
|
||||||
|
this->_deviceInfo.isTextureSmoothingSupported = false;
|
||||||
this->isShaderSupported = false;
|
this->isShaderSupported = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
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");
|
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.uniformPolyEnableTexture = glGetUniformLocation(OGLRef.programGeometryID, "polyEnableTexture");
|
||||||
OGLRef.uniformPolyEnableFog = glGetUniformLocation(OGLRef.programGeometryID, "polyEnableFog");
|
OGLRef.uniformPolyEnableFog = glGetUniformLocation(OGLRef.programGeometryID, "polyEnableFog");
|
||||||
|
OGLRef.uniformTexSingleBitAlpha = glGetUniformLocation(OGLRef.programGeometryID, "texSingleBitAlpha");
|
||||||
|
|
||||||
return OGLERROR_NOERR;
|
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.
|
// 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
|
// Since our target resolution is only 256x192 pixels, using the most samples
|
||||||
// possible is the best thing to do.
|
// possible is the best thing to do.
|
||||||
GLint maxSamples = 0;
|
GLint maxSamples = (GLint)this->_deviceInfo.maxSamples;
|
||||||
glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSamples);
|
|
||||||
|
|
||||||
if (maxSamples < 2)
|
if (maxSamples < 2)
|
||||||
{
|
{
|
||||||
|
@ -3071,6 +3113,7 @@ Render3DError OpenGLRenderer_1_2::SetupTexture(const POLY &thePoly, bool enableT
|
||||||
if (this->isShaderSupported)
|
if (this->isShaderSupported)
|
||||||
{
|
{
|
||||||
glUniform1i(OGLRef.uniformPolyEnableTexture, GL_FALSE);
|
glUniform1i(OGLRef.uniformPolyEnableTexture, GL_FALSE);
|
||||||
|
glUniform1i(OGLRef.uniformTexSingleBitAlpha, GL_FALSE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -3084,6 +3127,7 @@ Render3DError OpenGLRenderer_1_2::SetupTexture(const POLY &thePoly, bool enableT
|
||||||
if (this->isShaderSupported)
|
if (this->isShaderSupported)
|
||||||
{
|
{
|
||||||
glUniform1i(OGLRef.uniformPolyEnableTexture, GL_TRUE);
|
glUniform1i(OGLRef.uniformPolyEnableTexture, GL_TRUE);
|
||||||
|
glUniform1i(OGLRef.uniformTexSingleBitAlpha, (params.texFormat != TEXMODE_A3I5 && params.texFormat != TEXMODE_A5I3) ? GL_TRUE : GL_FALSE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -3108,8 +3152,6 @@ Render3DError OpenGLRenderer_1_2::SetupTexture(const POLY &thePoly, bool enableT
|
||||||
OGLRef.freeTextureIDs.pop();
|
OGLRef.freeTextureIDs.pop();
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, (GLuint)this->currTexture->texid);
|
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_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));
|
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)
|
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:
|
case 2:
|
||||||
{
|
{
|
||||||
this->TextureUpscale<2>(textureSrc, texWidth, texHeight);
|
if (this->_textureSmooth)
|
||||||
textureSrc = this->_textureUpscaleBuffer;
|
{
|
||||||
|
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);
|
||||||
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
{
|
{
|
||||||
this->TextureUpscale<4>(textureSrc, texWidth, texHeight);
|
if (this->_textureSmooth)
|
||||||
textureSrc = this->_textureUpscaleBuffer;
|
{
|
||||||
|
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);
|
||||||
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureSrc);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -3313,8 +3411,7 @@ Render3DError OpenGLRenderer_1_2::SetFramebufferSize(size_t w, size_t h)
|
||||||
|
|
||||||
if (this->isMultisampledFBOSupported)
|
if (this->isMultisampledFBOSupported)
|
||||||
{
|
{
|
||||||
GLint maxSamples = 0;
|
GLint maxSamples = (GLint)this->_deviceInfo.maxSamples;
|
||||||
glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSamples);
|
|
||||||
|
|
||||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, OGLRef.rboMSGColorID);
|
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, OGLRef.rboMSGColorID);
|
||||||
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, maxSamples, GL_RGBA, w, h);
|
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)
|
if (this->isMultisampledFBOSupported)
|
||||||
{
|
{
|
||||||
GLint maxSamples = 0;
|
GLint maxSamples = (GLint)this->_deviceInfo.maxSamples;
|
||||||
glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSamples);
|
|
||||||
|
|
||||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, OGLRef.rboMSGColorID);
|
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, OGLRef.rboMSGColorID);
|
||||||
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, maxSamples, GL_RGBA, w, h);
|
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, maxSamples, GL_RGBA, w, h);
|
||||||
|
@ -3819,6 +3915,15 @@ Render3DError OpenGLRenderer_2_0::InitExtensions()
|
||||||
std::set<std::string> oglExtensionSet;
|
std::set<std::string> oglExtensionSet;
|
||||||
this->GetExtensionSet(&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
|
// Initialize OpenGL
|
||||||
this->InitTables();
|
this->InitTables();
|
||||||
|
|
||||||
|
@ -3859,6 +3964,8 @@ Render3DError OpenGLRenderer_2_0::InitExtensions()
|
||||||
{
|
{
|
||||||
this->DestroyGeometryProgram();
|
this->DestroyGeometryProgram();
|
||||||
this->isShaderSupported = false;
|
this->isShaderSupported = false;
|
||||||
|
this->_deviceInfo.isEdgeMarkSupported = false;
|
||||||
|
this->_deviceInfo.isFogSupported = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->isVBOSupported = true;
|
this->isVBOSupported = true;
|
||||||
|
@ -4694,10 +4801,12 @@ Render3DError OpenGLRenderer_2_0::SetupTexture(const POLY &thePoly, bool enableT
|
||||||
if (params.texFormat == TEXMODE_NONE || !enableTexturing)
|
if (params.texFormat == TEXMODE_NONE || !enableTexturing)
|
||||||
{
|
{
|
||||||
glUniform1i(OGLRef.uniformPolyEnableTexture, GL_FALSE);
|
glUniform1i(OGLRef.uniformPolyEnableTexture, GL_FALSE);
|
||||||
|
glUniform1i(OGLRef.uniformTexSingleBitAlpha, GL_FALSE);
|
||||||
return OGLERROR_NOERR;
|
return OGLERROR_NOERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
glUniform1i(OGLRef.uniformPolyEnableTexture, GL_TRUE);
|
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);
|
TexCacheItem *newTexture = TexCache_SetTexture(TexFormat_32bpp, thePoly.texParam, thePoly.texPalette);
|
||||||
if(newTexture != this->currTexture)
|
if(newTexture != this->currTexture)
|
||||||
|
@ -4717,8 +4826,6 @@ Render3DError OpenGLRenderer_2_0::SetupTexture(const POLY &thePoly, bool enableT
|
||||||
OGLRef.freeTextureIDs.pop();
|
OGLRef.freeTextureIDs.pop();
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, (GLuint)this->currTexture->texid);
|
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_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));
|
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)
|
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:
|
case 2:
|
||||||
{
|
{
|
||||||
this->TextureUpscale<2>(textureSrc, texWidth, texHeight);
|
if (this->_textureSmooth)
|
||||||
textureSrc = this->_textureUpscaleBuffer;
|
{
|
||||||
|
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);
|
||||||
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
{
|
{
|
||||||
this->TextureUpscale<4>(textureSrc, texWidth, texHeight);
|
if (this->_textureSmooth)
|
||||||
textureSrc = this->_textureUpscaleBuffer;
|
{
|
||||||
|
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);
|
||||||
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureSrc);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -389,7 +389,7 @@ struct OGLPolyStates
|
||||||
|
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
struct { GLubyte texSizeS, texSizeT, texParamPad[2]; };
|
struct { GLubyte texSizeS, texSizeT, texSingleBitAlpha, texParamPad[1]; };
|
||||||
GLubyte texParam[4];
|
GLubyte texParam[4];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -481,6 +481,7 @@ struct OGLRenderRef
|
||||||
|
|
||||||
GLint uniformPolyEnableTexture;
|
GLint uniformPolyEnableTexture;
|
||||||
GLint uniformPolyEnableFog;
|
GLint uniformPolyEnableFog;
|
||||||
|
GLint uniformTexSingleBitAlpha;
|
||||||
|
|
||||||
GLint uniformPolyStateIndex;
|
GLint uniformPolyStateIndex;
|
||||||
|
|
||||||
|
|
|
@ -122,6 +122,7 @@ static const char *GeometryVtxShader_150 = {"\
|
||||||
flat out uint polySetNewDepthForTranslucent;\n\
|
flat out uint polySetNewDepthForTranslucent;\n\
|
||||||
flat out uint polyMode;\n\
|
flat out uint polyMode;\n\
|
||||||
flat out uint polyID;\n\
|
flat out uint polyID;\n\
|
||||||
|
flat out uint texSingleBitAlpha;\n\
|
||||||
\n\
|
\n\
|
||||||
void main() \n\
|
void main() \n\
|
||||||
{ \n\
|
{ \n\
|
||||||
|
@ -138,6 +139,7 @@ static const char *GeometryVtxShader_150 = {"\
|
||||||
polySetNewDepthForTranslucent = polyStateFlags[3];\n\
|
polySetNewDepthForTranslucent = polyStateFlags[3];\n\
|
||||||
polyMode = polyStateValues[1];\n\
|
polyMode = polyStateValues[1];\n\
|
||||||
polyID = polyStateValues[2];\n\
|
polyID = polyStateValues[2];\n\
|
||||||
|
texSingleBitAlpha = polyStateTexParams[2];\n\
|
||||||
\n\
|
\n\
|
||||||
mat2 texScaleMtx = mat2( vec2(polyTexScale.x, 0.0), \n\
|
mat2 texScaleMtx = mat2( vec2(polyTexScale.x, 0.0), \n\
|
||||||
vec2( 0.0, polyTexScale.y)); \n\
|
vec2( 0.0, polyTexScale.y)); \n\
|
||||||
|
@ -163,6 +165,7 @@ static const char *GeometryFragShader_150 = {"\
|
||||||
flat in uint polySetNewDepthForTranslucent;\n\
|
flat in uint polySetNewDepthForTranslucent;\n\
|
||||||
flat in uint polyMode;\n\
|
flat in uint polyMode;\n\
|
||||||
flat in uint polyID;\n\
|
flat in uint polyID;\n\
|
||||||
|
flat in uint texSingleBitAlpha;\n\
|
||||||
\n\
|
\n\
|
||||||
layout (std140) uniform RenderStates\n\
|
layout (std140) uniform RenderStates\n\
|
||||||
{\n\
|
{\n\
|
||||||
|
@ -202,6 +205,20 @@ static const char *GeometryFragShader_150 = {"\
|
||||||
void main() \n\
|
void main() \n\
|
||||||
{ \n\
|
{ \n\
|
||||||
vec4 mainTexColor = bool(polyEnableTexture) ? texture(texRenderObject, vtxTexCoord) : vec4(1.0, 1.0, 1.0, 1.0);\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\
|
vec4 newFragColor = mainTexColor * vtxColor; \n\
|
||||||
\n\
|
\n\
|
||||||
if (polyMode == 1u) \n\
|
if (polyMode == 1u) \n\
|
||||||
|
@ -222,10 +239,10 @@ static const char *GeometryFragShader_150 = {"\
|
||||||
} \n\
|
} \n\
|
||||||
} \n\
|
} \n\
|
||||||
\n\
|
\n\
|
||||||
if (newFragColor.a == 0.0 || (state.enableAlphaTest && newFragColor.a < state.alphaTestRef)) \n\
|
if (newFragColor.a < 0.001 || (state.enableAlphaTest && newFragColor.a < state.alphaTestRef))\n\
|
||||||
{ \n\
|
{\n\
|
||||||
discard; \n\
|
discard;\n\
|
||||||
} \n\
|
}\n\
|
||||||
\n\
|
\n\
|
||||||
float vertW = (vtxPosition.w == 0.0) ? 0.00000001 : vtxPosition.w; \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\
|
// 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;
|
std::set<std::string> oglExtensionSet;
|
||||||
this->GetExtensionSet(&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
|
// Initialize OpenGL
|
||||||
this->InitTables();
|
this->InitTables();
|
||||||
|
|
||||||
|
@ -955,8 +984,7 @@ Render3DError OpenGLRenderer_3_2::CreateMultisampledFBO()
|
||||||
// Check the maximum number of samples that the GPU supports and use that.
|
// 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
|
// Since our target resolution is only 256x192 pixels, using the most samples
|
||||||
// possible is the best thing to do.
|
// possible is the best thing to do.
|
||||||
GLint maxSamples = 0;
|
GLint maxSamples = (GLint)this->_deviceInfo.maxSamples;
|
||||||
glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
|
|
||||||
|
|
||||||
if (maxSamples < 2)
|
if (maxSamples < 2)
|
||||||
{
|
{
|
||||||
|
@ -1387,6 +1415,7 @@ Render3DError OpenGLRenderer_3_2::BeginRender(const GFX3D &engine)
|
||||||
polyStates[i].polyID = polyAttr.polygonID;
|
polyStates[i].polyID = polyAttr.polygonID;
|
||||||
polyStates[i].texSizeS = texParams.sizeS;
|
polyStates[i].texSizeS = texParams.sizeS;
|
||||||
polyStates[i].texSizeT = texParams.sizeT;
|
polyStates[i].texSizeT = texParams.sizeT;
|
||||||
|
polyStates[i].texSingleBitAlpha = (texParams.texFormat != TEXMODE_A3I5 && texParams.texFormat != TEXMODE_A5I3) ? GL_TRUE : GL_FALSE;
|
||||||
|
|
||||||
for (size_t j = 0; j < polyType; j++)
|
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();
|
OGLRef.freeTextureIDs.pop();
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, (GLuint)this->currTexture->texid);
|
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_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));
|
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)
|
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:
|
case 2:
|
||||||
{
|
{
|
||||||
this->TextureUpscale<2>(textureSrc, texWidth, texHeight);
|
if (this->_textureSmooth)
|
||||||
textureSrc = this->_textureUpscaleBuffer;
|
{
|
||||||
|
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);
|
||||||
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
{
|
{
|
||||||
this->TextureUpscale<4>(textureSrc, texWidth, texHeight);
|
if (this->_textureSmooth)
|
||||||
textureSrc = this->_textureUpscaleBuffer;
|
{
|
||||||
|
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);
|
||||||
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureSrc);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1779,8 +1862,7 @@ Render3DError OpenGLRenderer_3_2::SetFramebufferSize(size_t w, size_t h)
|
||||||
|
|
||||||
if (this->isMultisampledFBOSupported)
|
if (this->isMultisampledFBOSupported)
|
||||||
{
|
{
|
||||||
GLint maxSamples = 0;
|
GLint maxSamples = (GLint)this->_deviceInfo.maxSamples;
|
||||||
glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
|
|
||||||
|
|
||||||
glBindRenderbuffer(GL_RENDERBUFFER, OGLRef.rboMSGColorID);
|
glBindRenderbuffer(GL_RENDERBUFFER, OGLRef.rboMSGColorID);
|
||||||
glRenderbufferStorageMultisample(GL_RENDERBUFFER, maxSamples, GL_RGBA, w, h);
|
glRenderbufferStorageMultisample(GL_RENDERBUFFER, maxSamples, GL_RGBA, w, h);
|
||||||
|
|
|
@ -2336,7 +2336,9 @@ void gfx3d_VBlankEndSignal(bool skipFrame)
|
||||||
if (CommonSettings.showGpu.main)
|
if (CommonSettings.showGpu.main)
|
||||||
{
|
{
|
||||||
CurrentRenderer->SetRenderNeedsFinish(true);
|
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);
|
CurrentRenderer->Render(gfx3d);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -1165,8 +1165,14 @@ GPU3DInterface gpu3DRasterize = {
|
||||||
|
|
||||||
SoftRasterizerRenderer::SoftRasterizerRenderer()
|
SoftRasterizerRenderer::SoftRasterizerRenderer()
|
||||||
{
|
{
|
||||||
_renderID = RENDERID_SOFTRASTERIZER;
|
_deviceInfo.renderID = RENDERID_SOFTRASTERIZER;
|
||||||
_renderName = "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;
|
_debug_drawClippedUserPoly = -1;
|
||||||
clippedPolys = clipper.clippedPolys = new GFX3D_Clipper::TClippedPoly[POLYLIST_SIZE*2];
|
clippedPolys = clipper.clippedPolys = new GFX3D_Clipper::TClippedPoly[POLYLIST_SIZE*2];
|
||||||
|
|
|
@ -265,8 +265,14 @@ void Render3D::operator delete(void *ptr)
|
||||||
|
|
||||||
Render3D::Render3D()
|
Render3D::Render3D()
|
||||||
{
|
{
|
||||||
_renderID = RENDERID_NULL;
|
_deviceInfo.renderID = RENDERID_NULL;
|
||||||
_renderName = "None";
|
_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;
|
static bool needTableInit = true;
|
||||||
|
|
||||||
|
@ -292,6 +298,7 @@ Render3D::Render3D()
|
||||||
_willFlushFramebufferRGBA5551 = true;
|
_willFlushFramebufferRGBA5551 = true;
|
||||||
|
|
||||||
_textureScalingFactor = 1;
|
_textureScalingFactor = 1;
|
||||||
|
_textureSmooth = false;
|
||||||
_textureDeposterizeBuffer = NULL;
|
_textureDeposterizeBuffer = NULL;
|
||||||
_textureUpscaleBuffer = NULL;
|
_textureUpscaleBuffer = NULL;
|
||||||
|
|
||||||
|
@ -303,14 +310,19 @@ Render3D::~Render3D()
|
||||||
// Do nothing.
|
// Do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Render3DDeviceInfo& Render3D::GetDeviceInfo()
|
||||||
|
{
|
||||||
|
return this->_deviceInfo;
|
||||||
|
}
|
||||||
|
|
||||||
RendererID Render3D::GetRenderID()
|
RendererID Render3D::GetRenderID()
|
||||||
{
|
{
|
||||||
return this->_renderID;
|
return this->_deviceInfo.renderID;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Render3D::GetName()
|
std::string Render3D::GetName()
|
||||||
{
|
{
|
||||||
return this->_renderName;
|
return this->_deviceInfo.renderName;
|
||||||
}
|
}
|
||||||
|
|
||||||
FragmentColor* Render3D::GetFramebuffer()
|
FragmentColor* Render3D::GetFramebuffer()
|
||||||
|
@ -381,7 +393,7 @@ void Render3D::SetRenderNeedsFinish(const bool renderNeedsFinish)
|
||||||
this->_renderNeedsFinish = 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 bool isScaleValid = ( (scalingFactor == 2) || (scalingFactor == 4) );
|
||||||
const size_t newScalingFactor = (isScaleValid) ? scalingFactor : 1;
|
const size_t newScalingFactor = (isScaleValid) ? scalingFactor : 1;
|
||||||
|
@ -416,6 +428,13 @@ void Render3D::SetTextureProcessingProperties(bool willDeposterize, size_t scali
|
||||||
needTexCacheReset = true;
|
needTexCacheReset = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (willSmooth != this->_textureSmooth)
|
||||||
|
{
|
||||||
|
this->_textureSmooth = willSmooth;
|
||||||
|
|
||||||
|
needTexCacheReset = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (needTexCacheReset)
|
if (needTexCacheReset)
|
||||||
{
|
{
|
||||||
TexCache_Reset();
|
TexCache_Reset();
|
||||||
|
|
|
@ -98,11 +98,24 @@ struct FragmentAttributesBuffer
|
||||||
void SetAll(const FragmentAttributes &attr);
|
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
|
class Render3D
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
RendererID _renderID;
|
Render3DDeviceInfo _deviceInfo;
|
||||||
std::string _renderName;
|
|
||||||
|
|
||||||
size_t _framebufferWidth;
|
size_t _framebufferWidth;
|
||||||
size_t _framebufferHeight;
|
size_t _framebufferHeight;
|
||||||
|
@ -116,6 +129,7 @@ protected:
|
||||||
bool _willFlushFramebufferRGBA5551;
|
bool _willFlushFramebufferRGBA5551;
|
||||||
|
|
||||||
size_t _textureScalingFactor;
|
size_t _textureScalingFactor;
|
||||||
|
bool _textureSmooth;
|
||||||
u32 *_textureDeposterizeBuffer;
|
u32 *_textureDeposterizeBuffer;
|
||||||
u32 *_textureUpscaleBuffer;
|
u32 *_textureUpscaleBuffer;
|
||||||
|
|
||||||
|
@ -147,6 +161,7 @@ public:
|
||||||
Render3D();
|
Render3D();
|
||||||
~Render3D();
|
~Render3D();
|
||||||
|
|
||||||
|
const Render3DDeviceInfo& GetDeviceInfo();
|
||||||
RendererID GetRenderID();
|
RendererID GetRenderID();
|
||||||
std::string GetName();
|
std::string GetName();
|
||||||
|
|
||||||
|
@ -179,7 +194,7 @@ public:
|
||||||
bool GetRenderNeedsFinish() const;
|
bool GetRenderNeedsFinish() const;
|
||||||
void SetRenderNeedsFinish(const bool renderNeedsFinish);
|
void SetRenderNeedsFinish(const bool renderNeedsFinish);
|
||||||
|
|
||||||
void SetTextureProcessingProperties(bool willDeposterize, size_t scalingFactor);
|
void SetTextureProcessingProperties(size_t scalingFactor, bool willDeposterize, bool willSmooth);
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef ENABLE_SSE2
|
#ifdef ENABLE_SSE2
|
||||||
|
|
|
@ -399,14 +399,19 @@ public:
|
||||||
//Texture conversion
|
//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 opaqueColor = (TEXFORMAT == TexFormat_32bpp) ? 0xFF : 0x1F;
|
||||||
const u8 palZeroTransparent = ( 1 - ((format>>29) & 1) ) * opaqueColor;
|
const u8 palZeroTransparent = ( 1 - ((format>>29) & 1) ) * opaqueColor;
|
||||||
|
|
||||||
switch (newitem->mode)
|
switch (newitem->mode)
|
||||||
{
|
{
|
||||||
case TEXMODE_A3I5:
|
case TEXMODE_A3I5:
|
||||||
{
|
{
|
||||||
for(int j=0;j<ms.numItems;j++) {
|
for(int j=0;j<ms.numItems;j++)
|
||||||
|
{
|
||||||
adr = ms.items[j].ptr;
|
adr = ms.items[j].ptr;
|
||||||
for(u32 x = 0; x < ms.items[j].len; x++)
|
for(u32 x = 0; x < ms.items[j].len; x++)
|
||||||
{
|
{
|
||||||
|
@ -422,71 +427,150 @@ public:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case TEXMODE_I2:
|
case TEXMODE_I2:
|
||||||
{
|
{
|
||||||
for(int j=0;j<ms.numItems;j++) {
|
if (palZeroTransparent == 0)
|
||||||
adr = ms.items[j].ptr;
|
{
|
||||||
for(u32 x = 0; x < ms.items[j].len; x++)
|
for(int j=0;j<ms.numItems;j++)
|
||||||
{
|
{
|
||||||
u8 bits;
|
adr = ms.items[j].ptr;
|
||||||
u16 c;
|
for(u32 x = 0; x < ms.items[j].len; x++)
|
||||||
|
{
|
||||||
|
u8 bits;
|
||||||
|
u16 c;
|
||||||
|
|
||||||
bits = (*adr)&0x3;
|
bits = (*adr)&0x3;
|
||||||
c = pal[bits];
|
c = pal[bits];
|
||||||
*dwdst++ = CONVERT(c,(bits == 0) ? palZeroTransparent : opaqueColor);
|
*dwdst++ = (bits == 0) ? 0 : CONVERT(c,opaqueColor);
|
||||||
|
|
||||||
bits = ((*adr)>>2)&0x3;
|
bits = ((*adr)>>2)&0x3;
|
||||||
c = pal[bits];
|
c = pal[bits];
|
||||||
*dwdst++ = CONVERT(c,(bits == 0) ? palZeroTransparent : opaqueColor);
|
*dwdst++ = (bits == 0) ? 0 : CONVERT(c,opaqueColor);
|
||||||
|
|
||||||
bits = ((*adr)>>4)&0x3;
|
bits = ((*adr)>>4)&0x3;
|
||||||
c = pal[bits];
|
c = pal[bits];
|
||||||
*dwdst++ = CONVERT(c,(bits == 0) ? palZeroTransparent : opaqueColor);
|
*dwdst++ = (bits == 0) ? 0 : CONVERT(c,opaqueColor);
|
||||||
|
|
||||||
bits = ((*adr)>>6)&0x3;
|
bits = ((*adr)>>6)&0x3;
|
||||||
c = pal[bits];
|
c = pal[bits];
|
||||||
*dwdst++ = CONVERT(c,(bits == 0) ? palZeroTransparent : opaqueColor);
|
*dwdst++ = (bits == 0) ? 0 : CONVERT(c,opaqueColor);
|
||||||
|
|
||||||
adr++;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case TEXMODE_I4:
|
|
||||||
|
case TEXMODE_I4:
|
||||||
{
|
{
|
||||||
for(int j=0;j<ms.numItems;j++) {
|
if (palZeroTransparent == 0)
|
||||||
adr = ms.items[j].ptr;
|
{
|
||||||
for(u32 x = 0; x < ms.items[j].len; x++)
|
for(int j=0;j<ms.numItems;j++)
|
||||||
{
|
{
|
||||||
u8 bits;
|
adr = ms.items[j].ptr;
|
||||||
u16 c;
|
for(u32 x = 0; x < ms.items[j].len; x++)
|
||||||
|
{
|
||||||
|
u8 bits;
|
||||||
|
u16 c;
|
||||||
|
|
||||||
bits = (*adr)&0xF;
|
bits = (*adr)&0xF;
|
||||||
c = pal[bits];
|
c = pal[bits];
|
||||||
*dwdst++ = CONVERT(c,(bits == 0) ? palZeroTransparent : opaqueColor);
|
*dwdst++ = (bits == 0) ? 0 : CONVERT(c,opaqueColor);
|
||||||
|
|
||||||
bits = ((*adr)>>4);
|
bits = ((*adr)>>4);
|
||||||
c = pal[bits];
|
c = pal[bits];
|
||||||
*dwdst++ = CONVERT(c,(bits == 0) ? palZeroTransparent : opaqueColor);
|
*dwdst++ = (bits == 0) ? 0 : CONVERT(c,opaqueColor);
|
||||||
adr++;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case TEXMODE_I8:
|
|
||||||
|
case TEXMODE_I8:
|
||||||
{
|
{
|
||||||
for(int j=0;j<ms.numItems;j++) {
|
if (palZeroTransparent == 0)
|
||||||
adr = ms.items[j].ptr;
|
{
|
||||||
for(u32 x = 0; x < ms.items[j].len; ++x)
|
for(int j=0;j<ms.numItems;j++)
|
||||||
{
|
{
|
||||||
u16 c = pal[*adr];
|
adr = ms.items[j].ptr;
|
||||||
*dwdst++ = CONVERT(c,(*adr == 0) ? palZeroTransparent : opaqueColor);
|
for(u32 x = 0; x < ms.items[j].len; ++x)
|
||||||
adr++;
|
{
|
||||||
|
u16 c = pal[*adr];
|
||||||
|
*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;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case TEXMODE_4X4:
|
case TEXMODE_4X4:
|
||||||
{
|
{
|
||||||
if(ms.numItems != 1) {
|
if(ms.numItems != 1) {
|
||||||
PROGINFO("Your 4x4 texture has overrun its texture slot.\n");
|
PROGINFO("Your 4x4 texture has overrun its texture slot.\n");
|
||||||
|
@ -544,7 +628,7 @@ public:
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
tmp_col[2] = RGB15TO32( PAL4X4(pal1offset+2), 0xFF );
|
tmp_col[2] = RGB15TO32( PAL4X4(pal1offset+2), 0xFF );
|
||||||
tmp_col[3] = RGB15TO32(0x7FFF, 0x00);
|
tmp_col[3] = 0x00000000;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -553,12 +637,12 @@ public:
|
||||||
( (((tmp_col[0] & 0x00FF0000) + (tmp_col[1] & 0x00FF0000)) >> 1) & 0x00FF0000 ) |
|
( (((tmp_col[0] & 0x00FF0000) + (tmp_col[1] & 0x00FF0000)) >> 1) & 0x00FF0000 ) |
|
||||||
( (((tmp_col[0] & 0x0000FF00) + (tmp_col[1] & 0x0000FF00)) >> 1) & 0x0000FF00 ) |
|
( (((tmp_col[0] & 0x0000FF00) + (tmp_col[1] & 0x0000FF00)) >> 1) & 0x0000FF00 ) |
|
||||||
0x000000FF;
|
0x000000FF;
|
||||||
tmp_col[3] = 0xFFFFFF00;
|
tmp_col[3] = 0x00000000;
|
||||||
#else
|
#else
|
||||||
tmp_col[2] = ( (((tmp_col[0] & 0x00FF00FF) + (tmp_col[1] & 0x00FF00FF)) >> 1) & 0x00FF00FF ) |
|
tmp_col[2] = ( (((tmp_col[0] & 0x00FF00FF) + (tmp_col[1] & 0x00FF00FF)) >> 1) & 0x00FF00FF ) |
|
||||||
( (((tmp_col[0] & 0x0000FF00) + (tmp_col[1] & 0x0000FF00)) >> 1) & 0x0000FF00 ) |
|
( (((tmp_col[0] & 0x0000FF00) + (tmp_col[1] & 0x0000FF00)) >> 1) & 0x0000FF00 ) |
|
||||||
0xFF000000;
|
0xFF000000;
|
||||||
tmp_col[3] = 0x00FFFFFF;
|
tmp_col[3] = 0x00000000;
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -634,9 +718,11 @@ public:
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TEXMODE_A5I3:
|
|
||||||
|
case TEXMODE_A5I3:
|
||||||
{
|
{
|
||||||
for(int j=0;j<ms.numItems;j++) {
|
for(int j=0;j<ms.numItems;j++)
|
||||||
|
{
|
||||||
adr = ms.items[j].ptr;
|
adr = ms.items[j].ptr;
|
||||||
for(u32 x = 0; x < ms.items[j].len; ++x)
|
for(u32 x = 0; x < ms.items[j].len; ++x)
|
||||||
{
|
{
|
||||||
|
@ -651,16 +737,18 @@ public:
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TEXMODE_16BPP:
|
|
||||||
|
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;
|
u16* map = (u16*)ms.items[j].ptr;
|
||||||
int len = ms.items[j].len>>1;
|
int len = ms.items[j].len>>1;
|
||||||
|
|
||||||
for(int x = 0; x < len; ++x)
|
for(int x = 0; x < len; ++x)
|
||||||
{
|
{
|
||||||
u16 c = map[x];
|
u16 c = map[x];
|
||||||
int alpha = ((c&0x8000)?opaqueColor:0);
|
*dwdst++ = (c & 0x8000) ? CONVERT(c&0x7FFF,opaqueColor) : 0;
|
||||||
*dwdst++ = CONVERT(c&0x7FFF,alpha);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue