parent
629da9c8e2
commit
d652249c34
|
@ -54,7 +54,7 @@ const GLfloat PostprocessVtxBuffer[16] = {-1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.
|
|||
0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f};
|
||||
const GLubyte PostprocessElementBuffer[6] = {0, 1, 2, 2, 3, 0};
|
||||
|
||||
const GLenum RenderDrawList[3] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_COLOR_ATTACHMENT2_EXT};
|
||||
const GLenum RenderDrawList[4] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_COLOR_ATTACHMENT2_EXT, GL_COLOR_ATTACHMENT3_EXT};
|
||||
|
||||
static bool BEGINGL()
|
||||
{
|
||||
|
@ -114,6 +114,7 @@ OGLEXT(PFNGLUNIFORM1FPROC, glUniform1f) // Core in v2.0
|
|||
OGLEXT(PFNGLUNIFORM1FVPROC, glUniform1fv) // Core in v2.0
|
||||
OGLEXT(PFNGLUNIFORM2FPROC, glUniform2f) // Core in v2.0
|
||||
OGLEXT(PFNGLUNIFORM4FPROC, glUniform4f) // Core in v2.0
|
||||
OGLEXT(PFNGLUNIFORM4FVPROC, glUniform4fv) // Core in v2.0
|
||||
OGLEXT(PFNGLDRAWBUFFERSPROC, glDrawBuffers) // Core in v2.0
|
||||
OGLEXT(PFNGLBINDATTRIBLOCATIONPROC, glBindAttribLocation) // Core in v2.0
|
||||
OGLEXT(PFNGLENABLEVERTEXATTRIBARRAYPROC, glEnableVertexAttribArray) // Core in v2.0
|
||||
|
@ -194,6 +195,7 @@ static void OGLLoadEntryPoints_Legacy()
|
|||
INITOGLEXT(PFNGLUNIFORM1FVPROC, glUniform1fv) // Core in v2.0
|
||||
INITOGLEXT(PFNGLUNIFORM2FPROC, glUniform2f) // Core in v2.0
|
||||
INITOGLEXT(PFNGLUNIFORM4FPROC, glUniform4f) // Core in v2.0
|
||||
INITOGLEXT(PFNGLUNIFORM4FVPROC, glUniform4fv) // Core in v2.0
|
||||
INITOGLEXT(PFNGLDRAWBUFFERSPROC, glDrawBuffers) // Core in v2.0
|
||||
INITOGLEXT(PFNGLBINDATTRIBLOCATIONPROC, glBindAttribLocation) // Core in v2.0
|
||||
INITOGLEXT(PFNGLENABLEVERTEXATTRIBARRAYPROC, glEnableVertexAttribArray) // Core in v2.0
|
||||
|
@ -326,17 +328,103 @@ static const char *fragmentShader_100 = {"\
|
|||
float newFragDepth = (stateUseWDepth) ? vtxPosition.w/4096.0 : clamp((vtxPosition.z/vertW) * 0.5 + 0.5, 0.0, 1.0); \n\
|
||||
\n\
|
||||
gl_FragData[0] = newFragColor;\n\
|
||||
gl_FragData[2] = vec4( float(polyEnableFog), float(stateEnableFogAlphaOnly), 0.0, 1.0);\n\
|
||||
if (newFragColor.a >= 1.0 || polySetNewDepthForTranslucent)\n\
|
||||
{\n\
|
||||
gl_FragData[1] = vec4( packVec3FromFloat(newFragDepth), 1.0);\n\
|
||||
}\n\
|
||||
gl_FragData[3] = vec4( float(polyEnableFog), float(stateEnableFogAlphaOnly), 0.0, 1.0);\n\
|
||||
if (newFragColor.a > 0.999) gl_FragData[2] = vec4(float(polyID)/63.0, float(stateEnableAntialiasing), 0.0, 1.0);\n\
|
||||
if (newFragColor.a > 0.999 || polySetNewDepthForTranslucent) gl_FragData[1] = vec4( packVec3FromFloat(newFragDepth), 1.0);\n\
|
||||
gl_FragDepth = newFragDepth;\n\
|
||||
} \n\
|
||||
"};
|
||||
|
||||
// Vertex shader for post-processing, GLSL 1.00
|
||||
static const char *PostprocessVertShader_100 = {"\
|
||||
// Vertex shader for applying edge marking, GLSL 1.00
|
||||
static const char *EdgeMarkVtxShader_100 = {"\
|
||||
attribute vec2 inPosition;\n\
|
||||
attribute vec2 inTexCoord0;\n\
|
||||
uniform vec2 framebufferSize;\n\
|
||||
varying vec2 texCoord[5];\n\
|
||||
\n\
|
||||
void main()\n\
|
||||
{\n\
|
||||
vec2 texInvScale = vec2(1.0/framebufferSize.x, 1.0/framebufferSize.y);\n\
|
||||
\n\
|
||||
texCoord[0] = inTexCoord0; // Center\n\
|
||||
texCoord[1] = inTexCoord0 + (vec2( 1.0, 0.0) * texInvScale); // Right\n\
|
||||
texCoord[2] = inTexCoord0 + (vec2( 0.0, 1.0) * texInvScale); // Down\n\
|
||||
texCoord[3] = inTexCoord0 + (vec2(-1.0, 0.0) * texInvScale); // Left\n\
|
||||
texCoord[4] = inTexCoord0 + (vec2( 0.0,-1.0) * texInvScale); // Up\n\
|
||||
\n\
|
||||
gl_Position = vec4(inPosition, 0.0, 1.0);\n\
|
||||
}\n\
|
||||
"};
|
||||
|
||||
// Fragment shader for applying edge marking, GLSL 1.00
|
||||
static const char *EdgeMarkFragShader_100 = {"\
|
||||
varying vec2 texCoord[5];\n\
|
||||
\n\
|
||||
uniform sampler2D texInFragColor;\n\
|
||||
uniform sampler2D texInFragDepth;\n\
|
||||
uniform sampler2D texInPolyID;\n\
|
||||
uniform vec4 stateEdgeColor[8];\n\
|
||||
\n\
|
||||
float unpackFloatFromVec3(const vec3 value)\n\
|
||||
{\n\
|
||||
const vec3 unpackRatio = vec3(256.0, 65536.0, 16777216.0);\n\
|
||||
return (dot(value, unpackRatio) / 16777215.0);\n\
|
||||
}\n\
|
||||
\n\
|
||||
void main()\n\
|
||||
{\n\
|
||||
vec4 inFragColor = texture2D(texInFragColor, texCoord[0]);\n\
|
||||
float inFragDepth = unpackFloatFromVec3(texture2D(texInFragDepth, texCoord[0]).rgb);\n\
|
||||
\n\
|
||||
vec4 inPolyIDAttributes[5];\n\
|
||||
inPolyIDAttributes[0] = texture2D(texInPolyID, texCoord[0]);\n\
|
||||
inPolyIDAttributes[1] = texture2D(texInPolyID, texCoord[1]);\n\
|
||||
inPolyIDAttributes[2] = texture2D(texInPolyID, texCoord[2]);\n\
|
||||
inPolyIDAttributes[3] = texture2D(texInPolyID, texCoord[3]);\n\
|
||||
inPolyIDAttributes[4] = texture2D(texInPolyID, texCoord[4]);\n\
|
||||
\n\
|
||||
int polyID[5];\n\
|
||||
polyID[0] = int((inPolyIDAttributes[0].r * 63.0) + 0.5);\n\
|
||||
polyID[1] = int((inPolyIDAttributes[1].r * 63.0) + 0.5);\n\
|
||||
polyID[2] = int((inPolyIDAttributes[2].r * 63.0) + 0.5);\n\
|
||||
polyID[3] = int((inPolyIDAttributes[3].r * 63.0) + 0.5);\n\
|
||||
polyID[4] = int((inPolyIDAttributes[4].r * 63.0) + 0.5);\n\
|
||||
\n\
|
||||
bool antialias[5];\n\
|
||||
antialias[0] = bool(inPolyIDAttributes[0].g);\n\
|
||||
antialias[1] = bool(inPolyIDAttributes[1].g);\n\
|
||||
antialias[2] = bool(inPolyIDAttributes[2].g);\n\
|
||||
antialias[3] = bool(inPolyIDAttributes[3].g);\n\
|
||||
antialias[4] = bool(inPolyIDAttributes[4].g);\n\
|
||||
\n\
|
||||
float depth[5];\n\
|
||||
depth[0] = unpackFloatFromVec3(texture2D(texInFragDepth, texCoord[0]).rgb);\n\
|
||||
depth[1] = unpackFloatFromVec3(texture2D(texInFragDepth, texCoord[1]).rgb);\n\
|
||||
depth[2] = unpackFloatFromVec3(texture2D(texInFragDepth, texCoord[2]).rgb);\n\
|
||||
depth[3] = unpackFloatFromVec3(texture2D(texInFragDepth, texCoord[3]).rgb);\n\
|
||||
depth[4] = unpackFloatFromVec3(texture2D(texInFragDepth, texCoord[4]).rgb);\n\
|
||||
\n\
|
||||
vec4 edgeColor = stateEdgeColor[polyID[0]/8];\n\
|
||||
bool doEdgeMark = false;\n\
|
||||
bool doAntialias = false;\n\
|
||||
\n\
|
||||
for (int i = 1; i < 5; i++)\n\
|
||||
{\n\
|
||||
if (polyID[0] != polyID[i] && depth[0] >= depth[i])\n\
|
||||
{\n\
|
||||
doEdgeMark = true;\n\
|
||||
edgeColor = stateEdgeColor[polyID[i]/8];\n\
|
||||
doAntialias = antialias[i];\n\
|
||||
break;\n\
|
||||
}\n\
|
||||
}\n\
|
||||
\n\
|
||||
gl_FragData[0] = (doEdgeMark) ? ((doAntialias) ? mix(edgeColor, inFragColor, 0.4) : edgeColor) : inFragColor;\n\
|
||||
}\n\
|
||||
"};
|
||||
|
||||
// Vertex shader for applying fog, GLSL 1.00
|
||||
static const char *FogVtxShader_100 = {"\
|
||||
attribute vec2 inPosition;\n\
|
||||
attribute vec2 inTexCoord0;\n\
|
||||
varying vec2 texCoord;\n\
|
||||
|
@ -353,7 +441,7 @@ static const char *FogFragShader_100 = {"\
|
|||
varying vec2 texCoord;\n\
|
||||
\n\
|
||||
uniform sampler2D texInFragColor;\n\
|
||||
uniform sampler2D texInFragDepthOnly;\n\
|
||||
uniform sampler2D texInFragDepth;\n\
|
||||
uniform sampler2D texInFogAttributes;\n\
|
||||
uniform vec4 stateFogColor;\n\
|
||||
uniform float stateFogDensity[32];\n\
|
||||
|
@ -369,7 +457,7 @@ static const char *FogFragShader_100 = {"\
|
|||
void main()\n\
|
||||
{\n\
|
||||
vec4 inFragColor = texture2D(texInFragColor, texCoord);\n\
|
||||
float inFragDepth = unpackFloatFromVec3(texture2D(texInFragDepthOnly, texCoord).rgb);\n\
|
||||
float inFragDepth = unpackFloatFromVec3(texture2D(texInFragDepth, texCoord).rgb);\n\
|
||||
vec4 inFogAttributes = texture2D(texInFogAttributes, texCoord);\n\
|
||||
\n\
|
||||
bool polyEnableFog = bool(inFogAttributes.r);\n\
|
||||
|
@ -886,7 +974,7 @@ OpenGLRenderer_1_2::~OpenGLRenderer_1_2()
|
|||
ref->color4fBuffer = NULL;
|
||||
|
||||
DestroyGeometryProgram();
|
||||
DestroyPostprocessingProgram();
|
||||
DestroyPostprocessingPrograms();
|
||||
DestroyVAOs();
|
||||
DestroyVBOs();
|
||||
DestroyPBOs();
|
||||
|
@ -941,9 +1029,11 @@ Render3DError OpenGLRenderer_1_2::InitExtensions()
|
|||
this->isShaderSupported = false;
|
||||
}
|
||||
|
||||
std::string postprocessVtxShaderString = std::string(PostprocessVertShader_100);
|
||||
std::string postprocessFogFragShaderString = std::string(FogFragShader_100);
|
||||
error = this->InitPostprocessingProgram(postprocessVtxShaderString, postprocessFogFragShaderString);
|
||||
std::string edgeMarkVtxShaderString = std::string(EdgeMarkVtxShader_100);
|
||||
std::string edgeMarkFragShaderString = std::string(EdgeMarkFragShader_100);
|
||||
std::string fogVtxShaderString = std::string(FogVtxShader_100);
|
||||
std::string fogFragShaderString = std::string(FogFragShader_100);
|
||||
error = this->InitPostprocessingPrograms(edgeMarkVtxShaderString, edgeMarkFragShaderString, fogVtxShaderString, fogFragShaderString);
|
||||
if (error != OGLERROR_NOERR)
|
||||
{
|
||||
this->DestroyGeometryProgram();
|
||||
|
@ -1293,9 +1383,11 @@ Render3DError OpenGLRenderer_1_2::CreateFBOs()
|
|||
// Set up FBO render targets
|
||||
glGenTextures(1, &OGLRef.texGColorID);
|
||||
glGenTextures(1, &OGLRef.texGDepthID);
|
||||
glGenTextures(1, &OGLRef.texGPolyID);
|
||||
glGenTextures(1, &OGLRef.texGFogAttrID);
|
||||
glGenTextures(1, &OGLRef.texGDepthStencilID);
|
||||
glGenTextures(1, &OGLRef.texPostprocessID);
|
||||
glGenTextures(1, &OGLRef.texPostprocessEdgeMarkID);
|
||||
glGenTextures(1, &OGLRef.texPostprocessFogID);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, OGLRef.texGColorID);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
|
@ -1319,6 +1411,13 @@ Render3DError OpenGLRenderer_1_2::CreateFBOs()
|
|||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, OGLRef.texGPolyID);
|
||||
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, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, OGLRef.texGFogAttrID);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
@ -1326,7 +1425,14 @@ Render3DError OpenGLRenderer_1_2::CreateFBOs()
|
|||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, OGLRef.texPostprocessID);
|
||||
glBindTexture(GL_TEXTURE_2D, OGLRef.texPostprocessEdgeMarkID);
|
||||
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, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, OGLRef.texPostprocessFogID);
|
||||
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, GL_CLAMP_TO_EDGE);
|
||||
|
@ -1342,7 +1448,8 @@ Render3DError OpenGLRenderer_1_2::CreateFBOs()
|
|||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboRenderID);
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, OGLRef.texGColorID, 0);
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, OGLRef.texGDepthID, 0);
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT2_EXT, GL_TEXTURE_2D, OGLRef.texGFogAttrID, 0);
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT2_EXT, GL_TEXTURE_2D, OGLRef.texGPolyID, 0);
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT3_EXT, GL_TEXTURE_2D, OGLRef.texGFogAttrID, 0);
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, OGLRef.texGDepthStencilID, 0);
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_TEXTURE_2D, OGLRef.texGDepthStencilID, 0);
|
||||
|
||||
|
@ -1354,19 +1461,23 @@ Render3DError OpenGLRenderer_1_2::CreateFBOs()
|
|||
glDeleteFramebuffersEXT(1, &OGLRef.fboRenderID);
|
||||
glDeleteFramebuffersEXT(1, &OGLRef.fboPostprocessID);
|
||||
glDeleteTextures(1, &OGLRef.texGColorID);
|
||||
glDeleteTextures(1, &OGLRef.texGDepthStencilID);
|
||||
glDeleteTextures(1, &OGLRef.texGDepthID);
|
||||
glDeleteTextures(1, &OGLRef.texGPolyID);
|
||||
glDeleteTextures(1, &OGLRef.texGFogAttrID);
|
||||
glDeleteTextures(1, &OGLRef.texGDepthStencilID);
|
||||
glDeleteTextures(1, &OGLRef.texPostprocessEdgeMarkID);
|
||||
glDeleteTextures(1, &OGLRef.texPostprocessFogID);
|
||||
|
||||
this->isFBOSupported = false;
|
||||
return OGLERROR_FBO_CREATE_ERROR;
|
||||
}
|
||||
|
||||
glDrawBuffers(3, RenderDrawList);
|
||||
glDrawBuffers(4, RenderDrawList);
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboPostprocessID);
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, OGLRef.texPostprocessID, 0);
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, OGLRef.texPostprocessEdgeMarkID, 0);
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, OGLRef.texPostprocessFogID, 0);
|
||||
|
||||
if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT)
|
||||
{
|
||||
|
@ -1377,9 +1488,11 @@ Render3DError OpenGLRenderer_1_2::CreateFBOs()
|
|||
glDeleteFramebuffersEXT(1, &OGLRef.fboPostprocessID);
|
||||
glDeleteTextures(1, &OGLRef.texGColorID);
|
||||
glDeleteTextures(1, &OGLRef.texGDepthID);
|
||||
glDeleteTextures(1, &OGLRef.texGPolyID);
|
||||
glDeleteTextures(1, &OGLRef.texGFogAttrID);
|
||||
glDeleteTextures(1, &OGLRef.texGDepthStencilID);
|
||||
glDeleteTextures(1, &OGLRef.texPostprocessID);
|
||||
glDeleteTextures(1, &OGLRef.texPostprocessEdgeMarkID);
|
||||
glDeleteTextures(1, &OGLRef.texPostprocessFogID);
|
||||
|
||||
this->isFBOSupported = false;
|
||||
return OGLERROR_FBO_CREATE_ERROR;
|
||||
|
@ -1408,10 +1521,11 @@ void OpenGLRenderer_1_2::DestroyFBOs()
|
|||
glDeleteFramebuffersEXT(1, &OGLRef.fboRenderID);
|
||||
glDeleteFramebuffersEXT(1, &OGLRef.fboPostprocessID);
|
||||
glDeleteTextures(1, &OGLRef.texGColorID);
|
||||
glDeleteTextures(1, &OGLRef.texGDepthStencilID);
|
||||
glDeleteTextures(1, &OGLRef.texGDepthID);
|
||||
glDeleteTextures(1, &OGLRef.texGPolyID);
|
||||
glDeleteTextures(1, &OGLRef.texGFogAttrID);
|
||||
glDeleteTextures(1, &OGLRef.texPostprocessID);
|
||||
glDeleteTextures(1, &OGLRef.texGDepthStencilID);
|
||||
glDeleteTextures(1, &OGLRef.texPostprocessEdgeMarkID);
|
||||
|
||||
OGLRef.fboRenderID = 0;
|
||||
OGLRef.fboPostprocessID = 0;
|
||||
|
@ -1442,6 +1556,7 @@ Render3DError OpenGLRenderer_1_2::CreateMultisampledFBO()
|
|||
// Set up FBO render targets
|
||||
glGenRenderbuffersEXT(1, &OGLRef.rboMSGColorID);
|
||||
glGenRenderbuffersEXT(1, &OGLRef.rboMSGDepthID);
|
||||
glGenRenderbuffersEXT(1, &OGLRef.rboMSGPolyID);
|
||||
glGenRenderbuffersEXT(1, &OGLRef.rboMSGFogAttrID);
|
||||
glGenRenderbuffersEXT(1, &OGLRef.rboMSGDepthStencilID);
|
||||
|
||||
|
@ -1449,6 +1564,8 @@ Render3DError OpenGLRenderer_1_2::CreateMultisampledFBO()
|
|||
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, maxSamples, GL_RGBA, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT);
|
||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, OGLRef.rboMSGDepthID);
|
||||
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, maxSamples, GL_RGBA, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT);
|
||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, OGLRef.rboMSGPolyID);
|
||||
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, maxSamples, GL_RGBA, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT);
|
||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, OGLRef.rboMSGFogAttrID);
|
||||
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, maxSamples, GL_RGBA, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT);
|
||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, OGLRef.rboMSGDepthStencilID);
|
||||
|
@ -1460,7 +1577,8 @@ Render3DError OpenGLRenderer_1_2::CreateMultisampledFBO()
|
|||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboMSIntermediateRenderID);
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, OGLRef.rboMSGColorID);
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_RENDERBUFFER_EXT, OGLRef.rboMSGDepthID);
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT2_EXT, GL_RENDERBUFFER_EXT, OGLRef.rboMSGFogAttrID);
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT2_EXT, GL_RENDERBUFFER_EXT, OGLRef.rboMSGPolyID);
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT3_EXT, GL_RENDERBUFFER_EXT, OGLRef.rboMSGFogAttrID);
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, OGLRef.rboMSGDepthStencilID);
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, OGLRef.rboMSGDepthStencilID);
|
||||
|
||||
|
@ -1472,6 +1590,7 @@ Render3DError OpenGLRenderer_1_2::CreateMultisampledFBO()
|
|||
glDeleteFramebuffersEXT(1, &OGLRef.fboMSIntermediateRenderID);
|
||||
glDeleteRenderbuffersEXT(1, &OGLRef.rboMSGColorID);
|
||||
glDeleteRenderbuffersEXT(1, &OGLRef.rboMSGDepthID);
|
||||
glDeleteRenderbuffersEXT(1, &OGLRef.rboMSGPolyID);
|
||||
glDeleteRenderbuffersEXT(1, &OGLRef.rboMSGFogAttrID);
|
||||
glDeleteRenderbuffersEXT(1, &OGLRef.rboMSGDepthStencilID);
|
||||
|
||||
|
@ -1497,6 +1616,7 @@ void OpenGLRenderer_1_2::DestroyMultisampledFBO()
|
|||
glDeleteFramebuffersEXT(1, &OGLRef.fboMSIntermediateRenderID);
|
||||
glDeleteRenderbuffersEXT(1, &OGLRef.rboMSGColorID);
|
||||
glDeleteRenderbuffersEXT(1, &OGLRef.rboMSGDepthID);
|
||||
glDeleteRenderbuffersEXT(1, &OGLRef.rboMSGPolyID);
|
||||
glDeleteRenderbuffersEXT(1, &OGLRef.rboMSGFogAttrID);
|
||||
glDeleteRenderbuffersEXT(1, &OGLRef.rboMSGDepthStencilID);
|
||||
|
||||
|
@ -1568,17 +1688,22 @@ Render3DError OpenGLRenderer_1_2::InitTables()
|
|||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_1_2::InitPostprocessingProgram(const std::string &vtxShader, const std::string &fragShader)
|
||||
Render3DError OpenGLRenderer_1_2::InitEdgeMarkProgramBindings()
|
||||
{
|
||||
return OGLERROR_FEATURE_UNSUPPORTED;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_1_2::InitPostprocessingProgramBindings()
|
||||
Render3DError OpenGLRenderer_1_2::InitPostprocessingPrograms(const std::string &edgeMarkVtxShader, const std::string &edgeMarkFragShader, const std::string &fogVtxShader, const std::string &fogFragShader)
|
||||
{
|
||||
return OGLERROR_FEATURE_UNSUPPORTED;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_1_2::DestroyPostprocessingProgram()
|
||||
Render3DError OpenGLRenderer_1_2::InitFogProgramBindings()
|
||||
{
|
||||
return OGLERROR_FEATURE_UNSUPPORTED;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_1_2::DestroyPostprocessingPrograms()
|
||||
{
|
||||
return OGLERROR_FEATURE_UNSUPPORTED;
|
||||
}
|
||||
|
@ -1624,11 +1749,13 @@ Render3DError OpenGLRenderer_1_2::UploadClearImage(const u16 *__restrict colorBu
|
|||
OGLRenderRef &OGLRef = *this->ref;
|
||||
|
||||
static GLuint depth[GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT];
|
||||
static GLuint polyID[GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT];
|
||||
static GLuint fogAttributes[GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT];
|
||||
|
||||
for (size_t i = 0; i < GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT; i++)
|
||||
{
|
||||
depth[i] = clearImageDepthStencilBuffer[i] >> 8;
|
||||
polyID[i] = (depthStencilBuffer[i] & 0x0000003F) | 0xFF000000;
|
||||
fogAttributes[i] = (fogBuffer[i]) ? 0xFF0000FF : 0xFF000000;
|
||||
}
|
||||
|
||||
|
@ -1642,6 +1769,10 @@ Render3DError OpenGLRenderer_1_2::UploadClearImage(const u16 *__restrict colorBu
|
|||
glBindTexture(GL_TEXTURE_2D, OGLRef.texGDepthID);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, depth);
|
||||
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB + OGLTextureUnitID_GPolyID);
|
||||
glBindTexture(GL_TEXTURE_2D, OGLRef.texGPolyID);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, polyID);
|
||||
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB + OGLTextureUnitID_FogAttr);
|
||||
glBindTexture(GL_TEXTURE_2D, OGLRef.texGFogAttrID);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, fogAttributes);
|
||||
|
@ -1897,14 +2028,19 @@ Render3DError OpenGLRenderer_1_2::DownsampleFBO()
|
|||
glDrawBuffer(GL_COLOR_ATTACHMENT1_EXT);
|
||||
glBlitFramebufferEXT(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
|
||||
// Blit the fog buffer
|
||||
// Blit the polygon ID buffer
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT2_EXT);
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT2_EXT);
|
||||
glBlitFramebufferEXT(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
|
||||
// Blit the fog buffer
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT3_EXT);
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT3_EXT);
|
||||
glBlitFramebufferEXT(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
|
||||
// Reset framebuffer targets
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||
glDrawBuffers(3, RenderDrawList);
|
||||
glDrawBuffers(4, RenderDrawList);
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboRenderID);
|
||||
}
|
||||
|
||||
|
@ -2103,6 +2239,7 @@ Render3DError OpenGLRenderer_1_2::EndRender(const u64 frameCount)
|
|||
TexCache_EvictFrame();
|
||||
|
||||
this->ReadBackPixels();
|
||||
this->didRenderEdgeMark = false;
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
@ -2149,45 +2286,54 @@ Render3DError OpenGLRenderer_1_2::ClearUsingImage(const u16 *__restrict colorBuf
|
|||
glDrawBuffer(GL_COLOR_ATTACHMENT1_EXT);
|
||||
glBlitFramebufferEXT(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
|
||||
// Blit the fog buffer
|
||||
// Blit the polygon ID buffer
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT2_EXT);
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT2_EXT);
|
||||
glBlitFramebufferEXT(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
|
||||
// Blit the fog buffer
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT3_EXT);
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT3_EXT);
|
||||
glBlitFramebufferEXT(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
|
||||
// Reset framebuffer targets
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||
glDrawBuffers(3, RenderDrawList);
|
||||
glDrawBuffers(4, RenderDrawList);
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboMSIntermediateRenderID);
|
||||
}
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_1_2::ClearUsingValues(const u8 r, const u8 g, const u8 b, const u8 a, const u32 clearDepth, const u8 clearStencil, const bool enableFog) const
|
||||
Render3DError OpenGLRenderer_1_2::ClearUsingValues(const u8 r, const u8 g, const u8 b, const u8 a, const u32 clearDepth, const u8 clearPolyID, const bool enableFog) const
|
||||
{
|
||||
if (this->isShaderSupported && this->isFBOSupported)
|
||||
{
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); // texGColorID
|
||||
glClearColor(divide5bitBy31_LUT[r], divide5bitBy31_LUT[g], divide5bitBy31_LUT[b], divide5bitBy31_LUT[a]);
|
||||
glClearDepth((GLclampd)clearDepth / (GLclampd)0x00FFFFFF);
|
||||
glClearStencil(clearStencil);
|
||||
glClearStencil(clearPolyID);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT1_EXT); // texGDepthID
|
||||
glClearColor((GLfloat)(clearDepth & 0x000000FF)/255.0f, (GLfloat)((clearDepth >> 8) & 0x000000FF)/255.0f, (GLfloat)((clearDepth >> 16) & 0x000000FF)/255.0f, 1.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT2_EXT); // texGFogAttrID
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT2_EXT); // texGPolyID
|
||||
glClearColor((GLfloat)clearPolyID/63.0f, 0.0, 0.0, 1.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT3_EXT); // texGFogAttrID
|
||||
glClearColor((enableFog) ? 1.0 : 0.0, 0.0, 0.0, 1.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glDrawBuffers(3, RenderDrawList);
|
||||
glDrawBuffers(4, RenderDrawList);
|
||||
}
|
||||
else
|
||||
{
|
||||
glClearColor(divide5bitBy31_LUT[r], divide5bitBy31_LUT[g], divide5bitBy31_LUT[b], divide5bitBy31_LUT[a]);
|
||||
glClearDepth((GLclampd)clearDepth / (GLclampd)0x00FFFFFF);
|
||||
glClearStencil(clearStencil);
|
||||
glClearStencil(clearPolyID);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
}
|
||||
|
||||
|
@ -2388,6 +2534,7 @@ Render3DError OpenGLRenderer_1_2::Reset()
|
|||
|
||||
this->gpuScreen3DHasNewData[0] = false;
|
||||
this->gpuScreen3DHasNewData[1] = false;
|
||||
didRenderEdgeMark = false;
|
||||
|
||||
glFinish();
|
||||
|
||||
|
@ -2486,11 +2633,13 @@ Render3DError OpenGLRenderer_1_3::UploadClearImage(const u16 *__restrict colorBu
|
|||
OGLRenderRef &OGLRef = *this->ref;
|
||||
|
||||
static GLuint depth[GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT];
|
||||
static GLuint polyID[GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT];
|
||||
static GLuint fogAttributes[GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT];
|
||||
|
||||
for (size_t i = 0; i < GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT; i++)
|
||||
{
|
||||
depth[i] = (depthStencilBuffer[i] >> 8) | 0xFF000000;
|
||||
polyID[i] = (depthStencilBuffer[i] & 0x0000003F) | 0xFF000000;
|
||||
fogAttributes[i] = (fogBuffer[i]) ? 0xFF0000FF : 0xFF000000;
|
||||
}
|
||||
|
||||
|
@ -2504,6 +2653,10 @@ Render3DError OpenGLRenderer_1_3::UploadClearImage(const u16 *__restrict colorBu
|
|||
glBindTexture(GL_TEXTURE_2D, OGLRef.texGDepthID);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, depth);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_GPolyID);
|
||||
glBindTexture(GL_TEXTURE_2D, OGLRef.texGPolyID);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, polyID);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_FogAttr);
|
||||
glBindTexture(GL_TEXTURE_2D, OGLRef.texGFogAttrID);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, fogAttributes);
|
||||
|
@ -2827,9 +2980,11 @@ Render3DError OpenGLRenderer_2_0::InitExtensions()
|
|||
return error;
|
||||
}
|
||||
|
||||
std::string postprocessVtxShaderString = std::string(PostprocessVertShader_100);
|
||||
std::string postprocessFogFragShaderString = std::string(FogFragShader_100);
|
||||
error = this->InitPostprocessingProgram(postprocessVtxShaderString, postprocessFogFragShaderString);
|
||||
std::string edgeMarkVtxShaderString = std::string(EdgeMarkVtxShader_100);
|
||||
std::string edgeMarkFragShaderString = std::string(EdgeMarkFragShader_100);
|
||||
std::string fogVtxShaderString = std::string(FogVtxShader_100);
|
||||
std::string fogFragShaderString = std::string(FogFragShader_100);
|
||||
error = this->InitPostprocessingPrograms(edgeMarkVtxShaderString, edgeMarkFragShaderString, fogVtxShaderString, fogFragShaderString);
|
||||
if (error != OGLERROR_NOERR)
|
||||
{
|
||||
this->DestroyGeometryProgram();
|
||||
|
@ -2918,42 +3073,136 @@ Render3DError OpenGLRenderer_2_0::InitFinalRenderStates(const std::set<std::stri
|
|||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_2_0::InitPostprocessingProgram(const std::string &vtxShader, const std::string &fragShader)
|
||||
Render3DError OpenGLRenderer_2_0::InitEdgeMarkProgramBindings()
|
||||
{
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
glBindAttribLocation(OGLRef.programEdgeMarkID, OGLVertexAttributeID_Position, "inPosition");
|
||||
glBindAttribLocation(OGLRef.programEdgeMarkID, OGLVertexAttributeID_TexCoord0, "inTexCoord0");
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_2_0::InitPostprocessingPrograms(const std::string &edgeMarkVtxShader, const std::string &edgeMarkFragShader, const std::string &fogVtxShader, const std::string &fogFragShader)
|
||||
{
|
||||
Render3DError error = OGLERROR_NOERR;
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
|
||||
OGLRef.vertexPostprocessShaderID = glCreateShader(GL_VERTEX_SHADER);
|
||||
if(!OGLRef.vertexPostprocessShaderID)
|
||||
OGLRef.vertexEdgeMarkShaderID = glCreateShader(GL_VERTEX_SHADER);
|
||||
if(!OGLRef.vertexEdgeMarkShaderID)
|
||||
{
|
||||
INFO("OpenGL: Failed to create the postprocess vertex shader.\n");
|
||||
INFO("OpenGL: Failed to create the edge mark vertex shader.\n");
|
||||
return OGLERROR_SHADER_CREATE_ERROR;
|
||||
}
|
||||
|
||||
const char *vtxShaderCStr = vtxShader.c_str();
|
||||
glShaderSource(OGLRef.vertexPostprocessShaderID, 1, (const GLchar **)&vtxShaderCStr, NULL);
|
||||
glCompileShader(OGLRef.vertexPostprocessShaderID);
|
||||
if (!this->ValidateShaderCompile(OGLRef.vertexPostprocessShaderID))
|
||||
const char *edgeMarkVtxShaderCStr = edgeMarkVtxShader.c_str();
|
||||
glShaderSource(OGLRef.vertexEdgeMarkShaderID, 1, (const GLchar **)&edgeMarkVtxShaderCStr, NULL);
|
||||
glCompileShader(OGLRef.vertexEdgeMarkShaderID);
|
||||
if (!this->ValidateShaderCompile(OGLRef.vertexEdgeMarkShaderID))
|
||||
{
|
||||
glDeleteShader(OGLRef.vertexPostprocessShaderID);
|
||||
INFO("OpenGL: Failed to compile the postprocess vertex shader.\n");
|
||||
glDeleteShader(OGLRef.vertexEdgeMarkShaderID);
|
||||
INFO("OpenGL: Failed to compile the edge mark vertex shader.\n");
|
||||
return OGLERROR_SHADER_CREATE_ERROR;
|
||||
}
|
||||
|
||||
OGLRef.fragmentEdgeMarkShaderID = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
if(!OGLRef.fragmentEdgeMarkShaderID)
|
||||
{
|
||||
glDeleteShader(OGLRef.vertexEdgeMarkShaderID);
|
||||
INFO("OpenGL: Failed to create the edge mark fragment shader.\n");
|
||||
return OGLERROR_SHADER_CREATE_ERROR;
|
||||
}
|
||||
|
||||
const char *edgeMarkFragShaderCStr = edgeMarkFragShader.c_str();
|
||||
glShaderSource(OGLRef.fragmentEdgeMarkShaderID, 1, (const GLchar **)&edgeMarkFragShaderCStr, NULL);
|
||||
glCompileShader(OGLRef.fragmentEdgeMarkShaderID);
|
||||
if (!this->ValidateShaderCompile(OGLRef.fragmentEdgeMarkShaderID))
|
||||
{
|
||||
glDeleteShader(OGLRef.vertexEdgeMarkShaderID);
|
||||
glDeleteShader(OGLRef.fragmentEdgeMarkShaderID);
|
||||
INFO("OpenGL: Failed to compile the edge mark fragment shader.\n");
|
||||
return OGLERROR_SHADER_CREATE_ERROR;
|
||||
}
|
||||
|
||||
OGLRef.programEdgeMarkID = glCreateProgram();
|
||||
if(!OGLRef.programEdgeMarkID)
|
||||
{
|
||||
glDeleteShader(OGLRef.vertexEdgeMarkShaderID);
|
||||
glDeleteShader(OGLRef.fragmentEdgeMarkShaderID);
|
||||
INFO("OpenGL: Failed to create the edge mark shader program.\n");
|
||||
return OGLERROR_SHADER_CREATE_ERROR;
|
||||
}
|
||||
|
||||
glAttachShader(OGLRef.programEdgeMarkID, OGLRef.vertexEdgeMarkShaderID);
|
||||
glAttachShader(OGLRef.programEdgeMarkID, OGLRef.fragmentEdgeMarkShaderID);
|
||||
|
||||
error = this->InitEdgeMarkProgramBindings();
|
||||
if (error != OGLERROR_NOERR)
|
||||
{
|
||||
glDetachShader(OGLRef.programEdgeMarkID, OGLRef.vertexEdgeMarkShaderID);
|
||||
glDetachShader(OGLRef.programEdgeMarkID, OGLRef.fragmentEdgeMarkShaderID);
|
||||
glDeleteProgram(OGLRef.programEdgeMarkID);
|
||||
glDeleteShader(OGLRef.vertexEdgeMarkShaderID);
|
||||
glDeleteShader(OGLRef.fragmentEdgeMarkShaderID);
|
||||
INFO("OpenGL: Failed to make the edge mark shader bindings.\n");
|
||||
return error;
|
||||
}
|
||||
|
||||
glLinkProgram(OGLRef.programEdgeMarkID);
|
||||
if (!this->ValidateShaderProgramLink(OGLRef.programEdgeMarkID))
|
||||
{
|
||||
glDetachShader(OGLRef.programEdgeMarkID, OGLRef.vertexEdgeMarkShaderID);
|
||||
glDetachShader(OGLRef.programEdgeMarkID, OGLRef.fragmentEdgeMarkShaderID);
|
||||
glDeleteProgram(OGLRef.programEdgeMarkID);
|
||||
glDeleteShader(OGLRef.vertexEdgeMarkShaderID);
|
||||
glDeleteShader(OGLRef.fragmentEdgeMarkShaderID);
|
||||
INFO("OpenGL: Failed to link the edge mark shader program.\n");
|
||||
return OGLERROR_SHADER_CREATE_ERROR;
|
||||
}
|
||||
|
||||
glValidateProgram(OGLRef.programEdgeMarkID);
|
||||
glUseProgram(OGLRef.programEdgeMarkID);
|
||||
|
||||
// Set up shader uniforms
|
||||
OGLRef.uniformTexGColor_EdgeMark = glGetUniformLocation(OGLRef.programEdgeMarkID, "texInFragColor");
|
||||
OGLRef.uniformTexGDepth_EdgeMark = glGetUniformLocation(OGLRef.programEdgeMarkID, "texInFragDepth");
|
||||
OGLRef.uniformTexGPolyID_EdgeMark = glGetUniformLocation(OGLRef.programEdgeMarkID, "texInPolyID");
|
||||
|
||||
OGLRef.uniformFramebufferSize = glGetUniformLocation(OGLRef.programEdgeMarkID, "framebufferSize");
|
||||
OGLRef.uniformStateEdgeColor = glGetUniformLocation(OGLRef.programEdgeMarkID, "stateEdgeColor");
|
||||
|
||||
// ------------------------------------------
|
||||
|
||||
OGLRef.vertexFogShaderID = glCreateShader(GL_VERTEX_SHADER);
|
||||
if(!OGLRef.vertexFogShaderID)
|
||||
{
|
||||
INFO("OpenGL: Failed to create the fog vertex shader.\n");
|
||||
return OGLERROR_SHADER_CREATE_ERROR;
|
||||
}
|
||||
|
||||
const char *fogVtxShaderCStr = fogVtxShader.c_str();
|
||||
glShaderSource(OGLRef.vertexFogShaderID, 1, (const GLchar **)&fogVtxShaderCStr, NULL);
|
||||
glCompileShader(OGLRef.vertexFogShaderID);
|
||||
if (!this->ValidateShaderCompile(OGLRef.vertexFogShaderID))
|
||||
{
|
||||
glDeleteShader(OGLRef.vertexFogShaderID);
|
||||
INFO("OpenGL: Failed to compile the fog vertex shader.\n");
|
||||
return OGLERROR_SHADER_CREATE_ERROR;
|
||||
}
|
||||
|
||||
OGLRef.fragmentFogShaderID = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
if(!OGLRef.fragmentFogShaderID)
|
||||
{
|
||||
glDeleteShader(OGLRef.vertexPostprocessShaderID);
|
||||
glDeleteShader(OGLRef.vertexFogShaderID);
|
||||
INFO("OpenGL: Failed to create the fog fragment shader.\n");
|
||||
return OGLERROR_SHADER_CREATE_ERROR;
|
||||
}
|
||||
|
||||
const char *fragShaderCStr = fragShader.c_str();
|
||||
glShaderSource(OGLRef.fragmentFogShaderID, 1, (const GLchar **)&fragShaderCStr, NULL);
|
||||
const char *fogFragShaderCStr = fogFragShader.c_str();
|
||||
glShaderSource(OGLRef.fragmentFogShaderID, 1, (const GLchar **)&fogFragShaderCStr, NULL);
|
||||
glCompileShader(OGLRef.fragmentFogShaderID);
|
||||
if (!this->ValidateShaderCompile(OGLRef.fragmentFogShaderID))
|
||||
{
|
||||
glDeleteShader(OGLRef.vertexPostprocessShaderID);
|
||||
glDeleteShader(OGLRef.vertexFogShaderID);
|
||||
glDeleteShader(OGLRef.fragmentFogShaderID);
|
||||
INFO("OpenGL: Failed to compile the fog fragment shader.\n");
|
||||
return OGLERROR_SHADER_CREATE_ERROR;
|
||||
|
@ -2962,22 +3211,22 @@ Render3DError OpenGLRenderer_2_0::InitPostprocessingProgram(const std::string &v
|
|||
OGLRef.programFogID = glCreateProgram();
|
||||
if(!OGLRef.programFogID)
|
||||
{
|
||||
glDeleteShader(OGLRef.vertexPostprocessShaderID);
|
||||
glDeleteShader(OGLRef.vertexFogShaderID);
|
||||
glDeleteShader(OGLRef.fragmentFogShaderID);
|
||||
INFO("OpenGL: Failed to create the fog shader program.\n");
|
||||
return OGLERROR_SHADER_CREATE_ERROR;
|
||||
}
|
||||
|
||||
glAttachShader(OGLRef.programFogID, OGLRef.vertexPostprocessShaderID);
|
||||
glAttachShader(OGLRef.programFogID, OGLRef.vertexFogShaderID);
|
||||
glAttachShader(OGLRef.programFogID, OGLRef.fragmentFogShaderID);
|
||||
|
||||
error = this->InitPostprocessingProgramBindings();
|
||||
error = this->InitFogProgramBindings();
|
||||
if (error != OGLERROR_NOERR)
|
||||
{
|
||||
glDetachShader(OGLRef.programFogID, OGLRef.vertexPostprocessShaderID);
|
||||
glDetachShader(OGLRef.programFogID, OGLRef.vertexFogShaderID);
|
||||
glDetachShader(OGLRef.programFogID, OGLRef.fragmentFogShaderID);
|
||||
glDeleteProgram(OGLRef.programFogID);
|
||||
glDeleteShader(OGLRef.vertexPostprocessShaderID);
|
||||
glDeleteShader(OGLRef.vertexFogShaderID);
|
||||
glDeleteShader(OGLRef.fragmentFogShaderID);
|
||||
INFO("OpenGL: Failed to make the fog shader bindings.\n");
|
||||
return error;
|
||||
|
@ -2986,10 +3235,10 @@ Render3DError OpenGLRenderer_2_0::InitPostprocessingProgram(const std::string &v
|
|||
glLinkProgram(OGLRef.programFogID);
|
||||
if (!this->ValidateShaderProgramLink(OGLRef.programFogID))
|
||||
{
|
||||
glDetachShader(OGLRef.programFogID, OGLRef.vertexPostprocessShaderID);
|
||||
glDetachShader(OGLRef.programFogID, OGLRef.vertexFogShaderID);
|
||||
glDetachShader(OGLRef.programFogID, OGLRef.fragmentFogShaderID);
|
||||
glDeleteProgram(OGLRef.programFogID);
|
||||
glDeleteShader(OGLRef.vertexPostprocessShaderID);
|
||||
glDeleteShader(OGLRef.vertexFogShaderID);
|
||||
glDeleteShader(OGLRef.fragmentFogShaderID);
|
||||
INFO("OpenGL: Failed to link the fog shader program.\n");
|
||||
return OGLERROR_SHADER_CREATE_ERROR;
|
||||
|
@ -2999,9 +3248,9 @@ Render3DError OpenGLRenderer_2_0::InitPostprocessingProgram(const std::string &v
|
|||
glUseProgram(OGLRef.programFogID);
|
||||
|
||||
// Set up shader uniforms
|
||||
OGLRef.uniformTexGColor = glGetUniformLocation(OGLRef.programFogID, "texInFragColor");
|
||||
OGLRef.uniformTexGDepth = glGetUniformLocation(OGLRef.programFogID, "texInFragDepthOnly");
|
||||
OGLRef.uniformTexGFog = glGetUniformLocation(OGLRef.programFogID, "texInFogAttributes");
|
||||
OGLRef.uniformTexGColor_Fog = glGetUniformLocation(OGLRef.programFogID, "texInFragColor");
|
||||
OGLRef.uniformTexGDepth_Fog = glGetUniformLocation(OGLRef.programFogID, "texInFragDepth");
|
||||
OGLRef.uniformTexGFog_Fog = glGetUniformLocation(OGLRef.programFogID, "texInFogAttributes");
|
||||
|
||||
OGLRef.uniformStateFogColor = glGetUniformLocation(OGLRef.programFogID, "stateFogColor");
|
||||
OGLRef.uniformStateFogDensity = glGetUniformLocation(OGLRef.programFogID, "stateFogDensity");
|
||||
|
@ -3014,7 +3263,7 @@ Render3DError OpenGLRenderer_2_0::InitPostprocessingProgram(const std::string &v
|
|||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_2_0::InitPostprocessingProgramBindings()
|
||||
Render3DError OpenGLRenderer_2_0::InitFogProgramBindings()
|
||||
{
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
glBindAttribLocation(OGLRef.programFogID, OGLVertexAttributeID_Position, "inPosition");
|
||||
|
@ -3023,16 +3272,23 @@ Render3DError OpenGLRenderer_2_0::InitPostprocessingProgramBindings()
|
|||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_2_0::DestroyPostprocessingProgram()
|
||||
Render3DError OpenGLRenderer_2_0::DestroyPostprocessingPrograms()
|
||||
{
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
|
||||
glUseProgram(0);
|
||||
glDetachShader(OGLRef.programFogID, OGLRef.vertexPostprocessShaderID);
|
||||
glDetachShader(OGLRef.programEdgeMarkID, OGLRef.vertexEdgeMarkShaderID);
|
||||
glDetachShader(OGLRef.programEdgeMarkID, OGLRef.fragmentEdgeMarkShaderID);
|
||||
glDetachShader(OGLRef.programFogID, OGLRef.vertexFogShaderID);
|
||||
glDetachShader(OGLRef.programFogID, OGLRef.fragmentFogShaderID);
|
||||
|
||||
glDeleteProgram(OGLRef.programEdgeMarkID);
|
||||
glDeleteProgram(OGLRef.programFogID);
|
||||
|
||||
glDeleteShader(OGLRef.vertexEdgeMarkShaderID);
|
||||
glDeleteShader(OGLRef.fragmentEdgeMarkShaderID);
|
||||
glDeleteShader(OGLRef.vertexFogShaderID);
|
||||
glDeleteShader(OGLRef.fragmentFogShaderID);
|
||||
glDeleteShader(OGLRef.vertexPostprocessShaderID);
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
@ -3162,6 +3418,100 @@ Render3DError OpenGLRenderer_2_0::BeginRender(const GFX3D_State *renderState)
|
|||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_2_0::RenderEdgeMarking(const u16 *colorTable)
|
||||
{
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
|
||||
const GLfloat oglColor[4*8] = {divide5bitBy31_LUT[(colorTable[0] ) & 0x001F],
|
||||
divide5bitBy31_LUT[(colorTable[0] >> 5) & 0x001F],
|
||||
divide5bitBy31_LUT[(colorTable[0] >> 10) & 0x001F],
|
||||
1.0f,
|
||||
divide5bitBy31_LUT[(colorTable[1] ) & 0x001F],
|
||||
divide5bitBy31_LUT[(colorTable[1] >> 5) & 0x001F],
|
||||
divide5bitBy31_LUT[(colorTable[1] >> 10) & 0x001F],
|
||||
1.0f,
|
||||
divide5bitBy31_LUT[(colorTable[2] ) & 0x001F],
|
||||
divide5bitBy31_LUT[(colorTable[2] >> 5) & 0x001F],
|
||||
divide5bitBy31_LUT[(colorTable[2] >> 10) & 0x001F],
|
||||
1.0f,
|
||||
divide5bitBy31_LUT[(colorTable[3] ) & 0x001F],
|
||||
divide5bitBy31_LUT[(colorTable[3] >> 5) & 0x001F],
|
||||
divide5bitBy31_LUT[(colorTable[3] >> 10) & 0x001F],
|
||||
1.0f,
|
||||
divide5bitBy31_LUT[(colorTable[4] ) & 0x001F],
|
||||
divide5bitBy31_LUT[(colorTable[4] >> 5) & 0x001F],
|
||||
divide5bitBy31_LUT[(colorTable[4] >> 10) & 0x001F],
|
||||
1.0f,
|
||||
divide5bitBy31_LUT[(colorTable[5] ) & 0x001F],
|
||||
divide5bitBy31_LUT[(colorTable[5] >> 5) & 0x001F],
|
||||
divide5bitBy31_LUT[(colorTable[5] >> 10) & 0x001F],
|
||||
1.0f,
|
||||
divide5bitBy31_LUT[(colorTable[6] ) & 0x001F],
|
||||
divide5bitBy31_LUT[(colorTable[6] >> 5) & 0x001F],
|
||||
divide5bitBy31_LUT[(colorTable[6] >> 10) & 0x001F],
|
||||
1.0f,
|
||||
divide5bitBy31_LUT[(colorTable[7] ) & 0x001F],
|
||||
divide5bitBy31_LUT[(colorTable[7] >> 5) & 0x001F],
|
||||
divide5bitBy31_LUT[(colorTable[7] >> 10) & 0x001F],
|
||||
1.0f};
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER_EXT, OGLRef.fboPostprocessID);
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||
glUseProgram(OGLRef.programEdgeMarkID);
|
||||
glUniform1i(OGLRef.uniformTexGColor_EdgeMark, OGLTextureUnitID_GColor);
|
||||
glUniform1i(OGLRef.uniformTexGDepth_EdgeMark, OGLTextureUnitID_GDepth);
|
||||
glUniform1i(OGLRef.uniformTexGPolyID_EdgeMark, OGLTextureUnitID_GPolyID);
|
||||
glUniform2f(OGLRef.uniformFramebufferSize, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT);
|
||||
glUniform4fv(OGLRef.uniformStateEdgeColor, 8, oglColor);
|
||||
|
||||
glViewport(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboPostprocessVtxID);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, OGLRef.iboPostprocessIndexID);
|
||||
|
||||
if (this->isVAOSupported)
|
||||
{
|
||||
glBindVertexArray(OGLRef.vaoPostprocessStatesID);
|
||||
}
|
||||
else
|
||||
{
|
||||
glEnableVertexAttribArray(OGLVertexAttributeID_Position);
|
||||
glEnableVertexAttribArray(OGLVertexAttributeID_TexCoord0);
|
||||
glVertexAttribPointer(OGLVertexAttributeID_Position, 2, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
glVertexAttribPointer(OGLVertexAttributeID_TexCoord0, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid *)(sizeof(GLfloat) * 8));
|
||||
}
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_GColor);
|
||||
glBindTexture(GL_TEXTURE_2D, OGLRef.texGColorID);
|
||||
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_GDepth);
|
||||
glBindTexture(GL_TEXTURE_2D, OGLRef.texGDepthID);
|
||||
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_GPolyID);
|
||||
glBindTexture(GL_TEXTURE_2D, OGLRef.texGPolyID);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, 0);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
if (this->isVAOSupported)
|
||||
{
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisableVertexAttribArray(OGLVertexAttributeID_Position);
|
||||
glDisableVertexAttribArray(OGLVertexAttributeID_TexCoord0);
|
||||
}
|
||||
|
||||
this->didRenderEdgeMark = true;
|
||||
|
||||
return RENDER3DERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_2_0::RenderFog(const u8 *densityTable, const u32 color, const u32 offset, const u8 shift)
|
||||
{
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
|
@ -3186,10 +3536,12 @@ Render3DError OpenGLRenderer_2_0::RenderFog(const u8 *densityTable, const u32 co
|
|||
const GLfloat oglFogStep = (GLfloat)(0x0400 >> shift) / 32767.0f;
|
||||
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboPostprocessID);
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT1_EXT);
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT1_EXT);
|
||||
glUseProgram(OGLRef.programFogID);
|
||||
glUniform1i(OGLRef.uniformTexGColor, OGLTextureUnitID_GColor);
|
||||
glUniform1i(OGLRef.uniformTexGDepth, OGLTextureUnitID_GDepth);
|
||||
glUniform1i(OGLRef.uniformTexGFog, OGLTextureUnitID_FogAttr);
|
||||
glUniform1i(OGLRef.uniformTexGColor_Fog, OGLTextureUnitID_GColor);
|
||||
glUniform1i(OGLRef.uniformTexGDepth_Fog, OGLTextureUnitID_GDepth);
|
||||
glUniform1i(OGLRef.uniformTexGFog_Fog, OGLTextureUnitID_FogAttr);
|
||||
glUniform4f(OGLRef.uniformStateFogColor, oglColor[0], oglColor[1], oglColor[2], oglColor[3]);
|
||||
glUniform1f(OGLRef.uniformStateFogOffset, oglOffset);
|
||||
glUniform1f(OGLRef.uniformStateFogStep, oglFogStep);
|
||||
|
@ -3217,7 +3569,7 @@ Render3DError OpenGLRenderer_2_0::RenderFog(const u8 *densityTable, const u32 co
|
|||
}
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_GColor);
|
||||
glBindTexture(GL_TEXTURE_2D, OGLRef.texGColorID);
|
||||
glBindTexture(GL_TEXTURE_2D, (this->didRenderEdgeMark) ? OGLRef.texPostprocessEdgeMarkID : OGLRef.texGColorID);
|
||||
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_GDepth);
|
||||
glBindTexture(GL_TEXTURE_2D, OGLRef.texGDepthID);
|
||||
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_FogAttr);
|
||||
|
|
|
@ -133,6 +133,7 @@ EXTERNOGLEXT(PFNGLUNIFORM1FPROC, glUniform1f) // Core in v2.0
|
|||
EXTERNOGLEXT(PFNGLUNIFORM1FVPROC, glUniform1fv) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLUNIFORM2FPROC, glUniform2f) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLUNIFORM4FPROC, glUniform4f) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLUNIFORM4FVPROC, glUniform4fv) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLDRAWBUFFERSPROC, glDrawBuffers) // Core in v2.0
|
||||
|
||||
// Generic vertex attributes
|
||||
|
@ -216,6 +217,7 @@ EXTERNOGLEXT(PFNGLUNIFORM1FPROC, glUniform1f) // Core in v2.0
|
|||
EXTERNOGLEXT(PFNGLUNIFORM1FVPROC, glUniform1fv) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLUNIFORM2FPROC, glUniform2f) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLUNIFORM4FPROC, glUniform4f) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLUNIFORM4FVPROC, glUniform4fv) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLDRAWBUFFERSPROC, glDrawBuffers) // Core in v2.0
|
||||
|
||||
// Generic vertex attributes
|
||||
|
@ -279,6 +281,7 @@ enum OGLTextureUnitID
|
|||
OGLTextureUnitID_ToonTable = 1,
|
||||
OGLTextureUnitID_GColor,
|
||||
OGLTextureUnitID_GDepth,
|
||||
OGLTextureUnitID_GPolyID,
|
||||
OGLTextureUnitID_FogAttr
|
||||
};
|
||||
|
||||
|
@ -317,15 +320,18 @@ struct OGLRenderRef
|
|||
|
||||
// FBO
|
||||
GLuint texGColorID;
|
||||
GLuint texGDepthStencilID;
|
||||
GLuint texGDepthID;
|
||||
GLuint texGFogAttrID;
|
||||
GLuint texPostprocessID;
|
||||
GLuint texGPolyID;
|
||||
GLuint texGDepthStencilID;
|
||||
GLuint texPostprocessEdgeMarkID;
|
||||
GLuint texPostprocessFogID;
|
||||
|
||||
GLuint rboMSGColorID;
|
||||
GLuint rboMSGDepthStencilID;
|
||||
GLuint rboMSGDepthID;
|
||||
GLuint rboMSGPolyID;
|
||||
GLuint rboMSGFogAttrID;
|
||||
GLuint rboMSGDepthStencilID;
|
||||
GLuint rboMSPostprocessID;
|
||||
|
||||
GLuint fboRenderID;
|
||||
|
@ -338,7 +344,8 @@ struct OGLRenderRef
|
|||
GLuint fragmentGeometryShaderID;
|
||||
GLuint programGeometryID;
|
||||
|
||||
GLuint vertexPostprocessShaderID;
|
||||
GLuint vertexEdgeMarkShaderID;
|
||||
GLuint vertexFogShaderID;
|
||||
GLuint fragmentEdgeMarkShaderID;
|
||||
GLuint fragmentFogShaderID;
|
||||
GLuint programEdgeMarkID;
|
||||
|
@ -346,10 +353,14 @@ struct OGLRenderRef
|
|||
|
||||
GLuint uniformTexRenderObject;
|
||||
GLuint uniformTexToonTable;
|
||||
GLuint uniformTexGColor;
|
||||
GLuint uniformTexGDepth;
|
||||
GLuint uniformTexGFog;
|
||||
GLuint uniformTexGColor_EdgeMark;
|
||||
GLuint uniformTexGDepth_EdgeMark;
|
||||
GLuint uniformTexGPolyID_EdgeMark;
|
||||
GLuint uniformTexGColor_Fog;
|
||||
GLuint uniformTexGDepth_Fog;
|
||||
GLuint uniformTexGFog_Fog;
|
||||
|
||||
GLint uniformFramebufferSize;
|
||||
GLint uniformStateToonShadingMode;
|
||||
GLint uniformStateEnableAlphaTest;
|
||||
GLint uniformStateEnableAntialiasing;
|
||||
|
@ -357,6 +368,7 @@ struct OGLRenderRef
|
|||
GLint uniformStateEnableFogAlphaOnly;
|
||||
GLint uniformStateUseWDepth;
|
||||
GLint uniformStateAlphaTestRef;
|
||||
GLint uniformStateEdgeColor;
|
||||
GLint uniformStateFogColor;
|
||||
GLint uniformStateFogDensity;
|
||||
GLint uniformStateFogOffset;
|
||||
|
@ -397,7 +409,7 @@ extern GPU3DInterface gpu3Dgl;
|
|||
extern GPU3DInterface gpu3DglOld;
|
||||
extern GPU3DInterface gpu3Dgl_3_2;
|
||||
|
||||
extern const GLenum RenderDrawList[3];
|
||||
extern const GLenum RenderDrawList[4];
|
||||
extern CACHE_ALIGN const GLfloat divide5bitBy31_LUT[32];
|
||||
extern const GLfloat PostprocessVtxBuffer[16];;
|
||||
extern const GLubyte PostprocessElementBuffer[6];
|
||||
|
@ -452,6 +464,7 @@ protected:
|
|||
|
||||
CACHE_ALIGN u32 GPU_screen3D[2][GFX3D_FRAMEBUFFER_WIDTH * GFX3D_FRAMEBUFFER_HEIGHT * sizeof(u32)];
|
||||
bool gpuScreen3DHasNewData[2];
|
||||
bool didRenderEdgeMark;
|
||||
size_t doubleBufferIndex;
|
||||
|
||||
// OpenGL-specific methods
|
||||
|
@ -470,9 +483,10 @@ protected:
|
|||
virtual Render3DError InitTextures() = 0;
|
||||
virtual Render3DError InitFinalRenderStates(const std::set<std::string> *oglExtensionSet) = 0;
|
||||
virtual Render3DError InitTables() = 0;
|
||||
virtual Render3DError InitPostprocessingProgram(const std::string &vtxShader, const std::string &fragShader) = 0;
|
||||
virtual Render3DError InitPostprocessingProgramBindings() = 0;
|
||||
virtual Render3DError DestroyPostprocessingProgram() = 0;
|
||||
virtual Render3DError InitEdgeMarkProgramBindings() = 0;
|
||||
virtual Render3DError InitPostprocessingPrograms(const std::string &edgeMarkVtxShader, const std::string &edgeMarkFragShader, const std::string &fogVtxShader, const std::string &fogFragShader) = 0;
|
||||
virtual Render3DError InitFogProgramBindings() = 0;
|
||||
virtual Render3DError DestroyPostprocessingPrograms() = 0;
|
||||
|
||||
virtual Render3DError LoadGeometryShaders(std::string &outVertexShaderProgram, std::string &outFragmentShaderProgram) = 0;
|
||||
virtual Render3DError InitGeometryProgramBindings() = 0;
|
||||
|
@ -527,9 +541,10 @@ protected:
|
|||
virtual Render3DError LoadGeometryShaders(std::string &outVertexShaderProgram, std::string &outFragmentShaderProgram);
|
||||
virtual Render3DError InitGeometryProgramBindings();
|
||||
virtual void DestroyGeometryProgram();
|
||||
virtual Render3DError InitPostprocessingProgram(const std::string &vtxShader, const std::string &fragShader);
|
||||
virtual Render3DError InitPostprocessingProgramBindings();
|
||||
virtual Render3DError DestroyPostprocessingProgram();
|
||||
virtual Render3DError InitEdgeMarkProgramBindings();
|
||||
virtual Render3DError InitPostprocessingPrograms(const std::string &edgeMarkVtxShader, const std::string &edgeMarkFragShader, const std::string &fogVtxShader, const std::string &fogFragShader);
|
||||
virtual Render3DError InitFogProgramBindings();
|
||||
virtual Render3DError DestroyPostprocessingPrograms();
|
||||
|
||||
virtual Render3DError CreateToonTable();
|
||||
virtual Render3DError DestroyToonTable();
|
||||
|
@ -553,7 +568,7 @@ protected:
|
|||
virtual Render3DError UpdateToonTable(const u16 *toonTableBuffer);
|
||||
|
||||
virtual Render3DError ClearUsingImage(const u16 *__restrict colorBuffer, const u32 *__restrict depthStencilBuffer, const bool *__restrict fogBuffer);
|
||||
virtual Render3DError ClearUsingValues(const u8 r, const u8 g, const u8 b, const u8 a, const u32 clearDepth, const u8 clearStencil, const bool enableFog) const;
|
||||
virtual Render3DError ClearUsingValues(const u8 r, const u8 g, const u8 b, const u8 a, const u32 clearDepth, const u8 clearPolyID, const bool enableFog) const;
|
||||
|
||||
virtual Render3DError SetupPolygon(const POLY *thePoly);
|
||||
virtual Render3DError SetupTexture(const POLY *thePoly, bool enableTexturing);
|
||||
|
@ -607,15 +622,17 @@ class OpenGLRenderer_2_0 : public OpenGLRenderer_1_5
|
|||
protected:
|
||||
virtual Render3DError InitExtensions();
|
||||
virtual Render3DError InitFinalRenderStates(const std::set<std::string> *oglExtensionSet);
|
||||
virtual Render3DError InitPostprocessingProgram(const std::string &vtxShader, const std::string &fragShader);
|
||||
virtual Render3DError InitPostprocessingProgramBindings();
|
||||
virtual Render3DError DestroyPostprocessingProgram();
|
||||
virtual Render3DError InitEdgeMarkProgramBindings();
|
||||
virtual Render3DError InitPostprocessingPrograms(const std::string &edgeMarkVtxShader, const std::string &edgeMarkFragShader, const std::string &fogVtxShader, const std::string &fogFragShader);
|
||||
virtual Render3DError InitFogProgramBindings();
|
||||
virtual Render3DError DestroyPostprocessingPrograms();
|
||||
|
||||
virtual Render3DError SetupVertices(const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList, GLushort *outIndexBuffer, size_t *outIndexCount);
|
||||
virtual Render3DError EnableVertexAttributes(const VERTLIST *vertList, const GLushort *indexBuffer, const size_t vertIndexCount);
|
||||
virtual Render3DError DisableVertexAttributes();
|
||||
|
||||
virtual Render3DError BeginRender(const GFX3D_State *renderState);
|
||||
virtual Render3DError RenderEdgeMarking(const u16 *colorTable);
|
||||
virtual Render3DError RenderFog(const u8 *densityTable, const u32 color, const u32 offset, const u8 shift);
|
||||
|
||||
virtual Render3DError SetupPolygon(const POLY *thePoly);
|
||||
|
|
|
@ -126,8 +126,9 @@ static const char *GeometryFragShader_150 = {"\
|
|||
uniform bool polyEnableTexture; \n\
|
||||
uniform bool polyEnableFog;\n\
|
||||
\n\
|
||||
out vec4 outFragColor; \n\
|
||||
out vec4 outFragColor;\n\
|
||||
out vec4 outFragDepth;\n\
|
||||
out vec4 outPolyID;\n\
|
||||
out vec4 outFogAttributes;\n\
|
||||
\n\
|
||||
vec3 packVec3FromFloat(const float value)\n\
|
||||
|
@ -170,25 +171,117 @@ static const char *GeometryFragShader_150 = {"\
|
|||
\n\
|
||||
outFragColor = newFragColor;\n\
|
||||
outFogAttributes = vec4( float(polyEnableFog), float(stateEnableFogAlphaOnly), 0.0, 1.0);\n\
|
||||
if (newFragColor.a >= 1.0 || polySetNewDepthForTranslucent)\n\
|
||||
{\n\
|
||||
outFragDepth = vec4( packVec3FromFloat(newFragDepth), 1.0);\n\
|
||||
}\n\
|
||||
if (newFragColor.a > 0.999) outPolyID = vec4(float(polyID)/63.0, float(stateEnableAntialiasing), 0.0, 1.0);\n\
|
||||
if (newFragColor.a > 0.999 || polySetNewDepthForTranslucent) outFragDepth = vec4( packVec3FromFloat(newFragDepth), 1.0);\n\
|
||||
gl_FragDepth = newFragDepth;\n\
|
||||
} \n\
|
||||
"};
|
||||
|
||||
// Vertex shader for post-processing, GLSL 1.50
|
||||
static const char *PostprocessVtxShader_150 = {"\
|
||||
// Vertex shader for applying edge marking, GLSL 1.50
|
||||
static const char *EdgeMarkVtxShader_150 = {"\
|
||||
#version 150\n\
|
||||
\n\
|
||||
in vec2 inPosition;\n\
|
||||
in vec2 inTexCoord0;\n\
|
||||
uniform vec2 framebufferSize;\n\
|
||||
out vec2 texCoord[5];\n\
|
||||
\n\
|
||||
void main()\n\
|
||||
{\n\
|
||||
vec2 texInvScale = vec2(1.0/framebufferSize.x, 1.0/framebufferSize.y);\n\
|
||||
\n\
|
||||
texCoord[0] = inTexCoord0; // Center\n\
|
||||
texCoord[1] = inTexCoord0 + (vec2( 1.0, 0.0) * texInvScale); // Right\n\
|
||||
texCoord[2] = inTexCoord0 + (vec2( 0.0, 1.0) * texInvScale); // Down\n\
|
||||
texCoord[3] = inTexCoord0 + (vec2(-1.0, 0.0) * texInvScale); // Left\n\
|
||||
texCoord[4] = inTexCoord0 + (vec2( 0.0,-1.0) * texInvScale); // Up\n\
|
||||
\n\
|
||||
gl_Position = vec4(inPosition, 0.0, 1.0);\n\
|
||||
}\n\
|
||||
"};
|
||||
|
||||
// Fragment shader for applying edge marking, GLSL 1.50
|
||||
static const char *EdgeMarkFragShader_150 = {"\
|
||||
#version 150\n\
|
||||
\n\
|
||||
in vec2 texCoord[5];\n\
|
||||
\n\
|
||||
uniform sampler2D texInFragColor;\n\
|
||||
uniform sampler2D texInFragDepth;\n\
|
||||
uniform sampler2D texInPolyID;\n\
|
||||
uniform vec4 stateEdgeColor[8];\n\
|
||||
\n\
|
||||
out vec4 outFragColor;\n\
|
||||
\n\
|
||||
float unpackFloatFromVec3(const vec3 value)\n\
|
||||
{\n\
|
||||
const vec3 unpackRatio = vec3(256.0, 65536.0, 16777216.0);\n\
|
||||
return (dot(value, unpackRatio) / 16777215.0);\n\
|
||||
}\n\
|
||||
\n\
|
||||
void main()\n\
|
||||
{\n\
|
||||
vec4 inFragColor = texture(texInFragColor, texCoord[0]);\n\
|
||||
float inFragDepth = unpackFloatFromVec3(texture(texInFragDepth, texCoord[0]).rgb);\n\
|
||||
\n\
|
||||
vec4 inPolyIDAttributes[5];\n\
|
||||
inPolyIDAttributes[0] = texture(texInPolyID, texCoord[0]);\n\
|
||||
inPolyIDAttributes[1] = texture(texInPolyID, texCoord[1]);\n\
|
||||
inPolyIDAttributes[2] = texture(texInPolyID, texCoord[2]);\n\
|
||||
inPolyIDAttributes[3] = texture(texInPolyID, texCoord[3]);\n\
|
||||
inPolyIDAttributes[4] = texture(texInPolyID, texCoord[4]);\n\
|
||||
\n\
|
||||
int polyID[5];\n\
|
||||
polyID[0] = int((inPolyIDAttributes[0].r * 63.0) + 0.5);\n\
|
||||
polyID[1] = int((inPolyIDAttributes[1].r * 63.0) + 0.5);\n\
|
||||
polyID[2] = int((inPolyIDAttributes[2].r * 63.0) + 0.5);\n\
|
||||
polyID[3] = int((inPolyIDAttributes[3].r * 63.0) + 0.5);\n\
|
||||
polyID[4] = int((inPolyIDAttributes[4].r * 63.0) + 0.5);\n\
|
||||
\n\
|
||||
bool antialias[5];\n\
|
||||
antialias[0] = bool(inPolyIDAttributes[0].g);\n\
|
||||
antialias[1] = bool(inPolyIDAttributes[1].g);\n\
|
||||
antialias[2] = bool(inPolyIDAttributes[2].g);\n\
|
||||
antialias[3] = bool(inPolyIDAttributes[3].g);\n\
|
||||
antialias[4] = bool(inPolyIDAttributes[4].g);\n\
|
||||
\n\
|
||||
float depth[5];\n\
|
||||
depth[0] = unpackFloatFromVec3(texture(texInFragDepth, texCoord[0]).rgb);\n\
|
||||
depth[1] = unpackFloatFromVec3(texture(texInFragDepth, texCoord[1]).rgb);\n\
|
||||
depth[2] = unpackFloatFromVec3(texture(texInFragDepth, texCoord[2]).rgb);\n\
|
||||
depth[3] = unpackFloatFromVec3(texture(texInFragDepth, texCoord[3]).rgb);\n\
|
||||
depth[4] = unpackFloatFromVec3(texture(texInFragDepth, texCoord[4]).rgb);\n\
|
||||
\n\
|
||||
vec4 edgeColor = stateEdgeColor[polyID[0]/8];\n\
|
||||
bool doEdgeMark = false;\n\
|
||||
bool doAntialias = false;\n\
|
||||
\n\
|
||||
for (int i = 1; i < 5; i++)\n\
|
||||
{\n\
|
||||
if (polyID[0] != polyID[i] && depth[0] >= depth[i])\n\
|
||||
{\n\
|
||||
doEdgeMark = true;\n\
|
||||
edgeColor = stateEdgeColor[polyID[i]/8];\n\
|
||||
doAntialias = antialias[i];\n\
|
||||
break;\n\
|
||||
}\n\
|
||||
}\n\
|
||||
\n\
|
||||
outFragColor = (doEdgeMark) ? ((doAntialias) ? mix(edgeColor, inFragColor, 0.4) : edgeColor) : inFragColor;\n\
|
||||
}\n\
|
||||
"};
|
||||
|
||||
// Vertex shader for applying fog, GLSL 1.50
|
||||
static const char *FogVtxShader_150 = {"\
|
||||
#version 150\n\
|
||||
\n\
|
||||
in vec2 inPosition;\n\
|
||||
in vec2 inTexCoord0;\n\
|
||||
out vec2 texCoord;\n\
|
||||
\n\
|
||||
void main() \n\
|
||||
{ \n\
|
||||
texCoord = inTexCoord0; \n\
|
||||
void main()\n\
|
||||
{\n\
|
||||
texCoord = inTexCoord0;\n\
|
||||
gl_Position = vec4(inPosition, 0.0, 1.0);\n\
|
||||
}\n\
|
||||
"};
|
||||
|
@ -200,7 +293,7 @@ static const char *FogFragShader_150 = {"\
|
|||
in vec2 texCoord;\n\
|
||||
\n\
|
||||
uniform sampler2D texInFragColor;\n\
|
||||
uniform sampler2D texInFragDepthOnly;\n\
|
||||
uniform sampler2D texInFragDepth;\n\
|
||||
uniform sampler2D texInFogAttributes;\n\
|
||||
uniform vec4 stateFogColor;\n\
|
||||
uniform float stateFogDensity[32];\n\
|
||||
|
@ -218,7 +311,7 @@ static const char *FogFragShader_150 = {"\
|
|||
void main()\n\
|
||||
{\n\
|
||||
vec4 inFragColor = texture(texInFragColor, texCoord);\n\
|
||||
float inFragDepth = unpackFloatFromVec3(texture(texInFragDepthOnly, texCoord).rgb);\n\
|
||||
float inFragDepth = unpackFloatFromVec3(texture(texInFragDepth, texCoord).rgb);\n\
|
||||
vec4 inFogAttributes = texture(texInFogAttributes, texCoord);\n\
|
||||
\n\
|
||||
bool polyEnableFog = bool(inFogAttributes.r);\n\
|
||||
|
@ -300,9 +393,11 @@ Render3DError OpenGLRenderer_3_2::InitExtensions()
|
|||
return error;
|
||||
}
|
||||
|
||||
std::string postprocessVtxShaderString = std::string(PostprocessVtxShader_150);
|
||||
std::string postprocessFogFragShaderString = std::string(FogFragShader_150);
|
||||
error = this->InitPostprocessingProgram(postprocessVtxShaderString, postprocessFogFragShaderString);
|
||||
std::string edgeMarkVtxShaderString = std::string(EdgeMarkVtxShader_150);
|
||||
std::string edgeMarkFragShaderString = std::string(EdgeMarkFragShader_150);
|
||||
std::string fogVtxShaderString = std::string(FogVtxShader_150);
|
||||
std::string fogFragShaderString = std::string(FogFragShader_150);
|
||||
error = this->InitPostprocessingPrograms(edgeMarkVtxShaderString, edgeMarkFragShaderString, fogVtxShaderString, fogFragShaderString);
|
||||
if (error != OGLERROR_NOERR)
|
||||
{
|
||||
this->DestroyGeometryProgram();
|
||||
|
@ -348,7 +443,17 @@ Render3DError OpenGLRenderer_3_2::InitExtensions()
|
|||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_3_2::InitPostprocessingProgramBindings()
|
||||
Render3DError OpenGLRenderer_3_2::InitEdgeMarkProgramBindings()
|
||||
{
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
glBindAttribLocation(OGLRef.programEdgeMarkID, OGLVertexAttributeID_Position, "inPosition");
|
||||
glBindAttribLocation(OGLRef.programEdgeMarkID, OGLVertexAttributeID_TexCoord0, "inTexCoord0");
|
||||
glBindFragDataLocation(OGLRef.programEdgeMarkID, 0, "outFragColor");
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_3_2::InitFogProgramBindings()
|
||||
{
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
glBindAttribLocation(OGLRef.programFogID, OGLVertexAttributeID_Position, "inPosition");
|
||||
|
@ -364,10 +469,12 @@ Render3DError OpenGLRenderer_3_2::CreateFBOs()
|
|||
|
||||
// Set up FBO render targets
|
||||
glGenTextures(1, &OGLRef.texGColorID);
|
||||
glGenTextures(1, &OGLRef.texGDepthStencilID);
|
||||
glGenTextures(1, &OGLRef.texGDepthID);
|
||||
glGenTextures(1, &OGLRef.texGPolyID);
|
||||
glGenTextures(1, &OGLRef.texGFogAttrID);
|
||||
glGenTextures(1, &OGLRef.texPostprocessID);
|
||||
glGenTextures(1, &OGLRef.texGDepthStencilID);
|
||||
glGenTextures(1, &OGLRef.texPostprocessEdgeMarkID);
|
||||
glGenTextures(1, &OGLRef.texPostprocessFogID);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, OGLRef.texGColorID);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
|
@ -391,6 +498,13 @@ Render3DError OpenGLRenderer_3_2::CreateFBOs()
|
|||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, OGLRef.texGPolyID);
|
||||
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, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, OGLRef.texGFogAttrID);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
@ -398,7 +512,14 @@ Render3DError OpenGLRenderer_3_2::CreateFBOs()
|
|||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, OGLRef.texPostprocessID);
|
||||
glBindTexture(GL_TEXTURE_2D, OGLRef.texPostprocessEdgeMarkID);
|
||||
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, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, OGLRef.texPostprocessFogID);
|
||||
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, GL_CLAMP_TO_EDGE);
|
||||
|
@ -414,7 +535,8 @@ Render3DError OpenGLRenderer_3_2::CreateFBOs()
|
|||
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboRenderID);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, OGLRef.texGColorID, 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, OGLRef.texGDepthID, 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, OGLRef.texGFogAttrID, 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, OGLRef.texGPolyID, 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, OGLRef.texGFogAttrID, 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, OGLRef.texGDepthStencilID, 0);
|
||||
|
||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||
|
@ -425,10 +547,12 @@ Render3DError OpenGLRenderer_3_2::CreateFBOs()
|
|||
glDeleteFramebuffers(1, &OGLRef.fboRenderID);
|
||||
glDeleteFramebuffers(1, &OGLRef.fboPostprocessID);
|
||||
glDeleteTextures(1, &OGLRef.texGColorID);
|
||||
glDeleteTextures(1, &OGLRef.texGDepthStencilID);
|
||||
glDeleteTextures(1, &OGLRef.texGDepthID);
|
||||
glDeleteTextures(1, &OGLRef.texGPolyID);
|
||||
glDeleteTextures(1, &OGLRef.texGFogAttrID);
|
||||
glDeleteTextures(1, &OGLRef.texPostprocessID);
|
||||
glDeleteTextures(1, &OGLRef.texGDepthStencilID);
|
||||
glDeleteTextures(1, &OGLRef.texPostprocessEdgeMarkID);
|
||||
glDeleteTextures(1, &OGLRef.texPostprocessFogID);
|
||||
|
||||
OGLRef.fboRenderID = 0;
|
||||
OGLRef.fboPostprocessID = 0;
|
||||
|
@ -436,11 +560,12 @@ Render3DError OpenGLRenderer_3_2::CreateFBOs()
|
|||
return OGLERROR_FBO_CREATE_ERROR;
|
||||
}
|
||||
|
||||
glDrawBuffers(3, RenderDrawList);
|
||||
glDrawBuffers(4, RenderDrawList);
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboPostprocessID);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, OGLRef.texPostprocessID, 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, OGLRef.texPostprocessEdgeMarkID, 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, OGLRef.texPostprocessFogID, 0);
|
||||
|
||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||
{
|
||||
|
@ -450,10 +575,12 @@ Render3DError OpenGLRenderer_3_2::CreateFBOs()
|
|||
glDeleteFramebuffers(1, &OGLRef.fboRenderID);
|
||||
glDeleteFramebuffers(1, &OGLRef.fboPostprocessID);
|
||||
glDeleteTextures(1, &OGLRef.texGColorID);
|
||||
glDeleteTextures(1, &OGLRef.texGDepthStencilID);
|
||||
glDeleteTextures(1, &OGLRef.texGDepthID);
|
||||
glDeleteTextures(1, &OGLRef.texGPolyID);
|
||||
glDeleteTextures(1, &OGLRef.texGFogAttrID);
|
||||
glDeleteTextures(1, &OGLRef.texPostprocessID);
|
||||
glDeleteTextures(1, &OGLRef.texGDepthStencilID);
|
||||
glDeleteTextures(1, &OGLRef.texPostprocessEdgeMarkID);
|
||||
glDeleteTextures(1, &OGLRef.texPostprocessFogID);
|
||||
|
||||
OGLRef.fboRenderID = 0;
|
||||
OGLRef.fboPostprocessID = 0;
|
||||
|
@ -484,10 +611,12 @@ void OpenGLRenderer_3_2::DestroyFBOs()
|
|||
glDeleteFramebuffers(1, &OGLRef.fboRenderID);
|
||||
glDeleteFramebuffers(1, &OGLRef.fboPostprocessID);
|
||||
glDeleteTextures(1, &OGLRef.texGColorID);
|
||||
glDeleteTextures(1, &OGLRef.texGDepthStencilID);
|
||||
glDeleteTextures(1, &OGLRef.texGDepthID);
|
||||
glDeleteTextures(1, &OGLRef.texGPolyID);
|
||||
glDeleteTextures(1, &OGLRef.texGFogAttrID);
|
||||
glDeleteTextures(1, &OGLRef.texPostprocessID);
|
||||
glDeleteTextures(1, &OGLRef.texGDepthStencilID);
|
||||
glDeleteTextures(1, &OGLRef.texPostprocessEdgeMarkID);
|
||||
glDeleteTextures(1, &OGLRef.texPostprocessFogID);
|
||||
|
||||
OGLRef.fboRenderID = 0;
|
||||
OGLRef.fboPostprocessID = 0;
|
||||
|
@ -518,6 +647,7 @@ Render3DError OpenGLRenderer_3_2::CreateMultisampledFBO()
|
|||
// Set up FBO render targets
|
||||
glGenRenderbuffers(1, &OGLRef.rboMSGColorID);
|
||||
glGenRenderbuffers(1, &OGLRef.rboMSGDepthID);
|
||||
glGenRenderbuffers(1, &OGLRef.rboMSGPolyID);
|
||||
glGenRenderbuffers(1, &OGLRef.rboMSGFogAttrID);
|
||||
glGenRenderbuffers(1, &OGLRef.rboMSGDepthStencilID);
|
||||
|
||||
|
@ -525,6 +655,8 @@ Render3DError OpenGLRenderer_3_2::CreateMultisampledFBO()
|
|||
glRenderbufferStorageMultisample(GL_RENDERBUFFER, maxSamples, GL_RGBA, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, OGLRef.rboMSGDepthID);
|
||||
glRenderbufferStorageMultisample(GL_RENDERBUFFER, maxSamples, GL_RGBA, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, OGLRef.rboMSGPolyID);
|
||||
glRenderbufferStorageMultisample(GL_RENDERBUFFER, maxSamples, GL_RGBA, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, OGLRef.rboMSGFogAttrID);
|
||||
glRenderbufferStorageMultisample(GL_RENDERBUFFER, maxSamples, GL_RGBA, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, OGLRef.rboMSGDepthStencilID);
|
||||
|
@ -536,7 +668,8 @@ Render3DError OpenGLRenderer_3_2::CreateMultisampledFBO()
|
|||
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboMSIntermediateRenderID);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, OGLRef.rboMSGColorID);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, OGLRef.rboMSGDepthID);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_RENDERBUFFER, OGLRef.rboMSGFogAttrID);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_RENDERBUFFER, OGLRef.rboMSGPolyID);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_RENDERBUFFER, OGLRef.rboMSGFogAttrID);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, OGLRef.rboMSGDepthStencilID);
|
||||
|
||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||
|
@ -547,6 +680,7 @@ Render3DError OpenGLRenderer_3_2::CreateMultisampledFBO()
|
|||
glDeleteFramebuffers(1, &OGLRef.fboMSIntermediateRenderID);
|
||||
glDeleteRenderbuffers(1, &OGLRef.rboMSGColorID);
|
||||
glDeleteRenderbuffers(1, &OGLRef.rboMSGDepthID);
|
||||
glDeleteRenderbuffers(1, &OGLRef.rboMSGPolyID);
|
||||
glDeleteRenderbuffers(1, &OGLRef.rboMSGFogAttrID);
|
||||
glDeleteRenderbuffers(1, &OGLRef.rboMSGDepthStencilID);
|
||||
|
||||
|
@ -574,6 +708,7 @@ void OpenGLRenderer_3_2::DestroyMultisampledFBO()
|
|||
glDeleteFramebuffers(1, &OGLRef.fboMSIntermediateRenderID);
|
||||
glDeleteRenderbuffers(1, &OGLRef.rboMSGColorID);
|
||||
glDeleteRenderbuffers(1, &OGLRef.rboMSGDepthID);
|
||||
glDeleteRenderbuffers(1, &OGLRef.rboMSGPolyID);
|
||||
glDeleteRenderbuffers(1, &OGLRef.rboMSGFogAttrID);
|
||||
glDeleteRenderbuffers(1, &OGLRef.rboMSGDepthStencilID);
|
||||
|
||||
|
@ -652,7 +787,8 @@ Render3DError OpenGLRenderer_3_2::InitGeometryProgramBindings()
|
|||
glBindAttribLocation(OGLRef.programGeometryID, OGLVertexAttributeID_Color, "inColor");
|
||||
glBindFragDataLocation(OGLRef.programGeometryID, 0, "outFragColor");
|
||||
glBindFragDataLocation(OGLRef.programGeometryID, 1, "outFragDepth");
|
||||
glBindFragDataLocation(OGLRef.programGeometryID, 2, "outFogAttributes");
|
||||
glBindFragDataLocation(OGLRef.programGeometryID, 2, "outPolyID");
|
||||
glBindFragDataLocation(OGLRef.programGeometryID, 3, "outFogAttributes");
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
@ -695,7 +831,7 @@ Render3DError OpenGLRenderer_3_2::SelectRenderingFramebuffer()
|
|||
|
||||
OGLRef.selectedRenderingFBO = (CommonSettings.GFX3D_Renderer_Multisample) ? OGLRef.fboMSIntermediateRenderID : OGLRef.fboRenderID;
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.selectedRenderingFBO);
|
||||
glDrawBuffers(3, RenderDrawList);
|
||||
glDrawBuffers(4, RenderDrawList);
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
@ -719,20 +855,100 @@ Render3DError OpenGLRenderer_3_2::DownsampleFBO()
|
|||
glDrawBuffer(GL_COLOR_ATTACHMENT1);
|
||||
glBlitFramebuffer(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
|
||||
// Blit the fog buffer
|
||||
// Blit the polygon ID buffer
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT2);
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT2);
|
||||
glBlitFramebuffer(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
|
||||
// Blit the fog buffer
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT3);
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT3);
|
||||
glBlitFramebuffer(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
|
||||
// Reset framebuffer targets
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
||||
glDrawBuffers(3, RenderDrawList);
|
||||
glDrawBuffers(4, RenderDrawList);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboRenderID);
|
||||
}
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_3_2::RenderEdgeMarking(const u16 *colorTable)
|
||||
{
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
|
||||
const GLfloat oglColor[4*8] = {divide5bitBy31_LUT[(colorTable[0] ) & 0x001F],
|
||||
divide5bitBy31_LUT[(colorTable[0] >> 5) & 0x001F],
|
||||
divide5bitBy31_LUT[(colorTable[0] >> 10) & 0x001F],
|
||||
1.0f,
|
||||
divide5bitBy31_LUT[(colorTable[1] ) & 0x001F],
|
||||
divide5bitBy31_LUT[(colorTable[1] >> 5) & 0x001F],
|
||||
divide5bitBy31_LUT[(colorTable[1] >> 10) & 0x001F],
|
||||
1.0f,
|
||||
divide5bitBy31_LUT[(colorTable[2] ) & 0x001F],
|
||||
divide5bitBy31_LUT[(colorTable[2] >> 5) & 0x001F],
|
||||
divide5bitBy31_LUT[(colorTable[2] >> 10) & 0x001F],
|
||||
1.0f,
|
||||
divide5bitBy31_LUT[(colorTable[3] ) & 0x001F],
|
||||
divide5bitBy31_LUT[(colorTable[3] >> 5) & 0x001F],
|
||||
divide5bitBy31_LUT[(colorTable[3] >> 10) & 0x001F],
|
||||
1.0f,
|
||||
divide5bitBy31_LUT[(colorTable[4] ) & 0x001F],
|
||||
divide5bitBy31_LUT[(colorTable[4] >> 5) & 0x001F],
|
||||
divide5bitBy31_LUT[(colorTable[4] >> 10) & 0x001F],
|
||||
1.0f,
|
||||
divide5bitBy31_LUT[(colorTable[5] ) & 0x001F],
|
||||
divide5bitBy31_LUT[(colorTable[5] >> 5) & 0x001F],
|
||||
divide5bitBy31_LUT[(colorTable[5] >> 10) & 0x001F],
|
||||
1.0f,
|
||||
divide5bitBy31_LUT[(colorTable[6] ) & 0x001F],
|
||||
divide5bitBy31_LUT[(colorTable[6] >> 5) & 0x001F],
|
||||
divide5bitBy31_LUT[(colorTable[6] >> 10) & 0x001F],
|
||||
1.0f,
|
||||
divide5bitBy31_LUT[(colorTable[7] ) & 0x001F],
|
||||
divide5bitBy31_LUT[(colorTable[7] >> 5) & 0x001F],
|
||||
divide5bitBy31_LUT[(colorTable[7] >> 10) & 0x001F],
|
||||
1.0f};
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboPostprocessID);
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
||||
glUseProgram(OGLRef.programEdgeMarkID);
|
||||
glUniform1i(OGLRef.uniformTexGColor_EdgeMark, OGLTextureUnitID_GColor);
|
||||
glUniform1i(OGLRef.uniformTexGDepth_EdgeMark, OGLTextureUnitID_GDepth);
|
||||
glUniform1i(OGLRef.uniformTexGPolyID_EdgeMark, OGLTextureUnitID_GPolyID);
|
||||
glUniform2f(OGLRef.uniformFramebufferSize, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT);
|
||||
glUniform4fv(OGLRef.uniformStateEdgeColor, 8, oglColor);
|
||||
|
||||
glViewport(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboPostprocessVtxID);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, OGLRef.iboPostprocessIndexID);
|
||||
glBindVertexArray(OGLRef.vaoPostprocessStatesID);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_GColor);
|
||||
glBindTexture(GL_TEXTURE_2D, OGLRef.texGColorID);
|
||||
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_GDepth);
|
||||
glBindTexture(GL_TEXTURE_2D, OGLRef.texGDepthID);
|
||||
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_GPolyID);
|
||||
glBindTexture(GL_TEXTURE_2D, OGLRef.texGPolyID);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, 0);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
glBindVertexArray(0);
|
||||
|
||||
this->didRenderEdgeMark = true;
|
||||
|
||||
return RENDER3DERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_3_2::RenderFog(const u8 *densityTable, const u32 color, const u32 offset, const u8 shift)
|
||||
{
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
|
@ -752,10 +968,12 @@ Render3DError OpenGLRenderer_3_2::RenderFog(const u8 *densityTable, const u32 co
|
|||
const GLfloat oglFogStep = (GLfloat)(0x0400 >> shift) / 32767.0f;
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboPostprocessID);
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT1);
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT1);
|
||||
glUseProgram(OGLRef.programFogID);
|
||||
glUniform1i(OGLRef.uniformTexGColor, OGLTextureUnitID_GColor);
|
||||
glUniform1i(OGLRef.uniformTexGDepth, OGLTextureUnitID_GDepth);
|
||||
glUniform1i(OGLRef.uniformTexGFog, OGLTextureUnitID_FogAttr);
|
||||
glUniform1i(OGLRef.uniformTexGColor_Fog, OGLTextureUnitID_GColor);
|
||||
glUniform1i(OGLRef.uniformTexGDepth_Fog, OGLTextureUnitID_GDepth);
|
||||
glUniform1i(OGLRef.uniformTexGFog_Fog, OGLTextureUnitID_FogAttr);
|
||||
glUniform4f(OGLRef.uniformStateFogColor, oglColor[0], oglColor[1], oglColor[2], oglColor[3]);
|
||||
glUniform1f(OGLRef.uniformStateFogOffset, oglOffset);
|
||||
glUniform1f(OGLRef.uniformStateFogStep, oglFogStep);
|
||||
|
@ -772,7 +990,7 @@ Render3DError OpenGLRenderer_3_2::RenderFog(const u8 *densityTable, const u32 co
|
|||
glBindVertexArray(OGLRef.vaoPostprocessStatesID);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_GColor);
|
||||
glBindTexture(GL_TEXTURE_2D, OGLRef.texGColorID);
|
||||
glBindTexture(GL_TEXTURE_2D, (this->didRenderEdgeMark) ? OGLRef.texPostprocessEdgeMarkID : OGLRef.texGColorID);
|
||||
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_GDepth);
|
||||
glBindTexture(GL_TEXTURE_2D, OGLRef.texGDepthID);
|
||||
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_FogAttr);
|
||||
|
@ -808,14 +1026,19 @@ Render3DError OpenGLRenderer_3_2::ClearUsingImage(const u16 *__restrict colorBuf
|
|||
glDrawBuffer(GL_COLOR_ATTACHMENT1);
|
||||
glBlitFramebuffer(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
|
||||
// Blit the fog buffer
|
||||
// Blit the polygon ID buffer
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT2);
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT2);
|
||||
glBlitFramebuffer(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
|
||||
// Blit the fog buffer
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT3);
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT3);
|
||||
glBlitFramebuffer(0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, 0, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
|
||||
// Reset framebuffer targets
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
||||
glDrawBuffers(3, RenderDrawList);
|
||||
glDrawBuffers(4, RenderDrawList);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboMSIntermediateRenderID);
|
||||
}
|
||||
|
||||
|
|
|
@ -61,7 +61,8 @@ class OpenGLRenderer_3_2 : public OpenGLRenderer_2_1
|
|||
{
|
||||
protected:
|
||||
virtual Render3DError InitExtensions();
|
||||
virtual Render3DError InitPostprocessingProgramBindings();
|
||||
virtual Render3DError InitEdgeMarkProgramBindings();
|
||||
virtual Render3DError InitFogProgramBindings();
|
||||
virtual Render3DError CreateFBOs();
|
||||
virtual void DestroyFBOs();
|
||||
virtual Render3DError CreateMultisampledFBO();
|
||||
|
@ -77,6 +78,7 @@ protected:
|
|||
virtual Render3DError DisableVertexAttributes();
|
||||
virtual Render3DError SelectRenderingFramebuffer();
|
||||
virtual Render3DError DownsampleFBO();
|
||||
virtual Render3DError RenderEdgeMarking(const u16 *colorTable);
|
||||
virtual Render3DError RenderFog(const u8 *densityTable, const u32 color, const u32 offset, const u8 shift);
|
||||
|
||||
virtual Render3DError ClearUsingImage(const u16 *__restrict colorBuffer, const u32 *__restrict depthStencilBuffer, const bool *__restrict fogBuffer);
|
||||
|
|
|
@ -126,6 +126,11 @@ Render3DError Render3D::RenderGeometry(const GFX3D_State *renderState, const VER
|
|||
return RENDER3DERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError Render3D::RenderEdgeMarking(const u16 *colorTable)
|
||||
{
|
||||
return RENDER3DERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError Render3D::RenderFog(const u8 *densityTable, const u32 color, const u32 offset, const u8 shift)
|
||||
{
|
||||
return RENDER3DERROR_NOERR;
|
||||
|
@ -209,7 +214,7 @@ Render3DError Render3D::ClearUsingImage(const u16 *__restrict colorBuffer, const
|
|||
return RENDER3DERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError Render3D::ClearUsingValues(const u8 r, const u8 g, const u8 b, const u8 a, const u32 clearDepth, const u8 clearStencil, const bool enableFog) const
|
||||
Render3DError Render3D::ClearUsingValues(const u8 r, const u8 g, const u8 b, const u8 a, const u32 clearDepth, const u8 clearPolyID, const bool enableFog) const
|
||||
{
|
||||
return RENDER3DERROR_NOERR;
|
||||
}
|
||||
|
@ -252,6 +257,11 @@ Render3DError Render3D::Render(const GFX3D_State *renderState, const VERTLIST *v
|
|||
|
||||
this->RenderGeometry(renderState, vertList, polyList, indexList);
|
||||
|
||||
if (renderState->enableEdgeMarking)
|
||||
{
|
||||
this->RenderEdgeMarking((const u16 *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]+0x0330));
|
||||
}
|
||||
|
||||
if (renderState->enableFog)
|
||||
{
|
||||
this->RenderFog(MMU.MMU_MEM[ARMCPU_ARM9][0x40]+0x0360, renderState->fogColor, renderState->fogOffset, renderState->fogShift);
|
||||
|
|
|
@ -90,6 +90,7 @@ protected:
|
|||
|
||||
virtual Render3DError BeginRender(const GFX3D_State *renderState);
|
||||
virtual Render3DError RenderGeometry(const GFX3D_State *renderState, const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList);
|
||||
virtual Render3DError RenderEdgeMarking(const u16 *colorTable);
|
||||
virtual Render3DError RenderFog(const u8 *densityTable, const u32 color, const u32 offset, const u8 shift);
|
||||
virtual Render3DError EndRender(const u64 frameCount);
|
||||
|
||||
|
@ -97,7 +98,7 @@ protected:
|
|||
|
||||
virtual Render3DError ClearFramebuffer(const GFX3D_State *renderState);
|
||||
virtual Render3DError ClearUsingImage(const u16 *__restrict colorBuffer, const u32 *__restrict depthStencilBuffer, const bool *__restrict fogBuffer);
|
||||
virtual Render3DError ClearUsingValues(const u8 r, const u8 g, const u8 b, const u8 a, const u32 clearDepth, const u8 clearStencil, const bool enableFog) const;
|
||||
virtual Render3DError ClearUsingValues(const u8 r, const u8 g, const u8 b, const u8 a, const u32 clearDepth, const u8 clearPolyID, const bool enableFog) const;
|
||||
|
||||
virtual Render3DError SetupPolygon(const POLY *thePoly);
|
||||
virtual Render3DError SetupTexture(const POLY *thePoly, bool enableTexturing);
|
||||
|
|
Loading…
Reference in New Issue