UFO: Alien Invasion
Loading...
Searching...
No Matches
r_bsp.cpp
Go to the documentation of this file.
1
5
6/*
7Copyright (C) 1997-2001 Id Software, Inc.
8
9This program is free software; you can redistribute it and/or
10modify it under the terms of the GNU General Public License
11as published by the Free Software Foundation; either version 2
12of the License, or (at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17
18See the GNU General Public License for more details.
19
20You should have received a copy of the GNU General Public License
21along with this program; if not, write to the Free Software
22Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
24*/
25
26#include "r_local.h"
27#include "r_lightmap.h"
28#include "r_material.h"
29#include "r_light.h"
30#include "r_draw.h"
31
32/*
33=============================================================
34BRUSH MODELS
35=============================================================
36*/
37
38#define BACKFACE_EPSILON 0.01
39
40#define MAX_BSPS_TO_RENDER 1024
41
42typedef struct bspRenderRef_s {
47
49static int numBspRRefs;
50
57static int R_CullBox (const vec3_t mins, const vec3_t maxs)
58{
59 int i;
60 int cullState = 0;
61
62 if (r_nocull->integer)
63 return PSIDE_FRONT;
64
65 for (i = lengthof(r_locals.frustum) - 1; i >= 0; i--) {
66 int planeSide = TR_BoxOnPlaneSide(mins, maxs, &r_locals.frustum[i]);
67 if (planeSide == PSIDE_BACK)
68 return PSIDE_BACK; /* completely culled away */
69 cullState |= planeSide;
70 }
71
72 return cullState;
73}
74
75
83bool R_CullSphere (const vec3_t centre, const float radius, const unsigned int clipflags)
84{
85 unsigned int i;
86 unsigned int bit;
87 const cBspPlane_t* p;
88
89 if (r_nocull->integer)
90 return false;
91
92 for (i = lengthof(r_locals.frustum), bit = 1, p = r_locals.frustum; i > 0; i--, bit <<= 1, p++) {
93 if (!(clipflags & bit))
94 continue;
95 if (DotProduct(centre, p->normal) - p->dist <= -radius)
96 return true;
97 }
98
99 return false;
100}
101
109{
110 /* no surfaces */
111 if (!e->model->bsp.nummodelsurfaces)
112 return true;
113
114 AABB modBox = e->model->modBox;
115 if (e->isOriginBrushModel) {
116 modBox.expand(e->model->radius);
117 } else {
118 modBox.shift(e->origin);
119 }
120
121 return R_CullBox(modBox.getMins(), modBox.getMaxs()) == PSIDE_BACK;
122}
123
124/*
125=============================================================
126WORLD MODEL
127=============================================================
128*/
129
134void R_DrawBspNormals (int tile)
135{
136 const vec4_t color = {1.0, 0.0, 0.0, 1.0};
137
138 if (!r_shownormals->integer)
139 return;
140
142
143 R_ResetArrayState(); /* default arrays */
144
145 R_Color(color);
146
147 int k = 0;
148 const mBspModel_t* bsp = &r_mapTiles[tile]->bsp;
149 const mBspSurface_t* surf = bsp->surfaces;
150 for (int i = 0; i < bsp->numsurfaces; i++, surf++) {
151 if (surf->frame != r_locals.frame)
152 continue; /* not visible */
153
154 if (surf->texinfo->flags & SURF_WARP)
155 continue; /* don't care */
156
157 if (r_shownormals->integer > 1 && !(surf->texinfo->flags & SURF_PHONG))
158 continue; /* don't care */
159
160 /* avoid overflows, draw in batches */
161 if (k > r_state.array_size - 512) {
162 glDrawArrays(GL_LINES, 0, k / 3);
163 k = 0;
164
165 refdef.batchCount++;
166 }
167
168 for (int j = 0; j < surf->numedges; j++) {
169 vec3_t end;
170 const GLfloat* vertex = &bsp->verts[(surf->index + j) * 3];
171 const GLfloat* normal = &bsp->normals[(surf->index + j) * 3];
172
173 VectorMA(vertex, 12.0, normal, end);
174
175 memcpy(&r_state.vertex_array_3d[k], vertex, sizeof(vec3_t));
176 memcpy(&r_state.vertex_array_3d[k + 3], end, sizeof(vec3_t));
177 k += sizeof(vec3_t) / sizeof(vec_t) * 2;
179 }
180 }
181
182 glDrawArrays(GL_LINES, 0, k / 3);
183
184 refdef.batchCount++;
185
187
188 R_Color(nullptr);
189}
190
200static void R_RecursiveVisibleWorldNode (const mBspNode_t* node, int tile)
201{
202 /* if a leaf node, nothing to mark */
203 if (node->contents > CONTENTS_NODE)
204 return;
205
206 /* pathfinding nodes are invalid here */
207 assert(node->plane);
208
209 mBspSurface_t* surf = r_mapTiles[tile]->bsp.surfaces + node->firstsurface;
210 for (int i = 0; i < node->numsurfaces; i++, surf++)
211 surf->frame = r_locals.frame;
212
213 /* recurse down the children */
216}
217
227static void R_RecursiveWorldNode (const mBspNode_t* node, int tile)
228{
229 /* if a leaf node, nothing to mark */
230 if (node->contents > CONTENTS_NODE)
231 return;
232
233 int cullState = R_CullBox(node->minmaxs.mins, node->minmaxs.maxs);
234
235 if (cullState == PSIDE_BACK)
236 return; /* culled out */
237
238 /* pathfinding nodes are invalid here */
239 assert(node->plane);
240
241 mBspSurface_t* surf = r_mapTiles[tile]->bsp.surfaces + node->firstsurface;
242 for (int i = 0; i < node->numsurfaces; i++, surf++)
243 surf->frame = r_locals.frame;
244
245 /* recurse down the children */
247 if (cullState == PSIDE_FRONT) {
248 /* completely inside the frustum - no need to do any further checks */
251 } else {
252 /* partially clipped by frustum - recurse to do finer checks */
253 R_RecursiveWorldNode(node->children[0], tile);
254 R_RecursiveWorldNode(node->children[1], tile);
255 }
256}
257
265static void R_RecurseWorld (const mBspNode_t* node, int tile)
266{
267 /* skip special pathfinding nodes */
268 if (node->contents == CONTENTS_PATHFINDING_NODE) {
269 R_RecurseWorld(node->children[0], tile);
270 R_RecurseWorld(node->children[1], tile);
271 } else {
272 R_RecursiveWorldNode(node, tile);
273 }
274}
275
276
282{
283 if (!r_drawworld->integer)
284 return;
285
286 const int mask = 1 << refdef.worldlevel;
287
288 for (int tile = 0; tile < r_numMapTiles; tile++) {
289 /* don't draw weaponclip, actorclip and stepon */
290 for (int i = 0; i <= LEVEL_LASTVISIBLE; i++) {
291 /* check the worldlevel flags */
292 if (i && !(i & mask))
293 continue;
294
295 mBspModel_t* bspModel = &r_mapTiles[tile]->bsp;
296 mBspHeader_t* header = &bspModel->submodels[i];
297 if (!header->numfaces)
298 continue;
299
300 R_RecurseWorld(bspModel->nodes + header->headnode, tile);
301 }
302 }
303}
304
305/*
306=============================================================
307Deferred rendering
308=============================================================
309*/
310
312{
313 numBspRRefs = 0;
314}
315
324void R_AddBspRRef (const mBspModel_t* model, const vec3_t origin, const vec3_t angles, const bool forceVisibility)
325{
327 Com_Printf("Cannot add BSP model rendering reference: MAX_BSPS_TO_RENDER exceeded\n");
328 return;
329 }
330
331 if (!model) {
332 Com_Printf("R_AddBspRRef: null model!\n");
333 return;
334 }
335
337 bspRR->bsp = model;
338 VectorCopy(origin, bspRR->origin);
339 VectorCopy(angles, bspRR->angles);
340
341 if (!forceVisibility)
342 return;
343
344 mBspSurface_t* surf = &model->surfaces[model->firstmodelsurface];
345 for (int i = 0; i < model->nummodelsurfaces; i++, surf++) {
346 /* visible flag for rendering */
347 surf->frame = r_locals.frame;
348 }
349}
350
351typedef void (*drawSurfaceFunc)(const mBspSurfaces_t* surfs, glElementIndex_t* indexPtr);
352
358{
359 glEnable(GL_CULL_FACE);
360 glCullFace(GL_FRONT); /* our triangles are backwards to what OpenGL expects, so tell it to render only back faces */
361
362 for (int i = 0; i < numBspRRefs; i++) {
363 const bspRenderRef_t* const bspRR = &bspRRefs[i];
364 const mBspModel_t* const bsp = bspRR->bsp;
365 const mBspModel_t* const tile = &r_mapTiles[bsp->maptile]->bsp; /* This is required to find the tile (world) bsp model to which arrays belong (submodels do not own arrays, but use world model ones) */
366 glElementIndex_t* indexPtr;
367
368 if (!bsp->sorted_surfaces[surfType]->count)
369 continue;
370
371 R_SetArrayState(tile);
372
373 /* Vertex buffers are nullptr-based, arrays are not */
374 if (qglBindBuffer && r_vertexbuffers->integer)
375 indexPtr = nullptr;
376 else
377 indexPtr = tile->indexes;
378
379 glPushMatrix();
380
381 glTranslatef(bspRR->origin[0], bspRR->origin[1], bspRR->origin[2]);
382 glRotatef(bspRR->angles[YAW], 0, 0, 1);
383 glRotatef(bspRR->angles[PITCH], 0, 1, 0);
384 glRotatef(bspRR->angles[ROLL], 1, 0, 0);
385
386 drawFunc(bsp->sorted_surfaces[surfType], indexPtr);
387
389#if 0
390 /* show model bounding box */
391 if (r_showbox->integer) {
392 const model_t* model = bspRR->bsp;
393 R_DrawBoundingBox(model->mins, model->maxs);
394 }
395#endif
396
397 glPopMatrix();
398 }
399
400 /* and restore array pointers */
402
403 glCullFace(GL_BACK);
404 glDisable(GL_CULL_FACE);
405}
406
411{
413 R_EnableLighting(r_state.world_program, true);
415
417
418 R_EnableLighting(nullptr, false);
419 R_EnableGlowMap(nullptr);
421}
422
427{
428 R_EnableWarp(r_state.warp_program, true);
429
431
432 R_EnableWarp(nullptr, false);
433 R_EnableGlowMap(nullptr);
434}
435
437{
438 R_EnableAlphaTest(true);
439 R_EnableLighting(r_state.world_program, true);
441
443
444 R_EnableLighting(nullptr, false);
445 R_EnableGlowMap(nullptr);
446 R_EnableAlphaTest(false);
447}
448
453
458
463{
464 assert(r_state.blend_enabled);
466
468
470}
471
476{
477 assert(r_state.blend_enabled);
478 R_EnableWarp(r_state.warp_program, true);
479
481
482 R_EnableWarp(nullptr, false);
483 R_EnableGlowMap(nullptr);
484}
rendererData_t refdef
Definition r_main.cpp:45
void R_Color(const vec4_t rgba)
Change the color to given value.
Definition r_state.cpp:1011
Definition aabb.h:42
const vec3_t & getMaxs() const
Definition aabb.h:128
vec3_t maxs
Definition aabb.h:258
vec3_t mins
Definition aabb.h:257
const vec3_t & getMins() const
Definition aabb.h:116
void shift(const vec3_t shiftVec)
shove the whole box by the given vector
Definition aabb.h:246
void expand(const float byVal)
expand the box in all directions, but clip them to the maximum boundaries
Definition aabb.h:240
void Com_Printf(const char *const fmt,...)
Definition common.cpp:428
#define SURF_PHONG
Definition defines.h:263
#define LEVEL_LASTVISIBLE
Definition defines.h:348
#define SURF_WARP
Definition defines.h:256
#define PSIDE_BACK
Definition defines.h:368
#define PSIDE_FRONT
Definition defines.h:367
voidpf uLong int origin
Definition ioapi.h:45
void VectorMA(const vec3_t veca, const float scale, const vec3_t vecb, vec3_t outVector)
Sets vector_out (vc) to vevtor1 (va) + scale * vector2 (vb).
Definition mathlib.cpp:261
#define YAW
Definition mathlib.h:55
#define PITCH
Definition mathlib.h:54
#define ROLL
Definition mathlib.h:56
void R_SetArrayState(const mBspModel_t *bsp)
Definition r_array.cpp:153
void R_ResetArrayState(void)
Definition r_array.cpp:185
static void R_RecursiveVisibleWorldNode(const mBspNode_t *node, int tile)
Recurse down the bsp tree and mark all surfaces as visible for being rendered.
Definition r_bsp.cpp:200
void R_RenderBlendWarpBspRRefs(void)
Draw all warped translucent bsp surfaces via warp shader and with blend enabled.
Definition r_bsp.cpp:475
void R_RenderOpaqueBspRRefs(void)
Draw all simple opaque bsp surfaces with multitexture enabled and light enabled.
Definition r_bsp.cpp:410
void R_GetLevelSurfaceLists(void)
Fills the surface chains for the current worldlevel and hide other levels.
Definition r_bsp.cpp:281
#define MAX_BSPS_TO_RENDER
Definition r_bsp.cpp:40
void R_RenderOpaqueWarpBspRRefs(void)
Draw all warped opaque bsp surfaces via warp shader.
Definition r_bsp.cpp:426
static void R_RecursiveWorldNode(const mBspNode_t *node, int tile)
Recurse down the bsp tree and mark surfaces that are visible (not culled) for being rendered.
Definition r_bsp.cpp:227
void R_DrawBspNormals(int tile)
Developer tool for viewing BSP vertex normals. Only Phong interpolated surfaces show their normals wh...
Definition r_bsp.cpp:134
bool R_CullBspModel(const entity_t *e)
Returns true if the specified entity is completely culled by the view frustum, false otherwise.
Definition r_bsp.cpp:108
static int R_CullBox(const vec3_t mins, const vec3_t maxs)
Returns whether if the specified bounding box is completely culled by the view frustum (PSIDE_BACK),...
Definition r_bsp.cpp:57
static void R_RecurseWorld(const mBspNode_t *node, int tile)
Wrapper that recurses the bsp nodes but skip the pathfinding nodes.
Definition r_bsp.cpp:265
void R_RenderMaterialBspRRefs(void)
Definition r_bsp.cpp:449
void R_RenderBlendBspRRefs(void)
Draw all translucent bsp surfaces with multitexture enabled and blend enabled.
Definition r_bsp.cpp:462
static bspRenderRef_t bspRRefs[MAX_BSPS_TO_RENDER]
Definition r_bsp.cpp:48
bool R_CullSphere(const vec3_t centre, const float radius, const unsigned int clipflags)
Performs a spherical frustum check.
Definition r_bsp.cpp:83
void R_AddBspRRef(const mBspModel_t *model, const vec3_t origin, const vec3_t angles, const bool forceVisibility)
Adds bsp render references.
Definition r_bsp.cpp:324
void R_RenderAlphaTestBspRRefs(void)
Definition r_bsp.cpp:436
static void R_RenderBspRRefs(drawSurfaceFunc drawFunc, surfaceArrayType_t surfType)
Definition r_bsp.cpp:357
void R_ClearBspRRefs(void)
Definition r_bsp.cpp:311
void(* drawSurfaceFunc)(const mBspSurfaces_t *surfs, glElementIndex_t *indexPtr)
Definition r_bsp.cpp:351
static int numBspRRefs
Definition r_bsp.cpp:49
void R_RenderFlareBspRRefs(void)
Definition r_bsp.cpp:454
void R_DrawBoundingBox(const AABB &absBox)
Draws the model bounding box.
Definition r_draw.cpp:690
void R_DrawFlareSurfaces(const mBspSurfaces_t *surfs, glElementIndex_t *indexPtr)
Flares are batched by their texture. Usually, this means one draw operation for all flares in view....
Definition r_flare.cpp:69
QGL_EXTERN void(APIENTRY *qglActiveTexture)(GLenum texture)
QGL_EXTERN GLint i
Definition r_gl.h:113
GLuint glElementIndex_t
Definition r_gl.h:57
void R_EnableWorldLights(void)
Set up lighting data for the GLSL world shader.
Definition r_light.cpp:108
lightmap definitions
local graphics definitions
void R_DrawSurfaces(const mBspSurfaces_t *surfs, glElementIndex_t *indexPtr)
General surface drawing function, that draw the surface chains.
Definition r_surface.cpp:98
cvar_t * r_shownormals
Definition r_main.cpp:102
cvar_t * r_vertexbuffers
Definition r_main.cpp:94
void R_DrawMaterialSurfaces(const mBspSurfaces_t *surfs, glElementIndex_t *indexPtr)
Iterates the specified surfaces list, updating materials as they are encountered, and rendering all v...
cvar_t * r_drawworld
Definition r_main.cpp:61
cvar_t * r_nocull
Definition r_main.cpp:62
cvar_t * r_showbox
Definition r_main.cpp:92
rlocals_t r_locals
Definition r_main.cpp:49
rstate_t r_state
Definition r_main.cpp:48
Header file for the render material subsystem.
int r_numMapTiles
Definition r_model.cpp:33
model_t * r_mapTiles[MAX_MAPTILES]
The world model(s).
Definition r_model.cpp:32
surfaceArrayType_t
@ S_MATERIAL
@ S_ALPHA_TEST
@ S_BLEND
@ S_OPAQUE_WARP
@ S_FLARE
@ S_OPAQUE
@ S_BLEND_WARP
#define CONTENTS_NODE
#define CONTENTS_PATHFINDING_NODE
void R_EnableAlphaTest(bool enable)
Definition r_state.cpp:277
void R_EnableTexture(gltexunit_t *texunit, bool enable)
Definition r_state.cpp:303
void R_EnableGlowMap(const image_t *image)
Definition r_state.cpp:664
bool R_EnableLighting(r_program_t *program, bool enable)
Enables hardware-accelerated lighting with the specified program. This should be called after any tex...
Definition r_state.cpp:350
void R_EnableWarp(r_program_t *program, bool enable)
Definition r_state.cpp:496
void R_ReallocateStateArrays(int size)
Reallocate arrays of GL primitives if needed.
Definition r_state.cpp:1029
#define texunit_diffuse
Definition r_state.h:68
#define texunit_lightmap
Definition r_state.h:69
#define lengthof(x)
Definition shared.h:105
vec3_t angles
Definition r_bsp.cpp:45
vec3_t origin
Definition r_bsp.cpp:44
const mBspModel_t * bsp
Definition r_bsp.cpp:43
plane_t structure
Definition typedefs.h:20
float dist
Definition typedefs.h:22
vec3_t normal
Definition typedefs.h:21
struct model_s * model
Definition r_entity.h:97
vec3_t origin
Definition r_entity.h:101
bool isOriginBrushModel
Definition r_entity.h:115
brush model
glElementIndex_t * indexes
mBspSurfaces_t * sorted_surfaces[NUM_SURFACES_ARRAYS]
float * normals
mBspSurface_t * surfaces
mBspHeader_t * submodels
mBspNode_t * nodes
unsigned short firstsurface
cBspPlane_t * plane
struct mBspNode_s * children[2]
unsigned short numsurfaces
mBspTexInfo_t * texinfo
unsigned int index
surfaces are assigned to arrays based on their primary rendering type and then sorted by world textur...
int TR_BoxOnPlaneSide(const vec3_t mins, const vec3_t maxs, const TR_PLANE_TYPE *plane)
Returns PSIDE_FRONT, PSIDE_BACK, or PSIDE_BOTH.
Definition tracing.cpp:542
float vec_t
Definition ufotypes.h:37
vec_t vec3_t[3]
Definition ufotypes.h:39
vec_t vec4_t[4]
Definition ufotypes.h:40
#define VectorCopy(src, dest)
Definition vector.h:51
#define DotProduct(x, y)
Returns the distance between two 3-dimensional vectors.
Definition vector.h:44