|
|
|
@ -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; |
|
|
|
|
|
|
|
|