forked from ShuriZma/suyu
gl_rasterizer: implement custom clip plane
This commit is contained in:
parent
ea51a3af26
commit
addbcd5784
|
@ -169,6 +169,8 @@ RasterizerOpenGL::RasterizerOpenGL() : shader_dirty(true) {
|
|||
glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, proctex_diff_lut_buffer.handle);
|
||||
|
||||
// Sync fixed function OpenGL state
|
||||
SyncClipEnabled();
|
||||
SyncClipCoef();
|
||||
SyncCullMode();
|
||||
SyncBlendEnabled();
|
||||
SyncBlendFuncs();
|
||||
|
@ -401,6 +403,18 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) {
|
|||
SyncCullMode();
|
||||
break;
|
||||
|
||||
// Clipping plane
|
||||
case PICA_REG_INDEX(rasterizer.clip_enable):
|
||||
SyncClipEnabled();
|
||||
break;
|
||||
|
||||
case PICA_REG_INDEX_WORKAROUND(rasterizer.clip_coef[0], 0x48):
|
||||
case PICA_REG_INDEX_WORKAROUND(rasterizer.clip_coef[1], 0x49):
|
||||
case PICA_REG_INDEX_WORKAROUND(rasterizer.clip_coef[2], 0x4a):
|
||||
case PICA_REG_INDEX_WORKAROUND(rasterizer.clip_coef[3], 0x4b):
|
||||
SyncClipCoef();
|
||||
break;
|
||||
|
||||
// Depth modifiers
|
||||
case PICA_REG_INDEX(rasterizer.viewport_depth_range):
|
||||
SyncDepthScale();
|
||||
|
@ -1280,6 +1294,20 @@ void RasterizerOpenGL::SetShader() {
|
|||
}
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncClipEnabled() {
|
||||
state.clip_distance[1] = Pica::g_state.regs.rasterizer.clip_enable != 0;
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncClipCoef() {
|
||||
const auto raw_clip_coef = Pica::g_state.regs.rasterizer.GetClipCoef();
|
||||
const GLvec4 new_clip_coef = {raw_clip_coef.x.ToFloat32(), raw_clip_coef.y.ToFloat32(),
|
||||
raw_clip_coef.z.ToFloat32(), raw_clip_coef.w.ToFloat32()};
|
||||
if (new_clip_coef != uniform_block_data.data.clip_coef) {
|
||||
uniform_block_data.data.clip_coef = new_clip_coef;
|
||||
uniform_block_data.dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncCullMode() {
|
||||
const auto& regs = Pica::g_state.regs;
|
||||
|
||||
|
|
|
@ -151,14 +151,21 @@ private:
|
|||
LightSrc light_src[8];
|
||||
alignas(16) GLvec4 const_color[6]; // A vec4 color for each of the six tev stages
|
||||
alignas(16) GLvec4 tev_combiner_buffer_color;
|
||||
alignas(16) GLvec4 clip_coef;
|
||||
};
|
||||
|
||||
static_assert(
|
||||
sizeof(UniformData) == 0x460,
|
||||
sizeof(UniformData) == 0x470,
|
||||
"The size of the UniformData structure has changed, update the structure in the shader");
|
||||
static_assert(sizeof(UniformData) < 16384,
|
||||
"UniformData structure must be less than 16kb as per the OpenGL spec");
|
||||
|
||||
/// Syncs the clip enabled status to match the PICA register
|
||||
void SyncClipEnabled();
|
||||
|
||||
/// Syncs the clip coefficients to match the PICA register
|
||||
void SyncClipCoef();
|
||||
|
||||
/// Sets the OpenGL shader in accordance with the current PICA register state
|
||||
void SetShader();
|
||||
|
||||
|
|
|
@ -24,6 +24,42 @@ using TevStageConfig = TexturingRegs::TevStageConfig;
|
|||
|
||||
namespace GLShader {
|
||||
|
||||
static const std::string UniformBlockDef = R"(
|
||||
#define NUM_TEV_STAGES 6
|
||||
#define NUM_LIGHTS 8
|
||||
|
||||
struct LightSrc {
|
||||
vec3 specular_0;
|
||||
vec3 specular_1;
|
||||
vec3 diffuse;
|
||||
vec3 ambient;
|
||||
vec3 position;
|
||||
vec3 spot_direction;
|
||||
float dist_atten_bias;
|
||||
float dist_atten_scale;
|
||||
};
|
||||
|
||||
layout (std140) uniform shader_data {
|
||||
vec2 framebuffer_scale;
|
||||
int alphatest_ref;
|
||||
float depth_scale;
|
||||
float depth_offset;
|
||||
int scissor_x1;
|
||||
int scissor_y1;
|
||||
int scissor_x2;
|
||||
int scissor_y2;
|
||||
vec3 fog_color;
|
||||
vec2 proctex_noise_f;
|
||||
vec2 proctex_noise_a;
|
||||
vec2 proctex_noise_p;
|
||||
vec3 lighting_global_ambient;
|
||||
LightSrc light_src[NUM_LIGHTS];
|
||||
vec4 const_color[NUM_TEV_STAGES];
|
||||
vec4 tev_combiner_buffer_color;
|
||||
vec4 clip_coef;
|
||||
};
|
||||
)";
|
||||
|
||||
PicaShaderConfig PicaShaderConfig::BuildFromRegs(const Pica::Regs& regs) {
|
||||
PicaShaderConfig res;
|
||||
|
||||
|
@ -1008,8 +1044,6 @@ std::string GenerateFragmentShader(const PicaShaderConfig& config) {
|
|||
|
||||
std::string out = R"(
|
||||
#version 330 core
|
||||
#define NUM_TEV_STAGES 6
|
||||
#define NUM_LIGHTS 8
|
||||
|
||||
in vec4 primary_color;
|
||||
in vec2 texcoord[3];
|
||||
|
@ -1021,36 +1055,6 @@ in vec4 gl_FragCoord;
|
|||
|
||||
out vec4 color;
|
||||
|
||||
struct LightSrc {
|
||||
vec3 specular_0;
|
||||
vec3 specular_1;
|
||||
vec3 diffuse;
|
||||
vec3 ambient;
|
||||
vec3 position;
|
||||
vec3 spot_direction;
|
||||
float dist_atten_bias;
|
||||
float dist_atten_scale;
|
||||
};
|
||||
|
||||
layout (std140) uniform shader_data {
|
||||
vec2 framebuffer_scale;
|
||||
int alphatest_ref;
|
||||
float depth_scale;
|
||||
float depth_offset;
|
||||
int scissor_x1;
|
||||
int scissor_y1;
|
||||
int scissor_x2;
|
||||
int scissor_y2;
|
||||
vec3 fog_color;
|
||||
vec2 proctex_noise_f;
|
||||
vec2 proctex_noise_a;
|
||||
vec2 proctex_noise_p;
|
||||
vec3 lighting_global_ambient;
|
||||
LightSrc light_src[NUM_LIGHTS];
|
||||
vec4 const_color[NUM_TEV_STAGES];
|
||||
vec4 tev_combiner_buffer_color;
|
||||
};
|
||||
|
||||
uniform sampler2D tex[3];
|
||||
uniform samplerBuffer lighting_lut;
|
||||
uniform samplerBuffer fog_lut;
|
||||
|
@ -1059,7 +1063,11 @@ uniform samplerBuffer proctex_color_map;
|
|||
uniform samplerBuffer proctex_alpha_map;
|
||||
uniform samplerBuffer proctex_lut;
|
||||
uniform samplerBuffer proctex_diff_lut;
|
||||
)";
|
||||
|
||||
out += UniformBlockDef;
|
||||
|
||||
out += R"(
|
||||
// Rotate the vector v by the quaternion q
|
||||
vec3 quaternion_rotate(vec4 q, vec3 v) {
|
||||
return v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v);
|
||||
|
@ -1190,6 +1198,12 @@ out float texcoord0_w;
|
|||
out vec4 normquat;
|
||||
out vec3 view;
|
||||
|
||||
)";
|
||||
|
||||
out += UniformBlockDef;
|
||||
|
||||
out += R"(
|
||||
|
||||
void main() {
|
||||
primary_color = vert_color;
|
||||
texcoord[0] = vert_texcoord0;
|
||||
|
@ -1200,7 +1214,7 @@ void main() {
|
|||
view = vert_view;
|
||||
gl_Position = vert_position;
|
||||
gl_ClipDistance[0] = -vert_position.z; // fixed PICA clipping plane z <= 0
|
||||
// TODO (wwylele): calculate gl_ClipDistance[1] from user-defined clipping plane
|
||||
gl_ClipDistance[1] = dot(clip_coef, vert_position);
|
||||
}
|
||||
)";
|
||||
|
||||
|
|
Loading…
Reference in New Issue