From d1143b4b5cf2344039c4cfea171bd2cffee6737e Mon Sep 17 00:00:00 2001 From: lewa_j Date: Sat, 17 Jan 2026 21:19:37 +0300 Subject: [PATCH] ref: dx2: add frustum, move Assert and some externs, get world pointer from engine --- ref/dx2/r_d3d.c | 3 + ref/dx2/r_frustum.c | 185 ++++++++++++++++++++++++++++++++++++++++++++ ref/dx2/r_frustum.h | 41 ++++++++++ ref/dx2/r_image.c | 3 - ref/dx2/r_local.h | 34 ++++++-- 5 files changed, 255 insertions(+), 11 deletions(-) create mode 100644 ref/dx2/r_frustum.c create mode 100644 ref/dx2/r_frustum.h diff --git a/ref/dx2/r_d3d.c b/ref/dx2/r_d3d.c index 8b2a594c..2dd0b373 100644 --- a/ref/dx2/r_d3d.c +++ b/ref/dx2/r_d3d.c @@ -278,6 +278,9 @@ qboolean R_Init( void ) return false; } + // see R_ProcessEntData for tr.entities initialization + tr.world = (struct world_static_s *)ENGINE_GET_PARM( PARM_GET_WORLD_PTR ); + dxc.renderMode = kRenderNormal; Vector4Set(dxc.currentColor, 1, 1, 1, 1); diff --git a/ref/dx2/r_frustum.c b/ref/dx2/r_frustum.c new file mode 100644 index 00000000..d78ef970 --- /dev/null +++ b/ref/dx2/r_frustum.c @@ -0,0 +1,185 @@ +/* +r_frustum.c - frustum test implementation +Copyright (C) 2016 Uncle Mike + +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 3 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. +*/ + +#include "r_local.h" +#include "xash3d_mathlib.h" + +static void GL_FrustumSetPlane( gl_frustum_t *out, int side, const vec3_t vecNormal, float flDist ) +{ + Assert( side >= 0 && side < FRUSTUM_PLANES ); + + out->planes[side].type = PlaneTypeForNormal( vecNormal ); + out->planes[side].signbits = SignbitsForPlane( vecNormal ); + VectorCopy( vecNormal, out->planes[side].normal ); + out->planes[side].dist = flDist; + + SetBits( out->clipFlags, BIT( side )); +} + +void GL_FrustumInitProj( gl_frustum_t *out, float flZNear, float flZFar, float flFovX, float flFovY ) +{ + float xs, xc; + vec3_t farpoint, nearpoint; + vec3_t normal, iforward; + + // horizontal fov used for left and right planes + SinCos( DEG2RAD( flFovX ) * 0.5f, &xs, &xc ); + + // setup left plane + VectorMAM( xs, RI.cull_vforward, -xc, RI.cull_vright, normal ); + GL_FrustumSetPlane( out, FRUSTUM_LEFT, normal, DotProduct( RI.cullorigin, normal )); + + // setup right plane + VectorMAM( xs, RI.cull_vforward, xc, RI.cull_vright, normal ); + GL_FrustumSetPlane( out, FRUSTUM_RIGHT, normal, DotProduct( RI.cullorigin, normal )); + + // vertical fov used for top and bottom planes + SinCos( DEG2RAD( flFovY ) * 0.5f, &xs, &xc ); + VectorNegate( RI.cull_vforward, iforward ); + + // setup bottom plane + VectorMAM( xs, RI.cull_vforward, -xc, RI.cull_vup, normal ); + GL_FrustumSetPlane( out, FRUSTUM_BOTTOM, normal, DotProduct( RI.cullorigin, normal )); + + // setup top plane + VectorMAM( xs, RI.cull_vforward, xc, RI.cull_vup, normal ); + GL_FrustumSetPlane( out, FRUSTUM_TOP, normal, DotProduct( RI.cullorigin, normal )); + + // setup far plane + VectorMA( RI.cullorigin, flZFar, RI.cull_vforward, farpoint ); + GL_FrustumSetPlane( out, FRUSTUM_FAR, iforward, DotProduct( iforward, farpoint )); + + // no need to setup backplane for general view. + if( flZNear == 0.0f ) return; + + // setup near plane + VectorMA( RI.cullorigin, flZNear, RI.cull_vforward, nearpoint ); + GL_FrustumSetPlane( out, FRUSTUM_NEAR, RI.cull_vforward, DotProduct( RI.cull_vforward, nearpoint )); +} + +void GL_FrustumInitOrtho( gl_frustum_t *out, float xLeft, float xRight, float yTop, float yBottom, float flZNear, float flZFar ) +{ + vec3_t iforward, iright, iup; + + // setup the near and far planes + float orgOffset = DotProduct( RI.cullorigin, RI.cull_vforward ); + VectorNegate( RI.cull_vforward, iforward ); + + // because quake ortho is inverted and far and near should be swaped + GL_FrustumSetPlane( out, FRUSTUM_FAR, iforward, -flZNear - orgOffset ); + GL_FrustumSetPlane( out, FRUSTUM_NEAR, RI.cull_vforward, flZFar + orgOffset ); + + // setup left and right planes + orgOffset = DotProduct( RI.cullorigin, RI.cull_vright ); + VectorNegate( RI.cull_vright, iright ); + + GL_FrustumSetPlane( out, FRUSTUM_LEFT, RI.cull_vright, xLeft + orgOffset ); + GL_FrustumSetPlane( out, FRUSTUM_RIGHT, iright, -xRight - orgOffset ); + + // setup top and buttom planes + orgOffset = DotProduct( RI.cullorigin, RI.cull_vup ); + VectorNegate( RI.cull_vup, iup ); + + GL_FrustumSetPlane( out, FRUSTUM_TOP, RI.cull_vup, yTop + orgOffset ); + GL_FrustumSetPlane( out, FRUSTUM_BOTTOM, iup, -yBottom - orgOffset ); +} + +// cull methods +qboolean GL_FrustumCullBox( const gl_frustum_t *out, const vec3_t mins, const vec3_t maxs, int userClipFlags ) +{ + int iClipFlags; + int i, bit; + + if( r_nocull.value ) + return false; + + if( userClipFlags != 0 ) + iClipFlags = userClipFlags; + else iClipFlags = out->clipFlags; + + for( i = FRUSTUM_PLANES, bit = 1; i > 0; i--, bit <<= 1 ) + { + const mplane_t *p = &out->planes[FRUSTUM_PLANES - i]; + + if( !FBitSet( iClipFlags, bit )) + continue; + + switch( p->signbits ) + { + case 0: + if( p->normal[0] * maxs[0] + p->normal[1] * maxs[1] + p->normal[2] * maxs[2] < p->dist ) + return true; + break; + case 1: + if( p->normal[0] * mins[0] + p->normal[1] * maxs[1] + p->normal[2] * maxs[2] < p->dist ) + return true; + break; + case 2: + if( p->normal[0] * maxs[0] + p->normal[1] * mins[1] + p->normal[2] * maxs[2] < p->dist ) + return true; + break; + case 3: + if( p->normal[0] * mins[0] + p->normal[1] * mins[1] + p->normal[2] * maxs[2] < p->dist ) + return true; + break; + case 4: + if( p->normal[0] * maxs[0] + p->normal[1] * maxs[1] + p->normal[2] * mins[2] < p->dist ) + return true; + break; + case 5: + if( p->normal[0] * mins[0] + p->normal[1] * maxs[1] + p->normal[2] * mins[2] < p->dist ) + return true; + break; + case 6: + if( p->normal[0] * maxs[0] + p->normal[1] * mins[1] + p->normal[2] * mins[2] < p->dist ) + return true; + break; + case 7: + if( p->normal[0] * mins[0] + p->normal[1] * mins[1] + p->normal[2] * mins[2] < p->dist ) + return true; + break; + default: + return false; + } + } + + return false; +} + +qboolean GL_FrustumCullSphere( const gl_frustum_t *out, const vec3_t center, float radius, int userClipFlags ) +{ + int iClipFlags; + int i, bit; + + if( r_nocull.value ) + return false; + + if( userClipFlags != 0 ) + iClipFlags = userClipFlags; + else iClipFlags = out->clipFlags; + + for( i = FRUSTUM_PLANES, bit = 1; i > 0; i--, bit <<= 1 ) + { + const mplane_t *p = &out->planes[FRUSTUM_PLANES - i]; + + if( !FBitSet( iClipFlags, bit )) + continue; + + if( DotProduct( center, p->normal ) - p->dist <= -radius ) + return true; + } + + return false; +} diff --git a/ref/dx2/r_frustum.h b/ref/dx2/r_frustum.h new file mode 100644 index 00000000..86588f9d --- /dev/null +++ b/ref/dx2/r_frustum.h @@ -0,0 +1,41 @@ +/* +r_frustum.h - frustum test implementation +Copyright (C) 2016 Uncle Mike + +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 3 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. +*/ + +#ifndef GL_FRUSTUM_H +#define GL_FRUSTUM_H + +// don't change this order +#define FRUSTUM_LEFT 0 +#define FRUSTUM_RIGHT 1 +#define FRUSTUM_BOTTOM 2 +#define FRUSTUM_TOP 3 +#define FRUSTUM_FAR 4 +#define FRUSTUM_NEAR 5 +#define FRUSTUM_PLANES 6 + +typedef struct gl_frustum_s +{ + mplane_t planes[FRUSTUM_PLANES]; + unsigned int clipFlags; +} gl_frustum_t; + +void GL_FrustumInitProj( gl_frustum_t *out, float flZNear, float flZFar, float flFovX, float flFovY ); +void GL_FrustumInitOrtho( gl_frustum_t *out, float xLeft, float xRight, float yTop, float yBottom, float flZNear, float flZFar ); + +// cull methods +qboolean GL_FrustumCullBox( const gl_frustum_t *out, const vec3_t mins, const vec3_t maxs, int userClipFlags ); +qboolean GL_FrustumCullSphere( const gl_frustum_t *out, const vec3_t centre, float radius, int userClipFlags ); + +#endif//GL_FRUSTUM_H diff --git a/ref/dx2/r_image.c b/ref/dx2/r_image.c index 0b58b558..9140f411 100644 --- a/ref/dx2/r_image.c +++ b/ref/dx2/r_image.c @@ -19,9 +19,6 @@ GNU General Public License for more details. #include "crtlib.h" #include "crclib.h" -#define Assert(x) if(!( x )) gEngfuncs.Host_Error( "assert failed at %s:%i\n", __FILE__, __LINE__ ) - - static dx_texture_t dx_textures[MAX_TEXTURES]; static dx_texture_t *dx_texturesHashTable[TEXTURES_HASH_SIZE]; static uint dx_numTextures; diff --git a/ref/dx2/r_local.h b/ref/dx2/r_local.h index da99e01b..dba3b395 100644 --- a/ref/dx2/r_local.h +++ b/ref/dx2/r_local.h @@ -16,7 +16,10 @@ GNU General Public License for more details. #pragma once +#include "ref_common.h" #include "ref_api.h" +#include "r_frustum.h" +#include "mod_local.h" #include "com_strings.h" #define DIRECTDRAW_VERSION 0x0200 @@ -24,10 +27,10 @@ GNU General Public License for more details. #include #include -extern poolhandle_t r_temppool; +#define Assert(x) if(!( x )) gEngfuncs.Host_Error( "assert failed at %s:%i\n", __FILE__, __LINE__ ) -extern ref_api_t gEngfuncs; -extern ref_client_t *gp_cl; + +extern poolhandle_t r_temppool; #define MAX_TEXTURES 8192 @@ -104,7 +107,7 @@ typedef struct cl_entity_t *currentbeam; // same as above but for beams int viewport[4]; - //gl_frustum_t frustum; + gl_frustum_t frustum; mleaf_t *viewleaf; mleaf_t *oldviewleaf; @@ -179,11 +182,11 @@ typedef struct double frametime; // special frametime for multipass rendering (will set to 0 on a nextview) // get from engine + world_static_t *world; cl_entity_t *entities; - uint max_entities; -} dx_globals_t; + int max_entities; -extern dx_globals_t tr; +} dx_globals_t; struct dx_context_s { @@ -206,8 +209,13 @@ struct dx_context_s }; typedef struct dx_context_s dx_context_t; +extern ref_instance_t RI; +extern dx_globals_t tr; extern dx_context_t dxc; +extern ref_api_t gEngfuncs; +extern ref_client_t *gp_cl; + const char *dxResultToStr( HRESULT r ); #define DXCheckRet(DST, CALL) \ @@ -280,7 +288,17 @@ void GL_FreeTexture( unsigned int texnum ); void R_OverrideTextureSourceSize( unsigned int textnum, unsigned int srcWidth, unsigned int srcHeight ); void GL_UpdateTexSize( int texnum, int width, int height, int depth ); -//r_surf.c +// r_math.c +void Matrix4x4_ToArrayFloatGL( const matrix4x4 in, float out[16] ); +void Matrix4x4_Concat( matrix4x4 out, const matrix4x4 in1, const matrix4x4 in2 ); +void Matrix4x4_ConcatTranslate( matrix4x4 out, float x, float y, float z ); +void Matrix4x4_ConcatRotate( matrix4x4 out, float angle, float x, float y, float z ); +void Matrix4x4_CreateProjection( matrix4x4 out, float xMax, float xMin, float yMax, float yMin, float zNear, float zFar ); +void Matrix4x4_CreateOrtho( matrix4x4 m, float xLeft, float xRight, float yBottom, float yTop, float zNear, float zFar ); +void Matrix4x4_CreateModelview( matrix4x4 out ); + + +// r_surf.c void GL_SubdivideSurface( model_t *mod, msurface_t *fa ); void GL_OrthoBounds( const float *mins, const float *maxs ); byte *Mod_GetCurrentVis( void );