From a733a29f4c5889251192184870cc451cacd9dc96 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 9 Jan 2017 22:13:26 +0000 Subject: [PATCH 1/7] Starting work on porting hw_clip.c/h code, Makefiles and CMake can compile them at least Other notes: * Renamed all new functions to have HWR_ prefix instead of gld_, for consistency * HWR_FrustrumSetup and HWR_SphereInFrustum are disabled and require HAVE_SPHEREFRUSTRUM. This is because 1) SRB2CB did not need the code, so presumably neither will we, and 2) there are some OpenGL API functions used there that due to our way of using OpenGL we don't use outside of r_opengl.c, which makes dealing with HWR_FrustrumSetup complicated in theory * The new clipping functions are not added to OpenGL's "main" rendering code itself just yet, they're just available to use now once hw_clip.h is included --- src/CMakeLists.txt | 2 + src/Makefile | 12 +- src/hardware/hw_clip.c | 465 +++++++++++++++++++++++++++++++++++++++++ src/hardware/hw_clip.h | 24 +++ 4 files changed, 497 insertions(+), 6 deletions(-) create mode 100644 src/hardware/hw_clip.c create mode 100644 src/hardware/hw_clip.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 46a42a92..0602de9d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -350,6 +350,7 @@ if(${SRB2_CONFIG_HWRENDER}) set(SRB2_HWRENDER_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_bsp.c ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_cache.c + ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_clip.c ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_draw.c ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_light.c ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_main.c @@ -358,6 +359,7 @@ if(${SRB2_CONFIG_HWRENDER}) ) set (SRB2_HWRENDER_HEADERS + ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_clip.h ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_data.h ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_defs.h ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_dll.h diff --git a/src/Makefile b/src/Makefile index 7a67c3f0..b159de3b 100644 --- a/src/Makefile +++ b/src/Makefile @@ -269,7 +269,7 @@ ifndef DC endif OPTS+=-DHWRENDER OBJS+=$(OBJDIR)/hw_bsp.o $(OBJDIR)/hw_draw.o $(OBJDIR)/hw_light.o \ - $(OBJDIR)/hw_main.o $(OBJDIR)/hw_md2.o $(OBJDIR)/hw_cache.o $(OBJDIR)/hw_trick.o + $(OBJDIR)/hw_main.o $(OBJDIR)/hw_clip.o $(OBJDIR)/hw_md2.o $(OBJDIR)/hw_cache.o $(OBJDIR)/hw_trick.o endif ifdef NOHS @@ -719,7 +719,7 @@ ifdef MINGW $(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \ doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \ command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \ - hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h am_map.h \ + hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h am_map.h \ d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ @@ -727,7 +727,7 @@ else $(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \ doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \ command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \ - hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h am_map.h \ + hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h am_map.h \ d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h $(CC) $(CFLAGS) $(WFLAGS) -I/usr/X11R6/include -c $< -o $@ @@ -880,7 +880,7 @@ ifndef NOHW $(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \ doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \ command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \ - hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h am_map.h \ + hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h am_map.h \ d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h $(CC) $(CFLAGS) $(WFLAGS) -D_WINDOWS -mwindows -c $< -o $@ @@ -888,7 +888,7 @@ $(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h $(OBJDIR)/ogl_win.o: hardware/r_opengl/ogl_win.c hardware/r_opengl/r_opengl.h \ doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \ command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \ - hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h am_map.h \ + hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h am_map.h \ d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h $(CC) $(CFLAGS) $(WFLAGS) -D_WINDOWS -mwindows -c $< -o $@ @@ -896,7 +896,7 @@ $(OBJDIR)/ogl_win.o: hardware/r_opengl/ogl_win.c hardware/r_opengl/r_opengl.h \ $(OBJDIR)/r_minigl.o: hardware/r_minigl/r_minigl.c hardware/r_opengl/r_opengl.h \ doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \ command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \ - hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h am_map.h \ + hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h am_map.h \ d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h $(CC) $(CFLAGS) $(WFLAGS) -D_WINDOWS -mwindows -c $< -o $@ diff --git a/src/hardware/hw_clip.c b/src/hardware/hw_clip.c new file mode 100644 index 00000000..47cbbfa2 --- /dev/null +++ b/src/hardware/hw_clip.c @@ -0,0 +1,465 @@ +/* Emacs style mode select -*- C++ -*- + *----------------------------------------------------------------------------- + * + * + * PrBoom: a Doom port merged with LxDoom and LSDLDoom + * based on BOOM, a modified and improved DOOM engine + * Copyright (C) 1999 by + * id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman + * Copyright (C) 1999-2000 by + * Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze + * Copyright 2005, 2006 by + * Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * DESCRIPTION: + * + *--------------------------------------------------------------------- + */ + +/* + * + ** gl_clipper.cpp + ** + ** Handles visibility checks. + ** Loosely based on the JDoom clipper. + ** + **--------------------------------------------------------------------------- + ** Copyright 2003 Tim Stump + ** All rights reserved. + ** + ** Redistribution and use in source and binary forms, with or without + ** modification, are permitted provided that the following conditions + ** are met: + ** + ** 1. Redistributions of source code must retain the above copyright + ** notice, this list of conditions and the following disclaimer. + ** 2. Redistributions in binary form must reproduce the above copyright + ** notice, this list of conditions and the following disclaimer in the + ** documentation and/or other materials provided with the distribution. + ** 3. The name of the author may not be used to endorse or promote products + ** derived from this software without specific prior written permission. + ** + ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + **--------------------------------------------------------------------------- + ** + */ + +#include +#include "../v_video.h" +#include "hw_clip.h" +#include "hw_glob.h" +#include "../r_state.h" +#include "../tables.h" +#include "r_opengl/r_opengl.h" + +#ifdef HAVE_SPHEREFRUSTRUM +static GLdouble viewMatrix[16]; +static GLdouble projMatrix[16]; +float frustum[6][4]; +#endif + +typedef struct clipnode_s + { + struct clipnode_s *prev, *next; + angle_t start, end; + } clipnode_t; + +clipnode_t *freelist; +clipnode_t *clipnodes; +clipnode_t *cliphead; + +static clipnode_t * HWR_clipnode_GetNew(void); +static clipnode_t * HWR_clipnode_NewRange(angle_t start, angle_t end); +static boolean HWR_clipper_IsRangeVisible(angle_t startAngle, angle_t endAngle); +static void HWR_clipper_AddClipRange(angle_t start, angle_t end); +static void HWR_clipper_RemoveRange(clipnode_t * range); +static void HWR_clipnode_Free(clipnode_t *node); + +static clipnode_t * HWR_clipnode_GetNew(void) +{ + if (freelist) + { + clipnode_t * p = freelist; + freelist = p->next; + return p; + } + else + { + return (clipnode_t*)malloc(sizeof(clipnode_t)); + } +} + +static clipnode_t * HWR_clipnode_NewRange(angle_t start, angle_t end) +{ + clipnode_t * c = HWR_clipnode_GetNew(); + c->start = start; + c->end = end; + c->next = c->prev=NULL; + return c; +} + +boolean HWR_clipper_SafeCheckRange(angle_t startAngle, angle_t endAngle) +{ + if(startAngle > endAngle) + { + return (HWR_clipper_IsRangeVisible(startAngle, ANGLE_MAX) || HWR_clipper_IsRangeVisible(0, endAngle)); + } + + return HWR_clipper_IsRangeVisible(startAngle, endAngle); +} + +static boolean HWR_clipper_IsRangeVisible(angle_t startAngle, angle_t endAngle) +{ + clipnode_t *ci; + ci = cliphead; + + if (endAngle == 0 && ci && ci->start == 0) + return false; + + while (ci != NULL && ci->start < endAngle) + { + if (startAngle >= ci->start && endAngle <= ci->end) + { + return false; + } + ci = ci->next; + } + + return true; +} + +static void HWR_clipnode_Free(clipnode_t *node) +{ + node->next = freelist; + freelist = node; +} + +static void HWR_clipper_RemoveRange(clipnode_t *range) +{ + if (range == cliphead) + { + cliphead = cliphead->next; + } + else + { + if (range->prev) + { + range->prev->next = range->next; + } + if (range->next) + { + range->next->prev = range->prev; + } + } + + HWR_clipnode_Free(range); +} + +void HWR_clipper_SafeAddClipRange(angle_t startangle, angle_t endangle) +{ + if(startangle > endangle) + { + // The range has to added in two parts. + HWR_clipper_AddClipRange(startangle, ANGLE_MAX); + HWR_clipper_AddClipRange(0, endangle); + } + else + { + // Add the range as usual. + HWR_clipper_AddClipRange(startangle, endangle); + } +} + +static void HWR_clipper_AddClipRange(angle_t start, angle_t end) +{ + clipnode_t *node, *temp, *prevNode, *node2, *delnode; + + if (cliphead) + { + //check to see if range contains any old ranges + node = cliphead; + while (node != NULL && node->start < end) + { + if (node->start >= start && node->end <= end) + { + temp = node; + node = node->next; + HWR_clipper_RemoveRange(temp); + } + else + { + if (node->start <= start && node->end >= end) + { + return; + } + else + { + node = node->next; + } + } + } + + //check to see if range overlaps a range (or possibly 2) + node = cliphead; + while (node != NULL && node->start <= end) + { + if (node->end >= start) + { + // we found the first overlapping node + if (node->start > start) + { + // the new range overlaps with this node's start point + node->start = start; + } + if (node->end < end) + { + node->end = end; + } + + node2 = node->next; + while (node2 && node2->start <= node->end) + { + if (node2->end > node->end) + { + node->end = node2->end; + } + + delnode = node2; + node2 = node2->next; + HWR_clipper_RemoveRange(delnode); + } + return; + } + node = node->next; + } + + //just add range + node = cliphead; + prevNode = NULL; + temp = HWR_clipnode_NewRange(start, end); + while (node != NULL && node->start < end) + { + prevNode = node; + node = node->next; + } + temp->next = node; + if (node == NULL) + { + temp->prev = prevNode; + if (prevNode) + { + prevNode->next = temp; + } + if (!cliphead) + { + cliphead = temp; + } + } + else + { + if (node == cliphead) + { + cliphead->prev = temp; + cliphead = temp; + } + else + { + temp->prev = prevNode; + prevNode->next = temp; + node->prev = temp; + } + } + } + else + { + temp = HWR_clipnode_NewRange(start, end); + cliphead = temp; + return; + } +} + +void HWR_clipper_Clear(void) +{ + clipnode_t *node = cliphead; + clipnode_t *temp; + + while (node != NULL) + { + temp = node; + node = node->next; + HWR_clipnode_Free(temp); + } + + cliphead = NULL; +} + +#define RMUL (1.6f/1.333333f) + +angle_t HWR_FrustumAngle(void) +{ + double floatangle; + angle_t a1; + + float tilt = (float)fabs(((double)(int)aimingangle) / ANG1); + + // NEWCLIP TODO: SRB2CBTODO: make a global render_fov for this function + + float render_fov = FIXED_TO_FLOAT(cv_grfov.value); + float render_fovratio = (float)BASEVIDWIDTH / (float)BASEVIDHEIGHT; // SRB2CBTODO: NEWCLIPTODO: Is this right? + float render_multiplier = 64.0f / render_fovratio / RMUL; + + if (tilt > 90.0f) + { + tilt = 90.0f; + } + + // If the pitch is larger than this you can look all around at a FOV of 90 + if (abs(aimingangle) > 46 * ANG1) + return 0xffffffff; + + // ok, this is a gross hack that barely works... + // but at least it doesn't overestimate too much... + floatangle = 2.0f + (45.0f + (tilt / 1.9f)) * (float)render_fov * 48.0f / render_multiplier / 90.0f; + a1 = ANG1 * (int)floatangle; + if (a1 >= ANGLE_180) + return 0xffffffff; + return a1; +} + +// SRB2CB I don't think used any of this stuff, let's disable for now since SRB2 probably doesn't want it either +// compiler complains about (p)glGetDoublev anyway, in case anyone wants this +// only r_opengl.c can use the base gl funcs as it turns out, that's a problem for whoever wants sphere frustum checks +// btw to renable define HAVE_SPHEREFRUSTRUM in hw_clip.h +#ifdef HAVE_SPHEREFRUSTRUM +// +// HWR_FrustrumSetup +// + +#define CALCMATRIX(a, b, c, d, e, f, g, h)\ +(float)(viewMatrix[a] * projMatrix[b] + \ +viewMatrix[c] * projMatrix[d] + \ +viewMatrix[e] * projMatrix[f] + \ +viewMatrix[g] * projMatrix[h]) + +#define NORMALIZE_PLANE(i)\ +t = (float)sqrt(\ +frustum[i][0] * frustum[i][0] + \ +frustum[i][1] * frustum[i][1] + \ +frustum[i][2] * frustum[i][2]); \ +frustum[i][0] /= t; \ +frustum[i][1] /= t; \ +frustum[i][2] /= t; \ +frustum[i][3] /= t + +void HWR_FrustrumSetup(void) +{ + float t; + float clip[16]; + + pglGetDoublev(GL_PROJECTION_MATRIX, projMatrix); + pglGetDoublev(GL_MODELVIEW_MATRIX, viewMatrix); + + clip[0] = CALCMATRIX(0, 0, 1, 4, 2, 8, 3, 12); + clip[1] = CALCMATRIX(0, 1, 1, 5, 2, 9, 3, 13); + clip[2] = CALCMATRIX(0, 2, 1, 6, 2, 10, 3, 14); + clip[3] = CALCMATRIX(0, 3, 1, 7, 2, 11, 3, 15); + + clip[4] = CALCMATRIX(4, 0, 5, 4, 6, 8, 7, 12); + clip[5] = CALCMATRIX(4, 1, 5, 5, 6, 9, 7, 13); + clip[6] = CALCMATRIX(4, 2, 5, 6, 6, 10, 7, 14); + clip[7] = CALCMATRIX(4, 3, 5, 7, 6, 11, 7, 15); + + clip[8] = CALCMATRIX(8, 0, 9, 4, 10, 8, 11, 12); + clip[9] = CALCMATRIX(8, 1, 9, 5, 10, 9, 11, 13); + clip[10] = CALCMATRIX(8, 2, 9, 6, 10, 10, 11, 14); + clip[11] = CALCMATRIX(8, 3, 9, 7, 10, 11, 11, 15); + + clip[12] = CALCMATRIX(12, 0, 13, 4, 14, 8, 15, 12); + clip[13] = CALCMATRIX(12, 1, 13, 5, 14, 9, 15, 13); + clip[14] = CALCMATRIX(12, 2, 13, 6, 14, 10, 15, 14); + clip[15] = CALCMATRIX(12, 3, 13, 7, 14, 11, 15, 15); + + // Right plane + frustum[0][0] = clip[ 3] - clip[ 0]; + frustum[0][1] = clip[ 7] - clip[ 4]; + frustum[0][2] = clip[11] - clip[ 8]; + frustum[0][3] = clip[15] - clip[12]; + NORMALIZE_PLANE(0); + + // Left plane + frustum[1][0] = clip[ 3] + clip[ 0]; + frustum[1][1] = clip[ 7] + clip[ 4]; + frustum[1][2] = clip[11] + clip[ 8]; + frustum[1][3] = clip[15] + clip[12]; + NORMALIZE_PLANE(1); + + // Bottom plane + frustum[2][0] = clip[ 3] + clip[ 1]; + frustum[2][1] = clip[ 7] + clip[ 5]; + frustum[2][2] = clip[11] + clip[ 9]; + frustum[2][3] = clip[15] + clip[13]; + NORMALIZE_PLANE(2); + + // Top plane + frustum[3][0] = clip[ 3] - clip[ 1]; + frustum[3][1] = clip[ 7] - clip[ 5]; + frustum[3][2] = clip[11] - clip[ 9]; + frustum[3][3] = clip[15] - clip[13]; + NORMALIZE_PLANE(3); + + // Far plane + frustum[4][0] = clip[ 3] - clip[ 2]; + frustum[4][1] = clip[ 7] - clip[ 6]; + frustum[4][2] = clip[11] - clip[10]; + frustum[4][3] = clip[15] - clip[14]; + NORMALIZE_PLANE(4); + + // Near plane + frustum[5][0] = clip[ 3] + clip[ 2]; + frustum[5][1] = clip[ 7] + clip[ 6]; + frustum[5][2] = clip[11] + clip[10]; + frustum[5][3] = clip[15] + clip[14]; + NORMALIZE_PLANE(5); +} + +boolean HWR_SphereInFrustum(float x, float y, float z, float radius) +{ + int p; + + for (p = 0; p < 4; p++) + { + if (frustum[p][0] * x + + frustum[p][1] * y + + frustum[p][2] * z + + frustum[p][3] <= -radius) + { + return false; + } + } + return true; +} +#endif diff --git a/src/hardware/hw_clip.h b/src/hardware/hw_clip.h new file mode 100644 index 00000000..c55041b7 --- /dev/null +++ b/src/hardware/hw_clip.h @@ -0,0 +1,24 @@ +/* + * hw_clip.h + * SRB2CB + * + * PrBoom's OpenGL clipping + * + * + */ + +// OpenGL BSP clipping +#include "../doomdef.h" +#include "../tables.h" +#include "../doomtype.h" + +//#define HAVE_SPHEREFRUSTRUM // enable if you want HWR_SphereInFrustum and related code + +boolean HWR_clipper_SafeCheckRange(angle_t startAngle, angle_t endAngle); +void HWR_clipper_SafeAddClipRange(angle_t startangle, angle_t endangle); +void HWR_clipper_Clear(void); +angle_t HWR_FrustumAngle(void); +#ifdef HAVE_SPHEREFRUSTRUM +void HWR_FrustrumSetup(void); +boolean HWR_SphereInFrustum(float x, float y, float z, float radius); +#endif From 1e98e3b4f20ae9517a66e79f2a464cbcda9e28b7 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 10 Jan 2017 18:01:03 +0000 Subject: [PATCH 2/7] More progress, NEWCLIP added to doomdef.h, sadly it actually all lags the game so I've disabled it for now Other notes: * on second thought I'll keep the hw_clip functions' gld prefixes rather than HWR, not like it matters either way * despite the extra lag it does fix the issues with translucent walls and such when displayed at different vertical angles, such as with the GFZ1 waterfall --- src/doomdef.h | 7 ++ src/hardware/hw_clip.c | 62 +++++------ src/hardware/hw_clip.h | 14 +-- src/hardware/hw_main.c | 240 ++++++++++++++++++++++++++++++++++++++++- 4 files changed, 280 insertions(+), 43 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index 7f641558..e5fa3a48 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -502,4 +502,11 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// \note Required for proper collision with moving sloped surfaces that have sector specials on them. //#define SECTORSPECIALSAFTERTHINK +/// FINALLY some real clipping that doesn't make walls dissappear AND speeds the game up +/// (that was the original comment from SRB2CB, sadly it is a lie and actually slows game down) +/// on the bright side it fixes some weird issues with translucent walls +/// \note SRB2CB port. +/// SRB2CB itself ported this from PrBoom+ +//#define NEWCLIP + #endif // __DOOMDEF__ diff --git a/src/hardware/hw_clip.c b/src/hardware/hw_clip.c index 47cbbfa2..8b01cabd 100644 --- a/src/hardware/hw_clip.c +++ b/src/hardware/hw_clip.c @@ -92,14 +92,14 @@ clipnode_t *freelist; clipnode_t *clipnodes; clipnode_t *cliphead; -static clipnode_t * HWR_clipnode_GetNew(void); -static clipnode_t * HWR_clipnode_NewRange(angle_t start, angle_t end); -static boolean HWR_clipper_IsRangeVisible(angle_t startAngle, angle_t endAngle); -static void HWR_clipper_AddClipRange(angle_t start, angle_t end); -static void HWR_clipper_RemoveRange(clipnode_t * range); -static void HWR_clipnode_Free(clipnode_t *node); +static clipnode_t * gld_clipnode_GetNew(void); +static clipnode_t * gld_clipnode_NewRange(angle_t start, angle_t end); +static boolean gld_clipper_IsRangeVisible(angle_t startAngle, angle_t endAngle); +static void gld_clipper_AddClipRange(angle_t start, angle_t end); +static void gld_clipper_RemoveRange(clipnode_t * range); +static void gld_clipnode_Free(clipnode_t *node); -static clipnode_t * HWR_clipnode_GetNew(void) +static clipnode_t * gld_clipnode_GetNew(void) { if (freelist) { @@ -113,26 +113,26 @@ static clipnode_t * HWR_clipnode_GetNew(void) } } -static clipnode_t * HWR_clipnode_NewRange(angle_t start, angle_t end) +static clipnode_t * gld_clipnode_NewRange(angle_t start, angle_t end) { - clipnode_t * c = HWR_clipnode_GetNew(); + clipnode_t * c = gld_clipnode_GetNew(); c->start = start; c->end = end; c->next = c->prev=NULL; return c; } -boolean HWR_clipper_SafeCheckRange(angle_t startAngle, angle_t endAngle) +boolean gld_clipper_SafeCheckRange(angle_t startAngle, angle_t endAngle) { if(startAngle > endAngle) { - return (HWR_clipper_IsRangeVisible(startAngle, ANGLE_MAX) || HWR_clipper_IsRangeVisible(0, endAngle)); + return (gld_clipper_IsRangeVisible(startAngle, ANGLE_MAX) || gld_clipper_IsRangeVisible(0, endAngle)); } - return HWR_clipper_IsRangeVisible(startAngle, endAngle); + return gld_clipper_IsRangeVisible(startAngle, endAngle); } -static boolean HWR_clipper_IsRangeVisible(angle_t startAngle, angle_t endAngle) +static boolean gld_clipper_IsRangeVisible(angle_t startAngle, angle_t endAngle) { clipnode_t *ci; ci = cliphead; @@ -152,13 +152,13 @@ static boolean HWR_clipper_IsRangeVisible(angle_t startAngle, angle_t endAngle) return true; } -static void HWR_clipnode_Free(clipnode_t *node) +static void gld_clipnode_Free(clipnode_t *node) { node->next = freelist; freelist = node; } -static void HWR_clipper_RemoveRange(clipnode_t *range) +static void gld_clipper_RemoveRange(clipnode_t *range) { if (range == cliphead) { @@ -176,25 +176,25 @@ static void HWR_clipper_RemoveRange(clipnode_t *range) } } - HWR_clipnode_Free(range); + gld_clipnode_Free(range); } -void HWR_clipper_SafeAddClipRange(angle_t startangle, angle_t endangle) +void gld_clipper_SafeAddClipRange(angle_t startangle, angle_t endangle) { if(startangle > endangle) { // The range has to added in two parts. - HWR_clipper_AddClipRange(startangle, ANGLE_MAX); - HWR_clipper_AddClipRange(0, endangle); + gld_clipper_AddClipRange(startangle, ANGLE_MAX); + gld_clipper_AddClipRange(0, endangle); } else { // Add the range as usual. - HWR_clipper_AddClipRange(startangle, endangle); + gld_clipper_AddClipRange(startangle, endangle); } } -static void HWR_clipper_AddClipRange(angle_t start, angle_t end) +static void gld_clipper_AddClipRange(angle_t start, angle_t end) { clipnode_t *node, *temp, *prevNode, *node2, *delnode; @@ -208,7 +208,7 @@ static void HWR_clipper_AddClipRange(angle_t start, angle_t end) { temp = node; node = node->next; - HWR_clipper_RemoveRange(temp); + gld_clipper_RemoveRange(temp); } else { @@ -250,7 +250,7 @@ static void HWR_clipper_AddClipRange(angle_t start, angle_t end) delnode = node2; node2 = node2->next; - HWR_clipper_RemoveRange(delnode); + gld_clipper_RemoveRange(delnode); } return; } @@ -260,7 +260,7 @@ static void HWR_clipper_AddClipRange(angle_t start, angle_t end) //just add range node = cliphead; prevNode = NULL; - temp = HWR_clipnode_NewRange(start, end); + temp = gld_clipnode_NewRange(start, end); while (node != NULL && node->start < end) { prevNode = node; @@ -296,13 +296,13 @@ static void HWR_clipper_AddClipRange(angle_t start, angle_t end) } else { - temp = HWR_clipnode_NewRange(start, end); + temp = gld_clipnode_NewRange(start, end); cliphead = temp; return; } } -void HWR_clipper_Clear(void) +void gld_clipper_Clear(void) { clipnode_t *node = cliphead; clipnode_t *temp; @@ -311,7 +311,7 @@ void HWR_clipper_Clear(void) { temp = node; node = node->next; - HWR_clipnode_Free(temp); + gld_clipnode_Free(temp); } cliphead = NULL; @@ -319,7 +319,7 @@ void HWR_clipper_Clear(void) #define RMUL (1.6f/1.333333f) -angle_t HWR_FrustumAngle(void) +angle_t gld_FrustumAngle(void) { double floatangle; angle_t a1; @@ -356,7 +356,7 @@ angle_t HWR_FrustumAngle(void) // btw to renable define HAVE_SPHEREFRUSTRUM in hw_clip.h #ifdef HAVE_SPHEREFRUSTRUM // -// HWR_FrustrumSetup +// gld_FrustrumSetup // #define CALCMATRIX(a, b, c, d, e, f, g, h)\ @@ -375,7 +375,7 @@ frustum[i][1] /= t; \ frustum[i][2] /= t; \ frustum[i][3] /= t -void HWR_FrustrumSetup(void) +void gld_FrustrumSetup(void) { float t; float clip[16]; @@ -446,7 +446,7 @@ void HWR_FrustrumSetup(void) NORMALIZE_PLANE(5); } -boolean HWR_SphereInFrustum(float x, float y, float z, float radius) +boolean gld_SphereInFrustum(float x, float y, float z, float radius) { int p; diff --git a/src/hardware/hw_clip.h b/src/hardware/hw_clip.h index c55041b7..3ba26e5e 100644 --- a/src/hardware/hw_clip.h +++ b/src/hardware/hw_clip.h @@ -12,13 +12,13 @@ #include "../tables.h" #include "../doomtype.h" -//#define HAVE_SPHEREFRUSTRUM // enable if you want HWR_SphereInFrustum and related code +//#define HAVE_SPHEREFRUSTRUM // enable if you want gld_SphereInFrustum and related code -boolean HWR_clipper_SafeCheckRange(angle_t startAngle, angle_t endAngle); -void HWR_clipper_SafeAddClipRange(angle_t startangle, angle_t endangle); -void HWR_clipper_Clear(void); -angle_t HWR_FrustumAngle(void); +boolean gld_clipper_SafeCheckRange(angle_t startAngle, angle_t endAngle); +void gld_clipper_SafeAddClipRange(angle_t startangle, angle_t endangle); +void gld_clipper_Clear(void); +angle_t gld_FrustumAngle(void); #ifdef HAVE_SPHEREFRUSTRUM -void HWR_FrustrumSetup(void); -boolean HWR_SphereInFrustum(float x, float y, float z, float radius); +void gld_FrustrumSetup(void); +boolean gld_SphereInFrustum(float x, float y, float z, float radius); #endif diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 7e815258..c10f4bf1 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -44,6 +44,10 @@ #endif #include "hw_md2.h" +#ifdef NEWCLIP +#include "hw_clip.h" +#endif + #define R_FAKEFLOORS #define HWPRECIP #define SORTING @@ -99,8 +103,9 @@ CV_PossibleValue_t granisotropicmode_cons_t[] = {{1, "MIN"}, {16, "MAX"}, {0, NU boolean drawsky = true; // needs fix: walls are incorrectly clipped one column less +#ifndef NEWCLIP static consvar_t cv_grclipwalls = {"gr_clipwalls", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; - +#endif //development variables for diverse uses static consvar_t cv_gralpha = {"gr_alpha", "160", 0, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL}; static consvar_t cv_grbeta = {"gr_beta", "0", 0, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -1030,6 +1035,7 @@ static void HWR_ProjectWall(wallVert3D * wallVerts, // (in fact a clipping plane that has a constant, so can clip with simple 2d) // with the wall segment // +#ifndef NEWCLIP static float HWR_ClipViewSegment(INT32 x, polyvertex_t *v1, polyvertex_t *v2) { float num, den; @@ -1058,6 +1064,7 @@ static float HWR_ClipViewSegment(INT32 x, polyvertex_t *v1, polyvertex_t *v2) return num / den; } +#endif // // HWR_SplitWall @@ -1333,7 +1340,11 @@ static void HWR_DrawSkyWall(wallVert3D *wallVerts, FSurfaceInfo *Surf, fixed_t b // Anything between means the wall segment has been clipped with solidsegs, // reducing wall overdraw to a minimum // +#ifdef NEWCLIP +static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom +#else static void HWR_StoreWallRange(double startfrac, double endfrac) +#endif { wallVert3D wallVerts[4]; v2d_t vs, ve; // start, end vertices of 2d line (view from above) @@ -1358,8 +1369,10 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) extracolormap_t *colormap; FSurfaceInfo Surf; +#ifndef NEWCLIP if (startfrac > endfrac) return; +#endif gr_sidedef = gr_curline->sidedef; gr_linedef = gr_curline->linedef; @@ -1408,15 +1421,19 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) // x offset the texture fixed_t texturehpeg = gr_sidedef->textureoffset + gr_curline->offset; +#ifndef NEWCLIP // clip texture s start/end coords with solidsegs if (startfrac > 0.0f && startfrac < 1.0f) cliplow = (float)(texturehpeg + (gr_curline->flength*FRACUNIT) * startfrac); else +#endif cliplow = (float)texturehpeg; +#ifndef NEWCLIP if (endfrac > 0.0f && endfrac < 1.0f) cliphigh = (float)(texturehpeg + (gr_curline->flength*FRACUNIT) * endfrac); else +#endif cliphigh = (float)(texturehpeg + (gr_curline->flength*FRACUNIT)); } @@ -2325,6 +2342,135 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) //Hurdler: end of 3d-floors test } +// From PrBoom: +// +// e6y: Check whether the player can look beyond this line +// +#ifdef NEWCLIP +// Don't modify anything here, just check +// Kalaron: Modified for sloped linedefs +static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacksector) +{ + fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends + fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends + + // GZDoom method of sloped line clipping + +#ifdef ESLOPE + if (afrontsector->f_slope || afrontsector->c_slope || abacksector->f_slope || abacksector->c_slope) + { + fixed_t v1x, v1y, v2x, v2y; // the seg's vertexes as fixed_t + v1x = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv1)->x); + v1y = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv1)->y); + v2x = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->x); + v2y = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->y); +#define SLOPEPARAMS(slope, end1, end2, normalheight) \ + if (slope) { \ + end1 = P_GetZAt(slope, v1x, v1y); \ + end2 = P_GetZAt(slope, v2x, v2y); \ + } else \ + end1 = end2 = normalheight; + + SLOPEPARAMS(afrontsector->f_slope, frontf1, frontf2, afrontsector->floorheight) + SLOPEPARAMS(afrontsector->c_slope, frontc1, frontc2, afrontsector->ceilingheight) + SLOPEPARAMS( abacksector->f_slope, backf1, backf2, abacksector->floorheight) + SLOPEPARAMS( abacksector->c_slope, backc1, backc2, abacksector->ceilingheight) +#undef SLOPEPARAMS + } + else +#endif + { + frontf1 = frontf2 = afrontsector->floorheight; + frontc1 = frontc2 = afrontsector->ceilingheight; + backf1 = backf2 = abacksector->floorheight; + backc1 = backc2 = abacksector->ceilingheight; + } + + // now check for closed sectors! + if (backc1 <= frontf1 && backc2 <= frontf2) + { + if (!seg->sidedef->toptexture) + return false; + + if (abacksector->ceilingpic == skyflatnum && afrontsector->ceilingpic == skyflatnum) + return false; + + return true; + } + + if (backf1 >= frontc1 && backf2 >= frontc2) + { + if (!seg->sidedef->bottomtexture) + return false; + + // properly render skies (consider door "open" if both floors are sky): + if (abacksector->ceilingpic == skyflatnum && afrontsector->ceilingpic == skyflatnum) + return false; + + return true; + } + + if (backc1 <= backf1 && backc2 <= backf2) + { + // preserve a kind of transparent door/lift special effect: + if (backc1 < frontc1 || backc2 < frontc2) + { + if (!seg->sidedef->toptexture) + return false; + } + if (backf1 > frontf1 || backf2 > frontf2) + { + if (!seg->sidedef->bottomtexture) + return false; + } + if (abacksector->ceilingpic == skyflatnum && afrontsector->ceilingpic == skyflatnum) + return false; + + if (abacksector->floorpic == skyflatnum && afrontsector->floorpic == skyflatnum) + return false; + + return true; + } + + + // Reject empty lines used for triggers and special events. + // Identical floor and ceiling on both sides, + // identical light levels on both sides, + // and no middle texture. + if ( +#ifdef POLYOBJECTS + !seg->polyseg && +#endif + gr_backsector->ceilingpic == gr_frontsector->ceilingpic + && gr_backsector->floorpic == gr_frontsector->floorpic +#ifdef ESLOPE + && gr_backsector->f_slope == gr_frontsector->f_slope + && gr_backsector->c_slope == gr_frontsector->c_slope +#endif + && gr_backsector->lightlevel == gr_frontsector->lightlevel + && !gr_curline->sidedef->midtexture + // Check offsets too! + && gr_backsector->floor_xoffs == gr_frontsector->floor_xoffs + && gr_backsector->floor_yoffs == gr_frontsector->floor_yoffs + && gr_backsector->floorpic_angle == gr_frontsector->floorpic_angle + && gr_backsector->ceiling_xoffs == gr_frontsector->ceiling_xoffs + && gr_backsector->ceiling_yoffs == gr_frontsector->ceiling_yoffs + && gr_backsector->ceilingpic_angle == gr_frontsector->ceilingpic_angle + // Consider altered lighting. + && gr_backsector->floorlightsec == gr_frontsector->floorlightsec + && gr_backsector->ceilinglightsec == gr_frontsector->ceilinglightsec + // Consider colormaps + && gr_backsector->extra_colormap == gr_frontsector->extra_colormap + && ((!gr_frontsector->ffloors && !gr_backsector->ffloors) + || gr_frontsector->tag == gr_backsector->tag)) + { + return false; + } + + + return false; +} +#else //Hurdler: just like in r_bsp.c #if 1 #define MAXSEGS MAXVIDWIDTH/2+1 @@ -2610,6 +2756,7 @@ static void HWR_ClearClipSegs(void) gr_solidsegs[1].last = 0x7fffffff; hw_newend = gr_solidsegs+2; } +#endif // NEWCLIP // -----------------+ // HWR_AddLine : Clips the given segment and adds any visible pieces to the line list. @@ -2618,17 +2765,20 @@ static void HWR_ClearClipSegs(void) // -----------------+ static void HWR_AddLine(seg_t * line) { - INT32 x1, x2; angle_t angle1, angle2; +#ifndef NEWCLIP + INT32 x1, x2; angle_t span, tspan; +#endif // SoM: Backsector needs to be run through R_FakeFlat static sector_t tempsec; fixed_t v1x, v1y, v2x, v2y; // the seg's vertexes as fixed_t - +#ifdef POLYOBJECTS if (line->polyseg && !(line->polyseg->flags & POF_RENDERSIDES)) return; +#endif gr_curline = line; @@ -2641,6 +2791,18 @@ static void HWR_AddLine(seg_t * line) angle1 = R_PointToAngle(v1x, v1y); angle2 = R_PointToAngle(v2x, v2y); +#ifdef NEWCLIP + // PrBoom: Back side, i.e. backface culling - read: endAngle >= startAngle! + if (angle2 - angle1 < ANGLE_180) + return; + + // PrBoom: use REAL clipping math YAYYYYYYY!!! + + if (!gld_clipper_SafeCheckRange(angle2, angle1)) + { + return; + } +#else // Clip to view edges. span = angle1 - angle2; @@ -2719,8 +2881,35 @@ static void HWR_AddLine(seg_t * line) return; } */ +#endif + gr_backsector = line->backsector; +#ifdef NEWCLIP + if (!line->backsector) + { + gld_clipper_SafeAddClipRange(angle2, angle1); + } + else + { + gr_backsector = R_FakeFlat(gr_backsector, &tempsec, NULL, NULL, true); + if (line->frontsector == line->backsector) + { + if (!line->sidedef->midtexture) + { + //e6y: nothing to do here! + //return; + } + } + if (CheckClip(line, gr_frontsector, gr_backsector)) + { + gld_clipper_SafeAddClipRange(angle2, angle1); + } + } + + HWR_ProcessSeg(); // Doesn't need arguments because they're defined globally :D + return; +#else // Single sided line? if (!gr_backsector) goto clipsolid; @@ -2835,6 +3024,7 @@ clipsolid: if (x1 == x2) goto clippass; HWR_ClipSolidWallSegment(x1, x2-1); +#endif } // HWR_CheckBBox @@ -2846,9 +3036,13 @@ clipsolid: static boolean HWR_CheckBBox(fixed_t *bspcoord) { - INT32 boxpos, sx1, sx2; + INT32 boxpos; fixed_t px1, py1, px2, py2; - angle_t angle1, angle2, span, tspan; + angle_t angle1, angle2; +#ifndef NEWCLIP + INT32 sx1, sx2; + angle_t span, tspan; +#endif // Find the corners of the box // that define the edges from current viewpoint. @@ -2874,6 +3068,11 @@ static boolean HWR_CheckBBox(fixed_t *bspcoord) px2 = bspcoord[checkcoord[boxpos][2]]; py2 = bspcoord[checkcoord[boxpos][3]]; +#ifdef NEWCLIP + angle1 = R_PointToAngle(px1, py1); + angle2 = R_PointToAngle(px2, py2); + return gld_clipper_SafeCheckRange(angle2, angle1); +#else // check clip list for an open space angle1 = R_PointToAngle2(dup_viewx>>1, dup_viewy>>1, px1>>1, py1>>1) - dup_viewangle; angle2 = R_PointToAngle2(dup_viewx>>1, dup_viewy>>1, px2>>1, py2>>1) - dup_viewangle; @@ -2921,6 +3120,7 @@ static boolean HWR_CheckBBox(fixed_t *bspcoord) return false; return HWR_ClipToSolidSegs(sx1, sx2 - 1); +#endif } #ifdef POLYOBJECTS @@ -5694,7 +5894,19 @@ if (0) #ifdef SORTING drawcount = 0; #endif +#ifdef NEWCLIP + if (rendermode == render_opengl) + { + angle_t a1 = gld_FrustumAngle(); + gld_clipper_Clear(); + gld_clipper_SafeAddClipRange(viewangle + a1, viewangle - a1); +#ifdef HAVE_SPHEREFRUSTRUM + gld_FrustrumSetup(); +#endif + } +#else HWR_ClearClipSegs(); +#endif //04/01/2000: Hurdler: added for T&L // Actually it only works on Walls and Planes @@ -5704,6 +5916,7 @@ if (0) HWR_RenderBSPNode((INT32)numnodes-1); +#ifndef NEWCLIP // Make a viewangle int so we can render things based on mouselook if (player == &players[consoleplayer]) viewangle = localaiming; @@ -5730,6 +5943,7 @@ if (0) dup_viewangle += ANGLE_90; } +#endif // Check for new console commands. NetUpdate(); @@ -5901,7 +6115,19 @@ if (0) #ifdef SORTING drawcount = 0; #endif +#ifdef NEWCLIP + if (rendermode == render_opengl) + { + angle_t a1 = gld_FrustumAngle(); + gld_clipper_Clear(); + gld_clipper_SafeAddClipRange(viewangle + a1, viewangle - a1); +#ifdef HAVE_SPHEREFRUSTRUM + gld_FrustrumSetup(); +#endif + } +#else HWR_ClearClipSegs(); +#endif //04/01/2000: Hurdler: added for T&L // Actually it only works on Walls and Planes @@ -5911,6 +6137,7 @@ if (0) HWR_RenderBSPNode((INT32)numnodes-1); +#ifndef NEWCLIP // Make a viewangle int so we can render things based on mouselook if (player == &players[consoleplayer]) viewangle = localaiming; @@ -5937,6 +6164,7 @@ if (0) dup_viewangle += ANGLE_90; } +#endif // Check for new console commands. NetUpdate(); @@ -6079,7 +6307,9 @@ static inline void HWR_AddEngineCommands(void) { // engine state variables //CV_RegisterVar(&cv_grzbuffer); +#ifndef NEWCLIP CV_RegisterVar(&cv_grclipwalls); +#endif // engine development mode variables // - usage may vary from version to version.. From c4569e61a8feab59eb5635daf536e9605048a176 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 10 Jan 2017 20:07:02 +0000 Subject: [PATCH 3/7] Made some efforts to improve efficiency of new code, hard to tell if I've made it better or worse though honestly R_IsEmptyLine is now a thing too btw --- src/hardware/hw_main.c | 94 +++++++++--------------------------------- src/r_bsp.c | 60 ++++++++++++++------------- src/r_bsp.h | 1 + 3 files changed, 52 insertions(+), 103 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index c10f4bf1..c148e7c4 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -2347,6 +2347,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) // e6y: Check whether the player can look beyond this line // #ifdef NEWCLIP +boolean checkforemptylines = true; // Don't modify anything here, just check // Kalaron: Modified for sloped linedefs static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacksector) @@ -2389,6 +2390,7 @@ static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacks // now check for closed sectors! if (backc1 <= frontf1 && backc2 <= frontf2) { + checkforemptylines = false; if (!seg->sidedef->toptexture) return false; @@ -2400,6 +2402,7 @@ static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacks if (backf1 >= frontc1 && backf2 >= frontc2) { + checkforemptylines = false; if (!seg->sidedef->bottomtexture) return false; @@ -2412,6 +2415,7 @@ static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacks if (backc1 <= backf1 && backc2 <= backf2) { + checkforemptylines = false; // preserve a kind of transparent door/lift special effect: if (backc1 < frontc1 || backc2 < frontc2) { @@ -2432,41 +2436,12 @@ static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacks return true; } - - // Reject empty lines used for triggers and special events. - // Identical floor and ceiling on both sides, - // identical light levels on both sides, - // and no middle texture. - if ( -#ifdef POLYOBJECTS - !seg->polyseg && -#endif - gr_backsector->ceilingpic == gr_frontsector->ceilingpic - && gr_backsector->floorpic == gr_frontsector->floorpic -#ifdef ESLOPE - && gr_backsector->f_slope == gr_frontsector->f_slope - && gr_backsector->c_slope == gr_frontsector->c_slope -#endif - && gr_backsector->lightlevel == gr_frontsector->lightlevel - && !gr_curline->sidedef->midtexture - // Check offsets too! - && gr_backsector->floor_xoffs == gr_frontsector->floor_xoffs - && gr_backsector->floor_yoffs == gr_frontsector->floor_yoffs - && gr_backsector->floorpic_angle == gr_frontsector->floorpic_angle - && gr_backsector->ceiling_xoffs == gr_frontsector->ceiling_xoffs - && gr_backsector->ceiling_yoffs == gr_frontsector->ceiling_yoffs - && gr_backsector->ceilingpic_angle == gr_frontsector->ceilingpic_angle - // Consider altered lighting. - && gr_backsector->floorlightsec == gr_frontsector->floorlightsec - && gr_backsector->ceilinglightsec == gr_frontsector->ceilinglightsec - // Consider colormaps - && gr_backsector->extra_colormap == gr_frontsector->extra_colormap - && ((!gr_frontsector->ffloors && !gr_backsector->ffloors) - || gr_frontsector->tag == gr_backsector->tag)) - { - return false; - } - + if (backc1 != frontc1 || backc2 != frontc2 + || backf1 != frontf1 || backf2 != frontf2) + { + checkforemptylines = false; + return false; + } return false; } @@ -2802,6 +2777,8 @@ static void HWR_AddLine(seg_t * line) { return; } + + checkforemptylines = true; #else // Clip to view edges. span = angle1 - angle2; @@ -2893,18 +2870,17 @@ static void HWR_AddLine(seg_t * line) else { gr_backsector = R_FakeFlat(gr_backsector, &tempsec, NULL, NULL, true); - if (line->frontsector == line->backsector) - { - if (!line->sidedef->midtexture) - { - //e6y: nothing to do here! - //return; - } - } if (CheckClip(line, gr_frontsector, gr_backsector)) { gld_clipper_SafeAddClipRange(angle2, angle1); + checkforemptylines = false; } + // Reject empty lines used for triggers and special events. + // Identical floor and ceiling on both sides, + // identical light levels on both sides, + // and no middle texture. + if (checkforemptylines && R_IsEmptyLine(line, gr_frontsector, gr_backsector)) + return; } HWR_ProcessSeg(); // Doesn't need arguments because they're defined globally :D @@ -2981,38 +2957,8 @@ static void HWR_AddLine(seg_t * line) // Identical floor and ceiling on both sides, // identical light levels on both sides, // and no middle texture. - if ( -#ifdef POLYOBJECTS - !line->polyseg && -#endif - gr_backsector->ceilingpic == gr_frontsector->ceilingpic - && gr_backsector->floorpic == gr_frontsector->floorpic -#ifdef ESLOPE - && gr_backsector->f_slope == gr_frontsector->f_slope - && gr_backsector->c_slope == gr_frontsector->c_slope -#endif - && gr_backsector->lightlevel == gr_frontsector->lightlevel - && !gr_curline->sidedef->midtexture - // Check offsets too! - && gr_backsector->floor_xoffs == gr_frontsector->floor_xoffs - && gr_backsector->floor_yoffs == gr_frontsector->floor_yoffs - && gr_backsector->floorpic_angle == gr_frontsector->floorpic_angle - && gr_backsector->ceiling_xoffs == gr_frontsector->ceiling_xoffs - && gr_backsector->ceiling_yoffs == gr_frontsector->ceiling_yoffs - && gr_backsector->ceilingpic_angle == gr_frontsector->ceilingpic_angle - // Consider altered lighting. - && gr_backsector->floorlightsec == gr_frontsector->floorlightsec - && gr_backsector->ceilinglightsec == gr_frontsector->ceilinglightsec - // Consider colormaps - && gr_backsector->extra_colormap == gr_frontsector->extra_colormap - && ((!gr_frontsector->ffloors && !gr_backsector->ffloors) - || gr_frontsector->tag == gr_backsector->tag)) - // SoM: For 3D sides... Boris, would you like to take a - // crack at rendering 3D sides? You would need to add the - // above check and add code to HWR_StoreWallRange... - { + if (R_IsEmptyLine(curline, frontsector, backsector)) return; - } clippass: if (x1 == x2) diff --git a/src/r_bsp.c b/src/r_bsp.c index abb11204..4ce89f00 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -365,6 +365,36 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel, return sec; } +boolean R_IsEmptyLine(seg_t *line, sector_t *front, sector_t *back) +{ + return ( +#ifdef POLYOBJECTS + !line->polyseg && +#endif + back->ceilingpic == front->ceilingpic + && back->floorpic == front->floorpic +#ifdef ESLOPE + && back->f_slope == front->f_slope + && back->c_slope == front->c_slope +#endif + && back->lightlevel == front->lightlevel + && !line->sidedef->midtexture + // Check offsets too! + && back->floor_xoffs == front->floor_xoffs + && back->floor_yoffs == front->floor_yoffs + && back->floorpic_angle == front->floorpic_angle + && back->ceiling_xoffs == front->ceiling_xoffs + && back->ceiling_yoffs == front->ceiling_yoffs + && back->ceilingpic_angle == front->ceilingpic_angle + // Consider altered lighting. + && back->floorlightsec == front->floorlightsec + && back->ceilinglightsec == front->ceilinglightsec + // Consider colormaps + && back->extra_colormap == front->extra_colormap + && ((!front->ffloors && !back->ffloors) + || front->tag == back->tag)); +} + // // R_AddLine // Clips the given segment and adds any visible pieces to the line list. @@ -526,36 +556,8 @@ static void R_AddLine(seg_t *line) // Identical floor and ceiling on both sides, identical light levels on both sides, // and no middle texture. - if ( -#ifdef POLYOBJECTS - !line->polyseg && -#endif - backsector->ceilingpic == frontsector->ceilingpic - && backsector->floorpic == frontsector->floorpic -#ifdef ESLOPE - && backsector->f_slope == frontsector->f_slope - && backsector->c_slope == frontsector->c_slope -#endif - && backsector->lightlevel == frontsector->lightlevel - && !curline->sidedef->midtexture - // Check offsets too! - && backsector->floor_xoffs == frontsector->floor_xoffs - && backsector->floor_yoffs == frontsector->floor_yoffs - && backsector->floorpic_angle == frontsector->floorpic_angle - && backsector->ceiling_xoffs == frontsector->ceiling_xoffs - && backsector->ceiling_yoffs == frontsector->ceiling_yoffs - && backsector->ceilingpic_angle == frontsector->ceilingpic_angle - // Consider altered lighting. - && backsector->floorlightsec == frontsector->floorlightsec - && backsector->ceilinglightsec == frontsector->ceilinglightsec - // Consider colormaps - && backsector->extra_colormap == frontsector->extra_colormap - && ((!frontsector->ffloors && !backsector->ffloors) - || frontsector->tag == backsector->tag)) - { + if (R_IsEmptyLine(line, frontsector, backsector)) return; - } - clippass: R_ClipPassWallSegment(x1, x2 - 1); diff --git a/src/r_bsp.h b/src/r_bsp.h index e871b5dd..80824831 100644 --- a/src/r_bsp.h +++ b/src/r_bsp.h @@ -50,6 +50,7 @@ extern polyobj_t **po_ptrs; // temp ptr array to sort polyobject pointers sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel, INT32 *ceilinglightlevel, boolean back); +boolean R_IsEmptyLine(seg_t *line, sector_t *front, sector_t *back); INT32 R_GetPlaneLight(sector_t *sector, fixed_t planeheight, boolean underside); void R_Prep3DFloors(sector_t *sector); From 8ba0f2a177086a26313aac58eb8ff4b2ecc95c09 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 12 Jan 2017 21:44:27 +0000 Subject: [PATCH 4/7] clipping code didn't seem so bad this time (at least compared to without), let's enable it now? --- src/doomdef.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doomdef.h b/src/doomdef.h index e5fa3a48..ff09144e 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -507,6 +507,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// on the bright side it fixes some weird issues with translucent walls /// \note SRB2CB port. /// SRB2CB itself ported this from PrBoom+ -//#define NEWCLIP +#define NEWCLIP #endif // __DOOMDEF__ From 3608f73d39a60fe79c368691f8171a20691ea4ce Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 16 Jan 2017 15:48:07 +0000 Subject: [PATCH 5/7] Updated SRB2.cbp for hw_clip.c/h --- SRB2.cbp | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/SRB2.cbp b/SRB2.cbp index 74ec96c6..5aa623fa 100644 --- a/SRB2.cbp +++ b/SRB2.cbp @@ -1174,6 +1174,39 @@ HW3SOUND for 3D hardware sound support