|
|
|
@ -75,6 +75,12 @@ void RasterizerOpenGL::InitObjects() {
|
|
|
|
|
glEnableVertexAttribArray(GLShader::ATTRIBUTE_TEXCOORD1);
|
|
|
|
|
glEnableVertexAttribArray(GLShader::ATTRIBUTE_TEXCOORD2);
|
|
|
|
|
|
|
|
|
|
glVertexAttribPointer(GLShader::ATTRIBUTE_NORMQUAT, 4, GL_FLOAT, GL_FALSE, sizeof(HardwareVertex), (GLvoid*)offsetof(HardwareVertex, normquat));
|
|
|
|
|
glEnableVertexAttribArray(GLShader::ATTRIBUTE_NORMQUAT);
|
|
|
|
|
|
|
|
|
|
glVertexAttribPointer(GLShader::ATTRIBUTE_VIEW, 3, GL_FLOAT, GL_FALSE, sizeof(HardwareVertex), (GLvoid*)offsetof(HardwareVertex, view));
|
|
|
|
|
glEnableVertexAttribArray(GLShader::ATTRIBUTE_VIEW);
|
|
|
|
|
|
|
|
|
|
SetShader();
|
|
|
|
|
|
|
|
|
|
// Create textures for OGL framebuffer that will be rendered to, initially 1x1 to succeed in framebuffer creation
|
|
|
|
@ -283,6 +289,98 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) {
|
|
|
|
|
case PICA_REG_INDEX(tev_combiner_buffer_color):
|
|
|
|
|
SyncCombinerColor();
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
// Fragment lighting diffuse color
|
|
|
|
|
case PICA_REG_INDEX_WORKAROUND(lighting.light[0].diffuse, 0x142 + 0 * 0x10):
|
|
|
|
|
SyncLightDiffuse(0);
|
|
|
|
|
break;
|
|
|
|
|
case PICA_REG_INDEX_WORKAROUND(lighting.light[1].diffuse, 0x142 + 1 * 0x10):
|
|
|
|
|
SyncLightDiffuse(1);
|
|
|
|
|
break;
|
|
|
|
|
case PICA_REG_INDEX_WORKAROUND(lighting.light[2].diffuse, 0x142 + 2 * 0x10):
|
|
|
|
|
SyncLightDiffuse(2);
|
|
|
|
|
break;
|
|
|
|
|
case PICA_REG_INDEX_WORKAROUND(lighting.light[3].diffuse, 0x142 + 3 * 0x10):
|
|
|
|
|
SyncLightDiffuse(3);
|
|
|
|
|
break;
|
|
|
|
|
case PICA_REG_INDEX_WORKAROUND(lighting.light[4].diffuse, 0x142 + 4 * 0x10):
|
|
|
|
|
SyncLightDiffuse(4);
|
|
|
|
|
break;
|
|
|
|
|
case PICA_REG_INDEX_WORKAROUND(lighting.light[5].diffuse, 0x142 + 5 * 0x10):
|
|
|
|
|
SyncLightDiffuse(5);
|
|
|
|
|
break;
|
|
|
|
|
case PICA_REG_INDEX_WORKAROUND(lighting.light[6].diffuse, 0x142 + 6 * 0x10):
|
|
|
|
|
SyncLightDiffuse(6);
|
|
|
|
|
break;
|
|
|
|
|
case PICA_REG_INDEX_WORKAROUND(lighting.light[7].diffuse, 0x142 + 7 * 0x10):
|
|
|
|
|
SyncLightDiffuse(7);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
// Fragment lighting ambient color
|
|
|
|
|
case PICA_REG_INDEX_WORKAROUND(lighting.light[0].ambient, 0x143 + 0 * 0x10):
|
|
|
|
|
SyncLightAmbient(0);
|
|
|
|
|
break;
|
|
|
|
|
case PICA_REG_INDEX_WORKAROUND(lighting.light[1].ambient, 0x143 + 1 * 0x10):
|
|
|
|
|
SyncLightAmbient(1);
|
|
|
|
|
break;
|
|
|
|
|
case PICA_REG_INDEX_WORKAROUND(lighting.light[2].ambient, 0x143 + 2 * 0x10):
|
|
|
|
|
SyncLightAmbient(2);
|
|
|
|
|
break;
|
|
|
|
|
case PICA_REG_INDEX_WORKAROUND(lighting.light[3].ambient, 0x143 + 3 * 0x10):
|
|
|
|
|
SyncLightAmbient(3);
|
|
|
|
|
break;
|
|
|
|
|
case PICA_REG_INDEX_WORKAROUND(lighting.light[4].ambient, 0x143 + 4 * 0x10):
|
|
|
|
|
SyncLightAmbient(4);
|
|
|
|
|
break;
|
|
|
|
|
case PICA_REG_INDEX_WORKAROUND(lighting.light[5].ambient, 0x143 + 5 * 0x10):
|
|
|
|
|
SyncLightAmbient(5);
|
|
|
|
|
break;
|
|
|
|
|
case PICA_REG_INDEX_WORKAROUND(lighting.light[6].ambient, 0x143 + 6 * 0x10):
|
|
|
|
|
SyncLightAmbient(6);
|
|
|
|
|
break;
|
|
|
|
|
case PICA_REG_INDEX_WORKAROUND(lighting.light[7].ambient, 0x143 + 7 * 0x10):
|
|
|
|
|
SyncLightAmbient(7);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
// Fragment lighting position
|
|
|
|
|
case PICA_REG_INDEX_WORKAROUND(lighting.light[0].x, 0x144 + 0 * 0x10):
|
|
|
|
|
case PICA_REG_INDEX_WORKAROUND(lighting.light[0].z, 0x145 + 0 * 0x10):
|
|
|
|
|
SyncLightPosition(0);
|
|
|
|
|
break;
|
|
|
|
|
case PICA_REG_INDEX_WORKAROUND(lighting.light[1].x, 0x144 + 1 * 0x10):
|
|
|
|
|
case PICA_REG_INDEX_WORKAROUND(lighting.light[1].z, 0x145 + 1 * 0x10):
|
|
|
|
|
SyncLightPosition(1);
|
|
|
|
|
break;
|
|
|
|
|
case PICA_REG_INDEX_WORKAROUND(lighting.light[2].x, 0x144 + 2 * 0x10):
|
|
|
|
|
case PICA_REG_INDEX_WORKAROUND(lighting.light[2].z, 0x145 + 2 * 0x10):
|
|
|
|
|
SyncLightPosition(2);
|
|
|
|
|
break;
|
|
|
|
|
case PICA_REG_INDEX_WORKAROUND(lighting.light[3].x, 0x144 + 3 * 0x10):
|
|
|
|
|
case PICA_REG_INDEX_WORKAROUND(lighting.light[3].z, 0x145 + 3 * 0x10):
|
|
|
|
|
SyncLightPosition(3);
|
|
|
|
|
break;
|
|
|
|
|
case PICA_REG_INDEX_WORKAROUND(lighting.light[4].x, 0x144 + 4 * 0x10):
|
|
|
|
|
case PICA_REG_INDEX_WORKAROUND(lighting.light[4].z, 0x145 + 4 * 0x10):
|
|
|
|
|
SyncLightPosition(4);
|
|
|
|
|
break;
|
|
|
|
|
case PICA_REG_INDEX_WORKAROUND(lighting.light[5].x, 0x144 + 5 * 0x10):
|
|
|
|
|
case PICA_REG_INDEX_WORKAROUND(lighting.light[5].z, 0x145 + 5 * 0x10):
|
|
|
|
|
SyncLightPosition(5);
|
|
|
|
|
break;
|
|
|
|
|
case PICA_REG_INDEX_WORKAROUND(lighting.light[6].x, 0x144 + 6 * 0x10):
|
|
|
|
|
case PICA_REG_INDEX_WORKAROUND(lighting.light[6].z, 0x145 + 6 * 0x10):
|
|
|
|
|
SyncLightPosition(6);
|
|
|
|
|
break;
|
|
|
|
|
case PICA_REG_INDEX_WORKAROUND(lighting.light[7].x, 0x144 + 7 * 0x10):
|
|
|
|
|
case PICA_REG_INDEX_WORKAROUND(lighting.light[7].z, 0x145 + 7 * 0x10):
|
|
|
|
|
SyncLightPosition(7);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
// Fragment lighting global ambient color (emission + ambient * ambient)
|
|
|
|
|
case PICA_REG_INDEX_WORKAROUND(lighting.global_ambient, 0x1c0):
|
|
|
|
|
SyncGlobalAmbient();
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -503,6 +601,13 @@ void RasterizerOpenGL::SetShader() {
|
|
|
|
|
auto& tev_stages = Pica::g_state.regs.GetTevStages();
|
|
|
|
|
for (int index = 0; index < tev_stages.size(); ++index)
|
|
|
|
|
SyncTevConstColor(index, tev_stages[index]);
|
|
|
|
|
|
|
|
|
|
SyncGlobalAmbient();
|
|
|
|
|
for (int light_index = 0; light_index < 8; light_index++) {
|
|
|
|
|
SyncLightDiffuse(light_index);
|
|
|
|
|
SyncLightAmbient(light_index);
|
|
|
|
|
SyncLightPosition(light_index);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RasterizerOpenGL::SyncFramebuffer() {
|
|
|
|
@ -683,6 +788,42 @@ void RasterizerOpenGL::SyncTevConstColor(int stage_index, const Pica::Regs::TevS
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RasterizerOpenGL::SyncGlobalAmbient() {
|
|
|
|
|
auto color = PicaToGL::LightColor(Pica::g_state.regs.lighting.global_ambient);
|
|
|
|
|
if (color != uniform_block_data.data.lighting_global_ambient) {
|
|
|
|
|
uniform_block_data.data.lighting_global_ambient = color;
|
|
|
|
|
uniform_block_data.dirty = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RasterizerOpenGL::SyncLightDiffuse(int light_index) {
|
|
|
|
|
auto color = PicaToGL::LightColor(Pica::g_state.regs.lighting.light[light_index].diffuse);
|
|
|
|
|
if (color != uniform_block_data.data.light_src[light_index].diffuse) {
|
|
|
|
|
uniform_block_data.data.light_src[light_index].diffuse = color;
|
|
|
|
|
uniform_block_data.dirty = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RasterizerOpenGL::SyncLightAmbient(int light_index) {
|
|
|
|
|
auto color = PicaToGL::LightColor(Pica::g_state.regs.lighting.light[light_index].ambient);
|
|
|
|
|
if (color != uniform_block_data.data.light_src[light_index].ambient) {
|
|
|
|
|
uniform_block_data.data.light_src[light_index].ambient = color;
|
|
|
|
|
uniform_block_data.dirty = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RasterizerOpenGL::SyncLightPosition(int light_index) {
|
|
|
|
|
std::array<GLfloat, 3> position = {
|
|
|
|
|
Pica::float16::FromRawFloat16(Pica::g_state.regs.lighting.light[light_index].x).ToFloat32(),
|
|
|
|
|
Pica::float16::FromRawFloat16(Pica::g_state.regs.lighting.light[light_index].y).ToFloat32(),
|
|
|
|
|
Pica::float16::FromRawFloat16(Pica::g_state.regs.lighting.light[light_index].z).ToFloat32() };
|
|
|
|
|
|
|
|
|
|
if (position != uniform_block_data.data.light_src[light_index].position) {
|
|
|
|
|
uniform_block_data.data.light_src[light_index].position = position;
|
|
|
|
|
uniform_block_data.dirty = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RasterizerOpenGL::SyncDrawState() {
|
|
|
|
|
const auto& regs = Pica::g_state.regs;
|
|
|
|
|
|
|
|
|
|