mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-08 23:25:40 +12:00
[GPU] attempt to emulate the previous TEV color buffer
This commit is contained in:
parent
d153133070
commit
2e85f30c10
2 changed files with 54 additions and 2 deletions
|
@ -31,6 +31,8 @@ class Renderer {
|
||||||
GLint textureEnvCombinerLoc = -1;
|
GLint textureEnvCombinerLoc = -1;
|
||||||
GLint textureEnvColorLoc = -1;
|
GLint textureEnvColorLoc = -1;
|
||||||
GLint textureEnvScaleLoc = -1;
|
GLint textureEnvScaleLoc = -1;
|
||||||
|
GLint textureEnvUpdateBufferLoc = -1;
|
||||||
|
GLint textureEnvBufferColorLoc = -1;
|
||||||
|
|
||||||
// Depth configuration uniform locations
|
// Depth configuration uniform locations
|
||||||
GLint depthOffsetLoc = -1;
|
GLint depthOffsetLoc = -1;
|
||||||
|
|
|
@ -44,6 +44,8 @@ const char* fragmentShader = R"(
|
||||||
uniform uint u_textureEnvCombiner[6];
|
uniform uint u_textureEnvCombiner[6];
|
||||||
uniform vec4 u_textureEnvColor[6];
|
uniform vec4 u_textureEnvColor[6];
|
||||||
uniform uint u_textureEnvScale[6];
|
uniform uint u_textureEnvScale[6];
|
||||||
|
uniform uint u_textureEnvUpdateBuffer;
|
||||||
|
uniform vec4 u_textureEnvBufferColor;
|
||||||
|
|
||||||
// Depth control uniforms
|
// Depth control uniforms
|
||||||
uniform float u_depthScale;
|
uniform float u_depthScale;
|
||||||
|
@ -55,6 +57,10 @@ const char* fragmentShader = R"(
|
||||||
// TODO: figure out what the correct "initial" value used by TEV0 is.
|
// TODO: figure out what the correct "initial" value used by TEV0 is.
|
||||||
vec4 previous = vec4(1.0);
|
vec4 previous = vec4(1.0);
|
||||||
|
|
||||||
|
// TODO: presumably this needs to be initialized to the value of GPUREG_TEXENV_BUFFER_COLOR
|
||||||
|
vec4 buffer;
|
||||||
|
vec4 next_buffer;
|
||||||
|
|
||||||
vec4 tev_evaluate_source(int tev_id, int src_id) {
|
vec4 tev_evaluate_source(int tev_id, int src_id) {
|
||||||
vec4 source = vec4(1.0);
|
vec4 source = vec4(1.0);
|
||||||
|
|
||||||
|
@ -66,17 +72,19 @@ const char* fragmentShader = R"(
|
||||||
switch (rgb_source) {
|
switch (rgb_source) {
|
||||||
case 0u: source.rgb = colour.rgb; break; // Primary color, TODO: confirm that this is correct
|
case 0u: source.rgb = colour.rgb; break; // Primary color, TODO: confirm that this is correct
|
||||||
case 3u: source.rgb = texture(u_tex0, tex0_UVs).rgb; break; // Texture 0
|
case 3u: source.rgb = texture(u_tex0, tex0_UVs).rgb; break; // Texture 0
|
||||||
|
case 13u: source.rgb = buffer.rgb; break; // Previous buffer
|
||||||
case 14u: source.rgb = u_textureEnvColor[tev_id].rgb; break; // Constant (GPUREG_TEXENVi_COLOR)
|
case 14u: source.rgb = u_textureEnvColor[tev_id].rgb; break; // Constant (GPUREG_TEXENVi_COLOR)
|
||||||
case 15u: source.rgb = previous.rgb; break; // Previous (output from TEV #n-1)
|
case 15u: source.rgb = previous.rgb; break; // Previous (output from TEV #n-1)
|
||||||
default: break;//return vec4(0.0, 1.0, 1.0, 1.0); break; // TODO: implement remaining sources
|
default: return vec4(0.0, 1.0, 1.0, 1.0); break; // TODO: implement remaining sources
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (alpha_source) {
|
switch (alpha_source) {
|
||||||
case 0u: source.a = colour.a; break; // Primary color, TODO: confirm that this is correct
|
case 0u: source.a = colour.a; break; // Primary color, TODO: confirm that this is correct
|
||||||
case 3u: source.a = texture(u_tex0, tex0_UVs).a; break; // Texture 0
|
case 3u: source.a = texture(u_tex0, tex0_UVs).a; break; // Texture 0
|
||||||
|
case 13u: source.a = buffer.a; break; // Previous buffer
|
||||||
case 14u: source.a = u_textureEnvColor[tev_id].a; break; // Constant (GPUREG_TEXENVi_COLOR)
|
case 14u: source.a = u_textureEnvColor[tev_id].a; break; // Constant (GPUREG_TEXENVi_COLOR)
|
||||||
case 15u: source.a = previous.a; break; // Previous (output from TEV #n-1)
|
case 15u: source.a = previous.a; break; // Previous (output from TEV #n-1)
|
||||||
default: break;//return vec4(0.0, 1.0, 1.0, 1.0); break; // TODO: implement remaining sources
|
default: return vec4(0.0, 1.0, 1.0, 1.0); break; // TODO: implement remaining sources
|
||||||
}
|
}
|
||||||
|
|
||||||
uint rgb_operand = (u_textureEnvOperand[tev_id] >> (src_id * 4)) & 15u;
|
uint rgb_operand = (u_textureEnvOperand[tev_id] >> (src_id * 4)) & 15u;
|
||||||
|
@ -157,12 +165,37 @@ const char* fragmentShader = R"(
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
if ((u_textureConfig & 1u) != 0) { // Render texture 0 if enabled
|
if ((u_textureConfig & 1u) != 0) { // Render texture 0 if enabled
|
||||||
|
// TODO: fix all the redundancy
|
||||||
|
|
||||||
|
buffer = vec4(0.0);
|
||||||
|
next_buffer = u_textureEnvBufferColor;
|
||||||
|
|
||||||
previous = tev_combine(0);
|
previous = tev_combine(0);
|
||||||
|
buffer = next_buffer;
|
||||||
|
if ((u_textureEnvUpdateBuffer & 0x100u) != 0u) next_buffer.rgb = previous.rgb;
|
||||||
|
if ((u_textureEnvUpdateBuffer & 0x1000u) != 0u) next_buffer.a = previous.a;
|
||||||
|
|
||||||
previous = tev_combine(1);
|
previous = tev_combine(1);
|
||||||
|
buffer = next_buffer;
|
||||||
|
if ((u_textureEnvUpdateBuffer & 0x200u) != 0u) next_buffer.rgb = previous.rgb;
|
||||||
|
if ((u_textureEnvUpdateBuffer & 0x2000u) != 0u) next_buffer.a = previous.a;
|
||||||
|
|
||||||
previous = tev_combine(2);
|
previous = tev_combine(2);
|
||||||
|
buffer = next_buffer;
|
||||||
|
if ((u_textureEnvUpdateBuffer & 0x400u) != 0u) next_buffer.rgb = previous.rgb;
|
||||||
|
if ((u_textureEnvUpdateBuffer & 0x4000u) != 0u) next_buffer.a = previous.a;
|
||||||
|
|
||||||
previous = tev_combine(3);
|
previous = tev_combine(3);
|
||||||
|
buffer = next_buffer;
|
||||||
|
if ((u_textureEnvUpdateBuffer & 0x800u) != 0u) next_buffer.rgb = previous.rgb;
|
||||||
|
if ((u_textureEnvUpdateBuffer & 0x8000u) != 0u) next_buffer.a = previous.a;
|
||||||
|
|
||||||
previous = tev_combine(4);
|
previous = tev_combine(4);
|
||||||
|
buffer = next_buffer;
|
||||||
|
|
||||||
fragColour = tev_combine(5);
|
fragColour = tev_combine(5);
|
||||||
|
|
||||||
|
if((u_textureEnvUpdateBuffer & 0xFF00u) != 0u) {fragColour = vec4(1.0, 0.5, 1.0, 1.0); return; }
|
||||||
} else {
|
} else {
|
||||||
fragColour = colour;
|
fragColour = colour;
|
||||||
}
|
}
|
||||||
|
@ -299,6 +332,8 @@ void Renderer::initGraphicsContext() {
|
||||||
textureEnvCombinerLoc = OpenGL::uniformLocation(triangleProgram, "u_textureEnvCombiner");
|
textureEnvCombinerLoc = OpenGL::uniformLocation(triangleProgram, "u_textureEnvCombiner");
|
||||||
textureEnvColorLoc = OpenGL::uniformLocation(triangleProgram, "u_textureEnvColor");
|
textureEnvColorLoc = OpenGL::uniformLocation(triangleProgram, "u_textureEnvColor");
|
||||||
textureEnvScaleLoc = OpenGL::uniformLocation(triangleProgram, "u_textureEnvScale");
|
textureEnvScaleLoc = OpenGL::uniformLocation(triangleProgram, "u_textureEnvScale");
|
||||||
|
textureEnvUpdateBufferLoc = OpenGL::uniformLocation(triangleProgram, "u_textureEnvUpdateBuffer");
|
||||||
|
textureEnvBufferColorLoc = OpenGL::uniformLocation(triangleProgram, "u_textureEnvBufferColor");
|
||||||
|
|
||||||
depthScaleLoc = OpenGL::uniformLocation(triangleProgram, "u_depthScale");
|
depthScaleLoc = OpenGL::uniformLocation(triangleProgram, "u_depthScale");
|
||||||
depthOffsetLoc = OpenGL::uniformLocation(triangleProgram, "u_depthOffset");
|
depthOffsetLoc = OpenGL::uniformLocation(triangleProgram, "u_depthOffset");
|
||||||
|
@ -486,6 +521,21 @@ void Renderer::drawVertices(OpenGL::Primitives primType, Vertex* vertices, u32 c
|
||||||
glUniform1uiv(textureEnvCombinerLoc, 6, textureEnvCombinerRegs);
|
glUniform1uiv(textureEnvCombinerLoc, 6, textureEnvCombinerRegs);
|
||||||
glUniform4fv(textureEnvColorLoc, 6, (const GLfloat*)textureEnvColourRegs);
|
glUniform4fv(textureEnvColorLoc, 6, (const GLfloat*)textureEnvColourRegs);
|
||||||
glUniform1uiv(textureEnvScaleLoc, 6, textureEnvScaleRegs);
|
glUniform1uiv(textureEnvScaleLoc, 6, textureEnvScaleRegs);
|
||||||
|
glUniform1ui(textureEnvUpdateBufferLoc, regs[0xe0]);
|
||||||
|
|
||||||
|
// TODO: deduplicate color decoding
|
||||||
|
{
|
||||||
|
const u32 rgba = regs[0xfd];
|
||||||
|
const float r = (float)(rgba & 0xff) / 255.0f;
|
||||||
|
const float g = (float)((rgba >> 8) & 0xff) / 255.0f;
|
||||||
|
const float b = (float)((rgba >> 16) & 0xff) / 255.0f;
|
||||||
|
const float a = (float)(rgba >> 24) / 255.0f;
|
||||||
|
|
||||||
|
glUniform4f(textureEnvBufferColorLoc, r, g, b, a);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if(regs[0xfd] != 0)
|
||||||
|
// Helpers::warn("FOO %08x", regs[0xfd]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hack for rendering texture 1
|
// Hack for rendering texture 1
|
||||||
|
|
Loading…
Add table
Reference in a new issue