1 /*
2 glsl_bsp.c
3
4 GLSL bsps
5
6 Copyright (C) 2012 Bill Currie <bill@taniwha.org>
7
8 Author: Bill Currie <bill@taniwha.org>
9 Date: 2012/1/7
10
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License
13 as published by the Free Software Foundation; either version 2
14 of the License, or (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19
20 See the GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to:
24
25 Free Software Foundation, Inc.
26 59 Temple Place - Suite 330
27 Boston, MA 02111-1307, USA
28
29 */
30 #ifdef HAVE_CONFIG_H
31 # include "config.h"
32 #endif
33
34 #define NH_DEFINE
35 #include "namehack.h"
36
37 #ifdef HAVE_STRING_H
38 # include <string.h>
39 #endif
40 #ifdef HAVE_STRINGS_H
41 # include <strings.h>
42 #endif
43 #include <stdlib.h>
44
45 #include "qfalloca.h"
46
47 #include "QF/cvar.h"
48 #include "QF/dstring.h"
49 #include "QF/image.h"
50 #include "QF/render.h"
51 #include "QF/sys.h"
52 #include "QF/va.h"
53 #include "QF/vrect.h"
54
55 #include "QF/GLSL/defines.h"
56 #include "QF/GLSL/funcs.h"
57 #include "QF/GLSL/qf_bsp.h"
58 #include "QF/GLSL/qf_lightmap.h"
59 #include "QF/GLSL/qf_textures.h"
60 #include "QF/GLSL/qf_vid.h"
61
62 #include "r_internal.h"
63
64 typedef struct {
65 GLushort count;
66 GLushort indices[1];
67 } glslpoly_t;
68
69 #define ALLOC_CHUNK 64
70
71 static instsurf_t *waterchain = NULL;
72 static instsurf_t **waterchain_tail = &waterchain;
73 static instsurf_t *sky_chain;
74 static instsurf_t **sky_chain_tail = &sky_chain;
75
76 static texture_t **r_texture_chains;
77 static int r_num_texture_chains;
78 static int max_texture_chains;
79
80 // for world and non-instance models
81 static instsurf_t *static_instsurfs;
82 static instsurf_t **static_instsurfs_tail = &static_instsurfs;
83 static instsurf_t *free_static_instsurfs;
84
85 // for instance models
86 static elechain_t *elechains;
87 static elechain_t **elechains_tail = &elechains;
88 static elechain_t *free_elechains;
89 static elements_t *elementss;
90 static elements_t **elementss_tail = &elementss;
91 static elements_t *free_elementss;
92 static instsurf_t *instsurfs;
93 static instsurf_t **instsurfs_tail = &instsurfs;
94 static instsurf_t *free_instsurfs;
95
96 static GLuint bsp_vbo;
97 static mat4_t bsp_vp;
98
99 static GLuint skybox_tex;
100 static qboolean skybox_loaded;
101 static quat_t sky_rotation[2];
102 static quat_t sky_velocity;
103 static quat_t sky_fix;
104 static double sky_time;
105
106 static quat_t default_color = { 1, 1, 1, 1 };
107 static quat_t last_color;
108
109 static const char quakebsp_vert[] =
110 #include "quakebsp.vc"
111 ;
112
113 static const char quakebsp_frag[] =
114 #include "quakebsp.fc"
115 ;
116
117 static const char quaketurb_frag[] =
118 #include "quaketrb.fc"
119 ;
120
121 static const char quakesky_vert[] =
122 #include "quakesky.vc"
123 ;
124
125 static const char quakeskyid_frag[] =
126 #include "quakeski.fc"
127 ;
128
129 static const char quakeskybox_frag[] =
130 #include "quakeskb.fc"
131 ;
132
133 static struct {
134 int program;
135 shaderparam_t mvp_matrix;
136 shaderparam_t tlst;
137 shaderparam_t vertex;
138 shaderparam_t colormap;
139 shaderparam_t texture;
140 shaderparam_t lightmap;
141 shaderparam_t color;
142 shaderparam_t fog;
143 } quake_bsp = {
144 0,
145 {"mvp_mat", 1},
146 {"tlst", 0},
147 {"vertex", 0},
148 {"colormap", 1},
149 {"texture", 1},
150 {"lightmap", 1},
151 {"vcolor", 0},
152 {"fog", 1},
153 };
154
155 static struct {
156 int program;
157 shaderparam_t mvp_matrix;
158 shaderparam_t tlst;
159 shaderparam_t vertex;
160 shaderparam_t palette;
161 shaderparam_t texture;
162 shaderparam_t realtime;
163 shaderparam_t color;
164 shaderparam_t fog;
165 } quake_turb = {
166 0,
167 {"mvp_mat", 1},
168 {"tlst", 0},
169 {"vertex", 0},
170 {"palette", 1},
171 {"texture", 1},
172 {"realtime", 1},
173 {"vcolor", 0},
174 {"fog", 1},
175 };
176
177 static struct {
178 int program;
179 shaderparam_t mvp_matrix;
180 shaderparam_t sky_matrix;
181 shaderparam_t vertex;
182 shaderparam_t palette;
183 shaderparam_t solid;
184 shaderparam_t trans;
185 shaderparam_t realtime;
186 shaderparam_t fog;
187 } quake_skyid = {
188 0,
189 {"mvp_mat", 1},
190 {"sky_mat", 1},
191 {"vertex", 0},
192 {"palette", 1},
193 {"solid", 1},
194 {"trans", 1},
195 {"realtime", 1},
196 {"fog", 1},
197 };
198
199 static struct {
200 int program;
201 shaderparam_t mvp_matrix;
202 shaderparam_t sky_matrix;
203 shaderparam_t vertex;
204 shaderparam_t sky;
205 shaderparam_t fog;
206 } quake_skybox = {
207 0,
208 {"mvp_mat", 1},
209 {"sky_mat", 1},
210 {"vertex", 0},
211 {"sky", 1},
212 {"fog", 1},
213 };
214
215 static struct {
216 shaderparam_t *mvp_matrix;
217 shaderparam_t *sky_matrix;
218 shaderparam_t *vertex;
219 shaderparam_t *fog;
220 } sky_params;
221
222 #define CHAIN_SURF_F2B(surf,chain) \
223 do { \
224 instsurf_t *inst = (surf)->instsurf; \
225 if (__builtin_expect(!inst, 1)) \
226 (surf)->tinst = inst = get_instsurf (); \
227 inst->surface = (surf); \
228 *(chain##_tail) = inst; \
229 (chain##_tail) = &inst->tex_chain; \
230 *(chain##_tail) = 0; \
231 } while (0)
232
233 #define CHAIN_SURF_B2F(surf,chain) \
234 do { \
235 instsurf_t *inst = (surf)->instsurf; \
236 if (__builtin_expect(!inst, 1)) \
237 (surf)->tinst = inst = get_instsurf (); \
238 inst->surface = (surf); \
239 inst->tex_chain = (chain); \
240 (chain) = inst; \
241 } while (0)
242
243 #define GET_RELEASE(type,name) \
244 static inline type * \
245 get_##name (void) \
246 { \
247 type *ele; \
248 if (!free_##name##s) { \
249 int i; \
250 free_##name##s = calloc (ALLOC_CHUNK, sizeof (type)); \
251 for (i = 0; i < ALLOC_CHUNK - 1; i++) \
252 free_##name##s[i]._next = &free_##name##s[i + 1]; \
253 } \
254 ele = free_##name##s; \
255 free_##name##s = ele->_next; \
256 ele->_next = 0; \
257 *name##s_tail = ele; \
258 name##s_tail = &ele->_next; \
259 return ele; \
260 } \
261 static inline void \
262 release_##name##s (void) \
263 { \
264 if (name##s) { \
265 *name##s_tail = free_##name##s; \
266 free_##name##s = name##s; \
267 name##s = 0; \
268 name##s_tail = &name##s; \
269 } \
270 }
271
GET_RELEASE(elechain_t,elechain)272 GET_RELEASE (elechain_t, elechain)
273 GET_RELEASE (elements_t, elements)
274 GET_RELEASE (instsurf_t, static_instsurf)
275 GET_RELEASE (instsurf_t, instsurf)
276
277 void
278 glsl_R_AddTexture (texture_t *tex)
279 {
280 int i;
281 if (r_num_texture_chains == max_texture_chains) {
282 max_texture_chains += 64;
283 r_texture_chains = realloc (r_texture_chains,
284 max_texture_chains * sizeof (texture_t *));
285 for (i = r_num_texture_chains; i < max_texture_chains; i++)
286 r_texture_chains[i] = 0;
287 }
288 r_texture_chains[r_num_texture_chains++] = tex;
289 tex->tex_chain = 0;
290 tex->tex_chain_tail = &tex->tex_chain;
291 tex->elechain = 0;
292 tex->elechain_tail = &tex->elechain;
293 }
294
295 void
glsl_R_InitSurfaceChains(model_t * model)296 glsl_R_InitSurfaceChains (model_t *model)
297 {
298 int i;
299
300 release_static_instsurfs ();
301 release_instsurfs ();
302
303 for (i = 0; i < model->nummodelsurfaces; i++) {
304 model->surfaces[i].instsurf = get_static_instsurf ();
305 model->surfaces[i].instsurf->surface = &model->surfaces[i];
306 }
307 }
308
309 static inline void
clear_tex_chain(texture_t * tex)310 clear_tex_chain (texture_t *tex)
311 {
312 tex->tex_chain = 0;
313 tex->tex_chain_tail = &tex->tex_chain;
314 tex->elechain = 0;
315 tex->elechain_tail = &tex->elechain;
316 }
317
318 static void
clear_texture_chains(void)319 clear_texture_chains (void)
320 {
321 int i;
322
323 for (i = 0; i < r_num_texture_chains; i++) {
324 if (!r_texture_chains[i])
325 continue;
326 clear_tex_chain (r_texture_chains[i]);
327 }
328 clear_tex_chain (r_notexture_mip);
329 release_elechains ();
330 release_elementss ();
331 release_instsurfs ();
332 }
333
334 void
glsl_R_ClearElements(void)335 glsl_R_ClearElements (void)
336 {
337 release_elechains ();
338 release_elementss ();
339 }
340
341 static void
update_lightmap(msurface_t * surf)342 update_lightmap (msurface_t *surf)
343 {
344 int maps;
345
346 for (maps = 0; maps < MAXLIGHTMAPS && surf->styles[maps] != 255; maps++)
347 if (d_lightstylevalue[surf->styles[maps]] != surf->cached_light[maps])
348 goto dynamic;
349
350 if ((surf->dlightframe == r_framecount) || surf->cached_dlight) {
351 dynamic:
352 if (r_dynamic->int_val)
353 glsl_R_BuildLightMap (surf);
354 }
355 }
356
357 static inline void
chain_surface(msurface_t * surf,vec_t * transform,float * color)358 chain_surface (msurface_t *surf, vec_t *transform, float *color)
359 {
360 instsurf_t *is;
361
362 if (surf->flags & SURF_DRAWSKY) {
363 CHAIN_SURF_F2B (surf, sky_chain);
364 } else if ((surf->flags & SURF_DRAWTURB) || (color && color[3] < 1.0)) {
365 CHAIN_SURF_B2F (surf, waterchain);
366 } else {
367 texture_t *tex;
368
369 if (!surf->texinfo->texture->anim_total)
370 tex = surf->texinfo->texture;
371 else
372 tex = R_TextureAnimation (surf);
373 CHAIN_SURF_F2B (surf, tex->tex_chain);
374
375 update_lightmap (surf);
376 }
377 if (!(is = surf->instsurf))
378 is = surf->tinst;
379 is->transform = transform;
380 is->color = color;
381 }
382
383 static void
register_textures(model_t * model)384 register_textures (model_t *model)
385 {
386 int i;
387 texture_t *tex;
388
389 for (i = 0; i < model->numtextures; i++) {
390 tex = model->textures[i];
391 if (!tex)
392 continue;
393 glsl_R_AddTexture (tex);
394 }
395 }
396
397 void
glsl_R_ClearTextures(void)398 glsl_R_ClearTextures (void)
399 {
400 r_num_texture_chains = 0;
401 }
402
403 void
glsl_R_RegisterTextures(model_t ** models,int num_models)404 glsl_R_RegisterTextures (model_t **models, int num_models)
405 {
406 int i;
407 model_t *m;
408
409 glsl_R_ClearTextures ();
410 glsl_R_InitSurfaceChains (r_worldentity.model);
411 glsl_R_AddTexture (r_notexture_mip);
412 register_textures (r_worldentity.model);
413 for (i = 0; i < num_models; i++) {
414 m = models[i];
415 if (!m)
416 continue;
417 // sub-models are done as part of the main model
418 if (*m->name == '*')
419 continue;
420 // world has already been done, not interested in non-brush models
421 if (m == r_worldentity.model || m->type != mod_brush)
422 continue;
423 m->numsubmodels = 1; // no support for submodels in non-world model
424 register_textures (m);
425 }
426 }
427
428 static elechain_t *
add_elechain(texture_t * tex,int ec_index)429 add_elechain (texture_t *tex, int ec_index)
430 {
431 elechain_t *ec;
432
433 ec = get_elechain ();
434 ec->elements = get_elements ();
435 ec->index = ec_index;
436 ec->transform = 0;
437 ec->color = 0;
438 *tex->elechain_tail = ec;
439 tex->elechain_tail = &ec->next;
440 return ec;
441 }
442
443 static void
build_surf_displist(model_t ** models,msurface_t * fa,int base,dstring_t * vert_list)444 build_surf_displist (model_t **models, msurface_t *fa, int base,
445 dstring_t *vert_list)
446 {
447 int numverts;
448 int numtris;
449 int numindices;
450 int i;
451 vec_t *vec;
452 mvertex_t *vertices;
453 medge_t *edges;
454 int *surfedges;
455 int index;
456 bspvert_t *verts;
457 glslpoly_t *poly;
458 GLushort *ind;
459 float s, t;
460
461 if (fa->ec_index < 0) {
462 vertices = models[-fa->ec_index - 1]->vertexes;
463 edges = models[-fa->ec_index - 1]->edges;
464 surfedges = models[-fa->ec_index - 1]->surfedges;
465 } else {
466 vertices = r_worldentity.model->vertexes;
467 edges = r_worldentity.model->edges;
468 surfedges = r_worldentity.model->surfedges;
469 }
470 numverts = fa->numedges;
471 numtris = numverts - 2;
472 numindices = numtris * 3;
473 verts = alloca (numverts * sizeof (bspvert_t));
474 poly = malloc (field_offset (glslpoly_t, indices[numindices]));
475 poly->count = numindices;
476 for (i = 0, ind = poly->indices; i < numtris; i++) {
477 *ind++ = base;
478 *ind++ = base + i + 1;
479 *ind++ = base + i + 2;
480 }
481 fa->polys = (glpoly_t *) poly;
482
483 for (i = 0; i < numverts; i++) {
484 index = surfedges[fa->firstedge + i];
485 if (index > 0)
486 vec = vertices[edges[index].v[0]].position;
487 else
488 vec = vertices[edges[-index].v[1]].position;
489
490 s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3];
491 t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3];
492 VectorCopy (vec, verts[i].vertex);
493 verts[i].vertex[3] = 1;
494 verts[i].tlst[0] = s / fa->texinfo->texture->width;
495 verts[i].tlst[1] = t / fa->texinfo->texture->height;
496
497 //lightmap texture coordinates
498 if (!fa->lightpic) {
499 // sky and water textures don't have lightmaps
500 verts[i].tlst[2] = 0;
501 verts[i].tlst[3] = 0;
502 continue;
503 }
504 s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3];
505 t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3];
506 s -= fa->texturemins[0];
507 t -= fa->texturemins[1];
508 s += fa->lightpic->rect->x * 16 + 8;
509 t += fa->lightpic->rect->y * 16 + 8;
510 s /= 16;
511 t /= 16;
512 verts[i].tlst[2] = s * fa->lightpic->size;
513 verts[i].tlst[3] = t * fa->lightpic->size;
514 }
515 dstring_append (vert_list, (char *) verts, numverts * sizeof (bspvert_t));
516 }
517
518 void
glsl_R_BuildDisplayLists(model_t ** models,int num_models)519 glsl_R_BuildDisplayLists (model_t **models, int num_models)
520 {
521 int i, j;
522 int vertex_index_base;
523 model_t *m;
524 dmodel_t *dm;
525 msurface_t *surf;
526 dstring_t *vertices;
527
528 QuatSet (sqrt(0.5), 0, 0, sqrt(0.5), sky_fix); // proper skies
529 QuatSet (1, 0, 0, 0, sky_rotation[0]);
530 QuatCopy (sky_rotation[0], sky_rotation[1]);
531 QuatSet (0, 0, 0, 0, sky_velocity);
532 QuatExp (sky_velocity, sky_velocity);
533 sky_time = vr_data.realtime;
534
535 // now run through all surfaces, chaining them to their textures, thus
536 // effectively sorting the surfaces by texture (without worrying about
537 // surface order on the same texture chain).
538 for (i = 0; i < num_models; i++) {
539 m = models[i];
540 if (!m)
541 continue;
542 // sub-models are done as part of the main model
543 if (*m->name == '*')
544 continue;
545 // non-bsp models don't have surfaces.
546 dm = m->submodels;
547 for (j = 0; j < m->numsurfaces; j++) {
548 texture_t *tex;
549 if (j == dm->firstface + dm->numfaces) {
550 dm++;
551 if (dm - m->submodels == m->numsubmodels) {
552 // limit the surfaces
553 // probably never hit
554 Sys_Printf ("R_BuildDisplayLists: too many surfaces\n");
555 m->numsurfaces = j;
556 break;
557 }
558 }
559 surf = m->surfaces + j;
560 surf->ec_index = dm - m->submodels;
561 if (!surf->ec_index && m != r_worldentity.model)
562 surf->ec_index = -1 - i; // instanced model
563 tex = surf->texinfo->texture;
564 CHAIN_SURF_F2B (surf, tex->tex_chain);
565 }
566 }
567 // All vertices from all brush models go into one giant vbo.
568 vertices = dstring_new ();
569 vertex_index_base = 0;
570 // All usable surfaces have been chained to the (base) texture they use.
571 // Run through the textures, using their chains to build display maps.
572 // For animated textures, if a surface is on one texture of the group, it
573 // will be on all.
574 for (i = 0; i < r_num_texture_chains; i++) {
575 texture_t *tex;
576 instsurf_t *is;
577 elechain_t *ec = 0;
578 elements_t *el = 0;
579
580 tex = r_texture_chains[i];
581
582 for (is = tex->tex_chain; is; is = is->tex_chain) {
583 msurface_t *surf = is->surface;
584 if (!tex->elechain) {
585 ec = add_elechain (tex, surf->ec_index);
586 el = ec->elements;
587 el->base = (byte *) (intptr_t) vertices->size;
588 vertex_index_base = 0;
589 }
590 if (surf->ec_index != ec->index) { // next sub-model
591 ec = add_elechain (tex, surf->ec_index);
592 el = ec->elements;
593 el->base = (byte *) (intptr_t) vertices->size;
594 vertex_index_base = 0;
595 }
596 if (vertex_index_base + surf->numedges > 65535) {
597 // elements index overflow
598 el->next = get_elements ();
599 el = el->next;
600 el->base = (byte *) (intptr_t) vertices->size;
601 vertex_index_base = 0;
602 }
603 // we don't use it now, but pre-initializing the list won't hurt
604 if (!el->list)
605 el->list = dstring_new ();
606 dstring_clear (el->list);
607
608 surf->base = el->base;
609 build_surf_displist (models, surf, vertex_index_base, vertices);
610 vertex_index_base += surf->numedges;
611 }
612 }
613 clear_texture_chains ();
614 Sys_MaskPrintf (SYS_GLSL, "R_BuildDisplayLists: %ld verts total\n",
615 (long) (vertices->size / sizeof (bspvert_t)));
616 if (!bsp_vbo)
617 qfeglGenBuffers (1, &bsp_vbo);
618 qfeglBindBuffer (GL_ARRAY_BUFFER, bsp_vbo);
619 qfeglBufferData (GL_ARRAY_BUFFER, vertices->size, vertices->str,
620 GL_STATIC_DRAW);
621 qfeglBindBuffer (GL_ARRAY_BUFFER, 0);
622 dstring_delete (vertices);
623 }
624
625 static void
R_DrawBrushModel(entity_t * e)626 R_DrawBrushModel (entity_t *e)
627 {
628 float dot, radius;
629 int i;
630 unsigned k;
631 model_t *model;
632 plane_t *plane;
633 msurface_t *surf;
634 qboolean rotated;
635 vec3_t mins, maxs, org;
636
637 model = e->model;
638 if (e->transform[0] != 1 || e->transform[5] != 1 || e->transform[10] != 1) {
639 rotated = true;
640 radius = model->radius;
641 if (R_CullSphere (e->origin, radius))
642 return;
643 } else {
644 rotated = false;
645 VectorAdd (e->origin, model->mins, mins);
646 VectorAdd (e->origin, model->maxs, maxs);
647 if (R_CullBox (mins, maxs))
648 return;
649 }
650
651 VectorSubtract (r_refdef.vieworg, e->origin, org);
652 if (rotated) {
653 vec3_t temp;
654
655 VectorCopy (org, temp);
656 org[0] = DotProduct (temp, e->transform + 0);
657 org[1] = DotProduct (temp, e->transform + 4);
658 org[2] = DotProduct (temp, e->transform + 8);
659 }
660
661 // calculate dynamic lighting for bmodel if it's not an instanced model
662 if (model->firstmodelsurface != 0 && r_dlight_lightmap->int_val) {
663 vec3_t lightorigin;
664
665 for (k = 0; k < r_maxdlights; k++) {
666 if ((r_dlights[k].die < vr_data.realtime)
667 || (!r_dlights[k].radius))
668 continue;
669
670 VectorSubtract (r_dlights[k].origin, e->origin, lightorigin);
671 R_RecursiveMarkLights (lightorigin, &r_dlights[k], 1 << k,
672 model->nodes + model->hulls[0].firstclipnode);
673 }
674 }
675
676 surf = &model->surfaces[model->firstmodelsurface];
677
678 for (i = 0; i < model->nummodelsurfaces; i++, surf++) {
679 // find the node side on which we are
680 plane = surf->plane;
681
682 dot = PlaneDiff (org, plane);
683
684 // enqueue the polygon
685 if (((surf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON))
686 || (!(surf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON))) {
687 chain_surface (surf, e->transform, e->colormod);
688 }
689 }
690 }
691
692 static inline void
visit_leaf(mleaf_t * leaf)693 visit_leaf (mleaf_t *leaf)
694 {
695 // deal with model fragments in this leaf
696 if (leaf->efrags)
697 R_StoreEfrags (leaf->efrags);
698 }
699
700 static inline int
get_side(mnode_t * node)701 get_side (mnode_t *node)
702 {
703 // find the node side on which we are
704 plane_t *plane = node->plane;
705
706 if (plane->type < 3)
707 return (r_origin[plane->type] - plane->dist) < 0;
708 return (DotProduct (r_origin, plane->normal) - plane->dist) < 0;
709 }
710
711 static inline void
visit_node(mnode_t * node,int side)712 visit_node (mnode_t *node, int side)
713 {
714 int c;
715 msurface_t *surf;
716
717 // sneaky hack for side = side ? SURF_PLANEBACK : 0;
718 side = (~side + 1) & SURF_PLANEBACK;
719 // draw stuff
720 if ((c = node->numsurfaces)) {
721 surf = r_worldentity.model->surfaces + node->firstsurface;
722 for (; c; c--, surf++) {
723 if (surf->visframe != r_visframecount)
724 continue;
725
726 // side is either 0 or SURF_PLANEBACK
727 if (side ^ (surf->flags & SURF_PLANEBACK))
728 continue; // wrong side
729
730 chain_surface (surf, 0, 0);
731 }
732 }
733 }
734
735 static inline int
test_node(mnode_t * node)736 test_node (mnode_t *node)
737 {
738 if (node->contents < 0)
739 return 0;
740 if (node->visframe != r_visframecount)
741 return 0;
742 if (R_CullBox (node->minmaxs, node->minmaxs + 3))
743 return 0;
744 return 1;
745 }
746
747 static void
R_VisitWorldNodes(model_t * model)748 R_VisitWorldNodes (model_t *model)
749 {
750 typedef struct {
751 mnode_t *node;
752 int side;
753 } rstack_t;
754 rstack_t *node_ptr;
755 rstack_t *node_stack;
756 mnode_t *node;
757 mnode_t *front;
758 int side;
759
760 node = model->nodes;
761 // +2 for paranoia
762 node_stack = alloca ((model->depth + 2) * sizeof (rstack_t));
763 node_ptr = node_stack;
764
765 while (1) {
766 while (test_node (node)) {
767 side = get_side (node);
768 front = node->children[side];
769 if (test_node (front)) {
770 node_ptr->node = node;
771 node_ptr->side = side;
772 node_ptr++;
773 node = front;
774 continue;
775 }
776 if (front->contents < 0 && front->contents != CONTENTS_SOLID)
777 visit_leaf ((mleaf_t *) front);
778 visit_node (node, side);
779 node = node->children[!side];
780 }
781 if (node->contents < 0 && node->contents != CONTENTS_SOLID)
782 visit_leaf ((mleaf_t *) node);
783 if (node_ptr != node_stack) {
784 node_ptr--;
785 node = node_ptr->node;
786 side = node_ptr->side;
787 visit_node (node, side);
788 node = node->children[!side];
789 continue;
790 }
791 break;
792 }
793 if (node->contents < 0 && node->contents != CONTENTS_SOLID)
794 visit_leaf ((mleaf_t *) node);
795 }
796
797 static void
draw_elechain(elechain_t * ec,int matloc,int vertloc,int tlstloc,int colloc)798 draw_elechain (elechain_t *ec, int matloc, int vertloc, int tlstloc,
799 int colloc)
800 {
801 mat4_t mat;
802 elements_t *el;
803 int count;
804 float *color;
805
806 if (colloc >= 0) {
807 color = ec->color;
808 if (!color)
809 color = default_color;
810 if (!QuatCompare (color, last_color)) {
811 QuatCopy (color, last_color);
812 qfeglVertexAttrib4fv (quake_bsp.color.location, color);
813 }
814 }
815 if (ec->transform) {
816 Mat4Mult (bsp_vp, ec->transform, mat);
817 qfeglUniformMatrix4fv (matloc, 1, false, mat);
818 } else {
819 qfeglUniformMatrix4fv (matloc, 1, false, bsp_vp);
820 }
821 for (el = ec->elements; el; el = el->next) {
822 if (!el->list->size)
823 continue;
824 count = el->list->size / sizeof (GLushort);
825 qfeglVertexAttribPointer (vertloc, 4, GL_FLOAT,
826 0, sizeof (bspvert_t),
827 el->base + field_offset (bspvert_t, vertex));
828 if (tlstloc >= 0)
829 qfeglVertexAttribPointer (tlstloc, 4, GL_FLOAT,
830 0, sizeof (bspvert_t),
831 el->base + field_offset (bspvert_t,tlst));
832 qfeglDrawElements (GL_TRIANGLES, count,
833 GL_UNSIGNED_SHORT, el->list->str);
834 dstring_clear (el->list);
835 }
836 }
837
838 static void
bsp_begin(void)839 bsp_begin (void)
840 {
841 quat_t fog;
842
843 default_color[3] = 1;
844 QuatCopy (default_color, last_color);
845 qfeglVertexAttrib4fv (quake_bsp.color.location, default_color);
846
847 Mat4Mult (glsl_projection, glsl_view, bsp_vp);
848
849 qfeglUseProgram (quake_bsp.program);
850 qfeglEnableVertexAttribArray (quake_bsp.vertex.location);
851 qfeglEnableVertexAttribArray (quake_bsp.tlst.location);
852 qfeglDisableVertexAttribArray (quake_bsp.color.location);
853
854 qfeglVertexAttrib4fv (quake_bsp.color.location, default_color);
855
856 VectorCopy (glsl_Fog_GetColor (), fog);
857 fog[3] = glsl_Fog_GetDensity () / 64.0;
858 qfeglUniform4fv (quake_bsp.fog.location, 1, fog);
859
860 qfeglUniform1i (quake_bsp.colormap.location, 2);
861 qfeglActiveTexture (GL_TEXTURE0 + 2);
862 qfeglEnable (GL_TEXTURE_2D);
863 qfeglBindTexture (GL_TEXTURE_2D, glsl_colormap);
864
865 qfeglUniform1i (quake_bsp.lightmap.location, 1);
866 qfeglActiveTexture (GL_TEXTURE0 + 1);
867 qfeglEnable (GL_TEXTURE_2D);
868 qfeglBindTexture (GL_TEXTURE_2D, glsl_R_LightmapTexture ());
869
870 qfeglUniform1i (quake_bsp.texture.location, 0);
871 qfeglActiveTexture (GL_TEXTURE0 + 0);
872 qfeglEnable (GL_TEXTURE_2D);
873
874 qfeglBindBuffer (GL_ARRAY_BUFFER, bsp_vbo);
875 }
876
877 static void
bsp_end(void)878 bsp_end (void)
879 {
880 qfeglDisableVertexAttribArray (quake_bsp.vertex.location);
881 qfeglDisableVertexAttribArray (quake_bsp.tlst.location);
882
883 qfeglActiveTexture (GL_TEXTURE0 + 0);
884 qfeglDisable (GL_TEXTURE_2D);
885 qfeglActiveTexture (GL_TEXTURE0 + 1);
886 qfeglDisable (GL_TEXTURE_2D);
887 qfeglActiveTexture (GL_TEXTURE0 + 2);
888 qfeglDisable (GL_TEXTURE_2D);
889
890 qfeglBindBuffer (GL_ARRAY_BUFFER, 0);
891 }
892
893 static void
turb_begin(void)894 turb_begin (void)
895 {
896 quat_t fog;
897
898 default_color[3] = bound (0, r_wateralpha->value, 1);
899 QuatCopy (default_color, last_color);
900 qfeglVertexAttrib4fv (quake_bsp.color.location, default_color);
901
902 Mat4Mult (glsl_projection, glsl_view, bsp_vp);
903
904 qfeglUseProgram (quake_turb.program);
905 qfeglEnableVertexAttribArray (quake_turb.vertex.location);
906 qfeglEnableVertexAttribArray (quake_turb.tlst.location);
907 qfeglDisableVertexAttribArray (quake_turb.color.location);
908
909 qfeglVertexAttrib4fv (quake_turb.color.location, default_color);
910
911 VectorCopy (glsl_Fog_GetColor (), fog);
912 fog[3] = glsl_Fog_GetDensity () / 64.0;
913 qfeglUniform4fv (quake_turb.fog.location, 1, fog);
914
915 qfeglUniform1i (quake_turb.palette.location, 1);
916 qfeglActiveTexture (GL_TEXTURE0 + 1);
917 qfeglEnable (GL_TEXTURE_2D);
918 qfeglBindTexture (GL_TEXTURE_2D, glsl_palette);
919
920 qfeglUniform1f (quake_turb.realtime.location, vr_data.realtime);
921
922 qfeglUniform1i (quake_turb.texture.location, 0);
923 qfeglActiveTexture (GL_TEXTURE0 + 0);
924 qfeglEnable (GL_TEXTURE_2D);
925
926 qfeglBindBuffer (GL_ARRAY_BUFFER, bsp_vbo);
927 }
928
929 static void
turb_end(void)930 turb_end (void)
931 {
932 qfeglDisableVertexAttribArray (quake_turb.vertex.location);
933 qfeglDisableVertexAttribArray (quake_turb.tlst.location);
934
935 qfeglActiveTexture (GL_TEXTURE0 + 0);
936 qfeglDisable (GL_TEXTURE_2D);
937 qfeglActiveTexture (GL_TEXTURE0 + 1);
938 qfeglDisable (GL_TEXTURE_2D);
939
940 qfeglBindBuffer (GL_ARRAY_BUFFER, 0);
941 }
942
943 static void
spin(mat4_t mat)944 spin (mat4_t mat)
945 {
946 quat_t q;
947 mat4_t m;
948 float blend;
949
950 while (vr_data.realtime - sky_time > 1) {
951 QuatCopy (sky_rotation[1], sky_rotation[0]);
952 QuatMult (sky_velocity, sky_rotation[0], sky_rotation[1]);
953 sky_time += 1;
954 }
955 blend = bound (0, (vr_data.realtime - sky_time), 1);
956
957 QuatBlend (sky_rotation[0], sky_rotation[1], blend, q);
958 QuatMult (sky_fix, q, q);
959 Mat4Identity (mat);
960 VectorNegate (r_origin, mat + 12);
961 QuatToMatrix (q, m, 1, 1);
962 Mat4Mult (m, mat, mat);
963 }
964
965 static void
sky_begin(void)966 sky_begin (void)
967 {
968 mat4_t mat;
969 quat_t fog;
970
971 default_color[3] = 1;
972 QuatCopy (default_color, last_color);
973 qfeglVertexAttrib4fv (quake_bsp.color.location, default_color);
974
975 Mat4Mult (glsl_projection, glsl_view, bsp_vp);
976
977 if (skybox_loaded) {
978 sky_params.mvp_matrix = &quake_skybox.mvp_matrix;
979 sky_params.vertex = &quake_skybox.vertex;
980 sky_params.sky_matrix = &quake_skybox.sky_matrix;
981 sky_params.fog = &quake_skybox.fog;
982
983 qfeglUseProgram (quake_skybox.program);
984 qfeglEnableVertexAttribArray (quake_skybox.vertex.location);
985
986 qfeglUniform1i (quake_skybox.sky.location, 0);
987 qfeglActiveTexture (GL_TEXTURE0 + 0);
988 qfeglEnable (GL_TEXTURE_CUBE_MAP);
989 qfeglBindTexture (GL_TEXTURE_CUBE_MAP, skybox_tex);
990 } else {
991 sky_params.mvp_matrix = &quake_skyid.mvp_matrix;
992 sky_params.sky_matrix = &quake_skyid.sky_matrix;
993 sky_params.vertex = &quake_skyid.vertex;
994 sky_params.fog = &quake_skyid.fog;
995
996 qfeglUseProgram (quake_skyid.program);
997 qfeglEnableVertexAttribArray (quake_skyid.vertex.location);
998
999 qfeglUniform1i (quake_skyid.palette.location, 2);
1000 qfeglActiveTexture (GL_TEXTURE0 + 2);
1001 qfeglEnable (GL_TEXTURE_2D);
1002 qfeglBindTexture (GL_TEXTURE_2D, glsl_palette);
1003
1004 qfeglUniform1f (quake_skyid.realtime.location, vr_data.realtime);
1005
1006 qfeglUniform1i (quake_skyid.trans.location, 0);
1007 qfeglActiveTexture (GL_TEXTURE0 + 0);
1008 qfeglEnable (GL_TEXTURE_2D);
1009
1010 qfeglUniform1i (quake_skyid.solid.location, 1);
1011 qfeglActiveTexture (GL_TEXTURE0 + 1);
1012 qfeglEnable (GL_TEXTURE_2D);
1013 }
1014
1015 VectorCopy (glsl_Fog_GetColor (), fog);
1016 fog[3] = glsl_Fog_GetDensity () / 64.0;
1017 qfeglUniform4fv (sky_params.fog->location, 1, fog);
1018
1019 spin (mat);
1020 qfeglUniformMatrix4fv (sky_params.sky_matrix->location, 1, false, mat);
1021
1022 qfeglBindBuffer (GL_ARRAY_BUFFER, bsp_vbo);
1023 }
1024
1025 static void
sky_end(void)1026 sky_end (void)
1027 {
1028 qfeglDisableVertexAttribArray (sky_params.vertex->location);
1029
1030 qfeglActiveTexture (GL_TEXTURE0 + 0);
1031 qfeglDisable (GL_TEXTURE_2D);
1032 qfeglDisable (GL_TEXTURE_CUBE_MAP);
1033 qfeglActiveTexture (GL_TEXTURE0 + 1);
1034 qfeglDisable (GL_TEXTURE_2D);
1035 qfeglActiveTexture (GL_TEXTURE0 + 2);
1036 qfeglDisable (GL_TEXTURE_2D);
1037
1038 qfeglBindBuffer (GL_ARRAY_BUFFER, 0);
1039 }
1040
1041 static inline void
add_surf_elements(texture_t * tex,instsurf_t * is,elechain_t ** ec,elements_t ** el)1042 add_surf_elements (texture_t *tex, instsurf_t *is,
1043 elechain_t **ec, elements_t **el)
1044 {
1045 msurface_t *surf = is->surface;
1046 glslpoly_t *poly = (glslpoly_t *) surf->polys;
1047
1048 if (!tex->elechain) {
1049 (*ec) = add_elechain (tex, surf->ec_index);
1050 (*ec)->transform = is->transform;
1051 (*ec)->color = is->color;
1052 (*el) = (*ec)->elements;
1053 (*el)->base = surf->base;
1054 if (!(*el)->list)
1055 (*el)->list = dstring_new ();
1056 dstring_clear ((*el)->list);
1057 }
1058 if (is->transform != (*ec)->transform || is->color != (*ec)->color) {
1059 (*ec) = add_elechain (tex, surf->ec_index);
1060 (*ec)->transform = is->transform;
1061 (*ec)->color = is->color;
1062 (*el) = (*ec)->elements;
1063 (*el)->base = surf->base;
1064 if (!(*el)->list)
1065 (*el)->list = dstring_new ();
1066 dstring_clear ((*el)->list);
1067 }
1068 if (surf->base != (*el)->base) {
1069 (*el)->next = get_elements ();
1070 (*el) = (*el)->next;
1071 (*el)->base = surf->base;
1072 if (!(*el)->list)
1073 (*el)->list = dstring_new ();
1074 dstring_clear ((*el)->list);
1075 }
1076 dstring_append ((*el)->list, (char *) poly->indices,
1077 poly->count * sizeof (poly->indices[0]));
1078 }
1079
1080 static void
build_tex_elechain(texture_t * tex)1081 build_tex_elechain (texture_t *tex)
1082 {
1083 instsurf_t *is;
1084 elechain_t *ec = 0;
1085 elements_t *el = 0;
1086
1087 for (is = tex->tex_chain; is; is = is->tex_chain) {
1088 add_surf_elements (tex, is, &ec, &el);
1089 }
1090 }
1091
1092 void
glsl_R_DrawWorld(void)1093 glsl_R_DrawWorld (void)
1094 {
1095 entity_t worldent;
1096 int i;
1097
1098 clear_texture_chains (); // do this first for water and skys
1099
1100 memset (&worldent, 0, sizeof (worldent));
1101 worldent.model = r_worldentity.model;
1102
1103 currententity = &worldent;
1104
1105 R_VisitWorldNodes (worldent.model);
1106 if (r_drawentities->int_val) {
1107 entity_t *ent;
1108 for (ent = r_ent_queue; ent; ent = ent->next) {
1109 if (ent->model->type != mod_brush)
1110 continue;
1111 currententity = ent;
1112
1113 R_DrawBrushModel (ent);
1114 }
1115 }
1116
1117 glsl_R_FlushLightmaps ();
1118 bsp_begin ();
1119 qfeglActiveTexture (GL_TEXTURE0 + 0);
1120 for (i = 0; i < r_num_texture_chains; i++) {
1121 texture_t *tex;
1122 elechain_t *ec = 0;
1123
1124 tex = r_texture_chains[i];
1125
1126 build_tex_elechain (tex);
1127
1128 if (tex->elechain)
1129 qfeglBindTexture (GL_TEXTURE_2D, tex->gl_texturenum);
1130
1131 for (ec = tex->elechain; ec; ec = ec->next) {
1132 draw_elechain (ec, quake_bsp.mvp_matrix.location,
1133 quake_bsp.vertex.location,
1134 quake_bsp.tlst.location,
1135 quake_bsp.color.location);
1136 }
1137 tex->elechain = 0;
1138 tex->elechain_tail = &tex->elechain;
1139 }
1140 bsp_end ();
1141 }
1142
1143 void
glsl_R_DrawWaterSurfaces()1144 glsl_R_DrawWaterSurfaces ()
1145 {
1146 instsurf_t *is;
1147 msurface_t *surf;
1148 texture_t *tex = 0;
1149 elechain_t *ec = 0;
1150 elements_t *el = 0;
1151
1152 if (!waterchain)
1153 return;
1154
1155 turb_begin ();
1156 for (is = waterchain; is; is = is->tex_chain) {
1157 surf = is->surface;
1158 if (tex != surf->texinfo->texture) {
1159 if (tex) {
1160 qfeglBindTexture (GL_TEXTURE_2D, tex->gl_texturenum);
1161 for (ec = tex->elechain; ec; ec = ec->next)
1162 draw_elechain (ec, quake_turb.mvp_matrix.location,
1163 quake_turb.vertex.location,
1164 quake_turb.tlst.location,
1165 quake_turb.color.location);
1166 tex->elechain = 0;
1167 tex->elechain_tail = &tex->elechain;
1168 }
1169 tex = surf->texinfo->texture;
1170 }
1171 add_surf_elements (tex, is, &ec, &el);
1172 }
1173 if (tex) {
1174 qfeglBindTexture (GL_TEXTURE_2D, tex->gl_texturenum);
1175 for (ec = tex->elechain; ec; ec = ec->next)
1176 draw_elechain (ec, quake_turb.mvp_matrix.location,
1177 quake_turb.vertex.location,
1178 quake_turb.tlst.location,
1179 quake_turb.color.location);
1180 tex->elechain = 0;
1181 tex->elechain_tail = &tex->elechain;
1182 }
1183 turb_end ();
1184
1185 waterchain = 0;
1186 waterchain_tail = &waterchain;
1187 }
1188
1189 void
glsl_R_DrawSky(void)1190 glsl_R_DrawSky (void)
1191 {
1192 instsurf_t *is;
1193 msurface_t *surf;
1194 texture_t *tex = 0;
1195 elechain_t *ec = 0;
1196 elements_t *el = 0;
1197
1198 if (!sky_chain)
1199 return;
1200
1201 sky_begin ();
1202 for (is = sky_chain; is; is = is->tex_chain) {
1203 surf = is->surface;
1204 if (tex != surf->texinfo->texture) {
1205 if (tex) {
1206 if (!skybox_loaded) {
1207 qfeglActiveTexture (GL_TEXTURE0 + 0);
1208 qfeglBindTexture (GL_TEXTURE_2D, tex->sky_tex[0]);
1209 qfeglActiveTexture (GL_TEXTURE0 + 1);
1210 qfeglBindTexture (GL_TEXTURE_2D, tex->sky_tex[1]);
1211 }
1212 for (ec = tex->elechain; ec; ec = ec->next)
1213 draw_elechain (ec, sky_params.mvp_matrix->location,
1214 sky_params.vertex->location, -1, -1);
1215 tex->elechain = 0;
1216 tex->elechain_tail = &tex->elechain;
1217 }
1218 tex = surf->texinfo->texture;
1219 }
1220 add_surf_elements (tex, is, &ec, &el);
1221 }
1222 if (tex) {
1223 if (!skybox_loaded) {
1224 qfeglActiveTexture (GL_TEXTURE0 + 0);
1225 qfeglBindTexture (GL_TEXTURE_2D, tex->sky_tex[0]);
1226 qfeglActiveTexture (GL_TEXTURE0 + 1);
1227 qfeglBindTexture (GL_TEXTURE_2D, tex->sky_tex[1]);
1228 }
1229 for (ec = tex->elechain; ec; ec = ec->next)
1230 draw_elechain (ec, sky_params.mvp_matrix->location,
1231 sky_params.vertex->location, -1, -1);
1232 tex->elechain = 0;
1233 tex->elechain_tail = &tex->elechain;
1234 }
1235 sky_end ();
1236
1237 sky_chain = 0;
1238 sky_chain_tail = &sky_chain;
1239 }
1240
1241 void
glsl_R_InitBsp(void)1242 glsl_R_InitBsp (void)
1243 {
1244 int vert;
1245 int frag;
1246
1247 vert = GLSL_CompileShader ("quakebsp.vert", quakebsp_vert,
1248 GL_VERTEX_SHADER);
1249 frag = GLSL_CompileShader ("quakebsp.frag", quakebsp_frag,
1250 GL_FRAGMENT_SHADER);
1251 quake_bsp.program = GLSL_LinkProgram ("quakebsp", vert, frag);
1252 GLSL_ResolveShaderParam (quake_bsp.program, &quake_bsp.mvp_matrix);
1253 GLSL_ResolveShaderParam (quake_bsp.program, &quake_bsp.tlst);
1254 GLSL_ResolveShaderParam (quake_bsp.program, &quake_bsp.vertex);
1255 GLSL_ResolveShaderParam (quake_bsp.program, &quake_bsp.colormap);
1256 GLSL_ResolveShaderParam (quake_bsp.program, &quake_bsp.texture);
1257 GLSL_ResolveShaderParam (quake_bsp.program, &quake_bsp.lightmap);
1258 GLSL_ResolveShaderParam (quake_bsp.program, &quake_bsp.color);
1259 GLSL_ResolveShaderParam (quake_bsp.program, &quake_bsp.fog);
1260
1261 frag = GLSL_CompileShader ("quaketrb.frag", quaketurb_frag,
1262 GL_FRAGMENT_SHADER);
1263 quake_turb.program = GLSL_LinkProgram ("quaketrb", vert, frag);
1264 GLSL_ResolveShaderParam (quake_turb.program, &quake_turb.mvp_matrix);
1265 GLSL_ResolveShaderParam (quake_turb.program, &quake_turb.tlst);
1266 GLSL_ResolveShaderParam (quake_turb.program, &quake_turb.vertex);
1267 GLSL_ResolveShaderParam (quake_turb.program, &quake_turb.palette);
1268 GLSL_ResolveShaderParam (quake_turb.program, &quake_turb.texture);
1269 GLSL_ResolveShaderParam (quake_turb.program, &quake_turb.realtime);
1270 GLSL_ResolveShaderParam (quake_turb.program, &quake_turb.color);
1271 GLSL_ResolveShaderParam (quake_turb.program, &quake_turb.fog);
1272
1273 vert = GLSL_CompileShader ("quakesky.vert", quakesky_vert,
1274 GL_VERTEX_SHADER);
1275 frag = GLSL_CompileShader ("quakeski.frag", quakeskyid_frag,
1276 GL_FRAGMENT_SHADER);
1277 quake_skyid.program = GLSL_LinkProgram ("quakeskyid", vert, frag);
1278 GLSL_ResolveShaderParam (quake_skyid.program, &quake_skyid.mvp_matrix);
1279 GLSL_ResolveShaderParam (quake_skyid.program, &quake_skyid.sky_matrix);
1280 GLSL_ResolveShaderParam (quake_skyid.program, &quake_skyid.vertex);
1281 GLSL_ResolveShaderParam (quake_skyid.program, &quake_skyid.palette);
1282 GLSL_ResolveShaderParam (quake_skyid.program, &quake_skyid.solid);
1283 GLSL_ResolveShaderParam (quake_skyid.program, &quake_skyid.trans);
1284 GLSL_ResolveShaderParam (quake_skyid.program, &quake_skyid.realtime);
1285 GLSL_ResolveShaderParam (quake_skyid.program, &quake_skyid.fog);
1286
1287 frag = GLSL_CompileShader ("quakeskb.frag", quakeskybox_frag,
1288 GL_FRAGMENT_SHADER);
1289 quake_skybox.program = GLSL_LinkProgram ("quakeskybox", vert, frag);
1290 GLSL_ResolveShaderParam (quake_skybox.program, &quake_skybox.mvp_matrix);
1291 GLSL_ResolveShaderParam (quake_skybox.program, &quake_skybox.sky_matrix);
1292 GLSL_ResolveShaderParam (quake_skybox.program, &quake_skybox.vertex);
1293 GLSL_ResolveShaderParam (quake_skybox.program, &quake_skybox.sky);
1294 GLSL_ResolveShaderParam (quake_skybox.program, &quake_skybox.fog);
1295 }
1296
1297 static inline int
is_pow2(unsigned x)1298 is_pow2 (unsigned x)
1299 {
1300 int count;
1301
1302 for (count = 0; x; x >>= 1)
1303 if (x & 1)
1304 count++;
1305 return count == 1;
1306 }
1307
1308 // NOTE: this expects the destination tex_t to be set up: memory allocated
1309 // and dimentions/format etc already set. the size of the rect to be copied
1310 // is taken from dst. Also, dst->format and src->format must be the same, and
1311 // either 3 or 4, or bad things will happen. Also, no clipping is done, so if
1312 // x < 0 or y < 0 or x + dst->width > src->width
1313 // or y + dst->height > src->height, bad things will happen.
1314 static void
copy_sub_tex(tex_t * src,int x,int y,tex_t * dst)1315 copy_sub_tex (tex_t *src, int x, int y, tex_t *dst)
1316 {
1317 int dstbytes;
1318 int srcbytes;
1319 int i;
1320
1321 srcbytes = src->width * src->format;
1322 dstbytes = dst->width * dst->format;
1323
1324 x *= src->format;
1325 for (i = 0; i < dst->height; i++)
1326 memcpy (dst->data + i * dstbytes, src->data + (i + y) * srcbytes + x,
1327 dstbytes);
1328 }
1329
1330 void
glsl_R_LoadSkys(const char * sky)1331 glsl_R_LoadSkys (const char *sky)
1332 {
1333 const char *name;
1334 int i;
1335 tex_t *tex;
1336 // NOTE: quake's world and GL's world are rotated relative to each other
1337 // quake has x right, y in, z up. gl has x right, y up, z out
1338 // quake order: +x -x +z -z +y -y
1339 // gl order: +x -x +y -y +z -z
1340 // fizquake orger: -y +y +z -z +x -x
1341 // to get from quake order to fitzquake order, all that's needed is
1342 // a -90 degree rotation on the (quake) z-axis. This is taken care of in
1343 // the sky_matrix setup code.
1344 // However, from the player's perspective, skymaps have lf and rt
1345 // swapped, but everythink makes sense if looking at the cube from outside
1346 // along the positive y axis, with the front of the cube being the nearest
1347 // face. This matches nicely with Blender's default cube in front (num-1)
1348 // view.
1349 static const char *sky_suffix[] = { "ft", "bk", "up", "dn", "rt", "lf"};
1350 static int sky_coords[][2] = {
1351 {2, 0}, // front
1352 {0, 0}, // back
1353 {1, 1}, // up
1354 {0, 1}, // down
1355 {2, 1}, // left
1356 {1, 0}, // right
1357 };
1358
1359 if (!sky || !*sky)
1360 sky = r_skyname->string;
1361
1362 if (!*sky || !strcasecmp (sky, "none")) {
1363 skybox_loaded = false;
1364 return;
1365 }
1366
1367 if (!skybox_tex)
1368 qfeglGenTextures (1, &skybox_tex);
1369
1370 qfeglBindTexture (GL_TEXTURE_CUBE_MAP, skybox_tex);
1371
1372 //blender envmap
1373 // bk rt ft
1374 // dn up lt
1375 tex = LoadImage (name = va ("env/%s_map", sky));
1376 if (tex && tex->format >= 3 && tex->height * 3 == tex->width * 2
1377 && is_pow2 (tex->height)) {
1378 tex_t *sub;
1379 int size = tex->height / 2;
1380
1381 skybox_loaded = true;
1382 sub = malloc (field_offset (tex_t, data[size * size * tex->format]));
1383 sub->width = size;
1384 sub->height = size;
1385 sub->format = tex->format;
1386 sub->palette = tex->palette;
1387 for (i = 0; i < 6; i++) {
1388 int x, y;
1389 x = sky_coords[i][0] * size;
1390 y = sky_coords[i][1] * size;
1391 copy_sub_tex (tex, x, y, sub);
1392 qfeglTexImage2D (GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0,
1393 sub->format == 3 ? GL_RGB : GL_RGBA,
1394 sub->width, sub->height, 0,
1395 sub->format == 3 ? GL_RGB : GL_RGBA,
1396 GL_UNSIGNED_BYTE, sub->data);
1397 }
1398 free (sub);
1399 } else {
1400 skybox_loaded = true;
1401 for (i = 0; i < 6; i++) {
1402 tex = LoadImage (name = va ("env/%s%s", sky, sky_suffix[i]));
1403 if (!tex || tex->format < 3) { // FIXME pcx support
1404 Sys_MaskPrintf (SYS_GLSL, "Couldn't load %s\n", name);
1405 // also look in gfx/env, where Darkplaces looks for skies
1406 tex = LoadImage (name = va ("gfx/env/%s%s", sky,
1407 sky_suffix[i]));
1408 if (!tex || tex->format < 3) { // FIXME pcx support
1409 Sys_MaskPrintf (SYS_GLSL, "Couldn't load %s\n", name);
1410 skybox_loaded = false;
1411 continue;
1412 }
1413 }
1414 Sys_MaskPrintf (SYS_GLSL, "Loaded %s\n", name);
1415 qfeglTexImage2D (GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0,
1416 tex->format == 3 ? GL_RGB : GL_RGBA,
1417 tex->width, tex->height, 0,
1418 tex->format == 3 ? GL_RGB : GL_RGBA,
1419 GL_UNSIGNED_BYTE, tex->data);
1420 }
1421 }
1422 qfeglTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,
1423 GL_CLAMP_TO_EDGE);
1424 qfeglTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,
1425 GL_CLAMP_TO_EDGE);
1426 qfeglTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1427 qfeglTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1428 qfeglGenerateMipmap (GL_TEXTURE_CUBE_MAP);
1429 }
1430