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
This commit is contained in:
Monster Iestyn 2017-01-09 22:13:26 +00:00
parent 925a56ad98
commit a733a29f4c
4 changed files with 497 additions and 6 deletions

View File

@ -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

View File

@ -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 $@

465
src/hardware/hw_clip.c Normal file
View File

@ -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 <math.h>
#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

24
src/hardware/hw_clip.h Normal file
View File

@ -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