Skip to content

Commit d91739b

Browse files
committed
Use built-in OpenGL clip plane instead of custom variant
The current shaders compute the clip values in the vertex shader and then discard fragments if those values say that the fragment is clipped. I don't know why this was done but, as far as I can tell, this behavior can be fully replaced by using the built-in OpenGL clip-plane feature which should also reduce the amount of fragment shader invocations. This won't affect performance too much since we rarely use clip planes but it seems like the correct thing to do.
1 parent bb94d5b commit d91739b

File tree

7 files changed

+28
-82
lines changed

7 files changed

+28
-82
lines changed

code/def_files/main-f.sdr

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,6 @@ uniform float neardist;
8282
uniform float middist;
8383
uniform float fardist;
8484
#endif
85-
#ifdef FLAG_CLIP
86-
uniform int use_clip_plane;
87-
in float fragClipDistance;
88-
#endif
8985
#ifdef FLAG_NORMAL_ALPHA
9086
uniform vec2 normalAlphaMinMax;
9187
#endif
@@ -270,9 +266,6 @@ void main()
270266
if(fragNotVisible >= 0.9) { discard; }
271267
#endif
272268
#ifdef FLAG_SHADOW_MAP
273-
#ifdef FLAG_CLIP
274-
if(use_clip_plane == 1) { if(fragClipDistance <= 0.0) { discard; } }
275-
#endif
276269
// need depth and depth squared for variance shadow maps
277270
fragOut0 = vec4(fragPosition.z, fragPosition.z * fragPosition.z * VARIANCE_SHADOW_SCALE_INV, 0.0, 1.0);
278271
return;
@@ -444,10 +437,6 @@ void main()
444437
#ifdef FLAG_NORMAL_ALPHA
445438
float normViewOffset = dot(vec3(0.0, 0.0, 1.0), normal);
446439
baseColor.a = smoothstep(min(normalAlphaMinMax.x, normalAlphaMinMax.y), max(normalAlphaMinMax.x, normalAlphaMinMax.y), clamp(normalAlphaMinMax.x > normalAlphaMinMax.y ? normViewOffset : 1.0 - normViewOffset, 0.0, 1.0));
447-
#endif
448-
#ifdef FLAG_CLIP
449-
// for some odd reason if we try to discard the pixel early for plane clipping, it screws up glow maps so let's just do it down here.
450-
if(use_clip_plane == 1) { if(fragClipDistance <= 0.0) { discard; } }
451440
#endif
452441
fragOut0 = baseColor;
453442
#ifdef FLAG_DEFERRED

code/def_files/main-g.sdr

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,6 @@ out vec4 fragTexCoord;
1111
in float geoNotVisible[];
1212
out float fragNotVisible;
1313
#endif
14-
#ifdef FLAG_CLIP
15-
in float geoClipDistance[];
16-
out float fragClipDistance;
17-
#endif
1814
void main(void)
1915
{
2016
int instanceID = int(geoInstance[0]);
@@ -31,7 +27,7 @@ void main(void)
3127
fragNotVisible = geoNotVisible[0];
3228
#endif
3329
#ifdef FLAG_CLIP
34-
fragClipDistance = geoClipDistance[0];
30+
gl_ClipDistance[0] = gl_in[vert].gl_ClipDistance[0];
3531
#endif
3632
EmitVertex();
3733
}

