forked from eden-emu/eden
		
	gl_rasterizer: implement custom clip plane
This commit is contained in:
		
							parent
							
								
									ea51a3af26
								
							
						
					
					
						commit
						addbcd5784
					
				
					 3 changed files with 83 additions and 34 deletions
				
			
		|  | @ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 wwylele
						wwylele