Quake II RTX doxygen  1.0 dev
tess.c
Go to the documentation of this file.
1 /*
2 Copyright (C) 2003-2006 Andrey Nazarov
3 
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13 
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18 
19 #include "gl.h"
20 
22 
23 #define FACE_HASH_BITS 5
24 #define FACE_HASH_SIZE (1 << FACE_HASH_BITS)
25 #define FACE_HASH_MASK (FACE_HASH_SIZE - 1)
26 
27 static mface_t *faces_head[FACE_HASH_SIZE];
28 static mface_t **faces_next[FACE_HASH_SIZE];
29 static mface_t *faces_alpha;
30 
31 void GL_Flush2D(void)
32 {
33  glStateBits_t bits;
34 
35  if (!tess.numverts) {
36  return;
37  }
38 
40  if (tess.flags & 2) {
41  bits |= GLS_BLEND_BLEND;
42  } else if (tess.flags & 1) {
43  bits |= GLS_ALPHATEST_ENABLE;
44  }
45 
46  Scrap_Upload();
47 
48  GL_BindTexture(0, tess.texnum[0]);
49  GL_StateBits(bits);
51 
53  GL_TexCoordPointer(2, 4, tess.vertices + 2);
55 
57 
59 
60  if (gl_showtris->integer > 1) {
64  }
65 
67 
68  c.batchesDrawn2D++;
69 
70  tess.numindices = 0;
71  tess.numverts = 0;
72  tess.texnum[0] = 0;
73  tess.flags = 0;
74 }
75 
76 #define PARTICLE_SIZE (1 + M_SQRT1_2)
77 #define PARTICLE_SCALE (1 / (2 * PARTICLE_SIZE))
78 
79 void GL_DrawParticles(void)
80 {
81  particle_t *p;
82  int total, count;
83  vec3_t transformed;
84  vec_t scale, dist;
85  color_t color;
86  int numverts;
87  vec_t *dst_vert;
88  uint32_t *dst_color;
89  int blend;
90 
91  if (!glr.fd.num_particles)
92  return;
93 
94  if (gl_partstyle->integer)
95  blend = GLS_BLEND_ADD;
96  else
97  blend = GLS_BLEND_BLEND;
98 
100 
102  GL_TexCoordPointer(2, 5, tess.vertices + 3);
104 
105  p = glr.fd.particles;
106  total = glr.fd.num_particles;
107  do {
111 
112  count = total;
113  if (count > TESS_MAX_VERTICES / 3)
114  count = TESS_MAX_VERTICES / 3;
115 
116  total -= count;
117 
118  numverts = 0;
119  do {
120  VectorSubtract(p->origin, glr.fd.vieworg, transformed);
121  dist = DotProduct(transformed, glr.viewaxis[0]);
122 
123  scale = gl_partscale->value;
124  if (dist > 20)
125  scale += dist * 0.01f;
126 
127  if (p->color == -1) {
128  color.u32 = p->rgba.u32;
129  } else {
130  color.u32 = d_8to24table[p->color & 0xff];
131  color.u8[3] = 255 * p->alpha;
132  }
133 
134  dst_vert = tess.vertices + numverts * 5;
135  VectorMA(p->origin, scale * PARTICLE_SCALE, glr.viewaxis[1], dst_vert);
136  VectorMA(dst_vert, -scale * PARTICLE_SCALE, glr.viewaxis[2], dst_vert);
137  VectorMA(dst_vert, scale, glr.viewaxis[2], dst_vert + 5);
138  VectorMA(dst_vert, -scale, glr.viewaxis[1], dst_vert + 10);
139 
140  dst_vert[ 3] = 0; dst_vert[ 4] = 0;
141  dst_vert[ 8] = 0; dst_vert[ 9] = PARTICLE_SIZE;
142  dst_vert[13] = PARTICLE_SIZE; dst_vert[14] = 0;
143 
144  dst_color = (uint32_t *)tess.colors + numverts;
145  dst_color[0] = color.u32;
146  dst_color[1] = color.u32;
147  dst_color[2] = color.u32;
148 
149  p++;
150  numverts += 3;
151  } while (--count);
152 
153  qglDrawArrays(GL_TRIANGLES, 0, numverts);
154 
155  if (gl_showtris->integer) {
157  qglDrawArrays(GL_TRIANGLES, 0, numverts);
159  }
160  } while (total);
161 }
162 
163 /* all things serve the Beam */
164 void GL_DrawBeams(void)
165 {
166  vec3_t d1, d2, d3;
167  vec_t *start, *end;
168  color_t color;
169  vec_t *dst_vert;
170  uint32_t *dst_color;
171  QGL_INDEX_TYPE *dst_indices;
172  vec_t length;
173  int numverts;
174  int numindices;
175  entity_t *ent;
176  int i;
177 
178  if (!glr.num_beams) {
179  return;
180  }
181 
186 
188  GL_TexCoordPointer(2, 5, tess.vertices + 3);
190 
191  numverts = numindices = 0;
192  for (i = 0, ent = glr.fd.entities; i < glr.fd.num_entities; i++, ent++) {
193  if (!(ent->flags & RF_BEAM)) {
194  continue;
195  }
196 
197  start = ent->origin;
198  end = ent->oldorigin;
199  VectorSubtract(end, start, d1);
200  VectorSubtract(glr.fd.vieworg, start, d2);
201  CrossProduct(d1, d2, d3);
202  length = VectorLength(d3);
203  length = ent->frame * 1.2f / length;
204  VectorScale(d3, length, d3);
205 
206  length = VectorLength(d1);
207 
208  if (ent->skinnum == -1) {
209  color.u32 = ent->rgba.u32;
210  } else {
211  color.u32 = d_8to24table[ent->skinnum & 0xff];
212  color.u8[3] = 255 * ent->alpha;
213  }
214 
215  if (numverts + 4 > TESS_MAX_VERTICES ||
216  numindices + 6 > TESS_MAX_INDICES) {
217  qglDrawElements(GL_TRIANGLES, numindices,
219  numverts = numindices = 0;
220  }
221 
222  dst_vert = tess.vertices + numverts * 5;
223  VectorAdd(start, d3, dst_vert);
224  VectorSubtract(start, d3, dst_vert + 5);
225  VectorSubtract(end, d3, dst_vert + 10);
226  VectorAdd(end, d3, dst_vert + 15);
227 
228  dst_vert[3] = 0; dst_vert[4] = 0;
229  dst_vert[8] = 1; dst_vert[9] = 0;
230  dst_vert[13] = 1; dst_vert[14] = length;
231  dst_vert[18] = 0; dst_vert[19] = length;
232 
233  dst_color = (uint32_t *)tess.colors + numverts;
234  dst_color[0] = color.u32;
235  dst_color[1] = color.u32;
236  dst_color[2] = color.u32;
237  dst_color[3] = color.u32;
238 
239  dst_indices = tess.indices + numindices;
240  dst_indices[0] = numverts + 0;
241  dst_indices[1] = numverts + 2;
242  dst_indices[2] = numverts + 3;
243  dst_indices[3] = numverts + 0;
244  dst_indices[4] = numverts + 1;
245  dst_indices[5] = numverts + 2;
246 
247  numverts += 4;
248  numindices += 6;
249  }
250 
251  qglDrawElements(GL_TRIANGLES, numindices,
253 }
254 
255 void GL_BindArrays(void)
256 {
257  vec_t *ptr;
258 
259  if (gl_static.world.vertices) {
260  ptr = tess.vertices;
261  } else {
262  ptr = NULL;
263  qglBindBufferARB(GL_ARRAY_BUFFER_ARB, gl_static.world.bufnum);
264  }
265 
266  GL_VertexPointer(3, VERTEX_SIZE, ptr + 0);
267 
268  if (gl_lightmap->integer) {
269  GL_TexCoordPointer(2, VERTEX_SIZE, ptr + 6);
270  } else {
271  GL_TexCoordPointer(2, VERTEX_SIZE, ptr + 4);
272  if (lm.nummaps) {
273  GL_LightCoordPointer(2, VERTEX_SIZE, ptr + 6);
274  }
275  }
276 
277  GL_ColorBytePointer(4, VERTEX_SIZE, (GLubyte *)(ptr + 3));
278 
279  if (!gl_static.world.vertices) {
280  qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
281  }
282 }
283 
284 void GL_Flush3D(void)
285 {
286  glStateBits_t state = tess.flags;
287  glArrayBits_t array = GLA_VERTEX | GLA_TC;
288 
289  if (!tess.numindices) {
290  return;
291  }
292 
293  if (q_likely(tess.texnum[1])) {
294  state |= GLS_LIGHTMAP_ENABLE;
295  array |= GLA_LMTC;
296  }
297 
298  if (!(state & GLS_TEXTURE_REPLACE)) {
299  array |= GLA_COLOR;
300  }
301 
302  GL_StateBits(state);
303  GL_ArrayBits(array);
304 
305  GL_BindTexture(0, tess.texnum[0]);
306  if (q_likely(tess.texnum[1])) {
307  GL_BindTexture(1, tess.texnum[1]);
308  }
309 
310  if (gl_static.world.vertices) {
312  }
313 
315 
316  if (gl_showtris->integer) {
320  }
321 
322  if (gl_static.world.vertices) {
323  GL_UnlockArrays();
324  }
325 
326  c.batchesDrawn++;
327 
328  tess.texnum[0] = tess.texnum[1] = 0;
329  tess.numindices = 0;
330  tess.numverts = 0;
331  tess.flags = 0;
332 }
333 
334 static int GL_CopyVerts(mface_t *surf)
335 {
336  void *src, *dst;
337  int firstvert;
338 
339  if (tess.numverts + surf->numsurfedges > TESS_MAX_VERTICES) {
340  GL_Flush3D();
341  }
342 
343  src = gl_static.world.vertices + surf->firstvert * VERTEX_SIZE;
345  memcpy(dst, src, surf->numsurfedges * VERTEX_SIZE * sizeof(vec_t));
346 
347  firstvert = tess.numverts;
348  tess.numverts += surf->numsurfedges;
349  return firstvert;
350 }
351 
352 static int GL_TextureAnimation(mtexinfo_t *tex)
353 {
354  int c;
355 
356  if (q_unlikely(tex->next)) {
357  c = glr.ent->frame % tex->numframes;
358  while (c) {
359  tex = tex->next;
360  c--;
361  }
362  }
363 
364  return tex->image->texnum;
365 }
366 
367 void GL_DrawFace(mface_t *surf)
368 {
369  int numtris = surf->numsurfedges - 2;
370  int numindices = numtris * 3;
371  GLuint texnum[2];
372  QGL_INDEX_TYPE *dst_indices;
373  int i, j;
374 
375  if (q_unlikely(gl_lightmap->integer)) {
376  texnum[0] = surf->texnum[1];
377  if (!texnum[0])
378  texnum[0] = GL_TextureAnimation(surf->texinfo);
379  texnum[1] = 0;
380  } else {
381  texnum[0] = GL_TextureAnimation(surf->texinfo);
382  texnum[1] = surf->texnum[1];
383  }
384 
385  if (tess.texnum[0] != texnum[0] ||
386  tess.texnum[1] != texnum[1] ||
387  tess.flags != surf->statebits ||
388  tess.numindices + numindices > TESS_MAX_INDICES) {
389  GL_Flush3D();
390  }
391 
392  tess.texnum[0] = texnum[0];
393  tess.texnum[1] = texnum[1];
394  tess.flags = surf->statebits;
395 
396  if (q_unlikely(gl_static.world.vertices)) {
397  j = GL_CopyVerts(surf);
398  } else {
399  j = surf->firstvert;
400  }
401 
402  dst_indices = tess.indices + tess.numindices;
403  for (i = 0; i < numtris; i++) {
404  dst_indices[0] = j;
405  dst_indices[1] = j + (i + 1);
406  dst_indices[2] = j + (i + 2);
407  dst_indices += 3;
408  }
409  tess.numindices += numindices;
410 
411  c.trisDrawn += numtris;
412  c.facesTris += numtris;
413  c.facesDrawn++;
414 }
415 
416 static inline void GL_DrawChain(mface_t **head)
417 {
418  mface_t *face;
419 
420  for (face = *head; face; face = face->next) {
421  GL_DrawFace(face);
422  }
423 
424  *head = NULL;
425 }
426 
428 {
429  int i;
430 
431  for (i = 0; i < FACE_HASH_SIZE; i++) {
432  faces_next[i] = &faces_head[i];
433  }
434 }
435 
437 {
438  int i;
439 
440  for (i = 0; i < FACE_HASH_SIZE; i++) {
442  }
443 }
444 
446 {
447  if (!faces_alpha) {
448  return;
449  }
450 
451  glr.ent = &gl_world;
452 
454 
455  GL_BindArrays();
456 
458 
459  GL_Flush3D();
460 }
461 
462 void GL_AddSolidFace(mface_t *face)
463 {
464  unsigned hash;
465 
466  hash = face->texnum[0] ^ face->texnum[1] ^ face->statebits;
467  hash ^= hash >> FACE_HASH_BITS;
468  hash &= FACE_HASH_MASK;
469 
470  // preserve front-to-back ordering
471  face->next = NULL;
472  *faces_next[hash] = face;
473  faces_next[hash] = &face->next;
474 }
475 
476 void GL_AddAlphaFace(mface_t *face)
477 {
478  // draw back-to-front
479  face->next = faces_alpha;
480  faces_alpha = face;
481 }
482 
gl_partscale
cvar_t * gl_partscale
Definition: main.c:37
TESS_MAX_INDICES
#define TESS_MAX_INDICES
Definition: gl.h:460
statCounters_t::facesDrawn
int facesDrawn
Definition: gl.h:138
GLS_DEPTHTEST_DISABLE
@ GLS_DEPTHTEST_DISABLE
Definition: gl.h:284
gl_showtris
cvar_t * gl_showtris
Definition: main.c:61
FACE_HASH_SIZE
#define FACE_HASH_SIZE
Definition: tess.c:24
lm
lightmap_builder_t lm
Definition: surf.c:25
GL_DrawChain
static void GL_DrawChain(mface_t **head)
Definition: tess.c:416
glArrayBits_t
glArrayBits_t
Definition: gl.h:299
faces_next
static mface_t ** faces_next[FACE_HASH_SIZE]
Definition: tess.c:28
statCounters_t::batchesDrawn2D
int batchesDrawn2D
Definition: gl.h:149
GLS_CULL_DISABLE
@ GLS_CULL_DISABLE
Definition: gl.h:293
GL_ClearSolidFaces
void GL_ClearSolidFaces(void)
Definition: tess.c:427
tesselator_t::numindices
int numindices
Definition: gl.h:468
gl_lightmap
cvar_t * gl_lightmap
Definition: main.c:78
FACE_HASH_BITS
#define FACE_HASH_BITS
Definition: tess.c:23
GL_DrawAlphaFaces
void GL_DrawAlphaFaces(void)
Definition: tess.c:445
statCounters_t::trisDrawn
int trisDrawn
Definition: gl.h:142
faces_alpha
static mface_t * faces_alpha
Definition: tess.c:29
GL_CopyVerts
static int GL_CopyVerts(mface_t *surf)
Definition: tess.c:334
FACE_HASH_MASK
#define FACE_HASH_MASK
Definition: tess.c:25
GL_BindTexture
void GL_BindTexture(GLuint tmu, GLuint texnum)
Definition: state.c:40
GLS_TEXTURE_REPLACE
@ GLS_TEXTURE_REPLACE
Definition: gl.h:289
d_8to24table
uint32_t d_8to24table[256]
Definition: images.c:654
glRefdef_t::num_beams
int num_beams
Definition: gl.h:97
GLS_BLEND_BLEND
@ GLS_BLEND_BLEND
Definition: gl.h:285
GLS_LIGHTMAP_ENABLE
@ GLS_LIGHTMAP_ENABLE
Definition: gl.h:291
faces_head
static mface_t * faces_head[FACE_HASH_SIZE]
Definition: tess.c:27
TEXNUM_BEAM
#define TEXNUM_BEAM
Definition: gl.h:442
GL_LockArrays
static void GL_LockArrays(GLsizei count)
Definition: gl.h:361
gl_world
entity_t gl_world
Definition: main.c:32
GLA_VERTEX
@ GLA_VERTEX
Definition: gl.h:301
GL_UnlockArrays
static void GL_UnlockArrays(void)
Definition: gl.h:368
GL_DrawFace
void GL_DrawFace(mface_t *surf)
Definition: tess.c:367
GL_TextureAnimation
static int GL_TextureAnimation(mtexinfo_t *tex)
Definition: tess.c:352
GL_LightCoordPointer
static void GL_LightCoordPointer(GLint size, GLsizei stride, const GLfloat *pointer)
Definition: gl.h:345
TESS_MAX_VERTICES
#define TESS_MAX_VERTICES
Definition: gl.h:459
VERTEX_SIZE
#define VERTEX_SIZE
Definition: gl.h:245
GL_ArrayBits
void GL_ArrayBits(glArrayBits_t bits)
Definition: state.c:185
GLS_BLEND_ADD
@ GLS_BLEND_ADD
Definition: gl.h:286
Scrap_Upload
void Scrap_Upload(void)
Definition: images.c:220
PARTICLE_SCALE
#define PARTICLE_SCALE
Definition: tess.c:77
glRefdef_t::viewaxis
vec3_t viewaxis[3]
Definition: gl.h:82
glStatic_t::world
struct glStatic_t::@11 world
TEXNUM_PARTICLE
#define TEXNUM_PARTICLE
Definition: gl.h:441
GL_ColorBytePointer
static void GL_ColorBytePointer(GLint size, GLsizei stride, const GLubyte *pointer)
Definition: gl.h:351
glStateBits_t
glStateBits_t
Definition: gl.h:281
tess
tesselator_t tess
Definition: tess.c:21
tesselator_t::indices
QGL_INDEX_TYPE indices[TESS_MAX_INDICES]
Definition: gl.h:464
head
unsigned head
Definition: screen.c:529
GL_TexCoordPointer
static void GL_TexCoordPointer(GLint size, GLsizei stride, const GLfloat *pointer)
Definition: gl.h:339
GL_DisableOutlines
void GL_DisableOutlines(void)
Definition: state.c:471
glRefdef_t::viewmatrix
GLfloat viewmatrix[16]
Definition: gl.h:83
GL_Flush2D
void GL_Flush2D(void)
Definition: tess.c:31
QGL_INDEX_ENUM
#define QGL_INDEX_ENUM
Definition: gl.h:49
qglDrawArrays
#define qglDrawArrays
Definition: fixed.h:56
GL_AddAlphaFace
void GL_AddAlphaFace(mface_t *face)
Definition: tess.c:476
gl_partstyle
cvar_t * gl_partstyle
Definition: main.c:38
GL_DrawSolidFaces
void GL_DrawSolidFaces(void)
Definition: tess.c:436
GLA_LMTC
@ GLA_LMTC
Definition: gl.h:303
qglDrawElements
#define qglDrawElements
Definition: fixed.h:57
tesselator_t::texnum
GLuint texnum[MAX_TMUS]
Definition: gl.h:466
gl_static
glStatic_t gl_static
Definition: main.c:28
GLA_TC
@ GLA_TC
Definition: gl.h:302
tesselator_t::flags
int flags
Definition: gl.h:469
c
statCounters_t c
Definition: main.c:30
lightmap_builder_t::nummaps
int nummaps
Definition: gl.h:264
glr
glRefdef_t glr
Definition: main.c:27
tesselator_t::colors
GLubyte colors[4 *TESS_MAX_VERTICES]
Definition: gl.h:465
GL_VertexPointer
static void GL_VertexPointer(GLint size, GLsizei stride, const GLfloat *pointer)
Definition: gl.h:334
GL_Flush3D
void GL_Flush3D(void)
Definition: tess.c:284
GL_LoadMatrix
static void GL_LoadMatrix(const GLfloat *matrix)
Definition: gl.h:375
GLA_COLOR
@ GLA_COLOR
Definition: gl.h:304
qglBindBufferARB
PFNGLBINDBUFFERARBPROC qglBindBufferARB
Definition: fixed.c:42
statCounters_t::facesTris
int facesTris
Definition: gl.h:139
GL_DrawParticles
void GL_DrawParticles(void)
Definition: tess.c:79
gl.h
statCounters_t::batchesDrawn
int batchesDrawn
Definition: gl.h:143
GLS_ALPHATEST_ENABLE
@ GLS_ALPHATEST_ENABLE
Definition: gl.h:288
color
static vec4_t color
Definition: mesh.c:33
glStatic_t::bufnum
GLuint bufnum
Definition: gl.h:65
QGL_INDEX_TYPE
#define QGL_INDEX_TYPE
Definition: gl.h:48
tesselator_t::vertices
GLfloat vertices[VERTEX_SIZE *TESS_MAX_VERTICES]
Definition: gl.h:463
GL_AddSolidFace
void GL_AddSolidFace(mface_t *face)
Definition: tess.c:462
tesselator_t
Definition: gl.h:462
GLS_DEPTHMASK_FALSE
@ GLS_DEPTHMASK_FALSE
Definition: gl.h:283
GL_EnableOutlines
void GL_EnableOutlines(void)
Definition: state.c:460
GL_StateBits
void GL_StateBits(glStateBits_t bits)
Definition: state.c:60
GL_BindArrays
void GL_BindArrays(void)
Definition: tess.c:255
GL_DrawBeams
void GL_DrawBeams(void)
Definition: tess.c:164
glStatic_t::vertices
vec_t * vertices
Definition: gl.h:64
glRefdef_t::ent
entity_t * ent
Definition: gl.h:92
PARTICLE_SIZE
#define PARTICLE_SIZE
Definition: tess.c:76
glRefdef_t::fd
refdef_t fd
Definition: gl.h:81
tesselator_t::numverts
int numverts
Definition: gl.h:467