code/def_files/main-v.sdr

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,7 @@ uniform float thruster_scale;
5454
#endif
5555
#ifdef FLAG_CLIP
5656
uniform int use_clip_plane;
57-
uniform vec3 clip_normal;
58-
uniform vec3 clip_position;
59-
#ifdef FLAG_SHADOW_MAP
60-
out float geoClipDistance;
61-
#else
62-
out float fragClipDistance;
63-
#endif
57+
uniform vec4 clip_equation;
6458
#endif
6559
#ifdef FLAG_TRANSFORM
6660
#define TEXELS_PER_MATRIX 4
@@ -147,13 +141,11 @@ void main()
147141
fragFogDist = clamp((gl_Position.z - fogStart) * 0.75 * fogScale, 0.0, 1.0);
148142
#endif
149143
#ifdef FLAG_CLIP
150-
float clip_dist = 0.0;
151-
if(use_clip_plane == 1) clip_dist = dot(normalize((modelMatrix * orient * vertex).xyz - clip_position), clip_normal);
152-
#ifdef FLAG_SHADOW_MAP
153-
geoClipDistance = clip_dist;
154-
#else
155-
fragClipDistance = clip_dist;
156-
#endif
144+
if(use_clip_plane == 1) {
145+
gl_ClipDistance[0] = dot(clip_equation, modelMatrix * orient * vertex);
146+
} else {
147+
gl_ClipDistance[0] = -1.0f;
148+
}
157149
#endif
158150
#ifndef FLAG_SHADOW_MAP
159151
fragPosition = position;

code/graphics/opengl/gropenglshader.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ static opengl_shader_variant_t GL_shader_variants[] = {
184184
"Submodel Transforms" },
185185

186186
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_CLIP, "FLAG_CLIP",
187-
{ "use_clip_plane", "clip_normal", "clip_position" }, { },
187+
{ "use_clip_plane", "clip_equation" }, { },
188188
"Clip Plane" },
189189

190190
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_HDR, "FLAG_HDR",

code/graphics/opengl/gropenglstate.cpp

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -317,39 +317,19 @@ GLboolean opengl_state::PolygonOffsetFill(GLint state)
317317
return save_state;
318318
}
319319

