diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 3 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_gen.cpp | 9 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_state.cpp | 13 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_state.h | 3 | ||||
| -rw-r--r-- | src/video_core/swrasterizer/clipper.cpp | 4 | ||||
| -rw-r--r-- | src/video_core/swrasterizer/rasterizer.h | 6 |
6 files changed, 28 insertions, 10 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 1c6c15a58..aa95ef21d 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -28,6 +28,9 @@ MICROPROFILE_DEFINE(OpenGL_Blits, "OpenGL", "Blits", MP_RGB(100, 100, 255)); | |||
| 28 | MICROPROFILE_DEFINE(OpenGL_CacheManagement, "OpenGL", "Cache Mgmt", MP_RGB(100, 255, 100)); | 28 | MICROPROFILE_DEFINE(OpenGL_CacheManagement, "OpenGL", "Cache Mgmt", MP_RGB(100, 255, 100)); |
| 29 | 29 | ||
| 30 | RasterizerOpenGL::RasterizerOpenGL() : shader_dirty(true) { | 30 | RasterizerOpenGL::RasterizerOpenGL() : shader_dirty(true) { |
| 31 | // Clipping plane 0 is always enabled for PICA fixed clip plane z <= 0 | ||
| 32 | state.clip_distance[0] = true; | ||
| 33 | |||
| 31 | // Create sampler objects | 34 | // Create sampler objects |
| 32 | for (size_t i = 0; i < texture_samplers.size(); ++i) { | 35 | for (size_t i = 0; i < texture_samplers.size(); ++i) { |
| 33 | texture_samplers[i].Create(); | 36 | texture_samplers[i].Create(); |
diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp index ae67aab05..015e69da9 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.cpp +++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp | |||
| @@ -1112,7 +1112,10 @@ vec4 secondary_fragment_color = vec4(0.0); | |||
| 1112 | "gl_FragCoord.y < scissor_y2)) discard;\n"; | 1112 | "gl_FragCoord.y < scissor_y2)) discard;\n"; |
| 1113 | } | 1113 | } |
| 1114 | 1114 | ||
| 1115 | out += "float z_over_w = 1.0 - gl_FragCoord.z * 2.0;\n"; | 1115 | // After perspective divide, OpenGL transform z_over_w from [-1, 1] to [near, far]. Here we use |
| 1116 | // default near = 0 and far = 1, and undo the transformation to get the original z_over_w, then | ||
| 1117 | // do our own transformation according to PICA specification. | ||
| 1118 | out += "float z_over_w = 2.0 * gl_FragCoord.z - 1.0;\n"; | ||
| 1116 | out += "float depth = z_over_w * depth_scale + depth_offset;\n"; | 1119 | out += "float depth = z_over_w * depth_scale + depth_offset;\n"; |
| 1117 | if (state.depthmap_enable == RasterizerRegs::DepthBuffering::WBuffering) { | 1120 | if (state.depthmap_enable == RasterizerRegs::DepthBuffering::WBuffering) { |
| 1118 | out += "depth /= gl_FragCoord.w;\n"; | 1121 | out += "depth /= gl_FragCoord.w;\n"; |
| @@ -1195,7 +1198,9 @@ void main() { | |||
| 1195 | texcoord0_w = vert_texcoord0_w; | 1198 | texcoord0_w = vert_texcoord0_w; |
| 1196 | normquat = vert_normquat; | 1199 | normquat = vert_normquat; |
| 1197 | view = vert_view; | 1200 | view = vert_view; |
| 1198 | gl_Position = vec4(vert_position.x, vert_position.y, -vert_position.z, vert_position.w); | 1201 | gl_Position = vert_position; |
| 1202 | gl_ClipDistance[0] = -vert_position.z; // fixed PICA clipping plane z <= 0 | ||
| 1203 | // TODO (wwylele): calculate gl_ClipDistance[1] from user-defined clipping plane | ||
| 1199 | } | 1204 | } |
| 1200 | )"; | 1205 | )"; |
| 1201 | 1206 | ||
diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp index bc9d34b84..06a905766 100644 --- a/src/video_core/renderer_opengl/gl_state.cpp +++ b/src/video_core/renderer_opengl/gl_state.cpp | |||
| @@ -68,6 +68,8 @@ OpenGLState::OpenGLState() { | |||
| 68 | draw.vertex_buffer = 0; | 68 | draw.vertex_buffer = 0; |
| 69 | draw.uniform_buffer = 0; | 69 | draw.uniform_buffer = 0; |
| 70 | draw.shader_program = 0; | 70 | draw.shader_program = 0; |
| 71 | |||
| 72 | clip_distance = {}; | ||
| 71 | } | 73 | } |
| 72 | 74 | ||
| 73 | void OpenGLState::Apply() const { | 75 | void OpenGLState::Apply() const { |
| @@ -261,6 +263,17 @@ void OpenGLState::Apply() const { | |||
| 261 | glUseProgram(draw.shader_program); | 263 | glUseProgram(draw.shader_program); |
| 262 | } | 264 | } |
| 263 | 265 | ||
| 266 | // Clip distance | ||
| 267 | for (size_t i = 0; i < clip_distance.size(); ++i) { | ||
| 268 | if (clip_distance[i] != cur_state.clip_distance[i]) { | ||
| 269 | if (clip_distance[i]) { | ||
| 270 | glEnable(GL_CLIP_DISTANCE0 + i); | ||
| 271 | } else { | ||
| 272 | glDisable(GL_CLIP_DISTANCE0 + i); | ||
| 273 | } | ||
| 274 | } | ||
| 275 | } | ||
| 276 | |||
| 264 | cur_state = *this; | 277 | cur_state = *this; |
| 265 | } | 278 | } |
| 266 | 279 | ||
diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h index 745a74479..437fe34c4 100644 --- a/src/video_core/renderer_opengl/gl_state.h +++ b/src/video_core/renderer_opengl/gl_state.h | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <array> | ||
| 7 | #include <glad/glad.h> | 8 | #include <glad/glad.h> |
| 8 | 9 | ||
| 9 | namespace TextureUnits { | 10 | namespace TextureUnits { |
| @@ -123,6 +124,8 @@ public: | |||
| 123 | GLuint shader_program; // GL_CURRENT_PROGRAM | 124 | GLuint shader_program; // GL_CURRENT_PROGRAM |
| 124 | } draw; | 125 | } draw; |
| 125 | 126 | ||
| 127 | std::array<bool, 2> clip_distance; // GL_CLIP_DISTANCE | ||
| 128 | |||
| 126 | OpenGLState(); | 129 | OpenGLState(); |
| 127 | 130 | ||
| 128 | /// Get the currently active OpenGL state | 131 | /// Get the currently active OpenGL state |
diff --git a/src/video_core/swrasterizer/clipper.cpp b/src/video_core/swrasterizer/clipper.cpp index 7537689b7..cdbc71502 100644 --- a/src/video_core/swrasterizer/clipper.cpp +++ b/src/video_core/swrasterizer/clipper.cpp | |||
| @@ -125,10 +125,6 @@ void ProcessTriangle(const OutputVertex& v0, const OutputVertex& v1, const Outpu | |||
| 125 | {Math::MakeVec(f0, f0, f0, -f1), Math::Vec4<float24>(f0, f0, f0, EPSILON)}, // w = EPSILON | 125 | {Math::MakeVec(f0, f0, f0, -f1), Math::Vec4<float24>(f0, f0, f0, EPSILON)}, // w = EPSILON |
| 126 | }}; | 126 | }}; |
| 127 | 127 | ||
| 128 | // TODO: If one vertex lies outside one of the depth clipping planes, some platforms (e.g. Wii) | ||
| 129 | // drop the whole primitive instead of clipping the primitive properly. We should test if | ||
| 130 | // this happens on the 3DS, too. | ||
| 131 | |||
| 132 | // Simple implementation of the Sutherland-Hodgman clipping algorithm. | 128 | // Simple implementation of the Sutherland-Hodgman clipping algorithm. |
| 133 | // TODO: Make this less inefficient (currently lots of useless buffering overhead happens here) | 129 | // TODO: Make this less inefficient (currently lots of useless buffering overhead happens here) |
| 134 | for (auto edge : clipping_edges) { | 130 | for (auto edge : clipping_edges) { |
diff --git a/src/video_core/swrasterizer/rasterizer.h b/src/video_core/swrasterizer/rasterizer.h index 2f0877581..66cd6cfd4 100644 --- a/src/video_core/swrasterizer/rasterizer.h +++ b/src/video_core/swrasterizer/rasterizer.h | |||
| @@ -19,10 +19,9 @@ struct Vertex : Shader::OutputVertex { | |||
| 19 | 19 | ||
| 20 | // Linear interpolation | 20 | // Linear interpolation |
| 21 | // factor: 0=this, 1=vtx | 21 | // factor: 0=this, 1=vtx |
| 22 | // Note: This function cannot be called after perspective divide | ||
| 22 | void Lerp(float24 factor, const Vertex& vtx) { | 23 | void Lerp(float24 factor, const Vertex& vtx) { |
| 23 | pos = pos * factor + vtx.pos * (float24::FromFloat32(1) - factor); | 24 | pos = pos * factor + vtx.pos * (float24::FromFloat32(1) - factor); |
| 24 | |||
| 25 | // TODO: Should perform perspective correct interpolation here... | ||
| 26 | quat = quat * factor + vtx.quat * (float24::FromFloat32(1) - factor); | 25 | quat = quat * factor + vtx.quat * (float24::FromFloat32(1) - factor); |
| 27 | color = color * factor + vtx.color * (float24::FromFloat32(1) - factor); | 26 | color = color * factor + vtx.color * (float24::FromFloat32(1) - factor); |
| 28 | tc0 = tc0 * factor + vtx.tc0 * (float24::FromFloat32(1) - factor); | 27 | tc0 = tc0 * factor + vtx.tc0 * (float24::FromFloat32(1) - factor); |
| @@ -30,12 +29,11 @@ struct Vertex : Shader::OutputVertex { | |||
| 30 | tc0_w = tc0_w * factor + vtx.tc0_w * (float24::FromFloat32(1) - factor); | 29 | tc0_w = tc0_w * factor + vtx.tc0_w * (float24::FromFloat32(1) - factor); |
| 31 | view = view * factor + vtx.view * (float24::FromFloat32(1) - factor); | 30 | view = view * factor + vtx.view * (float24::FromFloat32(1) - factor); |
| 32 | tc2 = tc2 * factor + vtx.tc2 * (float24::FromFloat32(1) - factor); | 31 | tc2 = tc2 * factor + vtx.tc2 * (float24::FromFloat32(1) - factor); |
| 33 | |||
| 34 | screenpos = screenpos * factor + vtx.screenpos * (float24::FromFloat32(1) - factor); | ||
| 35 | } | 32 | } |
| 36 | 33 | ||
| 37 | // Linear interpolation | 34 | // Linear interpolation |
| 38 | // factor: 0=v0, 1=v1 | 35 | // factor: 0=v0, 1=v1 |
| 36 | // Note: This function cannot be called after perspective divide | ||
| 39 | static Vertex Lerp(float24 factor, const Vertex& v0, const Vertex& v1) { | 37 | static Vertex Lerp(float24 factor, const Vertex& v0, const Vertex& v1) { |
| 40 | Vertex ret = v0; | 38 | Vertex ret = v0; |
| 41 | ret.Lerp(factor, v1); | 39 | ret.Lerp(factor, v1); |