UFO: Alien Invasion
Loading...
Searching...
No Matches
r_model_brush.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 "../../shared/parse.h"
29#include "r_light.h"
30#include "r_grass.h"
31
32/*
33===============================================================================
34BRUSHMODEL LOADING
35===============================================================================
36*/
37
41static const byte* mod_base;
52
56static void R_ModLoadLighting (const lump_t* l)
57{
58 /* map has no lightmap */
59 if (l->filelen == 0)
60 return;
61
62 r_worldmodel->bsp.lightdata = Mem_PoolAllocTypeN(byte, l->filelen, vid_lightPool);
63 r_worldmodel->bsp.lightquant = *(const byte*) (mod_base + l->fileofs);
64 memcpy(r_worldmodel->bsp.lightdata, mod_base + l->fileofs, l->filelen);
65}
66
67static void R_ModLoadVertexes (const lump_t* l)
68{
69 const dBspVertex_t* in = (const dBspVertex_t*) (mod_base + l->fileofs);
70 if (l->filelen % sizeof(*in))
71 Com_Error(ERR_DROP, "R_ModLoadVertexes: funny lump size in %s", r_worldmodel->name);
72
73 int count = l->filelen / sizeof(*in);
75 Com_DPrintf(DEBUG_RENDERER, "...verts: %i\n", count);
76
77 r_worldmodel->bsp.vertexes = out;
78 r_worldmodel->bsp.numvertexes = count;
79
80 for (int i = 0; i < count; i++, in++, out++) {
81 out->position[0] = LittleFloat(in->point[0]);
82 out->position[1] = LittleFloat(in->point[1]);
83 out->position[2] = LittleFloat(in->point[2]);
84 }
85}
86
87static void R_ModLoadNormals (const lump_t* l)
88{
89 const dBspNormal_t* in = (const dBspNormal_t*)(mod_base + l->fileofs);
90 if (l->filelen % sizeof(*in)) {
91 Com_Error(ERR_DROP, "R_LoadNormals: Funny lump size in %s.", r_worldmodel->name);
92 }
93 int count = l->filelen / sizeof(*in);
94
95 if (count != r_worldmodel->bsp.numvertexes) { /* ensure sane normals count */
96 Com_Error(ERR_DROP, "R_LoadNormals: unexpected normals count in %s: (%d != %d).",
97 r_worldmodel->name, count, r_worldmodel->bsp.numvertexes);
98 }
99
100 mBspVertex_t* out = r_worldmodel->bsp.vertexes;
101
102 for (int i = 0; i < count; i++, in++, out++) {
103 out->normal[0] = LittleFloat(in->normal[0]);
104 out->normal[1] = LittleFloat(in->normal[1]);
105 out->normal[2] = LittleFloat(in->normal[2]);
106 }
107}
108
109static inline float R_RadiusFromBounds (const vec3_t mins, const vec3_t maxs)
110{
111 vec3_t corner;
112
113 for (int i = 0; i < 3; i++)
114 corner[i] = fabsf(mins[i]) > fabsf(maxs[i]) ? fabsf(mins[i]) : fabsf(maxs[i]);
115
116 return VectorLength(corner);
117}
118
119
124static void R_ModLoadSubmodels (const lump_t* l)
125{
126 const dBspModel_t* in = (const dBspModel_t*) (mod_base + l->fileofs);
127 if (l->filelen % sizeof(*in))
128 Com_Error(ERR_DROP, "R_ModLoadSubmodels: funny lump size in %s", r_worldmodel->name);
129
130 int count = l->filelen / sizeof(*in);
132 Com_DPrintf(DEBUG_RENDERER, "...submodels: %i\n", count);
133
134 r_worldmodel->bsp.submodels = out;
135 r_worldmodel->bsp.numsubmodels = count;
136
137 for (int i = 0; i < count; i++, in++, out++) {
138 /* spread the mins / maxs by a pixel */
139 for (int j = 0; j < 3; j++) {
140 out->hBox.mins[j] = LittleFloat(in->dbmBox.mins[j]) - 1.0f + (float)shift[j];
141 out->hBox.maxs[j] = LittleFloat(in->dbmBox.maxs[j]) + 1.0f + (float)shift[j];
142 out->origin[j] = LittleFloat(in->origin[j]) + (float)shift[j];
143 }
144 out->radius = R_RadiusFromBounds(out->hBox.mins, out->hBox.maxs);
145 out->headnode = LittleLong(in->headnode);
146 out->firstface = LittleLong(in->firstface);
147 out->numfaces = LittleLong(in->numfaces);
148 }
149}
150
151static void R_ModLoadEdges (const lump_t* l)
152{
153 const dBspEdge_t* in = (const dBspEdge_t*) (mod_base + l->fileofs);
154 if (l->filelen % sizeof(*in))
155 Com_Error(ERR_DROP, "R_ModLoadEdges: funny lump size in %s", r_worldmodel->name);
156
157 int count = l->filelen / sizeof(*in);
159 Com_DPrintf(DEBUG_RENDERER, "...edges: %i\n", count);
160
161 r_worldmodel->bsp.edges = out;
162 r_worldmodel->bsp.numedges = count;
163
164 for (int i = 0; i < count; i++, in++, out++) {
165 out->v[0] = (unsigned short) LittleShort(in->v[0]);
166 out->v[1] = (unsigned short) LittleShort(in->v[1]);
167 }
168}
169
173static void R_ModLoadTexinfo (const char* mapZone, const lump_t* l)
174{
175 const dBspTexinfo_t* in = (const dBspTexinfo_t*) (mod_base + l->fileofs);
176 if (l->filelen % sizeof(*in))
177 Com_Error(ERR_DROP, "R_ModLoadTexinfo: funny lump size in %s", r_worldmodel->name);
178
179 int count = l->filelen / sizeof(*in);
181 Com_DPrintf(DEBUG_RENDERER, "...texinfo: %i\n", count);
182
183 r_worldmodel->bsp.texinfo = out;
184 r_worldmodel->bsp.numtexinfo = count;
185
186 for (int i = 0; i < count; i++, in++, out++) {
187 char name[MAX_QPATH];
188 for (int j = 0; j < 3; j++) {
189 out->uv[j] = LittleFloat(in->vecs[0][j]);
190 out->vv[j] = LittleFloat(in->vecs[1][j]);
191 }
192 out->u_offset = LittleFloat(in->vecs[0][3]);
193 out->v_offset = LittleFloat(in->vecs[1][3]);
194
195 out->flags = LittleLong(in->surfaceFlags);
196
197 /* exchange the textures with the ones that are needed for base assembly */
198 if (Q_strvalid(mapZone) && strstr(in->texture, "tex_terrain/dummy"))
199 Com_sprintf(name, sizeof(name), "textures/tex_terrain/%s", mapZone);
200 else
201 Com_sprintf(name, sizeof(name), "textures/%s", in->texture);
202
204 }
205}
206
210static void R_SetSurfaceExtents (mBspSurface_t* surf, const model_t* mod)
211{
212 vec3_t mins, maxs;
213 vec2_t stmins, stmaxs;
214 int i;
215 const mBspTexInfo_t* tex;
216
217 VectorSet(mins, 999999, 999999, 999999);
218 VectorSet(maxs, -999999, -999999, -999999);
219
220 Vector2Set(stmins, 999999, 999999);
221 Vector2Set(stmaxs, -999999, -999999);
222
223 tex = surf->texinfo;
224
225 for (i = 0; i < surf->numedges; i++) {
226 const int e = mod->bsp.surfedges[surf->firstedge + i];
227 const mBspVertex_t* v;
228 vec3_t position;
229 if (e >= 0)
230 v = &mod->bsp.vertexes[mod->bsp.edges[e].v[0]];
231 else
232 v = &mod->bsp.vertexes[mod->bsp.edges[-e].v[1]];
233
234 VectorCopy(v->position, position);
235
236 for (int j = 0; j < 3; j++) { /* calculate mins, maxs */
237 position[j] += (float)shift[j];
238 if (position[j] > maxs[j])
239 maxs[j] = position[j];
240 if (position[j] < mins[j])
241 mins[j] = position[j];
242 }
243
244 { /* calculate stmins, stmaxs */
245 const float valS = DotProduct(v->position, tex->uv) + tex->u_offset;
246 const float valT = DotProduct(v->position, tex->vv) + tex->v_offset;
247 stmins[0] = std::min(valS, stmins[0]);
248 stmaxs[0] = std::max(valS, stmaxs[0]);
249 stmins[1] = std::min(valT, stmins[1]);
250 stmaxs[1] = std::max(valT, stmaxs[1]);
251 }
252 }
253
254 surf->mbsBox.set(mins, maxs);
255 surf->mbsBox.getCenter(surf->center);
256
257 for (i = 0; i < 2; i++) {
258 const int bmins = floor(stmins[i] / surf->lightmap_scale);
259 const int bmaxs = ceil(stmaxs[i] / surf->lightmap_scale);
260
261 surf->stmins[i] = bmins * surf->lightmap_scale;
262 surf->stmaxs[i] = bmaxs * surf->lightmap_scale;
263
264 surf->stcenter[i] = (surf->stmaxs[i] + surf->stmins[i]) / 2.0;
265 surf->stextents[i] = (bmaxs - bmins) * surf->lightmap_scale;
266 }
267}
268
269static void R_ModLoadSurfaces (bool day, const lump_t* l)
270{
271 const dBspSurface_t* in = (const dBspSurface_t*) (mod_base + l->fileofs);
272 if (l->filelen % sizeof(*in))
273 Com_Error(ERR_DROP, "R_ModLoadSurfaces: funny lump size in %s", r_worldmodel->name);
274 int count = l->filelen / sizeof(*in);
276 Com_DPrintf(DEBUG_RENDERER, "...faces: %i\n", count);
277
278 r_worldmodel->bsp.surfaces = out;
279 r_worldmodel->bsp.numsurfaces = count;
280
281 for (int surfnum = 0; surfnum < count; surfnum++, in++, out++) {
282 uint16_t planenum;
283 int16_t side;
284 int ti;
285 int i;
286
287 out->firstedge = LittleLong(in->firstedge);
288 out->numedges = LittleShort(in->numedges);
289
290 /* resolve plane */
291 planenum = LittleShort(in->planenum);
292 out->plane = r_worldmodel->bsp.planes + planenum;
293
294 /* and sideness */
295 side = LittleShort(in->side);
296 if (side) {
297 out->flags |= MSURF_PLANEBACK;
298 VectorNegate(out->plane->normal, out->normal);
299 } else {
300 VectorCopy(out->plane->normal, out->normal);
301 }
302
303 ti = LittleShort(in->texinfo);
304 if (ti < 0 || ti >= r_worldmodel->bsp.numtexinfo)
305 Com_Error(ERR_DROP, "R_ModLoadSurfaces: bad texinfo number");
306 out->texinfo = r_worldmodel->bsp.texinfo + ti;
307
308 out->lightmap_scale = (1 << r_worldmodel->bsp.lightquant);
309
310 /* and size, texcoords, etc */
312
313 if (!(out->texinfo->flags & SURF_WARP))
314 out->flags |= MSURF_LIGHTMAP;
315
316 /* lastly lighting info */
317 if (day)
319 else
321
322 if (i == -1)
323 out->samples = nullptr;
324 else
325 out->samples = r_worldmodel->bsp.lightdata + i;
326
327 /* create lightmaps */
329
330 out->tile = r_numMapTiles - 1;
331 }
332}
333
338static void R_ModLoadNodes (const lump_t* l)
339{
340 const dBspNode_t* in = (const dBspNode_t*) (mod_base + l->fileofs);
341 if (l->filelen % sizeof(*in))
342 Com_Error(ERR_DROP, "R_ModLoadNodes: funny lump size in %s", r_worldmodel->name);
343
344 int count = l->filelen / sizeof(*in);
346 Com_DPrintf(DEBUG_RENDERER, "...nodes: %i\n", count);
347
348 r_worldmodel->bsp.nodes = out;
349 r_worldmodel->bsp.numnodes = count;
350
351 mBspNode_t* parent = nullptr;
352 for (int i = 0; i < count; i++, in++, out++) {
353 int j;
354 const int p = LittleLong(in->planenum);
355
356 /* skip special pathfinding nodes - they have a negative index */
357 if (p == PLANENUM_LEAF) {
358 /* in case of "special" pathfinding nodes (they don't have a plane)
359 * we have to set this to nullptr */
360 out->plane = nullptr;
362 parent = nullptr;
363 } else {
364 out->plane = r_worldmodel->bsp.planes + p;
365 /* differentiate from leafs */
366 out->contents = CONTENTS_NODE;
367 parent = out;
368 }
369
370 for (j = 0; j < 3; j++) {
371 out->minmaxs.mins[j] = LittleShort(in->mins[j]) + (float)shift[j];
372 out->minmaxs.maxs[j] = LittleShort(in->maxs[j]) + (float)shift[j];
373 }
374
376 out->numsurfaces = LittleShort(in->numfaces);
377
378 for (j = 0; j < 2; j++) {
379 const int p2 = LittleLong(in->children[j]);
380 if (p2 > LEAFNODE) {
381 assert(p2 < r_worldmodel->bsp.numnodes);
382 out->children[j] = r_worldmodel->bsp.nodes + p2;
383 } else {
384 assert((LEAFNODE - p2) < r_worldmodel->bsp.numleafs);
385 out->children[j] = (mBspNode_t*) (r_worldmodel->bsp.leafs + (LEAFNODE - p2));
386 }
387 out->children[j]->parent = parent;
388 }
389 }
390}
391
392static void R_ModLoadLeafs (const lump_t* l)
393{
394 const dBspLeaf_t* in = (const dBspLeaf_t*) (mod_base + l->fileofs);
395 if (l->filelen % sizeof(*in))
396 Com_Error(ERR_DROP, "R_ModLoadLeafs: funny lump size in %s", r_worldmodel->name);
397 const int count = l->filelen / sizeof(*in);
399 Com_DPrintf(DEBUG_RENDERER, "...leafs: %i\n", count);
400
401 r_worldmodel->bsp.leafs = out;
402 r_worldmodel->bsp.numleafs = count;
403
404 for (int i = 0; i < count; i++, in++, out++) {
405 for (int j = 0; j < 3; j++) {
406 out->minmaxs.mins[j] = LittleShort(in->mins[j]) + (float)shift[j];
407 out->minmaxs.maxs[j] = LittleShort(in->maxs[j]) + (float)shift[j];
408 }
409
410 out->contents = LittleLong(in->contentFlags);
411 }
412}
413
414static void R_ModLoadSurfedges (const lump_t* l)
415{
416 const int* in = (const int*) (mod_base + l->fileofs);
417 if (l->filelen % sizeof(*in))
418 Com_Error(ERR_DROP, "R_ModLoadSurfedges: funny lump size in %s", r_worldmodel->name);
419
420 int count = l->filelen / sizeof(*in);
422 Com_Error(ERR_DROP, "R_ModLoadSurfedges: bad surfedges count in %s: %i", r_worldmodel->name, count);
423
424 int* const out = Mem_PoolAllocTypeN(int, count, vid_modelPool);
425 Com_DPrintf(DEBUG_RENDERER, "...surface edges: %i\n", count);
426
427 r_worldmodel->bsp.surfedges = out;
428 r_worldmodel->bsp.numsurfedges = count;
429
430 for (int i = 0; i < count; i++)
431 out[i] = LittleLong(in[i]);
432}
433
437static void R_ModLoadPlanes (const lump_t* l)
438{
439 const dBspPlane_t* in = (const dBspPlane_t*) (mod_base + l->fileofs);
440 if (l->filelen % sizeof(*in))
441 Com_Error(ERR_DROP, "R_ModLoadPlanes: funny lump size in %s", r_worldmodel->name);
442
443 int count = l->filelen / sizeof(*in);
445 Com_DPrintf(DEBUG_RENDERER, "...planes: %i\n", count);
446
447 r_worldmodel->bsp.planes = out;
448 r_worldmodel->bsp.numplanes = count;
449
450 for (int i = 0; i < count; i++, in++, out++) {
451 for (int j = 0; j < 3; j++)
452 out->normal[j] = LittleFloat(in->normal[j]);
453 out->dist = LittleFloat(in->dist);
454 out->type = LittleLong(in->type);
455 }
456}
457
467static void R_ModShiftTile (void)
468{
469 mBspVertex_t* vert;
470 cBspPlane_t* plane;
471 int i, j;
472
473 /* we can't do this instantly, because of rounding errors on extents calculation */
474 /* shift vertexes */
475 for (i = 0, vert = r_worldmodel->bsp.vertexes; i < r_worldmodel->bsp.numvertexes; i++, vert++)
476 for (j = 0; j < 3; j++)
477 vert->position[j] += shift[j];
478
479 /* shift planes */
480 for (i = 0, plane = r_worldmodel->bsp.planes; i < r_worldmodel->bsp.numplanes; i++, plane++)
481 for (j = 0; j < 3; j++)
482 plane->dist += plane->normal[j] * shift[j];
483}
484
494{
495 int i;
496 int vertOfs, texCoordOfs, tangOfs;
497 float* vecShifted;
498 float soff, toff, s, t;
499 float* point, *sdir, *tdir;
500 vec4_t tangent;
501 vec3_t binormal;
502 mBspSurface_t* surf;
503 mBspVertex_t* vert;
504 int vertexCount, indexCount;
505
506 vertOfs = texCoordOfs = tangOfs = 0;
507 vertexCount = indexCount = 0;
508
509 for (i = 0, surf = mod->bsp.surfaces; i < mod->bsp.numsurfaces; i++, surf++) {
510 const int numedges = surf->numedges;
511 vertexCount += numedges;
512 if (numedges > 2) /* no triangles for degenerate polys */
513 indexCount += (numedges - 2) * 3;
514 }
515
516 surf = mod->bsp.surfaces;
517
518 /* allocate the vertex arrays */
519 mod->bsp.texcoords = Mem_PoolAllocTypeN(GLfloat, vertexCount * 2, vid_modelPool);
520 mod->bsp.lmtexcoords = Mem_PoolAllocTypeN(GLfloat, vertexCount * 2, vid_modelPool);
521 mod->bsp.verts = Mem_PoolAllocTypeN(GLfloat, vertexCount * 3, vid_modelPool);
522 mod->bsp.normals = Mem_PoolAllocTypeN(GLfloat, vertexCount * 3, vid_modelPool);
523 mod->bsp.tangents = Mem_PoolAllocTypeN(GLfloat, vertexCount * 4, vid_modelPool);
524 mod->bsp.indexes = Mem_PoolAllocTypeN(glElementIndex_t, indexCount, vid_modelPool); /* Will be filled at the end of map loading, after building surface lists */
525
526 for (i = 0; i < mod->bsp.numsurfaces; i++, surf++) {
527 surf->index = vertOfs / 3;
528 surf->firstTriangle = -1; /* Mark as "no triangles generated yet" */
529
530 for (int j = 0; j < surf->numedges; j++) {
531 const float* normal;
532 const int index = mod->bsp.surfedges[surf->firstedge + j];
533
534 /* vertex */
535 if (index > 0) { /* negative indices to differentiate which end of the edge */
536 const mBspEdge_t* edge = &mod->bsp.edges[index];
537 vert = &mod->bsp.vertexes[edge->v[0]];
538 } else {
539 const mBspEdge_t* edge = &mod->bsp.edges[-index];
540 vert = &mod->bsp.vertexes[edge->v[1]];
541 }
542
543 point = vert->position;
544
545 /* shift it for assembled maps */
546 vecShifted = &mod->bsp.verts[vertOfs];
547 /* origin (func_door, func_rotating) bmodels must not have shifted vertices,
548 * they are translated by their entity origin value */
549 if (surf->isOriginBrushModel)
550 VectorCopy(point, vecShifted);
551 else
552 VectorAdd(point, shift, vecShifted);
553
554 /* texture directional vectors and offsets */
555 sdir = surf->texinfo->uv;
556 soff = surf->texinfo->u_offset;
557
558 tdir = surf->texinfo->vv;
559 toff = surf->texinfo->v_offset;
560
561 /* texture coordinates */
562 s = DotProduct(point, sdir) + soff;
563 s /= surf->texinfo->image->width;
564
565 t = DotProduct(point, tdir) + toff;
566 t /= surf->texinfo->image->height;
567
568 mod->bsp.texcoords[texCoordOfs + 0] = s;
569 mod->bsp.texcoords[texCoordOfs + 1] = t;
570
571 if (surf->flags & MSURF_LIGHTMAP) { /* lightmap coordinates */
572 s = DotProduct(point, sdir) + soff;
573 s -= surf->stmins[0];
574 s += surf->light_s* surf->lightmap_scale;
575 s += surf->lightmap_scale / 2.0;
576 s /= r_lightmaps.size * surf->lightmap_scale;
577
578 t = DotProduct(point, tdir) + toff;
579 t -= surf->stmins[1];
580 t += surf->light_t* surf->lightmap_scale;
581 t += surf->lightmap_scale / 2.0;
582 t /= r_lightmaps.size * surf->lightmap_scale;
583 }
584
585 mod->bsp.lmtexcoords[texCoordOfs + 0] = s;
586 mod->bsp.lmtexcoords[texCoordOfs + 1] = t;
587
588 /* normal vectors */
589 if ((surf->texinfo->flags & SURF_PHONG) && VectorNotEmpty(vert->normal))
590 normal = vert->normal; /* phong shaded */
591 else
592 normal = surf->normal; /* per plane */
593
594 memcpy(&mod->bsp.normals[vertOfs], normal, sizeof(vec3_t));
595
596 /* tangent vector */
597 TangentVectors(normal, sdir, tdir, tangent, binormal);
598 memcpy(&mod->bsp.tangents[tangOfs], tangent, sizeof(vec4_t));
599
600 vertOfs += 3;
601 texCoordOfs += 2;
602 tangOfs += 4;
603 }
604 }
605
606 R_ReallocateStateArrays(vertOfs / 3);
607
608 if (qglBindBuffer) {
609 /* and also the vertex buffer objects */
610 qglGenBuffers(1, &mod->bsp.vertex_buffer);
611 qglBindBuffer(GL_ARRAY_BUFFER, mod->bsp.vertex_buffer);
612 qglBufferData(GL_ARRAY_BUFFER, vertOfs * sizeof(GLfloat), mod->bsp.verts, GL_STATIC_DRAW);
613
614 qglGenBuffers(1, &mod->bsp.texcoord_buffer);
615 qglBindBuffer(GL_ARRAY_BUFFER, mod->bsp.texcoord_buffer);
616 qglBufferData(GL_ARRAY_BUFFER, texCoordOfs * sizeof(GLfloat), mod->bsp.texcoords, GL_STATIC_DRAW);
617
618 qglGenBuffers(1, &mod->bsp.lmtexcoord_buffer);
619 qglBindBuffer(GL_ARRAY_BUFFER, mod->bsp.lmtexcoord_buffer);
620 qglBufferData(GL_ARRAY_BUFFER, texCoordOfs * sizeof(GLfloat), mod->bsp.lmtexcoords, GL_STATIC_DRAW);
621
622 qglGenBuffers(1, &mod->bsp.normal_buffer);
623 qglBindBuffer(GL_ARRAY_BUFFER, mod->bsp.normal_buffer);
624 qglBufferData(GL_ARRAY_BUFFER, vertOfs * sizeof(GLfloat), mod->bsp.normals, GL_STATIC_DRAW);
625
626 qglGenBuffers(1, &mod->bsp.tangent_buffer);
627 qglBindBuffer(GL_ARRAY_BUFFER, mod->bsp.tangent_buffer);
628 qglBufferData(GL_ARRAY_BUFFER, tangOfs * sizeof(GLfloat), mod->bsp.tangents, GL_STATIC_DRAW);
629
630 qglBindBuffer(GL_ARRAY_BUFFER, 0);
631 }
632}
633
634static void R_SortSurfacesArrays_ (mBspSurfaces_t* surfs, mBspSurfaces_t** r_sorted_surfaces)
635{
636 int i;
637
638 for (i = 0; i < surfs->count; i++) {
639 const int texindex = R_GetImageIndex(surfs->surfaces[i]->texinfo->image);
640 if (texindex < 0 || texindex >= MAX_GL_TEXTURES)
641 Com_Error(ERR_FATAL, "R_SortSurfacesArrays: bogus image pointer");
642 R_AddSurfaceToArray(r_sorted_surfaces[texindex], surfs->surfaces[i]);
643 }
644
645 surfs->count = 0;
646
647 for (i = 0; i < r_numImages; i++) {
648 mBspSurfaces_t* sorted = r_sorted_surfaces[i];
649 if (sorted && sorted->count) {
650 for (int j = 0; j < sorted->count; j++)
651 R_AddSurfaceToArray(surfs, sorted->surfaces[j]);
652
653 sorted->count = 0;
654 }
655 }
656}
657
662static void R_SortSurfacesArrays (const model_t* mod)
663{
664 const mBspSurface_t* surf, *s;
665 int i, ns;
667
668 /* resolve the start surface and total surface count */
669 s = &mod->bsp.surfaces[mod->bsp.firstmodelsurface];
670 ns = mod->bsp.nummodelsurfaces;
671
672 /* allocate the per-texture surfaces arrays and determine counts */
673 for (i = 0, surf = s; i < ns; i++, surf++) {
674 int index = R_GetImageIndex(surf->texinfo->image);
675 mBspSurfaces_t* surfs = r_sorted_surfaces[index];
676 if (!surfs) { /* allocate it */
678 r_sorted_surfaces[index] = surfs;
679 }
680
681 surfs->count++;
682 }
683
684 /* allocate the surfaces pointers based on counts */
685 for (i = 0; i < r_numImages; i++) {
686 mBspSurfaces_t* surfs = r_sorted_surfaces[i];
687 if (surfs) {
689 surfs->count = 0;
690 }
691 }
692
693 /* sort the model's surfaces arrays into the per-texture arrays */
694 for (i = 0; i < NUM_SURFACES_ARRAYS; i++) {
695 if (mod->bsp.sorted_surfaces[i]->count) {
696 R_SortSurfacesArrays_(mod->bsp.sorted_surfaces[i], r_sorted_surfaces);
697 Com_DPrintf(DEBUG_RENDERER, "%i: #%i surfaces\n", i, mod->bsp.sorted_surfaces[i]->count);
698 }
699 }
700
701 /* free the per-texture surfaces arrays */
702 for (i = 0; i < r_numImages; i++) {
703 mBspSurfaces_t* surfs = r_sorted_surfaces[i];
704 if (surfs) {
705 Mem_Free(surfs->surfaces);
706 Mem_Free(surfs);
707 }
708 }
709
710 Mem_Free(r_sorted_surfaces);
711}
712
714{
715 mBspSurface_t* surf, *s;
716 int i, ns;
717
718 /* allocate the surfaces array structures */
720 for (i = 0; i < NUM_SURFACES_ARRAYS; i++)
722
723 /* resolve the start surface and total surface count */
724 s = &mod->bsp.surfaces[mod->bsp.firstmodelsurface];
725 ns = mod->bsp.nummodelsurfaces;
726
727 /* determine the maximum counts for each rendered type in order to
728 * allocate only what is necessary for the specified model */
729 for (i = 0, surf = s; i < ns; i++, surf++) {
730 const mBspTexInfo_t* texinfo = surf->texinfo;
731 const material_t* material = &texinfo->image->material;
732 if (texinfo->flags & (SURF_BLEND33 | SURF_BLEND66)) {
733 if (texinfo->flags & SURF_WARP)
734 mod->bsp.blend_warp_surfaces->count++;
735 else
736 mod->bsp.blend_surfaces->count++;
737 } else {
738 if (texinfo->flags & SURF_WARP)
739 mod->bsp.opaque_warp_surfaces->count++;
740 else if (texinfo->flags & SURF_ALPHATEST)
741 mod->bsp.alpha_test_surfaces->count++;
742 else
743 mod->bsp.opaque_surfaces->count++;
744 }
745
746 if (material->flags & STAGE_RENDER)
747 mod->bsp.material_surfaces->count++;
748
749 if (material->flags & STAGE_FLARE)
750 mod->bsp.flare_surfaces->count++;
751 }
752
753 /* allocate the surfaces pointers based on the counts */
754 for (i = 0; i < NUM_SURFACES_ARRAYS; i++) {
755 mBspSurfaces_t* surfaces = mod->bsp.sorted_surfaces[i];
756 if (surfaces->count) {
758 surfaces->count = 0;
759 }
760 }
761
762 /* iterate the surfaces again, populating the allocated arrays based
763 * on primary render type */
764 for (i = 0, surf = s; i < ns; i++, surf++) {
765 const mBspTexInfo_t* texinfo = surf->texinfo;
766 const material_t* material = &texinfo->image->material;
767 if (texinfo->flags & (SURF_BLEND33 | SURF_BLEND66)) {
768 if (texinfo->flags & SURF_WARP)
769 R_AddSurfaceToArray(mod->bsp.blend_warp_surfaces, surf);
770 else
771 R_AddSurfaceToArray(mod->bsp.blend_surfaces, surf);
772 } else {
773 if (texinfo->flags & SURF_WARP)
774 R_AddSurfaceToArray(mod->bsp.opaque_warp_surfaces, surf);
775 else if (texinfo->flags & SURF_ALPHATEST)
776 R_AddSurfaceToArray(mod->bsp.alpha_test_surfaces, surf);
777 else
778 R_AddSurfaceToArray(mod->bsp.opaque_surfaces, surf);
779 }
780
781 if (material->flags & STAGE_RENDER)
782 R_AddSurfaceToArray(mod->bsp.material_surfaces, surf);
783
784 if (material->flags & STAGE_FLARE)
785 R_AddSurfaceToArray(mod->bsp.flare_surfaces, surf);
786 }
787
788 /* now sort them by texture */
790}
791
792static void R_LoadSurfacesArrays (void)
793{
794 int i;
795
796 for (i = 0; i < r_numMapTiles; i++)
798
799 for (i = 0; i < r_numModelsInline; i++)
801}
802
804
806{
807 mBspModel_t* bsp = &mod->bsp; /* can be aliased with baseTile, so beware */
808 mBspModel_t* baseTile = &r_mapTiles[bsp->maptile]->bsp;
809 int tris = 0;
810
811 Com_DPrintf(DEBUG_RENDERER, "Soup: model %i/%i\n", bsp->maptile, bsp->firstmodelsurface);
812
813 for (int i = 0; i < NUM_SURFACES_ARRAYS; i++) {
814 mBspSurfaces_t* surfaces = mod->bsp.sorted_surfaces[i];
815
816 for (int j = 0; j < surfaces->count; j++) {
817 mBspSurface_t* surf = surfaces->surfaces[j];
818
819 if (surf->firstTriangle >= 0)
820 continue; /* Already allocated */
821
822 surf->firstTriangle = baseTile->numIndexes / 3;
823
824 if (surf->numedges <= 2) {
825 /* degenerate poly, no triangles */
826 surf->numTriangles = 0;
827 } else {
828 /* Build triangle list for this surface */
829 int numTris = surf->numedges - 2;
830 surf->numTriangles = numTris;
831 for (int k = 0; k < numTris; k++) {
832 /* k'th element of triangle fan */
833 baseTile->indexes[baseTile->numIndexes++] = surf->index;
834 baseTile->indexes[baseTile->numIndexes++] = surf->index + k + 1;
835 baseTile->indexes[baseTile->numIndexes++] = surf->index + k + 2;
836 tris++;
837 }
838 }
839 }
840 }
841
842 totalBspTriangles += tris;
843 Com_DPrintf(DEBUG_RENDERER, " surfs: %i tris: %i\n", bsp->nummodelsurfaces, tris);
844}
845
847{
848 int i;
849
851
852 for (i = 0; i < r_numMapTiles; i++)
854
855 for (i = 0; i < r_numModelsInline; i++)
857
858 Com_Printf("World model: %i triangles\n", totalBspTriangles);
859
860 /* Create buffer objects for indexes */
861 if (qglBindBuffer) {
862 for (i = 0; i < r_numMapTiles; i++) {
863 mBspModel_t* bsp = &r_mapTiles[i]->bsp;
864
865 qglGenBuffers(1, &bsp->index_buffer);
866 qglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bsp->index_buffer);
867 qglBufferData(GL_ELEMENT_ARRAY_BUFFER, bsp->numIndexes * sizeof(glElementIndex_t), bsp->indexes, GL_STATIC_DRAW);
868 }
869
870 qglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
871 }
872}
873
877static void R_SetModel (mBspNode_t* node, model_t* mod)
878{
879 node->model = mod;
880
881 if (node->contents > CONTENTS_NODE)
882 return;
883
884 R_SetModel(node->children[0], mod);
885 R_SetModel(node->children[1], mod);
886}
887
888
892static void R_RecursiveSetModel (mBspNode_t* node, model_t* mod)
893{
894 /* skip special pathfinding nodes */
895 if (node->contents == CONTENTS_PATHFINDING_NODE) {
896 R_RecursiveSetModel(node->children[0], mod);
897 R_RecursiveSetModel(node->children[1], mod);
898 } else {
899 R_SetModel(node, mod);
900 }
901}
902
906static void R_SetupSubmodels (void)
907{
908 int i, j;
909
910 /* set up the submodels, the first 255 submodels are the models of the
911 * different levels, don't care about them */
912 for (i = NUM_REGULAR_MODELS; i < r_worldmodel->bsp.numsubmodels; i++) {
914 const mBspHeader_t* sub = &r_worldmodel->bsp.submodels[i];
915
916 /* copy most info from world */
917 *mod = *r_worldmodel;
918 mod->type = mod_bsp_submodel;
919
920 Com_sprintf(mod->name, sizeof(mod->name), "*%d", i);
921
922 /* copy the rest from the submodel */
923 mod->modBox.set(sub->hBox);
924 mod->radius = sub->radius;
925
926 mod->bsp.firstnode = sub->headnode;
927 mod->bsp.nodes = &r_worldmodel->bsp.nodes[mod->bsp.firstnode];
928 mod->bsp.maptile = r_numMapTiles - 1;
929 if (mod->bsp.firstnode >= r_worldmodel->bsp.numnodes)
930 Com_Error(ERR_DROP, "R_SetupSubmodels: Inline model %i has bad firstnode", i);
931
932 R_RecursiveSetModel(mod->bsp.nodes, mod);
933
934 mod->bsp.firstmodelsurface = sub->firstface;
935 mod->bsp.nummodelsurfaces = sub->numfaces;
936
937 /* submodel vertices of the surfaces must not be shifted in case of rmas */
938 for (j = mod->bsp.firstmodelsurface; j < mod->bsp.firstmodelsurface + mod->bsp.nummodelsurfaces; j++) {
940 }
941
942 /*mod->bsp.numleafs = sub->visleafs;*/
944 }
945}
946
951static void R_SetupWorldModel (void)
952{
953 int surfCount = r_worldmodel->bsp.numsurfaces;
954
955#ifdef DEBUG
956 /* validate surface allocation by submodels by checking the surface array range they are using */
957 /* start with inverted range to simplify code */
958 int first = surfCount, last = -1; /* @note range is [,) */
959 /* first NUM_REGULAR_MODELS submodels are the models of the different levels, don't care about them */
960 for (int i = NUM_REGULAR_MODELS; i < r_worldmodel->bsp.numsubmodels; i++) {
961 const mBspHeader_t* sub = &r_worldmodel->bsp.submodels[i];
962 int firstFace = sub->firstface;
963 int lastFace = firstFace + sub->numfaces;
964
965 if (lastFace <= firstFace)
966 continue; /* empty submodel, ignore it */
967
968 if (last >= 0 && (firstFace > last || lastFace < first))
969 Com_Printf("Warning: submodels may not combine to contigous range in the surface array, some world geometry could be missing as a result (submodel %i)\n", i);
970
971 if (firstFace < first)
972 first = firstFace;
973
974 if (lastFace > last)
975 last = lastFace;
976
977 Com_DPrintf(DEBUG_RENDERER, "Submodel %i, range %i..%i\n", i, firstFace, lastFace - 1);
978 }
979 surfCount = first;
980
981 if (last >= 0 && last != r_worldmodel->bsp.numsurfaces)
982 Com_Printf("Warning: %i surfaces are lost, some world geometry could be missing as a result\n", r_worldmodel->bsp.numsurfaces - last);
983#else
984 /* take a shortcut: assume that first submodel surfaces begin exactly after world model ones */
985 if (NUM_REGULAR_MODELS < r_worldmodel->bsp.numsubmodels)
986 surfCount = r_worldmodel->bsp.submodels[NUM_REGULAR_MODELS].firstface;
987#endif
988 Com_DPrintf(DEBUG_RENDERER, "World model, range 0..%i\n", surfCount - 1);
989
990 r_worldmodel->bsp.firstmodelsurface = 0;
991 r_worldmodel->bsp.nummodelsurfaces = surfCount;
992}
993
1005static void R_ModAddMapTile (const char* name, const char* mapZone, bool day, int sX, int sY, int sZ)
1006{
1007 int i;
1008 byte* buffer;
1009 dBspHeader_t* header;
1010 const int lightingLump = day ? LUMP_LIGHTING_DAY : LUMP_LIGHTING_NIGHT;
1011
1012 if (r_numMapTiles < 0 || r_numMapTiles >= MAX_MAPTILES)
1013 Com_Error(ERR_DROP, "R_ModAddMapTile: Too many map tiles");
1014
1015 /* alloc model and tile */
1019 Com_sprintf(r_worldmodel->name, sizeof(r_worldmodel->name), "maps/%s.bsp", name);
1020
1021 /* load the file */
1022 FS_LoadFile(r_worldmodel->name, &buffer);
1023 if (!buffer)
1024 Com_Error(ERR_DROP, "R_ModAddMapTile: %s not found", r_worldmodel->name);
1025
1026 /* init */
1027 r_worldmodel->type = mod_bsp;
1028 r_worldmodel->bsp.maptile = r_numMapTiles - 1;
1029
1030 /* prepare shifting */
1031 VectorSet(shift, sX * UNIT_SIZE, sY * UNIT_SIZE, sZ * UNIT_SIZE);
1032
1033 /* test version */
1034 header = (dBspHeader_t*) buffer;
1035 i = LittleLong(header->version);
1036 if (i != BSPVERSION)
1037 Com_Error(ERR_DROP, "R_ModAddMapTile: %s has wrong version number (%i should be %i)", r_worldmodel->name, i, BSPVERSION);
1038
1039 /* swap all the lumps */
1040 mod_base = (byte*) header;
1041
1042 BSP_SwapHeader(header, r_worldmodel->name);
1043
1044 /* load into heap */
1047 R_ModLoadEdges(&header->lumps[LUMP_EDGES]);
1049 R_ModLoadLighting(&header->lumps[lightingLump]);
1051 R_ModLoadTexinfo(mapZone, &header->lumps[LUMP_TEXINFO]);
1052 R_ModLoadSurfaces(day, &header->lumps[LUMP_FACES]);
1053 R_ModLoadLeafs(&header->lumps[LUMP_LEAFS]);
1054 R_ModLoadNodes(&header->lumps[LUMP_NODES]);
1056
1059
1061
1062 /* in case of random map assembly shift some vectors */
1063 if (VectorNotEmpty(shift))
1065
1066 FS_FreeFile(buffer);
1067}
1068
1077
1098void R_ModBeginLoading (const char* tiles, bool day, const char* pos, const char* mapName, const char* mapZone)
1099{
1100 char name[MAX_VAR];
1101 char base[MAX_QPATH];
1102
1103 assert(mapName);
1104
1105 /* clear any lights leftover in the active list from previous maps */
1107 /* remove all leftover grass */
1108 R_ClearGrass();
1109
1110 /* init */
1113 r_numMapTiles = 0;
1114
1115 /* load tiles */
1116 while (tiles) {
1117 /* get tile name */
1118 const char* token = Com_Parse(&tiles);
1119 if (!tiles) {
1120 /* finish */
1122 return;
1123 }
1124
1125 /* get base path */
1126 if (token[0] == '-') {
1127 Q_strncpyz(base, token + 1, sizeof(base));
1128 continue;
1129 }
1130
1131 /* get tile name */
1132 if (token[0] == '+')
1133 Com_sprintf(name, sizeof(name), "%s%s", base, token + 1);
1134 else
1135 Q_strncpyz(name, token, sizeof(name));
1136
1137 if (pos && pos[0]) {
1138 ipos3_t sh;
1139 /* get grid position and add a tile */
1140 for (int i = 0; i < 3; i++) {
1141 token = Com_Parse(&pos);
1142 if (!pos)
1143 Com_Error(ERR_DROP, "R_ModBeginLoading: invalid positions\n");
1144 sh[i] = atoi(token);
1145 }
1146 if (sh[0] <= -(PATHFINDING_WIDTH / 2) || sh[0] >= PATHFINDING_WIDTH / 2)
1147 Com_Error(ERR_DROP, "R_ModBeginLoading: invalid x position given: %i\n", sh[0]);
1148 if (sh[1] <= -(PATHFINDING_WIDTH / 2) || sh[1] >= PATHFINDING_WIDTH / 2)
1149 Com_Error(ERR_DROP, "R_ModBeginLoading: invalid y position given: %i\n", sh[1]);
1150 if (sh[2] >= PATHFINDING_HEIGHT)
1151 Com_Error(ERR_DROP, "R_ModBeginLoading: invalid z position given: %i\n", sh[2]);
1152 R_ModAddMapTile(name, mapZone, day, sh[0], sh[1], sh[2]);
1153 } else {
1154 /* load only a single tile, if no positions are specified */
1155 R_ModAddMapTile(name, mapZone, day, 0, 0, 0);
1157 return;
1158 }
1159 }
1160
1161 Com_Error(ERR_DROP, "R_ModBeginLoading: invalid tile names\n");
1162}
1163
1168{
1169 for (int i = 0; i < r_numMapTiles; i++) {
1170 model_t* mod = r_mapTiles[i];
1171 const size_t size = lengthof(mod->bsp.sorted_surfaces);
1172 for (int j = 0; j < size; j++)
1173 if (mod->bsp.sorted_surfaces[j]) {
1174 Mem_Free(mod->bsp.sorted_surfaces[j]);
1175 mod->bsp.sorted_surfaces[j] = nullptr;
1176 }
1177 }
1179}
#define LittleLong(X)
Definition byte.h:37
#define LittleShort(X)
Definition byte.h:35
#define LittleFloat(X)
Definition byte.h:57
memPool_t * vid_modelPool
Definition cl_main.cpp:90
memPool_t * vid_lightPool
Definition cl_main.cpp:89
vec3_t maxs
Definition aabb.h:258
vec3_t mins
Definition aabb.h:257
void getCenter(vec3_t center) const
Calculates the center of the bounding box.
Definition aabb.h:155
void set(const AABB &other)
Copies the values from the given aabb.
Definition aabb.h:60
void Com_DPrintf(int level, const char *fmt,...)
A Com_Printf that only shows up if the "developer" cvar is set.
Definition common.cpp:440
void Com_Error(int code, const char *fmt,...)
Definition common.cpp:459
void Com_Printf(const char *const fmt,...)
Definition common.cpp:428
#define ERR_DROP
Definition common.h:211
#define ERR_FATAL
Definition common.h:210
#define LUMP_EDGES
Definition defines.h:178
#define LIGHTMAP_NIGHT
Definition defines.h:363
#define LUMP_SURFEDGES
Definition defines.h:179
#define SURF_ALPHATEST
Definition defines.h:268
#define LUMP_LEAFS
Definition defines.h:176
#define LUMP_VERTEXES
Definition defines.h:169
#define SURF_ORIGIN
Definition defines.h:266
#define LUMP_LIGHTING_NIGHT
Definition defines.h:174
#define SURF_BLEND66
Definition defines.h:258
#define SURF_PHONG
Definition defines.h:263
#define MAX_MAP_SURFEDGES
Definition defines.h:147
#define LEAFNODE
Definition defines.h:44
#define PATHFINDING_WIDTH
absolute max
Definition defines.h:292
#define LUMP_PLANES
Definition defines.h:168
#define NUM_REGULAR_MODELS
Definition defines.h:354
#define UNIT_SIZE
Definition defines.h:121
#define LUMP_TEXINFO
Definition defines.h:172
#define LUMP_LIGHTING_DAY
Definition defines.h:175
#define LUMP_MODELS
Definition defines.h:180
#define DEBUG_RENDERER
Definition defines.h:62
#define PLANENUM_LEAF
Definition defines.h:45
#define SURF_WARP
Definition defines.h:256
#define LUMP_NORMALS
Definition defines.h:183
#define SURF_BLEND33
Definition defines.h:257
#define LUMP_FACES
Definition defines.h:173
#define PATHFINDING_HEIGHT
15 max, adjusting above 8 will require a rewrite to the DV code
Definition defines.h:294
#define LUMP_NODES
Definition defines.h:171
#define LIGHTMAP_DAY
Definition defines.h:364
int FS_LoadFile(const char *path, byte **buffer)
Filenames are relative to the quake search path.
Definition files.cpp:384
void FS_FreeFile(void *buffer)
Definition files.cpp:411
#define MAX_QPATH
Definition filesys.h:40
voidpf void uLong size
Definition ioapi.h:42
vec_t VectorLength(const vec3_t v)
Calculate the length of a vector.
Definition mathlib.cpp:434
void TangentVectors(const vec3_t normal, const vec3_t sdir, const vec3_t tdir, vec4_t tangent, vec3_t binormal)
Projects the normalized directional vectors on to the normal's plane. The fourth component of the res...
Definition mathlib.cpp:1057
#define Mem_PoolAllocTypeN(type, n, pool)
Definition mem.h:42
#define Mem_Free(ptr)
Definition mem.h:35
#define Mem_AllocTypeN(type, n)
Definition mem.h:38
#define Mem_PoolAllocType(type, pool)
Definition mem.h:43
const char * Com_Parse(const char *data_p[], char *target, size_t size, bool replaceWhitespaces)
Parse a token out of a string.
Definition parse.cpp:107
Shared parsing functions.
#define BSPVERSION
Definition qfiles.h:253
#define BSP_SwapHeader(header, name)
Definition qfiles.h:269
QGL_EXTERN GLuint count
Definition r_gl.h:99
QGL_EXTERN int GLboolean GLfloat * v
Definition r_gl.h:120
QGL_EXTERN GLuint index
Definition r_gl.h:110
QGL_EXTERN GLint i
Definition r_gl.h:113
QGL_EXTERN GLuint GLsizei GLsizei GLint GLenum GLchar * name
Definition r_gl.h:110
GLuint glElementIndex_t
Definition r_gl.h:57
void R_GenerateGrass()
Definition r_grass.cpp:228
void R_ClearGrass()
Definition r_grass.cpp:56
Pseudoinstanced grass generation and rendering.
image_t * R_FindImage(const char *pname, imagetype_t type)
Finds or loads the given image.
Definition r_image.cpp:603
int r_numImages
Definition r_image.cpp:41
int R_GetImageIndex(image_t *imagePtr)
Returns an index of the image pointer in the r_images linked list, as if r_images would be a plain co...
Definition r_image.cpp:702
#define MAX_GL_TEXTURES
Definition r_image.h:76
@ it_world
Definition r_image.h:54
void R_ClearStaticLights(void)
Remove all static light data.
Definition r_light.cpp:300
void R_BeginBuildingLightmaps(void)
lightmaps_t r_lightmaps
void R_CreateSurfaceLightmap(mBspSurface_t *surf)
void R_EndBuildingLightmaps(void)
lightmap definitions
local graphics definitions
void R_LoadMaterials(const char *map)
Load material definitions for each map that has one.
#define STAGE_FLARE
Definition r_material.h:48
#define STAGE_RENDER
Definition r_material.h:55
int r_numMapTiles
Definition r_model.cpp:33
int r_numModelsInline
Definition r_model.cpp:37
model_t r_modelsInline[MAX_MOD_KNOWN]
Definition r_model.cpp:36
model_t * r_mapTiles[MAX_MAPTILES]
The world model(s).
Definition r_model.cpp:32
model_t * R_AllocModelSlot(void)
Definition r_model.cpp:100
@ mod_bsp
Definition r_model.h:41
@ mod_bsp_submodel
Definition r_model.h:41
static void R_SortSurfacesArrays(const model_t *mod)
Reorders all surfaces arrays for the specified model, grouping the surface pointers by texture....
static void R_SetSurfaceExtents(mBspSurface_t *surf, const model_t *mod)
Fills in s->stmins[] and s->stmaxs[].
static void R_SetupWorldModel(void)
Sets up surface range for the world model.
static void R_ModLoadSurfaces(bool day, const lump_t *l)
static void R_SetupSubmodels(void)
Sets up bmodels (brush models) like doors and breakable objects.
static void R_LoadSurfacesArrays_(model_t *mod)
static void R_ModLoadPlanes(const lump_t *l)
static void R_LoadBspVertexArrays(model_t *mod)
Puts the map data into buffers.
static void R_LoadSurfacesArrays(void)
static const byte * mod_base
The model base pointer - bases for the lump offsets.
static model_t * r_worldmodel
The currently loaded world model for the actual tile.
static int totalBspTriangles
static void R_SetModel(mBspNode_t *node, model_t *mod)
static float R_RadiusFromBounds(const vec3_t mins, const vec3_t maxs)
static void R_RecursiveSetModel(mBspNode_t *node, model_t *mod)
static void R_ModAddMapTile(const char *name, const char *mapZone, bool day, int sX, int sY, int sZ)
static void R_ModLoadEdges(const lump_t *l)
static void R_ModLoadLeafs(const lump_t *l)
void R_ModReloadSurfacesArrays(void)
static void R_GenerateTriangleSoup_(model_t *mod)
static void R_ModShiftTile(void)
Shift the verts for map assemblies.
void R_ModBeginLoading(const char *tiles, bool day, const char *pos, const char *mapName, const char *mapZone)
Specifies the model that will be used as the world.
static void R_GenerateTriangleSoup()
static void R_ModLoadNodes(const lump_t *l)
static void R_ModLoadNormals(const lump_t *l)
static void R_ModLoadSubmodels(const lump_t *l)
Loads brush entities like func_door and func_breakable.
static void R_SortSurfacesArrays_(mBspSurfaces_t *surfs, mBspSurfaces_t **r_sorted_surfaces)
static void R_ModLoadTexinfo(const char *mapZone, const lump_t *l)
static void R_ModEndLoading(const char *mapName)
static ipos3_t shift
The shift array is used for random map assemblies (RMA) to shift the mins/maxs and stuff like that.
static void R_ModLoadSurfedges(const lump_t *l)
static void R_ModLoadVertexes(const lump_t *l)
static void R_ModLoadLighting(const lump_t *l)
Load the lightmap data.
#define R_AddSurfaceToArray(array, surf)
@ NUM_SURFACES_ARRAYS
#define MSURF_LIGHTMAP
#define MSURF_PLANEBACK
#define CONTENTS_NODE
#define CONTENTS_PATHFINDING_NODE
void R_ReallocateStateArrays(int size)
Reallocate arrays of GL primitives if needed.
Definition r_state.cpp:1029
#define Q_strvalid(string)
Definition shared.h:141
#define OBJZERO(obj)
Definition shared.h:178
#define MAX_VAR
Definition shared.h:36
#define lengthof(x)
Definition shared.h:105
void Q_strncpyz(char *dest, const char *src, size_t destsize)
Safe strncpy that ensures a trailing zero.
Definition shared.cpp:457
bool Com_sprintf(char *dest, size_t size, const char *fmt,...)
copies formatted string with buffer-size checking
Definition shared.cpp:494
plane_t structure
Definition typedefs.h:20
byte type
Definition typedefs.h:23
float dist
Definition typedefs.h:22
vec3_t normal
Definition typedefs.h:21
unsigned short v[2]
Definition typedefs.h:400
The BSP header definition with the data block directory.
Definition qfiles.h:262
uint32_t version
Definition qfiles.h:264
lump_t lumps[HEADER_LUMPS]
Definition qfiles.h:265
convex region of space in the BSP tree
Definition typedefs.h:416
short mins[3]
Definition typedefs.h:421
uint32_t contentFlags
Definition typedefs.h:417
short maxs[3]
Definition typedefs.h:422
int32_t headnode
Definition typedefs.h:357
int firstface
Definition typedefs.h:358
vec3_t origin
Definition typedefs.h:356
AABB dbmBox
Definition typedefs.h:355
int32_t planenum
Definition typedefs.h:379
short maxs[3]
Definition typedefs.h:382
unsigned short numfaces
Definition typedefs.h:384
unsigned short firstface
Definition typedefs.h:383
short mins[3]
Definition typedefs.h:381
int32_t children[2]
Definition typedefs.h:380
vec3_t normal
Definition typedefs.h:366
vec3_t normal
Definition typedefs.h:373
float dist
Definition typedefs.h:374
int lightofs[LIGHTMAP_MAX]
Definition typedefs.h:412
short texinfo
Definition typedefs.h:409
short numedges
Definition typedefs.h:408
uint16_t planenum
Definition typedefs.h:404
char texture[32]
Definition typedefs.h:392
uint32_t surfaceFlags
Definition typedefs.h:390
float vecs[2][4]
Definition typedefs.h:389
float point[3]
Definition typedefs.h:362
int height
Definition r_image.h:64
int width
Definition r_image.h:64
material_t material
Definition r_image.h:68
Directory of the different data blocks.
Definition qfiles.h:256
uint32_t filelen
Definition qfiles.h:258
uint32_t fileofs
Definition qfiles.h:257
unsigned short v[2]
brush model
glElementIndex_t * indexes
unsigned int tangent_buffer
unsigned int normal_buffer
mBspVertex_t * vertexes
mBspSurfaces_t * sorted_surfaces[NUM_SURFACES_ARRAYS]
float * normals
unsigned int index_buffer
unsigned int vertex_buffer
unsigned int texcoord_buffer
unsigned int lmtexcoord_buffer
float * lmtexcoords
float * texcoords
mBspSurface_t * surfaces
float * tangents
mBspEdge_t * edges
mBspNode_t * nodes
unsigned short firstsurface
struct model_s * model
cBspPlane_t * plane
struct mBspNode_s * children[2]
unsigned short numsurfaces
short stmaxs[2]
mBspTexInfo_t * texinfo
unsigned int index
short stmins[2]
unsigned int numTriangles
cBspPlane_t * plane
surfaces are assigned to arrays based on their primary rendering type and then sorted by world textur...
mBspSurface_t ** surfaces
image_t * image
unsigned flags
Definition r_material.h:157
modtype_t type
Definition r_model.h:46
float radius
Definition r_model.h:52
AABB modBox
Definition r_model.h:51
mBspModel_t bsp
Definition r_model.h:60
char name[MAX_QPATH]
Definition r_model.h:44
static const char * mapName
vec_t vec3_t[3]
Definition ufotypes.h:39
ipos_t ipos3_t[3]
Definition ufotypes.h:70
vec_t vec4_t[4]
Definition ufotypes.h:40
vec_t vec2_t[2]
Definition ufotypes.h:38
#define VectorNegate(src, dest)
Definition vector.h:58
#define VectorNotEmpty(a)
Definition vector.h:72
#define VectorCopy(src, dest)
Definition vector.h:51
#define Vector2Set(v, x, y)
Definition vector.h:61
#define VectorAdd(a, b, dest)
Definition vector.h:47
#define DotProduct(x, y)
Returns the distance between two 3-dimensional vectors.
Definition vector.h:44
#define VectorSet(v, x, y, z)
Definition vector.h:59