mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-21 05:09:34 -06:00
VideoCommon: Add class for quickly transforming and culling vertices on the CPU
This commit is contained in:
@ -65,6 +65,97 @@ void VertexShaderManager::Dirty()
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
Common::Matrix44 VertexShaderManager::LoadProjectionMatrix()
|
||||
{
|
||||
const auto& rawProjection = xfmem.projection.rawProjection;
|
||||
|
||||
switch (xfmem.projection.type)
|
||||
{
|
||||
case ProjectionType::Perspective:
|
||||
{
|
||||
const Common::Vec2 fov_multiplier = g_freelook_camera.IsActive() ?
|
||||
g_freelook_camera.GetFieldOfViewMultiplier() :
|
||||
Common::Vec2{1, 1};
|
||||
m_projection_matrix[0] = rawProjection[0] * g_ActiveConfig.fAspectRatioHackW * fov_multiplier.x;
|
||||
m_projection_matrix[1] = 0.0f;
|
||||
m_projection_matrix[2] = rawProjection[1] * g_ActiveConfig.fAspectRatioHackW * fov_multiplier.x;
|
||||
m_projection_matrix[3] = 0.0f;
|
||||
|
||||
m_projection_matrix[4] = 0.0f;
|
||||
m_projection_matrix[5] = rawProjection[2] * g_ActiveConfig.fAspectRatioHackH * fov_multiplier.y;
|
||||
m_projection_matrix[6] = rawProjection[3] * g_ActiveConfig.fAspectRatioHackH * fov_multiplier.y;
|
||||
m_projection_matrix[7] = 0.0f;
|
||||
|
||||
m_projection_matrix[8] = 0.0f;
|
||||
m_projection_matrix[9] = 0.0f;
|
||||
m_projection_matrix[10] = rawProjection[4];
|
||||
m_projection_matrix[11] = rawProjection[5];
|
||||
|
||||
m_projection_matrix[12] = 0.0f;
|
||||
m_projection_matrix[13] = 0.0f;
|
||||
|
||||
m_projection_matrix[14] = -1.0f;
|
||||
m_projection_matrix[15] = 0.0f;
|
||||
|
||||
g_stats.gproj = m_projection_matrix;
|
||||
}
|
||||
break;
|
||||
|
||||
case ProjectionType::Orthographic:
|
||||
{
|
||||
m_projection_matrix[0] = rawProjection[0];
|
||||
m_projection_matrix[1] = 0.0f;
|
||||
m_projection_matrix[2] = 0.0f;
|
||||
m_projection_matrix[3] = rawProjection[1];
|
||||
|
||||
m_projection_matrix[4] = 0.0f;
|
||||
m_projection_matrix[5] = rawProjection[2];
|
||||
m_projection_matrix[6] = 0.0f;
|
||||
m_projection_matrix[7] = rawProjection[3];
|
||||
|
||||
m_projection_matrix[8] = 0.0f;
|
||||
m_projection_matrix[9] = 0.0f;
|
||||
m_projection_matrix[10] = rawProjection[4];
|
||||
m_projection_matrix[11] = rawProjection[5];
|
||||
|
||||
m_projection_matrix[12] = 0.0f;
|
||||
m_projection_matrix[13] = 0.0f;
|
||||
|
||||
m_projection_matrix[14] = 0.0f;
|
||||
m_projection_matrix[15] = 1.0f;
|
||||
|
||||
g_stats.g2proj = m_projection_matrix;
|
||||
g_stats.proj = rawProjection;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ERROR_LOG_FMT(VIDEO, "Unknown projection type: {}", xfmem.projection.type);
|
||||
}
|
||||
|
||||
PRIM_LOG("Projection: {} {} {} {} {} {}", rawProjection[0], rawProjection[1], rawProjection[2],
|
||||
rawProjection[3], rawProjection[4], rawProjection[5]);
|
||||
|
||||
auto corrected_matrix = m_viewport_correction * Common::Matrix44::FromArray(m_projection_matrix);
|
||||
|
||||
if (g_freelook_camera.IsActive() && xfmem.projection.type == ProjectionType::Perspective)
|
||||
corrected_matrix *= g_freelook_camera.GetView();
|
||||
|
||||
g_freelook_camera.GetController()->SetClean();
|
||||
|
||||
return corrected_matrix;
|
||||
}
|
||||
|
||||
void VertexShaderManager::SetProjectionMatrix()
|
||||
{
|
||||
if (m_projection_changed || g_freelook_camera.GetController()->IsDirty())
|
||||
{
|
||||
m_projection_changed = false;
|
||||
auto corrected_matrix = LoadProjectionMatrix();
|
||||
memcpy(constants.projection.data(), corrected_matrix.data.data(), 4 * sizeof(float4));
|
||||
}
|
||||
}
|
||||
|
||||
// Syncs the shader constant buffers with xfmem
|
||||
// TODO: A cleaner way to control the matrices without making a mess in the parameters field
|
||||
void VertexShaderManager::SetConstants(const std::vector<std::string>& textures)
|
||||
@ -317,84 +408,7 @@ void VertexShaderManager::SetConstants(const std::vector<std::string>& textures)
|
||||
m_projection_changed = false;
|
||||
m_projection_graphics_mod_change = !projection_actions.empty();
|
||||
|
||||
const auto& rawProjection = xfmem.projection.rawProjection;
|
||||
|
||||
switch (xfmem.projection.type)
|
||||
{
|
||||
case ProjectionType::Perspective:
|
||||
{
|
||||
const Common::Vec2 fov_multiplier = g_freelook_camera.IsActive() ?
|
||||
g_freelook_camera.GetFieldOfViewMultiplier() :
|
||||
Common::Vec2{1, 1};
|
||||
m_projection_matrix[0] =
|
||||
rawProjection[0] * g_ActiveConfig.fAspectRatioHackW * fov_multiplier.x;
|
||||
m_projection_matrix[1] = 0.0f;
|
||||
m_projection_matrix[2] =
|
||||
rawProjection[1] * g_ActiveConfig.fAspectRatioHackW * fov_multiplier.x;
|
||||
m_projection_matrix[3] = 0.0f;
|
||||
|
||||
m_projection_matrix[4] = 0.0f;
|
||||
m_projection_matrix[5] =
|
||||
rawProjection[2] * g_ActiveConfig.fAspectRatioHackH * fov_multiplier.y;
|
||||
m_projection_matrix[6] =
|
||||
rawProjection[3] * g_ActiveConfig.fAspectRatioHackH * fov_multiplier.y;
|
||||
m_projection_matrix[7] = 0.0f;
|
||||
|
||||
m_projection_matrix[8] = 0.0f;
|
||||
m_projection_matrix[9] = 0.0f;
|
||||
m_projection_matrix[10] = rawProjection[4];
|
||||
m_projection_matrix[11] = rawProjection[5];
|
||||
|
||||
m_projection_matrix[12] = 0.0f;
|
||||
m_projection_matrix[13] = 0.0f;
|
||||
|
||||
m_projection_matrix[14] = -1.0f;
|
||||
m_projection_matrix[15] = 0.0f;
|
||||
|
||||
g_stats.gproj = m_projection_matrix;
|
||||
}
|
||||
break;
|
||||
|
||||
case ProjectionType::Orthographic:
|
||||
{
|
||||
m_projection_matrix[0] = rawProjection[0];
|
||||
m_projection_matrix[1] = 0.0f;
|
||||
m_projection_matrix[2] = 0.0f;
|
||||
m_projection_matrix[3] = rawProjection[1];
|
||||
|
||||
m_projection_matrix[4] = 0.0f;
|
||||
m_projection_matrix[5] = rawProjection[2];
|
||||
m_projection_matrix[6] = 0.0f;
|
||||
m_projection_matrix[7] = rawProjection[3];
|
||||
|
||||
m_projection_matrix[8] = 0.0f;
|
||||
m_projection_matrix[9] = 0.0f;
|
||||
m_projection_matrix[10] = rawProjection[4];
|
||||
m_projection_matrix[11] = rawProjection[5];
|
||||
|
||||
m_projection_matrix[12] = 0.0f;
|
||||
m_projection_matrix[13] = 0.0f;
|
||||
|
||||
m_projection_matrix[14] = 0.0f;
|
||||
m_projection_matrix[15] = 1.0f;
|
||||
|
||||
g_stats.g2proj = m_projection_matrix;
|
||||
g_stats.proj = rawProjection;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ERROR_LOG_FMT(VIDEO, "Unknown projection type: {}", xfmem.projection.type);
|
||||
}
|
||||
|
||||
PRIM_LOG("Projection: {} {} {} {} {} {}", rawProjection[0], rawProjection[1], rawProjection[2],
|
||||
rawProjection[3], rawProjection[4], rawProjection[5]);
|
||||
|
||||
auto corrected_matrix =
|
||||
m_viewport_correction * Common::Matrix44::FromArray(m_projection_matrix);
|
||||
|
||||
if (g_freelook_camera.IsActive() && xfmem.projection.type == ProjectionType::Perspective)
|
||||
corrected_matrix *= g_freelook_camera.GetView();
|
||||
auto corrected_matrix = LoadProjectionMatrix();
|
||||
|
||||
GraphicsModActionData::Projection projection{&corrected_matrix};
|
||||
for (auto action : projection_actions)
|
||||
@ -404,8 +418,6 @@ void VertexShaderManager::SetConstants(const std::vector<std::string>& textures)
|
||||
|
||||
memcpy(constants.projection.data(), corrected_matrix.data.data(), 4 * sizeof(float4));
|
||||
|
||||
g_freelook_camera.GetController()->SetClean();
|
||||
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user