UFO: Alien Invasion
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
r_bsp.cpp
Go to the documentation of this file.
1 
6 /*
7 Copyright (C) 1997-2001 Id Software, Inc.
8 
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License
11 as published by the Free Software Foundation; either version 2
12 of the License, or (at your option) any later version.
13 
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 
18 See the GNU General Public License for more details.
19 
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, 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 =============================================================
34 BRUSH MODELS
35 =============================================================
36 */
37 
38 #define BACKFACE_EPSILON 0.01
39 
40 #define MAX_BSPS_TO_RENDER 1024
41 
42 typedef struct bspRenderRef_s {
43  const mBspModel_t* bsp;
47 
49 static int numBspRRefs;
50 
57 static 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 
83 bool 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 
108 bool R_CullBspModel (const entity_t* e)
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 =============================================================
126 WORLD MODEL
127 =============================================================
128 */
129 
134 void 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 
200 static 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 */
214  R_RecursiveVisibleWorldNode(node->children[0], tile);
215  R_RecursiveVisibleWorldNode(node->children[1], tile);
216 }
217 
227 static 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 */
249  R_RecursiveVisibleWorldNode(node->children[0], tile);
250  R_RecursiveVisibleWorldNode(node->children[1], tile);
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 
265 static 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 =============================================================
307 Deferred rendering
308 =============================================================
309 */
310 
311 void R_ClearBspRRefs (void)
312 {
313  numBspRRefs = 0;
314 }
315 
324 void 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 
336  bspRenderRef_t* bspRR = &bspRRefs[numBspRRefs++];
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 
351 typedef void (*drawSurfaceFunc)(const mBspSurfaces_t* surfs, glElementIndex_t* indexPtr);
352 
357 static void R_RenderBspRRefs (drawSurfaceFunc drawFunc, surfaceArrayType_t surfType)
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 {
415 
417 
418  R_EnableLighting(nullptr, false);
419  R_EnableGlowMap(nullptr);
421 }
422 
427 {
429 
431 
432  R_EnableWarp(nullptr, false);
433  R_EnableGlowMap(nullptr);
434 }
435 
437 {
438  R_EnableAlphaTest(true);
441 
443 
444  R_EnableLighting(nullptr, false);
445  R_EnableGlowMap(nullptr);
446  R_EnableAlphaTest(false);
447 }
448 
450 {
452 }
453 
455 {
457 }
458 
463 {
464  assert(r_state.blend_enabled);
466 
468 
470 }
471 
476 {
477  assert(r_state.blend_enabled);
479 
481 
482  R_EnableWarp(nullptr, false);
483  R_EnableGlowMap(nullptr);
484 }
unsigned short numsurfaces
r_program_t * warp_program
Definition: r_state.h:134
#define VectorCopy(src, dest)
Definition: vector.h:51
void R_EnableTexture(gltexunit_t *texunit, bool enable)
Definition: r_state.cpp:303
cvar_t * r_vertexbuffers
Definition: r_main.cpp:94
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
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
vec3_t origin
Definition: bspfile.h:47
static void R_RenderBspRRefs(drawSurfaceFunc drawFunc, surfaceArrayType_t surfType)
Definition: r_bsp.cpp:357
#define PSIDE_BACK
Definition: defines.h:368
#define ROLL
Definition: mathlib.h:56
vec3_t normal
Definition: typedefs.h:21
mBspSurfaces_t * sorted_surfaces[NUM_SURFACES_ARRAYS]
model_t * r_mapTiles[MAX_MAPTILES]
The world model(s)
Definition: r_model.cpp:32
static bspRenderRef_t bspRRefs[MAX_BSPS_TO_RENDER]
Definition: r_bsp.cpp:48
voidpf uLong int origin
Definition: ioapi.h:45
void R_EnableAlphaTest(bool enable)
Definition: r_state.cpp:277
GLfloat * vertex_array_3d
Definition: r_state.h:100
Definition: aabb.h:42
#define LEVEL_LASTVISIBLE
Definition: defines.h:348
float dist
Definition: typedefs.h:22
surfaces are assigned to arrays based on their primary rendering type and then sorted by world textur...
vec3_t origin
Definition: r_bsp.cpp:44
float vec_t
Definition: ufotypes.h:37
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
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
void R_RenderMaterialBspRRefs(void)
Definition: r_bsp.cpp:449
int firstmodelsurface
static int numBspRRefs
Definition: r_bsp.cpp:49
local graphics definitions
void R_RenderAlphaTestBspRRefs(void)
Definition: r_bsp.cpp:436
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
mBspNode_t * nodes
void Com_Printf(const char *const fmt,...)
Definition: common.cpp:386
vec3_t angles
Definition: r_bsp.cpp:45
vec3_t maxs
Definition: aabb.h:258
#define PSIDE_FRONT
Definition: defines.h:367
const mBspModel_t * bsp
Definition: r_bsp.cpp:43
int integer
Definition: cvar.h:81
#define CONTENTS_NODE
#define texunit_lightmap
Definition: r_state.h:69
void R_DrawBoundingBox(const AABB &absBox)
Draws the model bounding box.
Definition: r_draw.cpp:690
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...
Definition: r_material.cpp:399
int r_numMapTiles
Definition: r_model.cpp:33
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
void R_Color(const vec4_t rgba)
Change the color to given value.
Definition: r_state.cpp:1011
#define YAW
Definition: mathlib.h:55
void expand(const float byVal)
expand the box in all directions, but clip them to the maximum boundaries
Definition: aabb.h:240
#define MAX_BSPS_TO_RENDER
Definition: r_bsp.cpp:40
lightmap definitions
void R_ClearBspRRefs(void)
Definition: r_bsp.cpp:311
bool R_CullSphere(const vec3_t centre, const float radius, const unsigned int clipflags)
Performs a spherical frustum check.
Definition: r_bsp.cpp:83
surfaceArrayType_t
glElementIndex_t * indexes
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
#define DotProduct(x, y)
Returns the distance between two 3-dimensional vectors.
Definition: vector.h:44
struct mBspNode_s * children[2]
void R_EnableWarp(r_program_t *program, bool enable)
Definition: r_state.cpp:496
rendererData_t refdef
Definition: r_main.cpp:45
cvar_t * r_showbox
Definition: r_main.cpp:92
cvar_t * r_drawworld
Definition: r_main.cpp:61
rlocals_t r_locals
Definition: r_main.cpp:49
int frame
Definition: r_local.h:109
cBspPlane_t * plane
int array_size
Definition: r_state.h:111
void R_ResetArrayState(void)
Definition: r_array.cpp:185
#define PITCH
Definition: mathlib.h:54
GLuint glElementIndex_t
Definition: r_gl.h:57
mBspTexInfo_t * texinfo
void R_GetLevelSurfaceLists(void)
Fills the surface chains for the current worldlevel and hide other levels.
Definition: r_bsp.cpp:281
#define SURF_PHONG
Definition: defines.h:263
int nummodelsurfaces
mBspSurface_t * surfaces
void R_RenderOpaqueBspRRefs(void)
Draw all simple opaque bsp surfaces with multitexture enabled and light enabled.
Definition: r_bsp.cpp:410
#define CONTENTS_PATHFINDING_NODE
const GLuint *typedef void(APIENTRY *GenRenderbuffersEXT_t)(GLsizei
Definition: r_gl.h:189
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
unsigned short firstsurface
#define texunit_diffuse
Definition: r_state.h:68
void(* drawSurfaceFunc)(const mBspSurfaces_t *surfs, glElementIndex_t *indexPtr)
Definition: r_bsp.cpp:351
uint32_t flags
Definition: r_model_brush.h:70
r_program_t * world_program
Definition: r_state.h:132
const vec3_t & getMins() const
Definition: aabb.h:116
float * verts
QGL_EXTERN GLint i
Definition: r_gl.h:113
cvar_t * r_shownormals
Definition: r_main.cpp:102
mBspHeader_t * submodels
struct bspRenderRef_s bspRenderRef_t
cBspPlane_t frustum[4]
Definition: r_local.h:107
void R_DrawSurfaces(const mBspSurfaces_t *surfs, glElementIndex_t *indexPtr)
General surface drawing function, that draw the surface chains.
Definition: r_surface.cpp:98
brush model
vec_t vec3_t[3]
Definition: ufotypes.h:39
void R_RenderBlendBspRRefs(void)
Draw all translucent bsp surfaces with multitexture enabled and blend enabled.
Definition: r_bsp.cpp:462
void R_SetArrayState(const mBspModel_t *bsp)
Definition: r_array.cpp:153
void shift(const vec3_t shiftVec)
shove the whole box by the given vector
Definition: aabb.h:246
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
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
rstate_t r_state
Definition: r_main.cpp:48
vec3_t mins
Definition: aabb.h:257
#define lengthof(x)
Definition: shared.h:105
void R_EnableWorldLights(void)
Set up lighting data for the GLSL world shader.
Definition: r_light.cpp:108
cvar_t * r_nocull
Definition: r_main.cpp:62
float * normals
void R_RenderBlendWarpBspRRefs(void)
Draw all warped translucent bsp surfaces via warp shader and with blend enabled.
Definition: r_bsp.cpp:475
void R_ReallocateStateArrays(int size)
Reallocate arrays of GL primitives if needed.
Definition: r_state.cpp:1029
#define SURF_WARP
Definition: defines.h:256
bool blend_enabled
Definition: r_state.h:149
const vec3_t & getMaxs() const
Definition: aabb.h:128
plane_t structure
Definition: typedefs.h:20
void R_RenderOpaqueWarpBspRRefs(void)
Draw all warped opaque bsp surfaces via warp shader.
Definition: r_bsp.cpp:426
void R_RenderFlareBspRRefs(void)
Definition: r_bsp.cpp:454
void R_EnableGlowMap(const image_t *image)
Definition: r_state.cpp:664
Header file for the render material subsystem.
unsigned int index
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
vec_t vec4_t[4]
Definition: ufotypes.h:40
mBspModel_t bsp
Definition: r_model.h:60