Merge pull request #2884 from wwylele/clip
gl_rasterizer: add clipping plane z<=0 defined in PICA
This commit is contained in:
commit
f84c965dec
@ -28,6 +28,9 @@ MICROPROFILE_DEFINE(OpenGL_Blits, "OpenGL", "Blits", MP_RGB(100, 100, 255));
|
|||||||
MICROPROFILE_DEFINE(OpenGL_CacheManagement, "OpenGL", "Cache Mgmt", MP_RGB(100, 255, 100));
|
MICROPROFILE_DEFINE(OpenGL_CacheManagement, "OpenGL", "Cache Mgmt", MP_RGB(100, 255, 100));
|
||||||
|
|
||||||
RasterizerOpenGL::RasterizerOpenGL() : shader_dirty(true) {
|
RasterizerOpenGL::RasterizerOpenGL() : shader_dirty(true) {
|
||||||
|
// Clipping plane 0 is always enabled for PICA fixed clip plane z <= 0
|
||||||
|
state.clip_distance[0] = true;
|
||||||
|
|
||||||
// Create sampler objects
|
// Create sampler objects
|
||||||
for (size_t i = 0; i < texture_samplers.size(); ++i) {
|
for (size_t i = 0; i < texture_samplers.size(); ++i) {
|
||||||
texture_samplers[i].Create();
|
texture_samplers[i].Create();
|
||||||
|
@ -1112,7 +1112,10 @@ vec4 secondary_fragment_color = vec4(0.0);
|
|||||||
"gl_FragCoord.y < scissor_y2)) discard;\n";
|
"gl_FragCoord.y < scissor_y2)) discard;\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
out += "float z_over_w = 1.0 - gl_FragCoord.z * 2.0;\n";
|
// After perspective divide, OpenGL transform z_over_w from [-1, 1] to [near, far]. Here we use
|
||||||
|
// default near = 0 and far = 1, and undo the transformation to get the original z_over_w, then
|
||||||
|
// do our own transformation according to PICA specification.
|
||||||
|
out += "float z_over_w = 2.0 * gl_FragCoord.z - 1.0;\n";
|
||||||
out += "float depth = z_over_w * depth_scale + depth_offset;\n";
|
out += "float depth = z_over_w * depth_scale + depth_offset;\n";
|
||||||
if (state.depthmap_enable == RasterizerRegs::DepthBuffering::WBuffering) {
|
if (state.depthmap_enable == RasterizerRegs::DepthBuffering::WBuffering) {
|
||||||
out += "depth /= gl_FragCoord.w;\n";
|
out += "depth /= gl_FragCoord.w;\n";
|
||||||
@ -1195,7 +1198,9 @@ void main() {
|
|||||||
texcoord0_w = vert_texcoord0_w;
|
texcoord0_w = vert_texcoord0_w;
|
||||||
normquat = vert_normquat;
|
normquat = vert_normquat;
|
||||||
view = vert_view;
|
view = vert_view;
|
||||||
gl_Position = vec4(vert_position.x, vert_position.y, -vert_position.z, vert_position.w);
|
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
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
|
||||||
|
@ -68,6 +68,8 @@ OpenGLState::OpenGLState() {
|
|||||||
draw.vertex_buffer = 0;
|
draw.vertex_buffer = 0;
|
||||||
draw.uniform_buffer = 0;
|
draw.uniform_buffer = 0;
|
||||||
draw.shader_program = 0;
|
draw.shader_program = 0;
|
||||||
|
|
||||||
|
clip_distance = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLState::Apply() const {
|
void OpenGLState::Apply() const {
|
||||||
@ -261,6 +263,17 @@ void OpenGLState::Apply() const {
|
|||||||
glUseProgram(draw.shader_program);
|
glUseProgram(draw.shader_program);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clip distance
|
||||||
|
for (size_t i = 0; i < clip_distance.size(); ++i) {
|
||||||
|
if (clip_distance[i] != cur_state.clip_distance[i]) {
|
||||||
|
if (clip_distance[i]) {
|
||||||
|
glEnable(GL_CLIP_DISTANCE0 + i);
|
||||||
|
} else {
|
||||||
|
glDisable(GL_CLIP_DISTANCE0 + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cur_state = *this;
|
cur_state = *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <glad/glad.h>
|
#include <glad/glad.h>
|
||||||
|
|
||||||
namespace TextureUnits {
|
namespace TextureUnits {
|
||||||
@ -123,6 +124,8 @@ public:
|
|||||||
GLuint shader_program; // GL_CURRENT_PROGRAM
|
GLuint shader_program; // GL_CURRENT_PROGRAM
|
||||||
} draw;
|
} draw;
|
||||||
|
|
||||||
|
std::array<bool, 2> clip_distance; // GL_CLIP_DISTANCE
|
||||||
|
|
||||||
OpenGLState();
|
OpenGLState();
|
||||||
|
|
||||||
/// Get the currently active OpenGL state
|
/// Get the currently active OpenGL state
|
||||||
|
@ -125,10 +125,6 @@ void ProcessTriangle(const OutputVertex& v0, const OutputVertex& v1, const Outpu
|
|||||||
{Math::MakeVec(f0, f0, f0, -f1), Math::Vec4<float24>(f0, f0, f0, EPSILON)}, // w = EPSILON
|
{Math::MakeVec(f0, f0, f0, -f1), Math::Vec4<float24>(f0, f0, f0, EPSILON)}, // w = EPSILON
|
||||||
}};
|
}};
|
||||||
|
|
||||||
// TODO: If one vertex lies outside one of the depth clipping planes, some platforms (e.g. Wii)
|
|
||||||
// drop the whole primitive instead of clipping the primitive properly. We should test if
|
|
||||||
// this happens on the 3DS, too.
|
|
||||||
|
|
||||||
// Simple implementation of the Sutherland-Hodgman clipping algorithm.
|
// Simple implementation of the Sutherland-Hodgman clipping algorithm.
|
||||||
// TODO: Make this less inefficient (currently lots of useless buffering overhead happens here)
|
// TODO: Make this less inefficient (currently lots of useless buffering overhead happens here)
|
||||||
for (auto edge : clipping_edges) {
|
for (auto edge : clipping_edges) {
|
||||||
|
@ -19,10 +19,9 @@ struct Vertex : Shader::OutputVertex {
|
|||||||
|
|
||||||
// Linear interpolation
|
// Linear interpolation
|
||||||
// factor: 0=this, 1=vtx
|
// factor: 0=this, 1=vtx
|
||||||
|
// Note: This function cannot be called after perspective divide
|
||||||
void Lerp(float24 factor, const Vertex& vtx) {
|
void Lerp(float24 factor, const Vertex& vtx) {
|
||||||
pos = pos * factor + vtx.pos * (float24::FromFloat32(1) - factor);
|
pos = pos * factor + vtx.pos * (float24::FromFloat32(1) - factor);
|
||||||
|
|
||||||
// TODO: Should perform perspective correct interpolation here...
|
|
||||||
quat = quat * factor + vtx.quat * (float24::FromFloat32(1) - factor);
|
quat = quat * factor + vtx.quat * (float24::FromFloat32(1) - factor);
|
||||||
color = color * factor + vtx.color * (float24::FromFloat32(1) - factor);
|
color = color * factor + vtx.color * (float24::FromFloat32(1) - factor);
|
||||||
tc0 = tc0 * factor + vtx.tc0 * (float24::FromFloat32(1) - factor);
|
tc0 = tc0 * factor + vtx.tc0 * (float24::FromFloat32(1) - factor);
|
||||||
@ -30,12 +29,11 @@ struct Vertex : Shader::OutputVertex {
|
|||||||
tc0_w = tc0_w * factor + vtx.tc0_w * (float24::FromFloat32(1) - factor);
|
tc0_w = tc0_w * factor + vtx.tc0_w * (float24::FromFloat32(1) - factor);
|
||||||
view = view * factor + vtx.view * (float24::FromFloat32(1) - factor);
|
view = view * factor + vtx.view * (float24::FromFloat32(1) - factor);
|
||||||
tc2 = tc2 * factor + vtx.tc2 * (float24::FromFloat32(1) - factor);
|
tc2 = tc2 * factor + vtx.tc2 * (float24::FromFloat32(1) - factor);
|
||||||
|
|
||||||
screenpos = screenpos * factor + vtx.screenpos * (float24::FromFloat32(1) - factor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Linear interpolation
|
// Linear interpolation
|
||||||
// factor: 0=v0, 1=v1
|
// factor: 0=v0, 1=v1
|
||||||
|
// Note: This function cannot be called after perspective divide
|
||||||
static Vertex Lerp(float24 factor, const Vertex& v0, const Vertex& v1) {
|
static Vertex Lerp(float24 factor, const Vertex& v0, const Vertex& v1) {
|
||||||
Vertex ret = v0;
|
Vertex ret = v0;
|
||||||
ret.Lerp(factor, v1);
|
ret.Lerp(factor, v1);
|
||||||
|
Loading…
Reference in New Issue
Block a user