320-
GLboolean opengl_state::ClipPlane(GLint num, GLint state)
321-
{
322-
Assert( (num >= 0) || (num < (int)(sizeof(clipplane_Status) / sizeof(GLboolean))) );
323-
324-
GLboolean save_state = clipplane_Status[num];
325-
326-
if ( !((state == -1) || (state == clipplane_Status[num])) ) {
327-
if (state) {
328-
Assert( state == GL_TRUE );
329-
clipplane_Status[num] = GL_TRUE;
330-
} else {
331-
clipplane_Status[num] = GL_FALSE;
332-
}
333-
}
334-
335-
return save_state;
336-
}
337-
338-
GLboolean opengl_state::ClipDistance(GLint num, GLint state)
320+
GLboolean opengl_state::ClipDistance(GLint num, bool state)
339321
{
340322
Assert( (num >= 0) && (num < (int)(sizeof(clipdistance_Status) / sizeof(GLboolean))) );
341323

342324
GLboolean save_state = clipdistance_Status[num];
343325

344-
if ( !((state == -1) || (state == clipdistance_Status[num])) ) {
326+
if (state != clipdistance_Status[num]) {
345327
if (state) {
346-
Assert( state == GL_TRUE );
347-
//glEnable(GL_CLIP_DISTANCE0+num);
348-
clipdistance_Status[num] = GL_TRUE;
328+
glEnable(GL_CLIP_DISTANCE0+num);
349329
} else {
350-
//glDisable(GL_CLIP_DISTANCE0+num);
351-
clipdistance_Status[num] = GL_FALSE;
330+
glDisable(GL_CLIP_DISTANCE0+num);
352331
}
332+
clipdistance_Status[num] = state;
353333
}
354334

355335
return save_state;

code/graphics/opengl/gropenglstate.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ class opengl_state
152152
GLboolean polygonoffsetfill_Status;
153153
GLboolean normalize_Status;
154154
GLboolean clipplane_Status[6];
155-
GLboolean clipdistance_Status[6];
155+
bool clipdistance_Status[6];
156156
GLboolean depthmask_Status;
157157
GLboolean colormask_Status;
158158

@@ -202,8 +202,7 @@ class opengl_state
202202
GLboolean StencilTest(GLint state = -1);
203203
GLboolean CullFace(GLint state = -1);
204204
GLboolean PolygonOffsetFill(GLint state = -1);
205-
GLboolean ClipPlane(GLint num, GLint state = -1);
206-
GLboolean ClipDistance(GLint num, GLint state = -1);
205+
GLboolean ClipDistance(GLint num, bool state = false);
207206
GLboolean DepthMask(GLint state = -1);
208207
GLboolean ColorMask(GLint state = -1);
209208

code/graphics/opengl/gropengltnl.cpp

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -793,26 +793,12 @@ void gr_opengl_start_clip_plane()
793793

794794
void gr_opengl_set_clip_plane(vec3d *clip_normal, vec3d *clip_point)
795795
{
796-
if ( Current_shader != NULL && Current_shader->shader == SDR_TYPE_MODEL) {
797-
return;
798-
}
799-
800796
if ( clip_normal == NULL || clip_point == NULL ) {
801-
GL_state.ClipPlane(0, GL_FALSE);
797+
GL_state.ClipDistance(0, false);
802798
} else {
803-
GLdouble clip_equation[4];
804-
805-
clip_equation[0] = (GLdouble)clip_normal->xyz.x;
806-
clip_equation[1] = (GLdouble)clip_normal->xyz.y;
807-
clip_equation[2] = (GLdouble)clip_normal->xyz.z;
808-
809-
clip_equation[3] = (GLdouble)(clip_normal->xyz.x * clip_point->xyz.x)
810-
+ (GLdouble)(clip_normal->xyz.y * clip_point->xyz.y)
811-
+ (GLdouble)(clip_normal->xyz.z * clip_point->xyz.z);
812-
clip_equation[3] *= -1.0;
799+
Assertion(Current_shader != NULL && Current_shader->shader == SDR_TYPE_MODEL, "Clip planes are only supported by the model shader!");
813800

814-
815-
GL_state.ClipPlane(0, GL_TRUE);
801+
GL_state.ClipDistance(0, true);
816802
}
817803
}
818804

@@ -902,7 +888,7 @@ void opengl_tnl_set_material(material* material_info, bool set_base_map)
902888

903889
material::clip_plane &clip_params = material_info->get_clip_plane();
904890

905-
if ( clip_params.enabled ) {
891+
if ( material_info->is_clipped() ) {
906892
gr_opengl_set_clip_plane(&clip_params.normal, &clip_params.position);
907893
} else {
908894
gr_opengl_set_clip_plane(NULL, NULL);
@@ -951,14 +937,18 @@ void opengl_tnl_set_model_material(model_material *material_info)
951937
}
952938

953939
if ( Current_shader->flags & SDR_FLAG_MODEL_CLIP ) {
954-
bool clip = material_info->is_clipped();
955-
956-
if ( clip ) {
940+
if (material_info->is_clipped()) {
957941
material::clip_plane &clip_info = material_info->get_clip_plane();
958942

959943
Current_shader->program->Uniforms.setUniformi("use_clip_plane", 1);
960-
Current_shader->program->Uniforms.setUniform3f("clip_normal", clip_info.normal);
961-
Current_shader->program->Uniforms.setUniform3f("clip_position", clip_info.position);
944+
945+
vec4 clip_equation;
946+
clip_equation.xyzw.x = clip_info.normal.xyz.x;
947+
clip_equation.xyzw.y = clip_info.normal.xyz.y;
948+
clip_equation.xyzw.z = clip_info.normal.xyz.z;
949+
clip_equation.xyzw.w = -vm_vec_dot(&clip_info.normal, &clip_info.position);
950+
951+
Current_shader->program->Uniforms.setUniform4f("clip_equation", clip_equation);
962952
} else {
963953
Current_shader->program->Uniforms.setUniformi("use_clip_plane", 0);
964954
}

0 commit comments

Comments
 (0)