rmeshstate_t m;
vec3_t beamdir, right, up, offset;
float length, t1, t2;
- memset(&m, 0, sizeof(m));
- m.blendfunc1 = GL_SRC_ALPHA;
- m.blendfunc2 = GL_ONE;
- if (r_lightningbeam_qmbtexture.integer && r_lightningbeamqmbtexture == NULL)
- r_lightningbeams_setupqmbtexture();
- if (!r_lightningbeam_qmbtexture.integer && r_lightningbeamtexture == NULL)
- r_lightningbeams_setuptexture();
- if (r_lightningbeam_qmbtexture.integer)
- m.tex[0] = R_GetTexture(r_lightningbeamqmbtexture);
- else
- m.tex[0] = R_GetTexture(r_lightningbeamtexture);
- R_Mesh_State(&m);
+
R_Mesh_Matrix(&r_identitymatrix);
// calculate beam direction (beamdir) vector and beam length
// (and realize that the whole polygon assembly orients itself to face
// the viewer)
- R_Mesh_GetSpace(12);
+ memset(&m, 0, sizeof(m));
+ if (r_lightningbeam_qmbtexture.integer)
+ m.tex[0] = R_GetTexture(r_lightningbeamqmbtexture);
+ else
+ m.tex[0] = R_GetTexture(r_lightningbeamtexture);
+ m.pointer_texcoord[0] = varray_texcoord2f[0];
+ R_Mesh_State_Texture(&m);
+
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
+ GL_DepthMask(false);
+ GL_DepthTest(true);
+ if (r_lightningbeam_qmbtexture.integer && r_lightningbeamqmbtexture == NULL)
+ r_lightningbeams_setupqmbtexture();
+ if (!r_lightningbeam_qmbtexture.integer && r_lightningbeamtexture == NULL)
+ r_lightningbeams_setuptexture();
// polygon 1, verts 0-3
VectorScale(right, r_lightningbeam_thickness.value, offset);
- R_CalcLightningBeamPolygonVertex3f(varray_vertex3f, b->start, b->end, offset);
- R_CalcLightningBeamPolygonTexCoord2f(varray_texcoord2f[0], t1, t2);
-
+ R_CalcLightningBeamPolygonVertex3f(varray_vertex3f + 0, b->start, b->end, offset);
// polygon 2, verts 4-7
VectorAdd(right, up, offset);
VectorScale(offset, r_lightningbeam_thickness.value * 0.70710681f, offset);
R_CalcLightningBeamPolygonVertex3f(varray_vertex3f + 12, b->start, b->end, offset);
- R_CalcLightningBeamPolygonTexCoord2f(varray_texcoord2f[0] + 8, t1 + 0.33, t2 + 0.33);
-
// polygon 3, verts 8-11
VectorSubtract(right, up, offset);
VectorScale(offset, r_lightningbeam_thickness.value * 0.70710681f, offset);
R_CalcLightningBeamPolygonVertex3f(varray_vertex3f + 24, b->start, b->end, offset);
+ R_CalcLightningBeamPolygonTexCoord2f(varray_texcoord2f[0] + 0, t1, t2);
+ R_CalcLightningBeamPolygonTexCoord2f(varray_texcoord2f[0] + 8, t1 + 0.33, t2 + 0.33);
R_CalcLightningBeamPolygonTexCoord2f(varray_texcoord2f[0] + 16, t1 + 0.66, t2 + 0.66);
+ GL_VertexPointer(varray_vertex3f);
if (fogenabled)
{
// per vertex colors if fog is used
- GL_UseColorArray();
+ GL_ColorPointer(varray_color4f);
R_FogLightningBeam_Vertex3f_Color4f(varray_vertex3f, varray_color4f, 12, r_lightningbeam_color_red.value, r_lightningbeam_color_green.value, r_lightningbeam_color_blue.value, 1);
}
else
CL_Particles_Init();
R_Particles_Init();
}
-
-float varray_vertex3f[12], varray_texcoord2f[1][8];
#endif
+float particle_vertex3f[12], particle_texcoord2f[8];
+
#ifdef WORKINGLQUAKE
void R_DrawParticle(particle_t *p)
{
}
#ifndef WORKINGLQUAKE
- memset(&m, 0, sizeof(m));
- if (p->blendmode == 0)
- {
- m.blendfunc1 = GL_SRC_ALPHA;
- m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
- }
- else if (p->blendmode == 1)
- {
- m.blendfunc1 = GL_SRC_ALPHA;
- m.blendfunc2 = GL_ONE;
- }
- else
- {
- m.blendfunc1 = GL_ZERO;
- m.blendfunc2 = GL_ONE_MINUS_SRC_COLOR;
- }
- m.tex[0] = R_GetTexture(tex->texture);
- R_Mesh_Matrix(&r_identitymatrix);
- R_Mesh_State(&m);
-
if (fogenabled && p->blendmode != PBLEND_MOD)
{
VectorSubtract(org, r_origin, fogvec);
GL_Color(cr, cg, cb, ca);
- R_Mesh_GetSpace(4);
+ R_Mesh_Matrix(&r_identitymatrix);
+
+ memset(&m, 0, sizeof(m));
+ m.tex[0] = R_GetTexture(tex->texture);
+ m.pointer_texcoord[0] = particle_texcoord2f;
+ R_Mesh_State_Texture(&m);
+
+ if (p->blendmode == 0)
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ else if (p->blendmode == 1)
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
+ else
+ GL_BlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
+ GL_DepthMask(false);
+ GL_DepthTest(true);
+ GL_VertexPointer(particle_vertex3f);
#endif
if (p->orientation == PARTICLE_BILLBOARD || p->orientation == PARTICLE_ORIENTED_DOUBLESIDED)
{
VectorScale(vright, p->scalex, right);
VectorScale(vup, p->scaley, up);
}
- varray_vertex3f[ 0] = org[0] - right[0] - up[0];
- varray_vertex3f[ 1] = org[1] - right[1] - up[1];
- varray_vertex3f[ 2] = org[2] - right[2] - up[2];
- varray_vertex3f[ 3] = org[0] - right[0] + up[0];
- varray_vertex3f[ 4] = org[1] - right[1] + up[1];
- varray_vertex3f[ 5] = org[2] - right[2] + up[2];
- varray_vertex3f[ 6] = org[0] + right[0] + up[0];
- varray_vertex3f[ 7] = org[1] + right[1] + up[1];
- varray_vertex3f[ 8] = org[2] + right[2] + up[2];
- varray_vertex3f[ 9] = org[0] + right[0] - up[0];
- varray_vertex3f[10] = org[1] + right[1] - up[1];
- varray_vertex3f[11] = org[2] + right[2] - up[2];
- varray_texcoord2f[0][0] = tex->s1;varray_texcoord2f[0][1] = tex->t2;
- varray_texcoord2f[0][2] = tex->s1;varray_texcoord2f[0][3] = tex->t1;
- varray_texcoord2f[0][4] = tex->s2;varray_texcoord2f[0][5] = tex->t1;
- varray_texcoord2f[0][6] = tex->s2;varray_texcoord2f[0][7] = tex->t2;
+ particle_vertex3f[ 0] = org[0] - right[0] - up[0];
+ particle_vertex3f[ 1] = org[1] - right[1] - up[1];
+ particle_vertex3f[ 2] = org[2] - right[2] - up[2];
+ particle_vertex3f[ 3] = org[0] - right[0] + up[0];
+ particle_vertex3f[ 4] = org[1] - right[1] + up[1];
+ particle_vertex3f[ 5] = org[2] - right[2] + up[2];
+ particle_vertex3f[ 6] = org[0] + right[0] + up[0];
+ particle_vertex3f[ 7] = org[1] + right[1] + up[1];
+ particle_vertex3f[ 8] = org[2] + right[2] + up[2];
+ particle_vertex3f[ 9] = org[0] + right[0] - up[0];
+ particle_vertex3f[10] = org[1] + right[1] - up[1];
+ particle_vertex3f[11] = org[2] + right[2] - up[2];
+ particle_texcoord2f[0] = tex->s1;particle_texcoord2f[1] = tex->t2;
+ particle_texcoord2f[2] = tex->s1;particle_texcoord2f[3] = tex->t1;
+ particle_texcoord2f[4] = tex->s2;particle_texcoord2f[5] = tex->t1;
+ particle_texcoord2f[6] = tex->s2;particle_texcoord2f[7] = tex->t2;
}
else if (p->orientation == PARTICLE_SPARK)
{
VectorMA(p->org, -p->scaley, p->vel, v);
VectorMA(p->org, p->scaley, p->vel, up2);
- R_CalcBeam_Vertex3f(varray_vertex3f, v, up2, p->scalex);
- varray_texcoord2f[0][0] = tex->s1;varray_texcoord2f[0][1] = tex->t2;
- varray_texcoord2f[0][2] = tex->s1;varray_texcoord2f[0][3] = tex->t1;
- varray_texcoord2f[0][4] = tex->s2;varray_texcoord2f[0][5] = tex->t1;
- varray_texcoord2f[0][6] = tex->s2;varray_texcoord2f[0][7] = tex->t2;
+ R_CalcBeam_Vertex3f(particle_vertex3f, v, up2, p->scalex);
+ particle_texcoord2f[0] = tex->s1;particle_texcoord2f[1] = tex->t2;
+ particle_texcoord2f[2] = tex->s1;particle_texcoord2f[3] = tex->t1;
+ particle_texcoord2f[4] = tex->s2;particle_texcoord2f[5] = tex->t1;
+ particle_texcoord2f[6] = tex->s2;particle_texcoord2f[7] = tex->t2;
}
else if (p->orientation == PARTICLE_BEAM)
{
- R_CalcBeam_Vertex3f(varray_vertex3f, p->org, p->vel2, p->scalex);
+ R_CalcBeam_Vertex3f(particle_vertex3f, p->org, p->vel2, p->scalex);
VectorSubtract(p->vel2, p->org, up);
VectorNormalizeFast(up);
v[0] = DotProduct(p->org, up) * (1.0f / 64.0f) - cl.time * 0.25;
v[1] = DotProduct(p->vel2, up) * (1.0f / 64.0f) - cl.time * 0.25;
- varray_texcoord2f[0][0] = 1;varray_texcoord2f[0][1] = v[0];
- varray_texcoord2f[0][2] = 0;varray_texcoord2f[0][3] = v[0];
- varray_texcoord2f[0][4] = 0;varray_texcoord2f[0][5] = v[1];
- varray_texcoord2f[0][6] = 1;varray_texcoord2f[0][7] = v[1];
+ particle_texcoord2f[0] = 1;particle_texcoord2f[1] = v[0];
+ particle_texcoord2f[2] = 0;particle_texcoord2f[3] = v[0];
+ particle_texcoord2f[4] = 0;particle_texcoord2f[5] = v[1];
+ particle_texcoord2f[6] = 1;particle_texcoord2f[7] = v[1];
}
else
Host_Error("R_DrawParticles: unknown particle orientation %i\n", p->orientation);
glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
glColor4f(cr, cg, cb, ca);
glBegin(GL_QUADS);
- glTexCoord2f(varray_texcoord2f[0][0], varray_texcoord2f[0][1]);glVertex3f(varray_vertex3f[ 0], varray_vertex3f[ 1], varray_vertex3f[ 2]);
- glTexCoord2f(varray_texcoord2f[0][2], varray_texcoord2f[0][3]);glVertex3f(varray_vertex3f[ 3], varray_vertex3f[ 4], varray_vertex3f[ 5]);
- glTexCoord2f(varray_texcoord2f[0][4], varray_texcoord2f[0][5]);glVertex3f(varray_vertex3f[ 6], varray_vertex3f[ 7], varray_vertex3f[ 8]);
- glTexCoord2f(varray_texcoord2f[0][6], varray_texcoord2f[0][7]);glVertex3f(varray_vertex3f[ 9], varray_vertex3f[10], varray_vertex3f[11]);
+ glTexCoord2f(particle_texcoord2f[0], particle_texcoord2f[1]);glVertex3f(particle_vertex3f[ 0], particle_vertex3f[ 1], particle_vertex3f[ 2]);
+ glTexCoord2f(particle_texcoord2f[2], particle_texcoord2f[3]);glVertex3f(particle_vertex3f[ 3], particle_vertex3f[ 4], particle_vertex3f[ 5]);
+ glTexCoord2f(particle_texcoord2f[4], particle_texcoord2f[5]);glVertex3f(particle_vertex3f[ 6], particle_vertex3f[ 7], particle_vertex3f[ 8]);
+ glTexCoord2f(particle_texcoord2f[6], particle_texcoord2f[7]);glVertex3f(particle_vertex3f[ 9], particle_vertex3f[10], particle_vertex3f[11]);
glEnd();
#else
R_Mesh_Draw(4, 2, polygonelements);
#include "image.h"
#include "jpeg.h"
-//#define MESH_VAR
-#define MESH_BATCH
-
-// 65536 is the max addressable on a Geforce 256 up until Geforce3
-// (excluding MX), seems a reasonable number...
-cvar_t gl_mesh_maxverts = {0, "gl_mesh_maxverts", "65536"};
-cvar_t gl_mesh_floatcolors = {0, "gl_mesh_floatcolors", "1"};
cvar_t gl_mesh_drawrangeelements = {0, "gl_mesh_drawrangeelements", "1"};
-#ifdef MESH_VAR
-cvar_t gl_mesh_vertex_array_range = {0, "gl_mesh_vertex_array_range", "0"};
-cvar_t gl_mesh_vertex_array_range_readfrequency = {0, "gl_mesh_vertex_array_range_readfrequency", "0.2"};
-cvar_t gl_mesh_vertex_array_range_writefrequency = {0, "gl_mesh_vertex_array_range_writefrequency", "0.2"};
-cvar_t gl_mesh_vertex_array_range_priority = {0, "gl_mesh_vertex_array_range_priority", "0.7"};
-#endif
-#ifdef MESH_BATCH
-cvar_t gl_mesh_batching = {0, "gl_mesh_batching", "1"};
-#endif
-cvar_t gl_mesh_copyarrays = {0, "gl_mesh_copyarrays", "1"};
+cvar_t gl_mesh_testarrayelement = {0, "gl_mesh_testarrayelement", "0"};
+cvar_t gl_mesh_testmanualfeeding = {0, "gl_mesh_testmanualfeeding", "0"};
cvar_t gl_delayfinish = {CVAR_SAVE, "gl_delayfinish", "0"};
+cvar_t gl_paranoid = {0, "gl_paranoid", "0"};
+cvar_t gl_printcheckerror = {0, "gl_printcheckerror", "0"};
cvar_t r_render = {0, "r_render", "1"};
cvar_t gl_dither = {CVAR_SAVE, "gl_dither", "1"}; // whether or not to use dithering
// these are externally accessible
int r_lightmapscalebit;
float r_colorscale;
-GLfloat *varray_vertex3f, *varray_buf_vertex3f;
-GLfloat *varray_color4f, *varray_buf_color4f;
-GLfloat *varray_texcoord3f[MAX_TEXTUREUNITS], *varray_buf_texcoord3f[MAX_TEXTUREUNITS];
-GLfloat *varray_texcoord2f[MAX_TEXTUREUNITS], *varray_buf_texcoord2f[MAX_TEXTUREUNITS];
-static qbyte *varray_buf_color4b;
-int mesh_maxverts;
-#ifdef MESH_VAR
-int mesh_var;
-float mesh_var_readfrequency;
-float mesh_var_writefrequency;
-float mesh_var_priority;
-#endif
-int varray_offset = 0, varray_offsetnext = 0;
-GLuint *varray_buf_elements3i;
-int mesh_maxelements = 32768;
-#ifdef MESH_BATCH
-int gl_batchvertexfirst = 0;
-int gl_batchvertexcount = 0;
-int gl_batchelementcount = 0;
-#endif
static matrix4x4_t backend_viewmatrix;
static matrix4x4_t backend_modelmatrix;
*elements++ = i + row + 1;
*/
-void GL_Backend_AllocElementsArray(void)
-{
- if (varray_buf_elements3i)
- Mem_Free(varray_buf_elements3i);
- varray_buf_elements3i = Mem_Alloc(gl_backend_mempool, mesh_maxelements * sizeof(GLuint));
-}
-
-void GL_Backend_FreeElementArray(void)
-{
- if (varray_buf_elements3i)
- Mem_Free(varray_buf_elements3i);
- varray_buf_elements3i = NULL;
-}
-
-void GL_Backend_CheckCvars(void)
-{
- if (gl_mesh_maxverts.integer < 1024)
- Cvar_SetValueQuick(&gl_mesh_maxverts, 1024);
- if (gl_mesh_maxverts.integer > 65536)
- Cvar_SetValueQuick(&gl_mesh_maxverts, 65536);
-#ifdef MESH_VAR
- if (gl_mesh_vertex_array_range.integer && !gl_support_var)
- Cvar_SetValueQuick(&gl_mesh_vertex_array_range, 0);
- if (gl_mesh_vertex_array_range_readfrequency.value < 0)
- Cvar_SetValueQuick(&gl_mesh_vertex_array_range_readfrequency, 0);
- if (gl_mesh_vertex_array_range_readfrequency.value > 1)
- Cvar_SetValueQuick(&gl_mesh_vertex_array_range_readfrequency, 1);
- if (gl_mesh_vertex_array_range_writefrequency.value < 0)
- Cvar_SetValueQuick(&gl_mesh_vertex_array_range_writefrequency, 0);
- if (gl_mesh_vertex_array_range_writefrequency.value > 1)
- Cvar_SetValueQuick(&gl_mesh_vertex_array_range_writefrequency, 1);
- if (gl_mesh_vertex_array_range_priority.value < 0)
- Cvar_SetValueQuick(&gl_mesh_vertex_array_range_priority, 0);
- if (gl_mesh_vertex_array_range_priority.value > 1)
- Cvar_SetValueQuick(&gl_mesh_vertex_array_range_priority, 1);
-#endif
-}
-
int polygonelements[768];
static void R_Mesh_CacheArray_Startup(void);
static void R_Mesh_CacheArray_Shutdown(void);
void GL_Backend_AllocArrays(void)
{
- int i, size;
- qbyte *data;
-
if (!gl_backend_mempool)
- {
gl_backend_mempool = Mem_AllocPool("GL_Backend");
- varray_buf_vertex3f = NULL;
- varray_buf_color4f = NULL;
- varray_buf_color4b = NULL;
- varray_buf_elements3i = NULL;
- for (i = 0;i < MAX_TEXTUREUNITS;i++)
- varray_buf_texcoord3f[i] = varray_buf_texcoord2f[i] = NULL;
- }
-
- if (varray_buf_vertex3f)
-#ifdef MESH_VAR
- VID_FreeVertexArrays(varray_buf_vertex3f);
-#else
- Mem_Free(varray_buf_vertex3f);
-#endif
- varray_buf_vertex3f = NULL;
- varray_buf_color4f = NULL;
- varray_buf_color4b = NULL;
- for (i = 0;i < MAX_TEXTUREUNITS;i++)
- varray_buf_texcoord3f[i] = varray_buf_texcoord2f[i] = NULL;
-
- mesh_maxverts = gl_mesh_maxverts.integer;
- size = mesh_maxverts * (sizeof(float[3]) + sizeof(float[4]) + sizeof(qbyte[4]) + (sizeof(float[3]) + sizeof(float[2])) * backendunits);
-#ifdef MESH_VAR
- mesh_var = gl_mesh_vertex_array_range.integer && gl_support_var;
- mesh_var_readfrequency = gl_mesh_vertex_array_range_readfrequency.value;
- mesh_var_writefrequency = gl_mesh_vertex_array_range_writefrequency.value;
- mesh_var_priority = gl_mesh_vertex_array_range_priority.value;
- data = VID_AllocVertexArrays(gl_backend_mempool, size, gl_mesh_vertex_array_range.integer, gl_mesh_vertex_array_range_readfrequency.value, gl_mesh_vertex_array_range_writefrequency.value, gl_mesh_vertex_array_range_priority.value);
-#else
- data = Mem_Alloc(gl_backend_mempool, size);
-#endif
-
- varray_buf_vertex3f = (void *)data;data += sizeof(float[3]) * mesh_maxverts;
- varray_buf_color4f = (void *)data;data += sizeof(float[4]) * mesh_maxverts;
- for (i = 0;i < backendunits;i++)
- {
- varray_buf_texcoord3f[i] = (void *)data;data += sizeof(float[3]) * mesh_maxverts;
- varray_buf_texcoord2f[i] = (void *)data;data += sizeof(float[2]) * mesh_maxverts;
- }
- for (;i < MAX_TEXTUREUNITS;i++)
- varray_buf_texcoord3f[i] = varray_buf_texcoord2f[i] = NULL;
- varray_buf_color4b = (void *)data;data += sizeof(qbyte[4]) * mesh_maxverts;
-
- GL_Backend_AllocElementsArray();
-
-#ifdef MESH_VAR
- if (mesh_var)
- {
- CHECKGLERROR
- qglVertexArrayRangeNV(size, varray_buf_vertex3f);
- CHECKGLERROR
- }
-#endif
-
R_Mesh_CacheArray_Startup();
}
void GL_Backend_FreeArrays(void)
{
- int i;
-
R_Mesh_CacheArray_Shutdown();
-
-#ifdef MESH_VAR
- if (mesh_var)
- {
- CHECKGLERROR
- qglDisableClientState(GL_VERTEX_ARRAY_RANGE_NV);
- CHECKGLERROR
- }
-#endif
-
- if (varray_buf_vertex3f)
-#ifdef MESH_VAR
- VID_FreeVertexArrays(varray_buf_vertex3f);
-#else
- Mem_Free(varray_buf_vertex3f);
-#endif
- varray_buf_vertex3f = NULL;
- varray_buf_color4f = NULL;
- varray_buf_color4b = NULL;
- for (i = 0;i < MAX_TEXTUREUNITS;i++)
- varray_buf_texcoord3f[i] = varray_buf_texcoord2f[i] = NULL;
- varray_buf_elements3i = NULL;
-
Mem_FreePool(&gl_backend_mempool);
}
static void gl_backend_start(void)
{
- GL_Backend_CheckCvars();
-
- Con_Printf("OpenGL Backend started with gl_mesh_maxverts %i\n", gl_mesh_maxverts.integer);
+ Con_Printf("OpenGL Backend started\n");
if (qglDrawRangeElements != NULL)
{
CHECKGLERROR
CHECKGLERROR
Con_Printf("glDrawRangeElements detected (max vertices %i, max indices %i)\n", gl_maxdrawrangeelementsvertices, gl_maxdrawrangeelementsindices);
}
- if (strstr(gl_renderer, "3Dfx"))
- {
- Con_Printf("3Dfx driver detected, forcing gl_mesh_floatcolors to 0 to prevent crashs\n");
- Cvar_SetValueQuick(&gl_mesh_floatcolors, 0);
- }
backendunits = min(MAX_TEXTUREUNITS, gl_textureunits);
GL_Backend_AllocArrays();
-#ifdef MESH_VAR
- if (mesh_var)
- {
- CHECKGLERROR
- qglEnableClientState(GL_VERTEX_ARRAY_RANGE_NV);
- CHECKGLERROR
- }
-#endif
- varray_offset = varray_offsetnext = 0;
-#ifdef MESH_BATCH
- gl_batchvertexfirst = 0;
- gl_batchvertexcount = 0;
- gl_batchelementcount = 0;
-#endif
-
backendactive = true;
}
Con_Printf("OpenGL Backend shutting down\n");
-#ifdef MESH_VAR
- if (mesh_var)
- {
- CHECKGLERROR
- qglDisableClientState(GL_VERTEX_ARRAY_RANGE_NV);
- CHECKGLERROR
- }
-#endif
-
GL_Backend_FreeArrays();
}
-void GL_Backend_ResizeArrays(int numvertices)
-{
- Cvar_SetValueQuick(&gl_mesh_maxverts, numvertices);
- GL_Backend_CheckCvars();
- mesh_maxverts = gl_mesh_maxverts.integer;
- GL_Backend_AllocArrays();
-}
-
static void gl_backend_newmap(void)
{
}
Cvar_RegisterVariable(&gl_dither);
Cvar_RegisterVariable(&gl_lockarrays);
Cvar_RegisterVariable(&gl_delayfinish);
+ Cvar_RegisterVariable(&gl_paranoid);
+ Cvar_RegisterVariable(&gl_printcheckerror);
#ifdef NORENDER
Cvar_SetValue("r_render", 0);
#endif
- Cvar_RegisterVariable(&gl_mesh_maxverts);
- Cvar_RegisterVariable(&gl_mesh_floatcolors);
Cvar_RegisterVariable(&gl_mesh_drawrangeelements);
-#ifdef MESH_VAR
- Cvar_RegisterVariable(&gl_mesh_vertex_array_range);
- Cvar_RegisterVariable(&gl_mesh_vertex_array_range_readfrequency);
- Cvar_RegisterVariable(&gl_mesh_vertex_array_range_writefrequency);
- Cvar_RegisterVariable(&gl_mesh_vertex_array_range_priority);
-#endif
-#ifdef MESH_BATCH
- Cvar_RegisterVariable(&gl_mesh_batching);
-#endif
- Cvar_RegisterVariable(&gl_mesh_copyarrays);
+ Cvar_RegisterVariable(&gl_mesh_testarrayelement);
+ Cvar_RegisterVariable(&gl_mesh_testmanualfeeding);
R_RegisterModule("GL_Backend", gl_backend_start, gl_backend_shutdown, gl_backend_newmap);
}
typedef struct gltextureunit_s
{
int t1d, t2d, t3d, tcubemap;
- int arrayenabled, arrayis3d;
+ int arrayenabled;
+ int arrayis3d;
const void *pointer_texcoord;
float rgbscale, alphascale;
int combinergb, combinealpha;
// FIXME: add more combine stuff
+ matrix4x4_t matrix;
}
gltextureunit_t;
int blendfunc2;
int blend;
GLboolean depthmask;
- int depthdisable;
+ int depthtest;
int unit;
int clientunit;
gltextureunit_t units[MAX_TEXTUREUNITS];
- int colorarray;
float color4f[4];
int lockrange_first;
int lockrange_count;
- int pointervertexcount;
const void *pointer_vertex;
const void *pointer_color;
}
{
int i;
gltextureunit_t *unit;
+ gl_state.unit = -1;
+ gl_state.clientunit = -1;
for (i = 0;i < backendunits;i++)
{
- if (qglActiveTexture)
- qglActiveTexture(GL_TEXTURE0_ARB + (gl_state.unit = i));CHECKGLERROR
- if (qglClientActiveTexture)
- qglClientActiveTexture(GL_TEXTURE0_ARB + (gl_state.clientunit = i));CHECKGLERROR
+ GL_ActiveTexture(i);
+ GL_ClientActiveTexture(i);
unit = gl_state.units + i;
unit->t1d = 0;
unit->t2d = 0;
unit->t3d = 0;
unit->tcubemap = 0;
- unit->arrayenabled = false;
- unit->arrayis3d = false;
unit->pointer_texcoord = NULL;
unit->rgbscale = 1;
unit->alphascale = 1;
unit->combinergb = GL_MODULATE;
unit->combinealpha = GL_MODULATE;
+
+ qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), NULL);CHECKGLERROR
qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
- qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), varray_buf_texcoord2f[i]);CHECKGLERROR
+
qglDisable(GL_TEXTURE_1D);CHECKGLERROR
qglDisable(GL_TEXTURE_2D);CHECKGLERROR
if (gl_texture3d)
void GL_Backend_ResetState(void)
{
memset(&gl_state, 0, sizeof(gl_state));
- gl_state.depthdisable = false;
+ gl_state.depthtest = true;
gl_state.blendfunc1 = GL_ONE;
gl_state.blendfunc2 = GL_ZERO;
gl_state.blend = false;
gl_state.depthmask = GL_TRUE;
- gl_state.colorarray = false;
gl_state.color4f[0] = gl_state.color4f[1] = gl_state.color4f[2] = gl_state.color4f[3] = 1;
gl_state.lockrange_first = 0;
gl_state.lockrange_count = 0;
- gl_state.pointervertexcount = 0;
gl_state.pointer_vertex = NULL;
gl_state.pointer_color = NULL;
CHECKGLERROR
- qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR
- qglDisableClientState(GL_VERTEX_ARRAY);CHECKGLERROR
qglEnable(GL_CULL_FACE);CHECKGLERROR
qglCullFace(GL_FRONT);CHECKGLERROR
qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR
qglDisable(GL_BLEND);CHECKGLERROR
qglDepthMask(gl_state.depthmask);CHECKGLERROR
- qglVertexPointer(3, GL_FLOAT, sizeof(float[3]), varray_buf_vertex3f);CHECKGLERROR
+
+ qglVertexPointer(3, GL_FLOAT, sizeof(float[3]), NULL);CHECKGLERROR
qglEnableClientState(GL_VERTEX_ARRAY);CHECKGLERROR
- if (gl_mesh_floatcolors.integer)
+
+ qglColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL);CHECKGLERROR
+ qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR
+
+ GL_Color(0, 0, 0, 0);
+ GL_Color(1, 1, 1, 1);
+
+ GL_SetupTextureState();
+}
+
+void GL_ActiveTexture(int num)
+{
+ if (gl_state.unit != num)
{
- qglColorPointer(4, GL_FLOAT, sizeof(float[4]), varray_buf_color4f);CHECKGLERROR
+ gl_state.unit = num;
+ if (qglActiveTexture)
+ {
+ qglActiveTexture(GL_TEXTURE0_ARB + gl_state.unit);
+ CHECKGLERROR
+ }
}
- else
+}
+
+void GL_ClientActiveTexture(int num)
+{
+ if (gl_state.clientunit != num)
{
- qglColorPointer(4, GL_UNSIGNED_BYTE, sizeof(qbyte[4]), varray_buf_color4b);CHECKGLERROR
+ gl_state.clientunit = num;
+ if (qglActiveTexture)
+ {
+ qglClientActiveTexture(GL_TEXTURE0_ARB + gl_state.clientunit);
+ CHECKGLERROR
+ }
}
- GL_Color(0, 0, 0, 0);
- GL_Color(1, 1, 1, 1);
+}
- GL_SetupTextureState();
+void GL_BlendFunc(int blendfunc1, int blendfunc2)
+{
+ if (gl_state.blendfunc1 != blendfunc1 || gl_state.blendfunc2 != blendfunc2)
+ {
+ qglBlendFunc(gl_state.blendfunc1 = blendfunc1, gl_state.blendfunc2 = blendfunc2);CHECKGLERROR
+ if (gl_state.blendfunc2 == GL_ZERO)
+ {
+ if (gl_state.blendfunc1 == GL_ONE)
+ {
+ if (gl_state.blend)
+ {
+ gl_state.blend = 0;
+ qglDisable(GL_BLEND);CHECKGLERROR
+ }
+ }
+ else
+ {
+ if (!gl_state.blend)
+ {
+ gl_state.blend = 1;
+ qglEnable(GL_BLEND);CHECKGLERROR
+ }
+ }
+ }
+ else
+ {
+ if (!gl_state.blend)
+ {
+ gl_state.blend = 1;
+ qglEnable(GL_BLEND);CHECKGLERROR
+ }
+ }
+ }
}
-void GL_UseColorArray(void)
+void GL_DepthMask(int state)
{
- if (!gl_state.colorarray)
+ if (gl_state.depthmask != state)
{
-#ifdef MESH_BATCH
- if (gl_batchelementcount)
- R_Mesh_EndBatch();
-#endif
- gl_state.colorarray = true;
- qglEnableClientState(GL_COLOR_ARRAY);CHECKGLERROR
+ qglDepthMask(gl_state.depthmask = state);CHECKGLERROR
+ }
+}
+
+void GL_DepthTest(int state)
+{
+ if (gl_state.depthtest != state)
+ {
+ gl_state.depthtest = state;
+ if (gl_state.depthtest)
+ {
+ qglEnable(GL_DEPTH_TEST);CHECKGLERROR
+ }
+ else
+ {
+ qglDisable(GL_DEPTH_TEST);CHECKGLERROR
+ }
+ }
+}
+
+void GL_VertexPointer(const float *p)
+{
+ if (gl_state.pointer_vertex != p)
+ {
+ gl_state.pointer_vertex = p;
+ CHECKGLERROR
+ qglVertexPointer(3, GL_FLOAT, sizeof(float[3]), gl_state.pointer_vertex);
+ CHECKGLERROR
+ }
+}
+
+void GL_ColorPointer(const float *p)
+{
+ if (gl_state.pointer_color != p)
+ {
+ CHECKGLERROR
+ if (!gl_state.pointer_color)
+ {
+ qglEnableClientState(GL_COLOR_ARRAY);
+ CHECKGLERROR
+ }
+ else if (!p)
+ {
+ qglDisableClientState(GL_COLOR_ARRAY);
+ CHECKGLERROR
+ }
+ gl_state.pointer_color = p;
+ qglColorPointer(4, GL_FLOAT, sizeof(float[4]), gl_state.pointer_color);
+ CHECKGLERROR
}
}
void GL_Color(float cr, float cg, float cb, float ca)
{
- if (gl_state.colorarray)
+ if (gl_state.pointer_color || gl_state.color4f[0] != cr || gl_state.color4f[1] != cg || gl_state.color4f[2] != cb || gl_state.color4f[3] != ca)
{
-#ifdef MESH_BATCH
- if (gl_batchelementcount)
- R_Mesh_EndBatch();
-#endif
- gl_state.colorarray = false;
- qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR
+ GL_ColorPointer(NULL);
gl_state.color4f[0] = cr;
gl_state.color4f[1] = cg;
gl_state.color4f[2] = cb;
gl_state.color4f[3] = ca;
+ CHECKGLERROR
qglColor4f(cr, cg, cb, ca);
- }
- else
- {
- if (gl_state.color4f[0] != cr || gl_state.color4f[1] != cg || gl_state.color4f[2] != cb || gl_state.color4f[3] != ca)
- {
-#ifdef MESH_BATCH
- if (gl_batchelementcount)
- R_Mesh_EndBatch();
-#endif
- gl_state.color4f[0] = cr;
- gl_state.color4f[1] = cg;
- gl_state.color4f[2] = cb;
- gl_state.color4f[3] = ca;
- qglColor4f(cr, cg, cb, ca);
- }
+ CHECKGLERROR
}
}
void R_Mesh_Start(void)
{
BACKENDACTIVECHECK
-
CHECKGLERROR
-
- GL_Backend_CheckCvars();
- if (mesh_maxverts != gl_mesh_maxverts.integer
-#ifdef MESH_VAR
- || mesh_var != (gl_mesh_vertex_array_range.integer && gl_support_var)
- || mesh_var_readfrequency != gl_mesh_vertex_array_range_readfrequency.value
- || mesh_var_writefrequency != gl_mesh_vertex_array_range_writefrequency.value
- || mesh_var_priority != gl_mesh_vertex_array_range_priority.value
-#endif
- )
- GL_Backend_ResizeArrays(gl_mesh_maxverts.integer);
-
GL_Backend_ResetState();
-#ifdef MESH_VAR
- if (!mesh_var)
- {
- gl_batchvertexfirst = gl_batchvertexcount = gl_batchelementcount = 0;
- varray_offset = varray_offsetnext = 0;
- }
-#else
- varray_offset = varray_offsetnext = 0;
-#endif
}
int gl_backend_rebindtextures;
-void GL_ConvertColorsFloatToByte(int first, int count)
-{
- int i, k;
- union {float f[4];int i[4];} *color4fi;
- struct {GLubyte c[4];} *color4b;
-
- // shift float to have 8bit fraction at base of number
- color4fi = (void *)(varray_buf_color4f + first * 4);
- for (i = 0;i < count;i++, color4fi++)
- {
- color4fi->f[0] += 32768.0f;
- color4fi->f[1] += 32768.0f;
- color4fi->f[2] += 32768.0f;
- color4fi->f[3] += 32768.0f;
- }
-
- // then read as integer and kill float bits...
- color4fi = (void *)(varray_buf_color4f + first * 4);
- color4b = (void *)(varray_buf_color4b + first * 4);
- for (i = 0;i < count;i++, color4fi++, color4b++)
- {
- k = color4fi->i[0] & 0x7FFFFF;color4b->c[0] = (GLubyte) min(k, 255);
- k = color4fi->i[1] & 0x7FFFFF;color4b->c[1] = (GLubyte) min(k, 255);
- k = color4fi->i[2] & 0x7FFFFF;color4b->c[2] = (GLubyte) min(k, 255);
- k = color4fi->i[3] & 0x7FFFFF;color4b->c[3] = (GLubyte) min(k, 255);
- }
-}
-
-/*
-// enlarges geometry buffers if they are too small
-void _R_Mesh_ResizeCheck(int numverts)
-{
- if (numverts > mesh_maxverts)
- {
- BACKENDACTIVECHECK
- GL_Backend_ResizeArrays(numverts + 100);
- GL_Backend_ResetState();
- }
-}
-*/
-
-void R_Mesh_EndBatch(void)
-{
-#ifdef MESH_BATCH
- if (gl_batchelementcount)
- {
- if (gl_state.pointervertexcount)
- Host_Error("R_Mesh_EndBatch: called with pointers enabled\n");
-
- if (gl_state.colorarray && !gl_mesh_floatcolors.integer && gl_state.pointer_color == NULL)
- GL_ConvertColorsFloatToByte(gl_batchvertexfirst, gl_batchvertexcount);
- if (r_render.integer)
- {
- //int i;for (i = 0;i < gl_batchelementcount;i++) if (varray_buf_elements3i[i] < gl_batchvertexfirst || varray_buf_elements3i[i] >= (gl_batchvertexfirst + gl_batchvertexcount)) Host_Error("R_Mesh_EndBatch: invalid element #%i (value %i) outside range %i-%i\n", i, varray_buf_elements3i[i], gl_batchvertexfirst, gl_batchvertexfirst + gl_batchvertexcount);
- CHECKGLERROR
- GL_LockArrays(gl_batchvertexfirst, gl_batchvertexcount);
- if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
- {
- qglDrawRangeElements(GL_TRIANGLES, gl_batchvertexfirst, gl_batchvertexfirst + gl_batchvertexcount, gl_batchelementcount, GL_UNSIGNED_INT, (const GLuint *) varray_buf_elements3i);CHECKGLERROR
- }
- else
- {
- qglDrawElements(GL_TRIANGLES, gl_batchelementcount, GL_UNSIGNED_INT, (const GLuint *) varray_buf_elements3i);CHECKGLERROR
- }
- GL_LockArrays(0, 0);
- }
- gl_batchelementcount = 0;
- gl_batchvertexcount = 0;
- }
-#endif
-}
-
void GL_Backend_RenumberElements(int *out, int count, const int *in, int offset)
{
int i;
- //if (offset)
+ if (offset)
+ {
for (i = 0;i < count;i++)
*out++ = *in++ + offset;
- //else
- // memcpy(out, in, sizeof(*out) * count);
-}
-
-// gets vertex buffer space for use with a following R_Mesh_Draw
-// (can be multiple Draw calls per GetSpace)
-void R_Mesh_GetSpace(int numverts)
-{
- int i;
-
- if (gl_state.pointervertexcount)
- Host_Error("R_Mesh_GetSpace: called with pointers enabled\n");
- if (gl_state.lockrange_count)
- Host_Error("R_Mesh_GetSpace: called with arrays locked\n");
-
- varray_offset = varray_offsetnext;
- if (varray_offset + numverts > mesh_maxverts)
- {
- //Con_Printf("R_Mesh_GetSpace: vertex buffer wrap\n");
-#ifdef MESH_BATCH
- if (gl_batchelementcount)
- R_Mesh_EndBatch();
-#endif
- varray_offset = 0;
-#ifdef MESH_VAR
- if (mesh_var)
- {
- CHECKGLERROR
- qglFlushVertexArrayRangeNV();
- CHECKGLERROR
- }
-#endif
- if (numverts > mesh_maxverts)
- {
- GL_Backend_ResizeArrays(numverts + 100);
- GL_Backend_ResetState();
- }
- }
-
- varray_vertex3f = varray_buf_vertex3f + varray_offset * 3;
- varray_color4f = varray_buf_color4f + varray_offset * 4;
- for (i = 0;i < backendunits;i++)
- {
- varray_texcoord3f[i] = varray_buf_texcoord3f[i] + varray_offset * 3;
- varray_texcoord2f[i] = varray_buf_texcoord2f[i] + varray_offset * 2;
}
-
- varray_offsetnext = varray_offset + numverts;
+ else
+ memcpy(out, in, sizeof(*out) * count);
}
-// renders triangles using vertices from the most recent GetSpace call
-// (can be multiple Draw calls per GetSpace)
+// renders triangles using vertices from the active arrays
+int paranoidblah = 0;
void R_Mesh_Draw(int numverts, int numtriangles, const int *elements)
{
int numelements = numtriangles * 3;
- if (numtriangles == 0 || numverts == 0)
+ if (numverts == 0 || numtriangles == 0)
{
Con_Printf("R_Mesh_Draw(%d, %d, %08p);\n", numverts, numtriangles, elements);
return;
c_meshs++;
c_meshelements += numelements;
CHECKGLERROR
- if (gl_state.pointervertexcount)
+ if (r_render.integer)
{
-#ifdef MESH_BATCH
- if (gl_batchelementcount)
- R_Mesh_EndBatch();
-#endif
- if (r_render.integer)
+ if (gl_paranoid.integer)
{
- GL_LockArrays(0, gl_state.pointervertexcount);
- if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
+ int i, j, size;
+ const int *p;
+ if (!qglIsEnabled(GL_VERTEX_ARRAY))
+ Con_Printf("R_Mesh_Draw: vertex array not enabled\n");
+ for (j = 0, size = numverts * (int)sizeof(float[3]), p = gl_state.pointer_vertex;j < size;j += sizeof(int), p++)
+ paranoidblah += *p;
+ if (gl_state.pointer_color)
{
- qglDrawRangeElements(GL_TRIANGLES, 0, gl_state.pointervertexcount, numelements, GL_UNSIGNED_INT, elements);CHECKGLERROR
+ if (!qglIsEnabled(GL_COLOR_ARRAY))
+ Con_Printf("R_Mesh_Draw: color array set but not enabled\n");
+ for (j = 0, size = numverts * (int)sizeof(float[4]), p = gl_state.pointer_color;j < size;j += sizeof(int), p++)
+ paranoidblah += *p;
}
- else
- {
- qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, elements);CHECKGLERROR
- }
- GL_LockArrays(0, 0);
- }
- }
-#ifdef MESH_BATCH
- else if (gl_mesh_batching.integer)
- {
- if (mesh_maxelements < gl_batchelementcount + numelements)
- {
- //Con_Printf("R_Mesh_Draw: enlarging elements array\n");
- if (gl_batchelementcount)
- R_Mesh_EndBatch();
- // round up to a multiple of 1024 and add another 1024 just for good measure
- mesh_maxelements = (gl_batchelementcount + numelements + 1024 + 1023) & ~1023;
- GL_Backend_AllocElementsArray();
- }
- if (varray_offset < gl_batchvertexfirst && gl_batchelementcount)
- R_Mesh_EndBatch();
- if (gl_batchelementcount == 0)
- {
- gl_batchvertexfirst = varray_offset;
- gl_batchvertexcount = 0;
- }
- if (gl_batchvertexcount < varray_offsetnext - gl_batchvertexfirst)
- gl_batchvertexcount = varray_offsetnext - gl_batchvertexfirst;
- GL_Backend_RenumberElements(varray_buf_elements3i + gl_batchelementcount, numelements, elements, varray_offset);
- //Con_Printf("off %i:%i, vertex %i:%i, element %i:%i\n", varray_offset, varray_offsetnext, gl_batchvertexfirst, gl_batchvertexfirst + gl_batchvertexcount, gl_batchelementcount, gl_batchelementcount + numelements);
- gl_batchelementcount += numelements;
- //{int i;for (i = 0;i < gl_batchelementcount;i++) if (varray_buf_elements3i[i] < gl_batchvertexfirst || varray_buf_elements3i[i] >= (gl_batchvertexfirst + gl_batchvertexcount)) Host_Error("R_Mesh_EndBatch: invalid element #%i (value %i) outside range %i-%i, there were previously %i elements and there are now %i elements, varray_offset is %i\n", i, varray_buf_elements3i[i], gl_batchvertexfirst, gl_batchvertexfirst + gl_batchvertexcount, gl_batchelementcount - numelements, gl_batchelementcount, varray_offset);}
- }
-#endif
- else
- {
- GL_Backend_RenumberElements(varray_buf_elements3i, numelements, elements, varray_offset);
- if (r_render.integer)
- {
- GL_LockArrays(varray_offset, numverts);
- if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
+ for (i = 0;i < backendunits;i++)
{
- qglDrawRangeElements(GL_TRIANGLES, varray_offset, varray_offset + numverts, numelements, GL_UNSIGNED_INT, varray_buf_elements3i);CHECKGLERROR
+ if (gl_state.units[i].t1d || gl_state.units[i].t2d || gl_state.units[i].t3d || gl_state.units[i].tcubemap || gl_state.units[i].arrayenabled)
+ {
+ if (gl_state.units[i].arrayenabled && !(gl_state.units[i].t1d || gl_state.units[i].t2d || gl_state.units[i].t3d || gl_state.units[i].tcubemap))
+ Con_Printf("R_Mesh_Draw: array enabled but no texture bound\n");
+ GL_ActiveTexture(i);
+ if (!qglIsEnabled(GL_TEXTURE_COORD_ARRAY))
+ Con_Printf("R_Mesh_Draw: texcoord array set but not enabled\n");
+ for (j = 0, size = numverts * ((gl_state.units[i].t3d || gl_state.units[i].tcubemap) ? (int)sizeof(float[3]) : (int)sizeof(float[2])), p = gl_state.units[i].pointer_texcoord;j < size;j += sizeof(int), p++)
+ paranoidblah += *p;
+ }
}
- else
+ for (i = 0;i < numtriangles * 3;i++)
{
- qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, varray_buf_elements3i);CHECKGLERROR
+ if (elements[i] < 0 || elements[i] >= numverts)
+ {
+ Con_Printf("R_Mesh_Draw: invalid vertex index %i (outside range 0 - %i) in elements list\n", elements[i], numverts);
+ return;
+ }
}
- GL_LockArrays(0, 0);
}
- }
-}
-
-// renders triangles using vertices from the most recent GetSpace call
-// (can be multiple Draw calls per GetSpace)
-void R_Mesh_Draw_NoBatching(int numverts, int numtriangles, const int *elements)
-{
- int numelements = numtriangles * 3;
- if (numtriangles == 0 || numverts == 0)
- {
- Con_Printf("R_Mesh_Draw_NoBatching(%d, %d, %08p);\n", numverts, numtriangles, elements);
- return;
- }
- c_meshs++;
- c_meshelements += numelements;
- CHECKGLERROR
- if (gl_state.pointervertexcount)
- {
- if (r_render.integer)
+ CHECKGLERROR
+ GL_LockArrays(0, numverts);
+ CHECKGLERROR
+ if (gl_mesh_testmanualfeeding.integer)
{
- GL_LockArrays(0, gl_state.pointervertexcount);
- if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
- {
- qglDrawRangeElements(GL_TRIANGLES, 0, gl_state.pointervertexcount, numelements, GL_UNSIGNED_INT, elements);CHECKGLERROR
- }
- else
+ int i, j;
+ const GLfloat *p;
+ qglBegin(GL_TRIANGLES);
+ for (i = 0;i < numtriangles * 3;i++)
{
- qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, elements);CHECKGLERROR
+ for (j = 0;j < backendunits;j++)
+ {
+ if (gl_state.units[j].pointer_texcoord)
+ {
+ if (backendunits > 1)
+ {
+ if (gl_state.units[j].t3d || gl_state.units[j].tcubemap)
+ {
+ p = ((const GLfloat *)(gl_state.units[j].pointer_texcoord)) + elements[i] * 3;
+ qglMultiTexCoord3f(GL_TEXTURE0_ARB + j, p[0], p[1], p[2]);
+ }
+ else
+ {
+ p = ((const GLfloat *)(gl_state.units[j].pointer_texcoord)) + elements[i] * 2;
+ qglMultiTexCoord2f(GL_TEXTURE0_ARB + j, p[0], p[1]);
+ }
+ }
+ else
+ {
+ if (gl_state.units[j].t3d || gl_state.units[j].tcubemap)
+ {
+ p = ((const GLfloat *)(gl_state.units[j].pointer_texcoord)) + elements[i] * 3;
+ qglTexCoord3f(p[0], p[1], p[2]);
+ }
+ else
+ {
+ p = ((const GLfloat *)(gl_state.units[j].pointer_texcoord)) + elements[i] * 2;
+ qglTexCoord2f(p[0], p[1]);
+ }
+ }
+ }
+ }
+ if (gl_state.pointer_color)
+ {
+ p = ((const GLfloat *)(gl_state.pointer_color)) + elements[i] * 4;
+ qglColor4f(p[0], p[1], p[2], p[3]);
+ }
+ p = ((const GLfloat *)(gl_state.pointer_vertex)) + elements[i] * 3;
+ qglVertex3f(p[0], p[1], p[2]);
}
- GL_LockArrays(0, 0);
+ qglEnd();
+ CHECKGLERROR
}
- }
- else
- {
- GL_Backend_RenumberElements(varray_buf_elements3i, numelements, elements, varray_offset);
- if (r_render.integer)
+ else if (gl_mesh_testarrayelement.integer)
{
- GL_LockArrays(varray_offset, numverts);
- if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
+ int i;
+ qglBegin(GL_TRIANGLES);
+ for (i = 0;i < numtriangles * 3;i++)
{
- qglDrawRangeElements(GL_TRIANGLES, varray_offset, varray_offset + numverts, numelements, GL_UNSIGNED_INT, varray_buf_elements3i);CHECKGLERROR
+ qglArrayElement(elements[i]);
}
- else
- {
- qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, varray_buf_elements3i);CHECKGLERROR
- }
- GL_LockArrays(0, 0);
+ qglEnd();
+ CHECKGLERROR
+ }
+ else if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
+ {
+ qglDrawRangeElements(GL_TRIANGLES, 0, numverts, numelements, GL_UNSIGNED_INT, elements);CHECKGLERROR
+ }
+ else
+ {
+ qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, elements);CHECKGLERROR
}
+ CHECKGLERROR
+ GL_LockArrays(0, 0);
+ CHECKGLERROR
}
}
{
int i;
BACKENDACTIVECHECK
-#ifdef MESH_BATCH
- if (gl_batchelementcount)
- R_Mesh_EndBatch();
-#endif
+ CHECKGLERROR
GL_LockArrays(0, 0);
+ CHECKGLERROR
for (i = backendunits - 1;i >= 0;i--)
{
{
if (memcmp(matrix, &backend_modelmatrix, sizeof(matrix4x4_t)))
{
-#ifdef MESH_BATCH
- if (gl_batchelementcount)
- R_Mesh_EndBatch();
-#endif
backend_modelmatrix = *matrix;
Matrix4x4_Concat(&backend_modelviewmatrix, &backend_viewmatrix, matrix);
Matrix4x4_Transpose(&backend_glmodelviewmatrix, &backend_modelviewmatrix);
}
}
-// sets up the requested state
-void R_Mesh_MainState(const rmeshstate_t *m)
+void R_Mesh_TextureMatrix(int unitnumber, const matrix4x4_t *matrix)
{
- const void *p;
- BACKENDACTIVECHECK
-
- if (gl_state.blendfunc1 != m->blendfunc1 || gl_state.blendfunc2 != m->blendfunc2)
- {
-#ifdef MESH_BATCH
- if (gl_batchelementcount)
- R_Mesh_EndBatch();
-#endif
- qglBlendFunc(gl_state.blendfunc1 = m->blendfunc1, gl_state.blendfunc2 = m->blendfunc2);CHECKGLERROR
- if (gl_state.blendfunc2 == GL_ZERO)
- {
- if (gl_state.blendfunc1 == GL_ONE)
- {
- if (gl_state.blend)
- {
- gl_state.blend = 0;
- qglDisable(GL_BLEND);CHECKGLERROR
- }
- }
- else
- {
- if (!gl_state.blend)
- {
- gl_state.blend = 1;
- qglEnable(GL_BLEND);CHECKGLERROR
- }
- }
- }
- else
- {
- if (!gl_state.blend)
- {
- gl_state.blend = 1;
- qglEnable(GL_BLEND);CHECKGLERROR
- }
- }
- }
- if (gl_state.depthdisable != m->depthdisable)
+ if (memcmp(&gl_state.units[unitnumber].matrix, matrix, sizeof(matrix4x4_t)))
{
-#ifdef MESH_BATCH
- if (gl_batchelementcount)
- R_Mesh_EndBatch();
-#endif
- gl_state.depthdisable = m->depthdisable;
- if (gl_state.depthdisable)
- qglDisable(GL_DEPTH_TEST);
- else
- qglEnable(GL_DEPTH_TEST);
- }
- if (gl_state.depthmask != (m->blendfunc2 == GL_ZERO || m->depthwrite))
- {
-#ifdef MESH_BATCH
- if (gl_batchelementcount)
- R_Mesh_EndBatch();
-#endif
- qglDepthMask(gl_state.depthmask = (m->blendfunc2 == GL_ZERO || m->depthwrite));CHECKGLERROR
- }
-
- if (gl_state.pointervertexcount != m->pointervertexcount)
- {
-#ifdef MESH_BATCH
- if (gl_batchelementcount)
- R_Mesh_EndBatch();
-#endif
- gl_state.pointervertexcount = m->pointervertexcount;
- }
-
- p = gl_state.pointervertexcount ? m->pointer_vertex : NULL;
- if (gl_state.pointer_vertex != p)
- {
-#ifdef MESH_BATCH
- if (gl_batchelementcount)
- R_Mesh_EndBatch();
-#endif
- gl_state.pointer_vertex = p;
- qglVertexPointer(3, GL_FLOAT, sizeof(float[3]), p ? p : varray_buf_vertex3f);CHECKGLERROR
- }
-
- p = gl_state.pointervertexcount ? m->pointer_color : NULL;
- if (gl_state.pointer_color != p)
- {
-#ifdef MESH_BATCH
- if (gl_batchelementcount)
- R_Mesh_EndBatch();
-#endif
- gl_state.pointer_color = p;
- if (p || gl_mesh_floatcolors.integer)
- qglColorPointer(4, GL_FLOAT, sizeof(float[4]), p ? p : varray_buf_color4f);
- else
- qglColorPointer(4, GL_UNSIGNED_BYTE, sizeof(GLubyte[4]), p ? p : varray_buf_color4b);
- CHECKGLERROR
+ matrix4x4_t tempmatrix;
+ gl_state.units[unitnumber].matrix = *matrix;
+ Matrix4x4_Transpose(&tempmatrix, &gl_state.units[unitnumber].matrix);
+ qglMatrixMode(GL_TEXTURE);
+ GL_ActiveTexture(unitnumber);
+ qglLoadMatrixf(&tempmatrix.m[0][0]);
+ qglMatrixMode(GL_MODELVIEW);
}
}
-void R_Mesh_TextureState(const rmeshstate_t *m)
+void R_Mesh_State_Texture(const rmeshstate_t *m)
{
- int i, combinergb, combinealpha;
- float scale;
+ int i, combinergb, combinealpha, scale, arrayis3d;
gltextureunit_t *unit;
- const void *p;
BACKENDACTIVECHECK
GL_SetupTextureState();
}
- for (i = 0;i < backendunits;i++)
+ for (i = 0, unit = gl_state.units;i < backendunits;i++, unit++)
{
- unit = gl_state.units + i;
- if (unit->t1d != m->tex1d[i] || unit->t2d != m->tex[i] || unit->t3d != m->tex3d[i] || unit->tcubemap != m->texcubemap[i])
+ if (unit->t1d != m->tex1d[i])
{
- if (m->tex3d[i] || m->texcubemap[i])
+ GL_ActiveTexture(i);
+ if (m->tex1d[i])
{
- if (!unit->arrayis3d)
- {
-#ifdef MESH_BATCH
- if (gl_batchelementcount)
- R_Mesh_EndBatch();
-#endif
- unit->arrayis3d = true;
- if (gl_state.clientunit != i)
- {
- qglClientActiveTexture(GL_TEXTURE0_ARB + (gl_state.clientunit = i));CHECKGLERROR
- }
- qglTexCoordPointer(3, GL_FLOAT, sizeof(float[3]), varray_buf_texcoord3f[i]);
- }
- if (!unit->arrayenabled)
- {
-#ifdef MESH_BATCH
- if (gl_batchelementcount)
- R_Mesh_EndBatch();
-#endif
- unit->arrayenabled = true;
- if (gl_state.clientunit != i)
- {
- qglClientActiveTexture(GL_TEXTURE0_ARB + (gl_state.clientunit = i));CHECKGLERROR
- }
- qglEnableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
- }
+ if (unit->t1d == 0)
+ qglEnable(GL_TEXTURE_1D);CHECKGLERROR
}
- else if (m->tex1d[i] || m->tex[i])
+ else
{
- if (unit->arrayis3d)
- {
-#ifdef MESH_BATCH
- if (gl_batchelementcount)
- R_Mesh_EndBatch();
-#endif
- unit->arrayis3d = false;
- if (gl_state.clientunit != i)
- {
- qglClientActiveTexture(GL_TEXTURE0_ARB + (gl_state.clientunit = i));CHECKGLERROR
- }
- qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), varray_buf_texcoord2f[i]);
- }
- if (!unit->arrayenabled)
- {
-#ifdef MESH_BATCH
- if (gl_batchelementcount)
- R_Mesh_EndBatch();
-#endif
- unit->arrayenabled = true;
- if (gl_state.clientunit != i)
- {
- qglClientActiveTexture(GL_TEXTURE0_ARB + (gl_state.clientunit = i));CHECKGLERROR
- }
- qglEnableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
- }
+ if (unit->t1d)
+ qglDisable(GL_TEXTURE_1D);CHECKGLERROR
+ }
+ qglBindTexture(GL_TEXTURE_1D, (unit->t1d = m->tex1d[i]));CHECKGLERROR
+ }
+ if (unit->t2d != m->tex[i])
+ {
+ GL_ActiveTexture(i);
+ if (m->tex[i])
+ {
+ if (unit->t2d == 0)
+ qglEnable(GL_TEXTURE_2D);CHECKGLERROR
}
else
{
- if (unit->arrayenabled)
- {
-#ifdef MESH_BATCH
- if (gl_batchelementcount)
- R_Mesh_EndBatch();
-#endif
- unit->arrayenabled = false;
- if (gl_state.clientunit != i)
- {
- qglClientActiveTexture(GL_TEXTURE0_ARB + (gl_state.clientunit = i));CHECKGLERROR
- }
- qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
- }
+ if (unit->t2d)
+ qglDisable(GL_TEXTURE_2D);CHECKGLERROR
}
- if (unit->t1d != m->tex1d[i])
+ qglBindTexture(GL_TEXTURE_2D, (unit->t2d = m->tex[i]));CHECKGLERROR
+ }
+ if (unit->t3d != m->tex3d[i])
+ {
+ GL_ActiveTexture(i);
+ if (m->tex3d[i])
{
-#ifdef MESH_BATCH
- if (gl_batchelementcount)
- R_Mesh_EndBatch();
-#endif
- if (gl_state.unit != i)
- {
- qglActiveTexture(GL_TEXTURE0_ARB + (gl_state.unit = i));CHECKGLERROR
- }
- if (m->tex1d[i])
- {
- if (unit->t1d == 0)
- qglEnable(GL_TEXTURE_1D);CHECKGLERROR
- }
- else
- {
- if (unit->t1d)
- qglDisable(GL_TEXTURE_1D);CHECKGLERROR
- }
- qglBindTexture(GL_TEXTURE_1D, (unit->t1d = m->tex1d[i]));CHECKGLERROR
+ if (unit->t3d == 0)
+ qglEnable(GL_TEXTURE_3D);CHECKGLERROR
}
- if (unit->t2d != m->tex[i])
+ else
{
-#ifdef MESH_BATCH
- if (gl_batchelementcount)
- R_Mesh_EndBatch();
-#endif
- if (gl_state.unit != i)
- {
- qglActiveTexture(GL_TEXTURE0_ARB + (gl_state.unit = i));CHECKGLERROR
- }
- if (m->tex[i])
- {
- if (unit->t2d == 0)
- qglEnable(GL_TEXTURE_2D);CHECKGLERROR
- }
- else
- {
- if (unit->t2d)
- qglDisable(GL_TEXTURE_2D);CHECKGLERROR
- }
- qglBindTexture(GL_TEXTURE_2D, (unit->t2d = m->tex[i]));CHECKGLERROR
+ if (unit->t3d)
+ qglDisable(GL_TEXTURE_3D);CHECKGLERROR
}
- if (unit->t3d != m->tex3d[i])
+ qglBindTexture(GL_TEXTURE_3D, (unit->t3d = m->tex3d[i]));CHECKGLERROR
+ }
+ if (unit->tcubemap != m->texcubemap[i])
+ {
+ GL_ActiveTexture(i);
+ if (m->texcubemap[i])
{
-#ifdef MESH_BATCH
- if (gl_batchelementcount)
- R_Mesh_EndBatch();
-#endif
- if (gl_state.unit != i)
- {
- qglActiveTexture(GL_TEXTURE0_ARB + (gl_state.unit = i));CHECKGLERROR
- }
- if (m->tex3d[i])
- {
- if (unit->t3d == 0)
- qglEnable(GL_TEXTURE_3D);CHECKGLERROR
- }
- else
- {
- if (unit->t3d)
- qglDisable(GL_TEXTURE_3D);CHECKGLERROR
- }
- qglBindTexture(GL_TEXTURE_3D, (unit->t3d = m->tex3d[i]));CHECKGLERROR
+ if (unit->tcubemap == 0)
+ qglEnable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
}
- if (unit->tcubemap != m->texcubemap[i])
+ else
{
-#ifdef MESH_BATCH
- if (gl_batchelementcount)
- R_Mesh_EndBatch();
-#endif
- if (gl_state.unit != i)
- {
- qglActiveTexture(GL_TEXTURE0_ARB + (gl_state.unit = i));CHECKGLERROR
- }
- if (m->texcubemap[i])
- {
- if (unit->tcubemap == 0)
- qglEnable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
- }
- else
- {
- if (unit->tcubemap)
- qglDisable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
- }
- qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, (unit->tcubemap = m->texcubemap[i]));CHECKGLERROR
+ if (unit->tcubemap)
+ qglDisable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
}
+ qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, (unit->tcubemap = m->texcubemap[i]));CHECKGLERROR
}
combinergb = m->texcombinergb[i];
if (!combinergb)
combinergb = GL_MODULATE;
if (unit->combinergb != combinergb)
{
-#ifdef MESH_BATCH
- if (gl_batchelementcount)
- R_Mesh_EndBatch();
-#endif
- if (gl_state.unit != i)
- {
- qglActiveTexture(GL_TEXTURE0_ARB + (gl_state.unit = i));CHECKGLERROR
- }
+ GL_ActiveTexture(i);
unit->combinergb = combinergb;
if (gl_combine.integer)
{
combinealpha = GL_MODULATE;
if (unit->combinealpha != combinealpha)
{
-#ifdef MESH_BATCH
- if (gl_batchelementcount)
- R_Mesh_EndBatch();
-#endif
- if (gl_state.unit != i)
- {
- qglActiveTexture(GL_TEXTURE0_ARB + (gl_state.unit = i));CHECKGLERROR
- }
+ GL_ActiveTexture(i);
unit->combinealpha = combinealpha;
if (gl_combine.integer)
{
}
}
scale = max(m->texrgbscale[i], 1);
- if (gl_state.units[i].rgbscale != scale)
+ if (unit->rgbscale != scale)
{
-#ifdef MESH_BATCH
- if (gl_batchelementcount)
- R_Mesh_EndBatch();
-#endif
- if (gl_state.unit != i)
- {
- qglActiveTexture(GL_TEXTURE0_ARB + (gl_state.unit = i));CHECKGLERROR
- }
- qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, (gl_state.units[i].rgbscale = scale));CHECKGLERROR
+ GL_ActiveTexture(i);
+ qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, (unit->rgbscale = scale));CHECKGLERROR
}
scale = max(m->texalphascale[i], 1);
- if (gl_state.units[i].alphascale != scale)
+ if (unit->alphascale != scale)
{
-#ifdef MESH_BATCH
- if (gl_batchelementcount)
- R_Mesh_EndBatch();
-#endif
- if (gl_state.unit != i)
- {
- qglActiveTexture(GL_TEXTURE0_ARB + (gl_state.unit = i));CHECKGLERROR
- }
- qglTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, (gl_state.units[i].alphascale = scale));CHECKGLERROR
+ GL_ActiveTexture(i);
+ qglTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, (unit->alphascale = scale));CHECKGLERROR
}
- if (unit->arrayenabled)
+ arrayis3d = unit->t3d || unit->tcubemap;
+ if (unit->pointer_texcoord != m->pointer_texcoord[i] || unit->arrayis3d != arrayis3d)
{
- p = gl_state.pointervertexcount ? m->pointer_texcoord[i] : NULL;
- if (unit->pointer_texcoord != p)
+ GL_ClientActiveTexture(i);
+ if (m->pointer_texcoord[i])
{
-#ifdef MESH_BATCH
- if (gl_batchelementcount)
- R_Mesh_EndBatch();
-#endif
- unit->pointer_texcoord = p;
- if (gl_state.clientunit != i)
+ if (!unit->arrayenabled)
{
- qglClientActiveTexture(GL_TEXTURE0_ARB + (gl_state.clientunit = i));CHECKGLERROR
+ unit->arrayenabled = true;
+ qglEnableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
}
- if (unit->arrayis3d)
- qglTexCoordPointer(3, GL_FLOAT, sizeof(float[3]), p ? p : varray_buf_texcoord3f[i]);
- else
- qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), p ? p : varray_buf_texcoord2f[i]);
- CHECKGLERROR
}
+ else
+ {
+ if (unit->arrayenabled)
+ {
+ unit->arrayenabled = false;
+ qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
+ }
+ }
+ unit->pointer_texcoord = m->pointer_texcoord[i];
+ unit->arrayis3d = arrayis3d;
+ if (unit->arrayis3d)
+ qglTexCoordPointer(3, GL_FLOAT, sizeof(float[3]), unit->pointer_texcoord);
+ else
+ qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), unit->pointer_texcoord);
+ CHECKGLERROR
}
}
}
-void R_Mesh_State(const rmeshstate_t *m)
-{
- R_Mesh_MainState(m);
- R_Mesh_TextureState(m);
-}
-
/*
==============================================================================
}
}
-// utility functions
-void R_Mesh_CopyVertex3f(const float *vertex3f, int numverts)
-{
-#ifdef MESH_VAR
- if (mesh_var)
- {
- float *out = varray_vertex3f;
- while (--numverts)
- {
- *out++ = *vertex3f++;
- *out++ = *vertex3f++;
- *out++ = *vertex3f++;
- }
- }
- else
-#endif
- memcpy(varray_vertex3f, vertex3f, numverts * sizeof(float[3]));
-}
-
-void R_Mesh_CopyTexCoord2f(int tmu, const float *texcoord2f, int numverts)
-{
-#ifdef MESH_VAR
- if (mesh_var)
- {
- float *out = varray_texcoord2f[tmu];
- while (numverts--)
- {
- *out++ = *texcoord2f++;
- *out++ = *texcoord2f++;
- }
- }
- else
-#endif
- memcpy(varray_texcoord2f[tmu], texcoord2f, numverts * sizeof(float[2]));
-}
-
-void R_Mesh_CopyColor4f(const float *color4f, int numverts)
-{
-#ifdef MESH_VAR
- if (mesh_var)
- {
- float *out = varray_color4f;
- while (numverts--)
- {
- *out++ = *color4f++;
- *out++ = *color4f++;
- *out++ = *color4f++;
- *out++ = *color4f++;
- }
- }
- else
-#endif
- memcpy(varray_color4f, color4f, numverts * sizeof(float[4]));
-}
+//===========================================================================
+// dynamic vertex array buffer subsystem
+//===========================================================================
-void R_ScrollTexCoord2f (float *out2f, const float *in2f, int numverts, float s, float t)
-{
- while (numverts--)
- {
- *out2f++ = *in2f++ + s;
- *out2f++ = *in2f++ + t;
- }
-}
+float varray_vertex3f[65536*3];
+float varray_color4f[65536*4];
+float varray_texcoord2f[4][65536*2];
+float varray_texcoord3f[4][65536*3];
+float varray_normal3f[65536*3];
//===========================================================================
// vertex array caching subsystem
#define POLYGONELEMENTS_MAXPOINTS 258
extern int polygonelements[768];
-void GL_SetupView_ViewPort (int x, int y, int width, int height);
-void GL_SetupView_Orientation_Identity (void);
-void GL_SetupView_Orientation_FromEntity (vec3_t origin, vec3_t angles);
-void GL_SetupView_Mode_Perspective (double fovx, double fovy, double zNear, double zFar);
-void GL_SetupView_Mode_PerspectiveInfiniteFarClip (double fovx, double fovy, double zNear);
-void GL_SetupView_Mode_Ortho (double x1, double y1, double x2, double y2, double zNear, double zFar);
-void GL_UseColorArray(void);
+void GL_SetupView_ViewPort(int x, int y, int width, int height);
+void GL_SetupView_Orientation_Identity(void);
+void GL_SetupView_Orientation_FromEntity(vec3_t origin, vec3_t angles);
+void GL_SetupView_Mode_Perspective(double fovx, double fovy, double zNear, double zFar);
+void GL_SetupView_Mode_PerspectiveInfiniteFarClip(double fovx, double fovy, double zNear);
+void GL_SetupView_Mode_Ortho(double x1, double y1, double x2, double y2, double zNear, double zFar);
+void GL_BlendFunc(int blendfunc1, int blendfunc2);
+void GL_DepthMask(int state);
+void GL_DepthTest(int state);
+void GL_VertexPointer(const float *p);
+void GL_ColorPointer(const float *p);
void GL_Color(float cr, float cg, float cb, float ca);
void GL_TransformToScreen(const vec4_t in, vec4_t out);
void GL_LockArrays(int first, int count);
+void GL_ActiveTexture(int num);
+void GL_ClientActiveTexture(int num);
extern cvar_t gl_lockarrays;
extern cvar_t gl_mesh_copyarrays;
+extern cvar_t gl_paranoid;
+extern cvar_t gl_printcheckerror;
extern int c_meshelements, c_meshs;
//input to R_Mesh_State
typedef struct
{
- int depthwrite; // force depth writing enabled even if polygon is not opaque
- int depthdisable; // disable depth read/write entirely
- int blendfunc1;
- int blendfunc2;
- //int wantoverbright;
+ // textures
int tex1d[MAX_TEXTUREUNITS];
int tex[MAX_TEXTUREUNITS];
int tex3d[MAX_TEXTUREUNITS];
int texcubemap[MAX_TEXTUREUNITS];
+ // texture combine settings
int texrgbscale[MAX_TEXTUREUNITS]; // used only if COMBINE is present
int texalphascale[MAX_TEXTUREUNITS]; // used only if COMBINE is present
int texcombinergb[MAX_TEXTUREUNITS]; // works with or without combine for some operations
int texcombinealpha[MAX_TEXTUREUNITS]; // does nothing without combine
- int pointervertexcount;
- const float *pointer_vertex;
- const float *pointer_color;
+ // pointers
const float *pointer_texcoord[MAX_TEXTUREUNITS];
}
rmeshstate_t;
// overbright rendering scale for the current state
extern int r_lightmapscalebit;
extern float r_colorscale;
-extern float *varray_vertex3f;
-extern float *varray_color4f;
-extern float *varray_texcoord3f[MAX_TEXTUREUNITS];
-extern float *varray_texcoord2f[MAX_TEXTUREUNITS];
-extern int mesh_maxverts;
// adds console variables and registers the render module (only call from GL_Init)
void gl_backend_init(void);
// sets up the requested transform matrix
void R_Mesh_Matrix(const matrix4x4_t *matrix);
-// sets up the requested state
-void R_Mesh_State(const rmeshstate_t *m);
-
-// sets up the requested main state
-void R_Mesh_MainState(const rmeshstate_t *m);
+// sets up the requested transform matrix
+void R_Mesh_TextureMatrix(int unitnumber, const matrix4x4_t *matrix);
-// sets up the requested texture state
-void R_Mesh_TextureState(const rmeshstate_t *m);
+// set up the requested state
+void R_Mesh_State_Texture(const rmeshstate_t *m);
-// forcefully ends a batch (do this before calling any gl functions directly)
-void R_Mesh_EndBatch(void);
-// prepares varray_* buffers for rendering a mesh
-void R_Mesh_GetSpace(int numverts);
-// renders a mesh (optionally with batching)
+// renders a mesh
void R_Mesh_Draw(int numverts, int numtriangles, const int *elements);
-// renders a mesh without affecting batching
-void R_Mesh_Draw_NoBatching(int numverts, int numtriangles, const int *elements);
-
-// copies a vertex3f array into varray_vertex3f
-void R_Mesh_CopyVertex3f(const float *vertex3f, int numverts);
-// copies a texcoord2f array into varray_texcoord[tmu]
-void R_Mesh_CopyTexCoord2f(int tmu, const float *texcoord2f, int numverts);
-// copies a color4f array into varray_color4f
-void R_Mesh_CopyColor4f(const float *color4f, int numverts);
-// copies a texcoord2f array into another array, with scrolling
-void R_ScrollTexCoord2f (float *out2f, const float *in2f, int numverts, float s, float t);
// saves a section of the rendered frame to a .tga or .jpg file
qboolean SCR_ScreenShot(char *filename, int x, int y, int width, int height, qboolean jpeg);
// used by R_Envmap_f and internally in backend, clears the frame
void R_ClearScreen(void);
// invoke refresh of frame
-void SCR_UpdateScreen (void);
+void SCR_UpdateScreen(void);
// public structure
typedef struct rcachearrayrequest_s
int R_Mesh_CacheArray(rcachearrayrequest_t *r);
+extern float varray_vertex3f[65536*3];
+extern float varray_color4f[65536*4];
+extern float varray_texcoord2f[4][65536*2];
+extern float varray_texcoord3f[4][65536*3];
+extern float varray_normal3f[65536*3];
+
#endif
float blendvertex3f[9] = {-5000, -5000, 10, 10000, -5000, 10, -5000, 10000, 10};
int quadelements[768];
-float textverts[128*4*3];
-float texttexcoords[128*4*2];
void R_DrawQueue(void)
{
int pos, num, chartexnum, overbright, texnum, additive, batch;
memset(&m, 0, sizeof(m));
m.tex[0] = 0;
- R_Mesh_TextureState(&m);
+ R_Mesh_State_Texture(&m);
currentpic = "";
pic = NULL;
dq = (drawqueue_t *)(r_refdef.drawqueue + pos);
additive = (dq->flags & DRAWFLAG_ADDITIVE) != 0;
color = dq->color;
- m.blendfunc1 = GL_SRC_ALPHA;
- if (additive)
- m.blendfunc2 = GL_ONE;
- else
- m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
- m.depthdisable = true;
+ GL_BlendFunc(GL_SRC_ALPHA, additive ? GL_ONE : GL_ONE_MINUS_SRC_ALPHA);
+ GL_DepthMask(true);
+ GL_DepthTest(false);
c[0] = (float) ((color >> 24) & 0xFF) * (1.0f / 255.0f) * r_colorscale;
c[1] = (float) ((color >> 16) & 0xFF) * (1.0f / 255.0f) * r_colorscale;
switch(dq->command)
{
case DRAWQUEUE_STRING:
+ GL_Color(c[0], c[1], c[2], c[3]);
str = (char *)(dq + 1);
if (strcmp("gfx/conchars", currentpic))
{
m.tex[0] = chartexnum;
}
batchcount = 0;
- at = texttexcoords;
- av = textverts;
- GL_Color(c[0], c[1], c[2], c[3]);
+ GL_VertexPointer(varray_vertex3f);
+ m.pointer_texcoord[0] = varray_texcoord2f[0];
+ R_Mesh_State_Texture(&m);
+ at = varray_texcoord2f[0];
+ av = varray_vertex3f;
while ((num = *str++) && x < vid.conwidth)
{
if (num != ' ')
batchcount++;
if (batchcount >= 128)
{
- if (gl_mesh_copyarrays.integer)
- {
- m.pointervertexcount = 0;
- m.pointer_vertex = NULL;
- m.pointer_texcoord[0] = NULL;
- m.pointer_color = NULL;
- R_Mesh_State(&m);
- R_Mesh_GetSpace(batchcount * 4);
- R_Mesh_CopyVertex3f(textverts, batchcount * 4);
- R_Mesh_CopyTexCoord2f(0, texttexcoords, batchcount * 4);
- }
- else
- {
- m.pointervertexcount = batchcount * 4;
- m.pointer_vertex = textverts;
- m.pointer_texcoord[0] = texttexcoords;
- m.pointer_color = NULL;
- R_Mesh_State(&m);
- }
R_Mesh_Draw(batchcount * 4, batchcount * 2, quadelements);
batchcount = 0;
- at = texttexcoords;
- av = textverts;
+ at = varray_texcoord2f[0];
+ av = varray_vertex3f;
}
}
x += w;
}
if (batchcount > 0)
- {
- if (gl_mesh_copyarrays.integer)
- {
- m.pointervertexcount = 0;
- m.pointer_vertex = NULL;
- m.pointer_texcoord[0] = NULL;
- m.pointer_color = NULL;
- R_Mesh_State(&m);
- R_Mesh_GetSpace(batchcount * 4);
- R_Mesh_CopyVertex3f(textverts, batchcount * 4);
- R_Mesh_CopyTexCoord2f(0, texttexcoords, batchcount * 4);
- }
- else
- {
- m.pointervertexcount = batchcount * 4;
- m.pointer_vertex = textverts;
- m.pointer_texcoord[0] = texttexcoords;
- m.pointer_color = NULL;
- R_Mesh_State(&m);
- }
R_Mesh_Draw(batchcount * 4, batchcount * 2, quadelements);
- }
break;
case DRAWQUEUE_MESH:
mesh = (void *)(dq + 1);
+ GL_VertexPointer(mesh->vertex3f);
+ GL_ColorPointer(mesh->color4f);
m.tex[0] = R_GetTexture(mesh->texture);
- GL_UseColorArray();
- if (gl_mesh_copyarrays.integer)
- {
- m.pointervertexcount = 0;
- m.pointer_vertex = NULL;
- m.pointer_texcoord[0] = NULL;
- m.pointer_color = NULL;
- R_Mesh_State(&m);
- R_Mesh_GetSpace(mesh->numvertices);
- R_Mesh_CopyVertex3f(mesh->vertex3f, mesh->numvertices);
- R_Mesh_CopyTexCoord2f(0, mesh->texcoord2f, mesh->numvertices);
- R_Mesh_CopyColor4f(mesh->color4f, mesh->numvertices);
- }
- else
- {
- m.pointervertexcount = mesh->numvertices;
- m.pointer_vertex = mesh->vertex3f;
- m.pointer_texcoord[0] = mesh->texcoord2f;
- m.pointer_color = mesh->color4f;
- R_Mesh_State(&m);
- }
+ m.pointer_texcoord[0] = mesh->texcoord2f;
+ R_Mesh_State_Texture(&m);
R_Mesh_Draw(mesh->numvertices, mesh->numtriangles, mesh->element3i);
currentpic = "\0";
break;
{
// all the blends ignore depth
memset(&m, 0, sizeof(m));
- m.depthdisable = true;
+ R_Mesh_State_Texture(&m);
+ GL_DepthMask(true);
+ GL_DepthTest(false);
if (v_color_enable.integer)
{
c[0] = v_color_white_r.value;
VectorScale(c, (float) (1 << v_overbrightbits.integer), c);
if (c[0] >= 1.01f || c[1] >= 1.01f || c[2] >= 1.01f)
{
- m.blendfunc1 = GL_DST_COLOR;
- m.blendfunc2 = GL_ONE;
- if (gl_mesh_copyarrays.integer)
- {
- R_Mesh_State(&m);
- R_Mesh_GetSpace(3);
- R_Mesh_CopyVertex3f(blendvertex3f, 3);
- }
- else
- {
- m.pointervertexcount = 3;
- m.pointer_vertex = blendvertex3f;
- R_Mesh_State(&m);
- }
+ GL_BlendFunc(GL_DST_COLOR, GL_ONE);
+ GL_VertexPointer(blendvertex3f);
while (c[0] >= 1.01f || c[1] >= 1.01f || c[2] >= 1.01f)
{
GL_Color(bound(0, c[0] - 1, 1), bound(0, c[1] - 1, 1), bound(0, c[2] - 1, 1), 1);
c[0] = c[1] = c[2] = v_brightness.value;
if (c[0] >= 0.01f || c[1] >= 0.01f || c[2] >= 0.01f)
{
- m.blendfunc1 = GL_ONE;
- m.blendfunc2 = GL_ONE;
- if (gl_mesh_copyarrays.integer)
- {
- m.pointervertexcount = 0;
- m.pointer_vertex = NULL;
- R_Mesh_State(&m);
- R_Mesh_GetSpace(3);
- R_Mesh_CopyVertex3f(blendvertex3f, 3);
- }
- else
- {
- m.pointervertexcount = 3;
- m.pointer_vertex = blendvertex3f;
- R_Mesh_State(&m);
- }
+ GL_BlendFunc(GL_ONE, GL_ONE);
+ GL_VertexPointer(blendvertex3f);
GL_Color(c[0], c[1], c[2], 1);
R_Mesh_Draw(3, 1, polygonelements);
}
#define MODELARRAY_TVECTOR 2
#define MODELARRAY_NORMAL 3
-void R_Model_Alias_GetMesh_Array3f(const entity_render_t *ent, aliasmesh_t *mesh, int whicharray, float *out3f)
+void R_Model_Alias_GetMesh_Array3f(const entity_render_t *ent, const aliasmesh_t *mesh, int whicharray, float *out3f)
{
int i, vertcount;
float lerp1, lerp2, lerp3, lerp4;
void R_DrawAliasModelCallback (const void *calldata1, int calldata2)
{
int c, fullbright, layernum, firstpass;
- float tint[3], fog, ifog, colorscale, ambientcolor4f[4], *fcolor;
+ float tint[3], fog, ifog, colorscale, ambientcolor4f[4];
vec3_t diff;
qbyte *bcolor;
rmeshstate_t m;
aliasmesh_t *mesh = ent->model->aliasdata_meshes + calldata2;
aliaslayer_t *layer;
aliasskin_t *skin;
- rcachearrayrequest_t request;
R_Mesh_Matrix(&ent->matrix);
|| ((layer->flags & ALIASLAYER_DIFFUSE) && (r_shadow_realtime_world.integer && r_ambient.integer <= 0 && r_fullbright.integer == 0 && !(ent->effects & EF_FULLBRIGHT))))
continue;
}
- memset(&m, 0, sizeof(m));
if (!firstpass || (ent->effects & EF_ADDITIVE))
{
- m.blendfunc1 = GL_SRC_ALPHA;
- m.blendfunc2 = GL_ONE;
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
+ GL_DepthMask(false);
}
else if ((skin->flags & ALIASSKIN_TRANSPARENT) || ent->alpha != 1.0)
{
- m.blendfunc1 = GL_SRC_ALPHA;
- m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ GL_DepthMask(false);
}
else
{
- m.blendfunc1 = GL_ONE;
- m.blendfunc2 = GL_ZERO;
+ GL_BlendFunc(GL_ONE, GL_ZERO);
+ GL_DepthMask(true);
}
+ GL_DepthTest(true);
firstpass = false;
expandaliasvert(mesh->num_vertices);
colorscale = r_colorscale;
- m.texrgbscale[0] = 1;
- m.tex[0] = R_GetTexture(layer->texture);
- if (gl_combine.integer && layer->flags & (ALIASLAYER_DIFFUSE | ALIASLAYER_SPECULAR))
+
+ memset(&m, 0, sizeof(m));
+ if (layer->texture != NULL)
{
- colorscale *= 0.25f;
- m.texrgbscale[0] = 4;
+ m.tex[0] = R_GetTexture(layer->texture);
+ m.pointer_texcoord[0] = mesh->data_texcoord2f;
+ if (gl_combine.integer && layer->flags & (ALIASLAYER_DIFFUSE | ALIASLAYER_SPECULAR))
+ {
+ colorscale *= 0.25f;
+ m.texrgbscale[0] = 4;
+ }
}
+ R_Mesh_State_Texture(&m);
+
c_alias_polys += mesh->num_triangles;
- if (gl_mesh_copyarrays.integer)
- {
- R_Mesh_State(&m);
- R_Mesh_GetSpace(mesh->num_vertices);
- if (layer->texture != NULL)
- R_Mesh_CopyTexCoord2f(0, mesh->data_texcoord2f, mesh->num_vertices);
- R_Model_Alias_GetMesh_Array3f(ent, mesh, MODELARRAY_VERTEX, varray_vertex3f);
- }
- else
- {
- m.pointervertexcount = mesh->num_vertices;
- memset(&request, 0, sizeof(request));
- request.data_size = mesh->num_vertices * sizeof(float[3]);
- request.id_pointer2 = mesh->data_aliasvertex3f;
- request.id_number1 = layernum;
- request.id_number2 = 0;
- request.id_number3 = CRC_Block((void *)ent->frameblend, sizeof(ent->frameblend));
- if (R_Mesh_CacheArray(&request))
- R_Model_Alias_GetMesh_Array3f(ent, mesh, MODELARRAY_VERTEX, request.data);
- m.pointer_vertex = request.data;
- m.pointer_texcoord[0] = layer->texture != NULL ? mesh->data_texcoord2f : NULL;
- }
+ GL_VertexPointer(varray_vertex3f);
+ R_Model_Alias_GetMesh_Array3f(ent, mesh, MODELARRAY_VERTEX, varray_vertex3f);
if (layer->flags & ALIASLAYER_FOG)
{
colorscale *= fog;
}
else
{
+ fullbright = !(layer->flags & ALIASLAYER_DIFFUSE) || r_fullbright.integer || (ent->effects & EF_FULLBRIGHT);
+ if (r_shadow_realtime_world.integer && !fullbright)
+ {
+ colorscale *= r_ambient.value * (2.0f / 128.0f);
+ fullbright = true;
+ }
if (layer->flags & (ALIASLAYER_COLORMAP_PANTS | ALIASLAYER_COLORMAP_SHIRT))
{
// 128-224 are backwards ranges
c = (ent->colormap & 0xF0);
c += (c >= 128 && c < 224) ? 4 : 12;
bcolor = (qbyte *) (&palette_complete[c]);
- fullbright = c >= 224;
+ fullbright = fullbright || c >= 224;
VectorScale(bcolor, (1.0f / 255.0f), tint);
}
else
- {
tint[0] = tint[1] = tint[2] = 1;
- fullbright = false;
- }
colorscale *= ifog;
- if (fullbright || !(layer->flags & ALIASLAYER_DIFFUSE) || r_fullbright.integer || (ent->effects & EF_FULLBRIGHT))
- GL_Color(tint[0] * colorscale, tint[1] * colorscale, tint[2] * colorscale, ent->alpha);
- else if (r_shadow_realtime_world.integer)
- {
- colorscale *= r_ambient.value * (2.0f / 128.0f);
+ if (fullbright)
GL_Color(tint[0] * colorscale, tint[1] * colorscale, tint[2] * colorscale, ent->alpha);
- }
else
{
if (R_LightModel(ambientcolor4f, ent, tint[0] * colorscale, tint[1] * colorscale, tint[2] * colorscale, ent->alpha, false))
{
- GL_UseColorArray();
- if (gl_mesh_copyarrays.integer)
- {
- R_Model_Alias_GetMesh_Array3f(ent, mesh, MODELARRAY_NORMAL, aliasvert_normal3f);
- R_LightModel_CalcVertexColors(ambientcolor4f, mesh->num_vertices, varray_vertex3f, aliasvert_normal3f, varray_color4f);
- }
- else
- {
- // request color4f cache
- request.data_size = mesh->num_vertices * sizeof(float[4]);
- request.id_pointer1 = ent;
- request.id_number2 = 2;
- request.id_number3 = CRC_Block((void *)ent->frameblend, sizeof(ent->frameblend)) + CRC_Block((void *)&ent->entlightstime, sizeof(ent->entlightstime));
- if (R_Mesh_CacheArray(&request))
- {
- // save off the color pointer before we blow away the request
- fcolor = request.data;
- m.pointer_color = fcolor;
- // request normal3f cache
- request.data_size = mesh->num_vertices * sizeof(float[3]);
- request.id_pointer1 = NULL;
- request.id_number2 = 3;
- request.id_number3 = CRC_Block((void *)ent->frameblend, sizeof(ent->frameblend));
- if (R_Mesh_CacheArray(&request))
- R_Model_Alias_GetMesh_Array3f(ent, mesh, MODELARRAY_NORMAL, request.data);
- R_LightModel_CalcVertexColors(ambientcolor4f, mesh->num_vertices, m.pointer_vertex, request.data, fcolor);
- }
- else
- m.pointer_color = request.data;
- }
+ GL_ColorPointer(varray_color4f);
+ R_Model_Alias_GetMesh_Array3f(ent, mesh, MODELARRAY_NORMAL, varray_normal3f);
+ R_LightModel_CalcVertexColors(ambientcolor4f, mesh->num_vertices, varray_vertex3f, varray_normal3f, varray_color4f);
}
else
GL_Color(ambientcolor4f[0], ambientcolor4f[1], ambientcolor4f[2], ambientcolor4f[3]);
}
}
- if (!gl_mesh_copyarrays.integer)
- R_Mesh_State(&m);
R_Mesh_Draw(mesh->num_vertices, mesh->num_triangles, mesh->data_element3i);
}
}
aliasskin_t *skin;
rmeshstate_t m;
float *v, plane[4], dist, projection[3], floororigin[3], surfnormal[3], lightdirection[3], v2[3];
- rcachearrayrequest_t request;
if ((ent->effects & EF_ADDITIVE) || ent->alpha < 1)
return;
R_Mesh_Matrix(&ent->matrix);
memset(&m, 0, sizeof(m));
- m.blendfunc1 = GL_SRC_ALPHA;
- m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
- if (gl_mesh_copyarrays.integer)
- R_Mesh_State(&m);
+ R_Mesh_State_Texture(&m);
+
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ GL_DepthMask(false);
+ GL_DepthTest(true);
+ GL_VertexPointer(varray_vertex3f);
GL_Color(0, 0, 0, 0.5);
// put a light direction in the entity's coordinate space
dist = -1.0f / DotProduct(projection, plane);
VectorScale(projection, dist, projection);
- memset(&request, 0, sizeof(request));
for (meshnum = 0, mesh = ent->model->aliasdata_meshes;meshnum < ent->model->aliasnum_meshes;meshnum++)
{
skin = R_FetchAliasSkin(ent, mesh);
if (skin->flags & ALIASSKIN_TRANSPARENT)
continue;
- if (gl_mesh_copyarrays.integer)
+ R_Model_Alias_GetMesh_Array3f(ent, mesh, MODELARRAY_VERTEX, varray_vertex3f);
+ for (i = 0, v = varray_vertex3f;i < mesh->num_vertices;i++, v += 3)
{
- R_Mesh_GetSpace(mesh->num_vertices);
- R_Model_Alias_GetMesh_Array3f(ent, mesh, MODELARRAY_VERTEX, varray_vertex3f);
- for (i = 0, v = varray_vertex3f;i < mesh->num_vertices;i++, v += 3)
- {
- dist = DotProduct(v, plane) - plane[3];
- if (dist > 0)
- VectorMA(v, dist, projection, v);
- }
- }
- else
- {
- request.data_size = mesh->num_vertices * sizeof(float[3]);
- request.id_pointer1 = mesh;
- request.id_number1 = CRC_Block((void *)&ent->matrix, sizeof(ent->matrix));
- request.id_number2 = CRC_Block((void *)&plane, sizeof(plane));
- request.id_number3 = CRC_Block((void *)&ent->frameblend, sizeof(ent->frameblend));
- m.pointervertexcount = mesh->num_vertices;
- if (R_Mesh_CacheArray(&request))
- {
- R_Model_Alias_GetMesh_Array3f(ent, mesh, MODELARRAY_VERTEX, request.data);
- for (i = 0, v = request.data;i < mesh->num_vertices;i++, v += 3)
- {
- dist = DotProduct(v, plane) - plane[3];
- if (dist > 0)
- VectorMA(v, dist, projection, v);
- }
- }
- m.pointer_vertex = request.data;
- R_Mesh_State(&m);
+ dist = DotProduct(v, plane) - plane[3];
+ if (dist > 0)
+ VectorMA(v, dist, projection, v);
}
c_alias_polys += mesh->num_triangles;
R_Mesh_Draw(mesh->num_vertices, mesh->num_triangles, mesh->data_element3i);
skin = R_FetchAliasSkin(ent, mesh);
if (skin->flags & ALIASSKIN_TRANSPARENT)
continue;
- R_Mesh_GetSpace(mesh->num_vertices * 2);
R_Model_Alias_GetMesh_Array3f(ent, mesh, MODELARRAY_VERTEX, varray_vertex3f);
- R_Shadow_Volume(mesh->num_vertices, mesh->num_triangles, mesh->data_element3i, mesh->data_neighbor3i, relativelightorigin, lightradius, projectdistance);
+ R_Shadow_Volume(mesh->num_vertices, mesh->num_triangles, varray_vertex3f, mesh->data_element3i, mesh->data_neighbor3i, relativelightorigin, lightradius, projectdistance);
}
}
}
}
ifog = 1 - fog;
- memset(&mstate, 0, sizeof(mstate));
if (ent->effects & EF_ADDITIVE)
{
- mstate.blendfunc1 = GL_SRC_ALPHA;
- mstate.blendfunc2 = GL_ONE;
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
+ GL_DepthMask(false);
}
else if (ent->alpha != 1.0 || R_TextureHasAlpha(texture))
{
- mstate.blendfunc1 = GL_SRC_ALPHA;
- mstate.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ GL_DepthMask(false);
}
else
{
- mstate.blendfunc1 = GL_ONE;
- mstate.blendfunc2 = GL_ZERO;
+ GL_BlendFunc(GL_ONE, GL_ZERO);
+ GL_DepthMask(true);
}
+ GL_DepthTest(true);
+ GL_VertexPointer(varray_vertex3f);
+
+ memset(&mstate, 0, sizeof(mstate));
colorscale = r_colorscale;
if (gl_combine.integer)
{
colorscale *= 0.25f;
}
mstate.tex[0] = R_GetTexture(texture);
- R_Mesh_State(&mstate);
+ mstate.pointer_texcoord[0] = ent->model->zymdata_texcoords;
+ R_Mesh_State_Texture(&mstate);
+
ZymoticLerpBones(ent->model->zymnum_bones, (zymbonematrix *) ent->model->zymdata_poses, ent->frameblend, ent->model->zymdata_bones);
- R_Mesh_GetSpace(numverts);
ZymoticTransformVerts(numverts, varray_vertex3f, ent->model->zymdata_vertbonecounts, ent->model->zymdata_verts);
- R_Mesh_CopyTexCoord2f(0, ent->model->zymdata_texcoords, ent->model->zymnum_verts);
ZymoticCalcNormal3f(numverts, varray_vertex3f, aliasvert_normal3f, ent->model->zymnum_shaders, ent->model->zymdata_renderlist);
if (R_LightModel(ambientcolor4f, ent, ifog * colorscale, ifog * colorscale, ifog * colorscale, ent->alpha, false))
{
- GL_UseColorArray();
+ GL_ColorPointer(varray_color4f);
R_LightModel_CalcVertexColors(ambientcolor4f, numverts, varray_vertex3f, aliasvert_normal3f, varray_color4f);
}
else
if (fog)
{
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ GL_DepthMask(false);
+ GL_DepthTest(true);
+ GL_VertexPointer(varray_vertex3f);
+
memset(&mstate, 0, sizeof(mstate));
- mstate.blendfunc1 = GL_SRC_ALPHA;
- mstate.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
// FIXME: need alpha mask for fogging...
//mstate.tex[0] = R_GetTexture(texture);
- R_Mesh_State(&mstate);
+ //mstate.pointer_texcoord = ent->model->zymdata_texcoords;
+ R_Mesh_State_Texture(&mstate);
+
GL_Color(fogcolor[0] * r_colorscale, fogcolor[1] * r_colorscale, fogcolor[2] * r_colorscale, ent->alpha * fog);
- R_Mesh_GetSpace(numverts);
ZymoticTransformVerts(numverts, varray_vertex3f, ent->model->zymdata_vertbonecounts, ent->model->zymdata_verts);
R_Mesh_Draw(numverts, numtriangles, elements);
c_alias_polys += numtriangles;
if (visiblevolumes)
{
memset(&m, 0, sizeof(m));
- m.blendfunc1 = GL_ONE;
- m.blendfunc2 = GL_ONE;
- if (r_shadow_visiblevolumes.integer >= 2)
- m.depthdisable = true;
- R_Mesh_State(&m);
+ R_Mesh_State_Texture(&m);
+
+ GL_BlendFunc(GL_ONE, GL_ONE);
+ GL_DepthMask(false);
+ GL_DepthTest(r_shadow_visiblevolumes.integer < 2);
qglDisable(GL_CULL_FACE);
GL_Color(0.0 * r_colorscale, 0.0125 * r_colorscale, 0.1 * r_colorscale, 1);
}
}
}
- if (!visiblevolumes)
+ if (visiblevolumes)
+ qglEnable(GL_CULL_FACE);
+ else
R_Shadow_Stage_End();
- qglEnable(GL_CULL_FACE);
qglDisable(GL_SCISSOR_TEST);
}
{
rmeshstate_t m;
float r;
+ float vertex3f[3*3];
if (r_refdef.viewblend[3] < 0.01f)
return;
- memset(&m, 0, sizeof(m));
- m.blendfunc1 = GL_SRC_ALPHA;
- m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
- m.depthdisable = true; // magic
R_Mesh_Matrix(&r_identitymatrix);
- R_Mesh_State(&m);
- R_Mesh_GetSpace(3);
- r = 64000;
- varray_vertex3f[0] = r_origin[0] + vpn[0] * 1.5 - vright[0] * r - vup[0] * r;
- varray_vertex3f[1] = r_origin[1] + vpn[1] * 1.5 - vright[1] * r - vup[1] * r;
- varray_vertex3f[2] = r_origin[2] + vpn[2] * 1.5 - vright[2] * r - vup[2] * r;
- varray_vertex3f[3] = r_origin[0] + vpn[0] * 1.5 - vright[0] * r + vup[0] * r * 3;
- varray_vertex3f[4] = r_origin[1] + vpn[1] * 1.5 - vright[1] * r + vup[1] * r * 3;
- varray_vertex3f[5] = r_origin[2] + vpn[2] * 1.5 - vright[2] * r + vup[2] * r * 3;
- varray_vertex3f[6] = r_origin[0] + vpn[0] * 1.5 + vright[0] * r * 3 - vup[0] * r;
- varray_vertex3f[7] = r_origin[1] + vpn[1] * 1.5 + vright[1] * r * 3 - vup[1] * r;
- varray_vertex3f[8] = r_origin[2] + vpn[2] * 1.5 + vright[2] * r * 3 - vup[2] * r;
+ memset(&m, 0, sizeof(m));
+ R_Mesh_State_Texture(&m);
+
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ GL_DepthMask(true);
+ GL_DepthTest(false); // magic
+ GL_VertexPointer(vertex3f);
GL_Color(r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]);
+ r = 64000;
+ vertex3f[0] = r_origin[0] + vpn[0] * 1.5 - vright[0] * r - vup[0] * r;
+ vertex3f[1] = r_origin[1] + vpn[1] * 1.5 - vright[1] * r - vup[1] * r;
+ vertex3f[2] = r_origin[2] + vpn[2] * 1.5 - vright[2] * r - vup[2] * r;
+ vertex3f[3] = r_origin[0] + vpn[0] * 1.5 - vright[0] * r + vup[0] * r * 3;
+ vertex3f[4] = r_origin[1] + vpn[1] * 1.5 - vright[1] * r + vup[1] * r * 3;
+ vertex3f[5] = r_origin[2] + vpn[2] * 1.5 - vright[2] * r + vup[2] * r * 3;
+ vertex3f[6] = r_origin[0] + vpn[0] * 1.5 + vright[0] * r * 3 - vup[0] * r;
+ vertex3f[7] = r_origin[1] + vpn[1] * 1.5 + vright[1] * r * 3 - vup[1] * r;
+ vertex3f[8] = r_origin[2] + vpn[2] * 1.5 + vright[2] * r * 3 - vup[2] * r;
R_Mesh_Draw(3, 1, polygonelements);
}
void R_DrawBBoxMesh(vec3_t mins, vec3_t maxs, float cr, float cg, float cb, float ca)
{
int i;
- float *v, *c, f1, f2, diff[3];
+ float *v, *c, f1, f2, diff[3], vertex3f[8*3], color4f[8*4];
rmeshstate_t m;
- m.blendfunc1 = GL_SRC_ALPHA;
- m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ GL_DepthMask(false);
+ GL_DepthTest(true);
R_Mesh_Matrix(&r_identitymatrix);
- R_Mesh_State(&m);
+
+ memset(&m, 0, sizeof(m));
+ R_Mesh_State_Texture(&m);
R_Mesh_GetSpace(8);
- varray_vertex[ 0] = mins[0];varray_vertex[ 1] = mins[1];varray_vertex[ 2] = mins[2];
- varray_vertex[ 4] = maxs[0];varray_vertex[ 5] = mins[1];varray_vertex[ 6] = mins[2];
- varray_vertex[ 8] = mins[0];varray_vertex[ 9] = maxs[1];varray_vertex[10] = mins[2];
- varray_vertex[12] = maxs[0];varray_vertex[13] = maxs[1];varray_vertex[14] = mins[2];
- varray_vertex[16] = mins[0];varray_vertex[17] = mins[1];varray_vertex[18] = maxs[2];
- varray_vertex[20] = maxs[0];varray_vertex[21] = mins[1];varray_vertex[22] = maxs[2];
- varray_vertex[24] = mins[0];varray_vertex[25] = maxs[1];varray_vertex[26] = maxs[2];
- varray_vertex[28] = maxs[0];varray_vertex[29] = maxs[1];varray_vertex[30] = maxs[2];
- R_FillColors(varray_color, 8, cr * r_colorscale, cg * r_colorscale, cb * r_colorscale, ca);
+ vertex3f[ 0] = mins[0];vertex3f[ 1] = mins[1];vertex3f[ 2] = mins[2];
+ vertex3f[ 3] = maxs[0];vertex3f[ 4] = mins[1];vertex3f[ 5] = mins[2];
+ vertex3f[ 6] = mins[0];vertex3f[ 7] = maxs[1];vertex3f[ 8] = mins[2];
+ vertex3f[ 9] = maxs[0];vertex3f[10] = maxs[1];vertex3f[11] = mins[2];
+ vertex3f[12] = mins[0];vertex3f[13] = mins[1];vertex3f[14] = maxs[2];
+ vertex3f[15] = maxs[0];vertex3f[16] = mins[1];vertex3f[17] = maxs[2];
+ vertex3f[18] = mins[0];vertex3f[19] = maxs[1];vertex3f[20] = maxs[2];
+ vertex3f[21] = maxs[0];vertex3f[22] = maxs[1];vertex3f[23] = maxs[2];
+ GL_ColorPointer(color);
+ R_FillColors(color, 8, cr * r_colorscale, cg * r_colorscale, cb * r_colorscale, ca);
if (fogenabled)
{
- for (i = 0, v = varray_vertex, c = varray_color;i < 8;i++, v += 4, c += 4)
+ for (i = 0, v = vertex, c = color;i < 8;i++, v += 4, c += 4)
{
VectorSubtract(v, r_origin, diff);
f2 = exp(fogdensity/DotProduct(diff, diff));
c[2] = c[2] * f1 + fogcolor[2] * f2;
}
}
- GL_UseColorArray();
R_Mesh_Draw(8, 12);
}
*/
1, 3, 4
};
+float nomodelvertex3f[6*3] =
+{
+ -16, 0, 0,
+ 16, 0, 0,
+ 0, -16, 0,
+ 0, 16, 0,
+ 0, 0, -16,
+ 0, 0, 16
+};
+
+float nomodelcolor4f[6*4] =
+{
+ 0.0f, 0.0f, 0.5f, 1.0f,
+ 0.0f, 0.0f, 0.5f, 1.0f,
+ 0.0f, 0.5f, 0.0f, 1.0f,
+ 0.0f, 0.5f, 0.0f, 1.0f,
+ 0.5f, 0.0f, 0.0f, 1.0f,
+ 0.5f, 0.0f, 0.0f, 1.0f
+};
+
void R_DrawNoModelCallback(const void *calldata1, int calldata2)
{
const entity_render_t *ent = calldata1;
int i;
float f1, f2, *c, diff[3];
+ float color4f[6*4];
rmeshstate_t m;
+ R_Mesh_Matrix(&ent->matrix);
+
memset(&m, 0, sizeof(m));
+ R_Mesh_State_Texture(&m);
+
if (ent->flags & EF_ADDITIVE)
{
- m.blendfunc1 = GL_SRC_ALPHA;
- m.blendfunc2 = GL_ONE;
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
+ GL_DepthMask(false);
}
else if (ent->alpha < 1)
{
- m.blendfunc1 = GL_SRC_ALPHA;
- m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ GL_DepthMask(false);
}
else
{
- m.blendfunc1 = GL_ONE;
- m.blendfunc2 = GL_ZERO;
+ GL_BlendFunc(GL_ONE, GL_ZERO);
+ GL_DepthMask(true);
}
- R_Mesh_Matrix(&ent->matrix);
- R_Mesh_State(&m);
-
- GL_UseColorArray();
- R_Mesh_GetSpace(6);
- varray_vertex3f[ 0] = -16;varray_vertex3f[ 1] = 0;varray_vertex3f[ 2] = 0;
- varray_vertex3f[ 3] = 16;varray_vertex3f[ 4] = 0;varray_vertex3f[ 5] = 0;
- varray_vertex3f[ 6] = 0;varray_vertex3f[ 7] = -16;varray_vertex3f[ 8] = 0;
- varray_vertex3f[ 9] = 0;varray_vertex3f[10] = 16;varray_vertex3f[11] = 0;
- varray_vertex3f[12] = 0;varray_vertex3f[13] = 0;varray_vertex3f[14] = -16;
- varray_vertex3f[15] = 0;varray_vertex3f[16] = 0;varray_vertex3f[17] = 16;
- varray_color4f[ 0] = 0.00f * r_colorscale;varray_color4f[ 1] = 0.00f * r_colorscale;varray_color4f[ 2] = 0.50f * r_colorscale;varray_color4f[ 3] = ent->alpha;
- varray_color4f[ 4] = 0.00f * r_colorscale;varray_color4f[ 5] = 0.00f * r_colorscale;varray_color4f[ 6] = 0.50f * r_colorscale;varray_color4f[ 7] = ent->alpha;
- varray_color4f[ 8] = 0.00f * r_colorscale;varray_color4f[ 9] = 0.50f * r_colorscale;varray_color4f[10] = 0.00f * r_colorscale;varray_color4f[11] = ent->alpha;
- varray_color4f[12] = 0.00f * r_colorscale;varray_color4f[13] = 0.50f * r_colorscale;varray_color4f[14] = 0.00f * r_colorscale;varray_color4f[15] = ent->alpha;
- varray_color4f[16] = 0.50f * r_colorscale;varray_color4f[17] = 0.00f * r_colorscale;varray_color4f[18] = 0.00f * r_colorscale;varray_color4f[19] = ent->alpha;
- varray_color4f[20] = 0.50f * r_colorscale;varray_color4f[21] = 0.00f * r_colorscale;varray_color4f[22] = 0.00f * r_colorscale;varray_color4f[23] = ent->alpha;
+ GL_DepthTest(true);
+ GL_VertexPointer(nomodelvertex3f);
if (fogenabled)
{
+ memcpy(color4f, nomodelcolor4f, sizeof(float[6*4]));
+ GL_ColorPointer(color4f);
VectorSubtract(ent->origin, r_origin, diff);
f2 = exp(fogdensity/DotProduct(diff, diff));
f1 = 1 - f2;
- for (i = 0, c = varray_color4f;i < 6;i++, c += 4)
+ for (i = 0, c = color4f;i < 6;i++, c += 4)
{
c[0] = (c[0] * f1 + fogcolor[0] * f2) * r_colorscale;
c[1] = (c[1] * f1 + fogcolor[1] * f2) * r_colorscale;
c[2] = (c[2] * f1 + fogcolor[2] * f2) * r_colorscale;
+ c[3] *= ent->alpha;
}
}
- else
+ else if (r_colorscale != 1 || ent->alpha != 1)
{
- for (i = 0, c = varray_color4f;i < 6;i++, c += 4)
+ memcpy(color4f, nomodelcolor4f, sizeof(float[6*4]));
+ GL_ColorPointer(color4f);
+ for (i = 0, c = color4f;i < 6;i++, c += 4)
{
c[0] *= r_colorscale;
c[1] *= r_colorscale;
c[2] *= r_colorscale;
+ c[3] *= ent->alpha;
}
}
+ else
+ GL_ColorPointer(nomodelcolor4f);
R_Mesh_Draw(6, 8, nomodelelements);
}
vert[11] = org2[2] + width * right2[2];
}
-void R_DrawSpriteMesh(const vec3_t origin, const vec3_t left, const vec3_t up, float scalex1, float scalex2, float scaley1, float scaley2)
+float spritetexcoord2f[4*2] = {0, 1, 0, 0, 1, 0, 1, 1};
+
+void R_DrawSprite(int blendfunc1, int blendfunc2, rtexture_t *texture, int depthdisable, const vec3_t origin, const vec3_t left, const vec3_t up, float scalex1, float scalex2, float scaley1, float scaley2, float cr, float cg, float cb, float ca)
{
- R_Mesh_GetSpace(4);
- varray_texcoord2f[0][0] = 0;varray_texcoord2f[0][1] = 1;
- varray_texcoord2f[0][2] = 0;varray_texcoord2f[0][3] = 0;
- varray_texcoord2f[0][4] = 1;varray_texcoord2f[0][5] = 0;
- varray_texcoord2f[0][6] = 1;varray_texcoord2f[0][7] = 1;
+ float diff[3];
+ rmeshstate_t m;
+
+ if (fogenabled)
+ {
+ VectorSubtract(origin, r_origin, diff);
+ ca *= 1 - exp(fogdensity/DotProduct(diff,diff));
+ }
+
+ R_Mesh_Matrix(&r_identitymatrix);
+ GL_Color(cr * r_colorscale, cg * r_colorscale, cb * r_colorscale, ca);
+ GL_VertexPointer(varray_vertex3f);
+ GL_BlendFunc(blendfunc1, blendfunc2);
+ GL_DepthMask(false);
+ GL_DepthTest(!depthdisable);
+
+ memset(&m, 0, sizeof(m));
+ m.tex[0] = R_GetTexture(texture);
+ m.pointer_texcoord[0] = spritetexcoord2f;
+ R_Mesh_State_Texture(&m);
+
varray_vertex3f[ 0] = origin[0] + left[0] * scalex2 + up[0] * scaley1;
varray_vertex3f[ 1] = origin[1] + left[1] * scalex2 + up[1] * scaley1;
varray_vertex3f[ 2] = origin[2] + left[2] * scalex2 + up[2] * scaley1;
R_Mesh_Matrix(&ent->matrix);
- // draw depth-only polys
- memset(&m, 0, sizeof(m));
+ GL_Color(fogcolor[0] * r_colorscale, fogcolor[1] * r_colorscale, fogcolor[2] * r_colorscale, 1);
if (skyrendermasked)
{
+ // depth-only (masking)
qglColorMask(0,0,0,0);
// just to make sure that braindead drivers don't draw anything
// despite that colormask...
- m.blendfunc1 = GL_ZERO;
- m.blendfunc2 = GL_ONE;
+ GL_BlendFunc(GL_ZERO, GL_ONE);
}
else
{
// fog sky
- m.blendfunc1 = GL_ONE;
- m.blendfunc2 = GL_ZERO;
+ GL_BlendFunc(GL_ONE, GL_ZERO);
}
- m.depthwrite = true;
- R_Mesh_State(&m);
+ GL_DepthMask(true);
+ GL_DepthTest(true);
+
+ memset(&m, 0, sizeof(m));
+ R_Mesh_State_Texture(&m);
+
while((surf = *surfchain++) != NULL)
{
if (surf->visframe == r_framecount)
{
for (mesh = surf->mesh;mesh;mesh = mesh->chain)
{
- GL_Color(fogcolor[0] * r_colorscale, fogcolor[1] * r_colorscale, fogcolor[2] * r_colorscale, 1);
- R_Mesh_GetSpace(mesh->numverts);
- R_Mesh_CopyVertex3f(mesh->vertex3f, mesh->numverts);
+ GL_VertexPointer(mesh->vertex3f);
R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->element3i);
}
}
float alpha;
float modelorg[3];
texture_t *texture;
- Matrix4x4_Transform(&ent->inversematrix, r_origin, modelorg);
+ matrix4x4_t tempmatrix;
+
+ // scrolling in texture matrix
+ Matrix4x4_CreateTranslate(&tempmatrix, sin(cl.time) * 0.125, sin(cl.time * 0.8f) * 0.125, 0);
+ R_Mesh_TextureMatrix(0, &tempmatrix);
R_Mesh_Matrix(&ent->matrix);
+ Matrix4x4_Transform(&ent->inversematrix, r_origin, modelorg);
memset(&m, 0, sizeof(m));
texture = surf->texinfo->texture->currentframe;
alpha = texture->currentalpha;
if (texture->rendertype == SURFRENDER_ADD)
{
- m.blendfunc1 = GL_SRC_ALPHA;
- m.blendfunc2 = GL_ONE;
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
+ GL_DepthMask(false);
}
else if (texture->rendertype == SURFRENDER_ALPHA)
{
- m.blendfunc1 = GL_SRC_ALPHA;
- m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ GL_DepthMask(false);
}
else
{
- m.blendfunc1 = GL_ONE;
- m.blendfunc2 = GL_ZERO;
+ GL_BlendFunc(GL_ONE, GL_ZERO);
+ GL_DepthMask(true);
}
m.tex[0] = R_GetTexture(texture->skin.base);
colorscale = r_colorscale;
m.texrgbscale[0] = 4;
colorscale *= 0.25f;
}
- R_Mesh_State(&m);
- GL_UseColorArray();
+ GL_DepthTest(true);
+ GL_ColorPointer(varray_color4f);
for (mesh = surf->mesh;mesh;mesh = mesh->chain)
{
- R_Mesh_GetSpace(mesh->numverts);
- R_Mesh_CopyVertex3f(mesh->vertex3f, mesh->numverts);
- R_ScrollTexCoord2f(varray_texcoord2f[0], mesh->texcoordtexture2f, mesh->numverts, sin(cl.time) * 0.125f, sin(cl.time * 0.8f) * 0.125f);
+ GL_VertexPointer(mesh->vertex3f);
+ m.pointer_texcoord[0] = mesh->texcoordtexture2f;
+ R_Mesh_State_Texture(&m);
f = surf->flags & SURF_DRAWFULLBRIGHT ? 1.0f : ((surf->flags & SURF_LIGHTMAP) ? 0 : 0.5f);
R_FillColors(varray_color4f, mesh->numverts, f, f, f, alpha);
if (!(surf->flags & SURF_DRAWFULLBRIGHT || ent->effects & EF_FULLBRIGHT))
if (fogenabled)
{
memset(&m, 0, sizeof(m));
- m.blendfunc1 = GL_SRC_ALPHA;
- m.blendfunc2 = GL_ONE;
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
+ GL_DepthMask(false);
+ GL_DepthTest(true);
m.tex[0] = R_GetTexture(texture->skin.fog);
- R_Mesh_State(&m);
for (mesh = surf->mesh;mesh;mesh = mesh->chain)
{
- R_Mesh_GetSpace(mesh->numverts);
- R_Mesh_CopyVertex3f(mesh->vertex3f, mesh->numverts);
- if (m.tex[0])
- R_Mesh_CopyTexCoord2f(0, mesh->texcoordtexture2f, mesh->numverts);
+ GL_VertexPointer(mesh->vertex3f);
+ m.pointer_texcoord[0] = mesh->texcoordtexture2f;
+ GL_ColorPointer(varray_color4f);
+ R_Mesh_State_Texture(&m);
RSurf_FogPassColors_Vertex3f_Color4f(mesh->vertex3f, varray_color4f, fogcolor[0], fogcolor[1], fogcolor[2], alpha, r_colorscale, mesh->numverts, modelorg);
R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->element3i);
}
}
+
+ Matrix4x4_CreateIdentity(&tempmatrix);
+ R_Mesh_TextureMatrix(0, &tempmatrix);
}
static void RSurfShader_Water(const entity_render_t *ent, const texture_t *texture, msurface_t **surfchain)
float base, colorscale;
const surfmesh_t *mesh;
rmeshstate_t m;
- rcachearrayrequest_t request;
float modelorg[3];
Matrix4x4_Transform(&ent->inversematrix, r_origin, modelorg);
- memset(&request, 0, sizeof(request));
memset(&m, 0, sizeof(m));
if (rendertype == SURFRENDER_ADD)
{
- m.blendfunc1 = GL_SRC_ALPHA;
- m.blendfunc2 = GL_ONE;
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
+ GL_DepthMask(false);
}
else if (rendertype == SURFRENDER_ALPHA)
{
- m.blendfunc1 = GL_SRC_ALPHA;
- m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ GL_DepthMask(false);
}
else
{
- m.blendfunc1 = GL_ONE;
- m.blendfunc2 = GL_ZERO;
+ GL_BlendFunc(GL_ONE, GL_ZERO);
+ GL_DepthMask(true);
}
m.tex[0] = R_GetTexture(texture->skin.base);
colorscale = r_colorscale;
colorscale *= 0.25f;
}
base = ent->effects & EF_FULLBRIGHT ? 2.0f : r_ambient.value * (1.0f / 64.0f);
- R_Mesh_State(&m);
- GL_UseColorArray();
+ GL_DepthTest(true);
+ GL_ColorPointer(varray_color4f);
for (mesh = surf->mesh;mesh;mesh = mesh->chain)
{
- if (gl_mesh_copyarrays.integer)
- {
- R_Mesh_GetSpace(mesh->numverts);
- R_Mesh_CopyVertex3f(mesh->vertex3f, mesh->numverts);
- R_Mesh_CopyTexCoord2f(0, mesh->texcoordtexture2f, mesh->numverts);
- R_FillColors(varray_color4f, mesh->numverts, base, base, base, currentalpha);
- if (!(ent->effects & EF_FULLBRIGHT))
- {
- if (surf->dlightframe == r_framecount)
- RSurf_LightSeparate_Vertex3f_Color4f(&ent->inversematrix, surf->dlightbits, mesh->numverts, mesh->vertex3f, varray_color4f, 1);
- if (surf->flags & SURF_LIGHTMAP)
- RSurf_AddLightmapToVertexColors_Color4f(mesh->lightmapoffsets, varray_color4f, mesh->numverts, surf->samples, ((surf->extents[0]>>4)+1)*((surf->extents[1]>>4)+1)*3, surf->styles);
- }
- RSurf_FogColors_Vertex3f_Color4f(mesh->vertex3f, varray_color4f, colorscale, mesh->numverts, modelorg);
- R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->element3i);
- }
- else
+ GL_VertexPointer(mesh->vertex3f);
+ m.pointer_texcoord[0] = mesh->texcoordtexture2f;
+ R_Mesh_State_Texture(&m);
+ R_FillColors(varray_color4f, mesh->numverts, base, base, base, currentalpha);
+ if (!(ent->effects & EF_FULLBRIGHT))
{
- m.pointervertexcount = mesh->numverts;
- m.pointer_vertex = mesh->vertex3f;
- m.pointer_texcoord[0] = mesh->texcoordtexture2f;
- // LordHavoc: this is not caching at all (difficult to
- // cache fogging information), it's just (ab)using the
- // cache system to get some memory
- request.data_size = mesh->numverts * sizeof(float[4]);
- request.id_pointer1 = ent;
- request.id_pointer2 = mesh;
- request.id_number1 = r_framecount;
- if (R_Mesh_CacheArray(&request))
- {
- R_FillColors(request.data, mesh->numverts, base, base, base, currentalpha);
- if (!(ent->effects & EF_FULLBRIGHT))
- {
- if (surf->dlightframe == r_framecount)
- RSurf_LightSeparate_Vertex3f_Color4f(&ent->inversematrix, surf->dlightbits, mesh->numverts, mesh->vertex3f, request.data, 1);
- if (surf->flags & SURF_LIGHTMAP)
- RSurf_AddLightmapToVertexColors_Color4f(mesh->lightmapoffsets, request.data, mesh->numverts, surf->samples, ((surf->extents[0]>>4)+1)*((surf->extents[1]>>4)+1)*3, surf->styles);
- }
- RSurf_FogColors_Vertex3f_Color4f(mesh->vertex3f, request.data, colorscale, mesh->numverts, modelorg);
- }
- m.pointer_color = request.data;
- R_Mesh_State(&m);
+ if (surf->dlightframe == r_framecount)
+ RSurf_LightSeparate_Vertex3f_Color4f(&ent->inversematrix, surf->dlightbits, mesh->numverts, mesh->vertex3f, varray_color4f, 1);
+ if (surf->flags & SURF_LIGHTMAP)
+ RSurf_AddLightmapToVertexColors_Color4f(mesh->lightmapoffsets, varray_color4f, mesh->numverts, surf->samples, ((surf->extents[0]>>4)+1)*((surf->extents[1]>>4)+1)*3, surf->styles);
}
+ RSurf_FogColors_Vertex3f_Color4f(mesh->vertex3f, varray_color4f, colorscale, mesh->numverts, modelorg);
+ R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->element3i);
}
}
{
const surfmesh_t *mesh;
rmeshstate_t m;
- rcachearrayrequest_t request;
float modelorg[3];
Matrix4x4_Transform(&ent->inversematrix, r_origin, modelorg);
- memset(&request, 0, sizeof(request));
memset(&m, 0, sizeof(m));
- m.blendfunc1 = GL_SRC_ALPHA;
- m.blendfunc2 = GL_ONE;
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
+ GL_DepthMask(false);
+ GL_DepthTest(true);
m.tex[0] = R_GetTexture(texture->skin.glow);
- R_Mesh_State(&m);
- GL_UseColorArray();
+ GL_ColorPointer(varray_color4f);
for (mesh = surf->mesh;mesh;mesh = mesh->chain)
{
- if (gl_mesh_copyarrays.integer)
- {
- R_Mesh_GetSpace(mesh->numverts);
- R_Mesh_CopyVertex3f(mesh->vertex3f, mesh->numverts);
- R_Mesh_CopyTexCoord2f(0, mesh->texcoordtexture2f, mesh->numverts);
- RSurf_FoggedColors_Vertex3f_Color4f(mesh->vertex3f, varray_color4f, 1, 1, 1, currentalpha, r_colorscale, mesh->numverts, modelorg);
- }
- else
- {
- m.pointervertexcount = mesh->numverts;
- m.pointer_vertex = mesh->vertex3f;
- if (m.tex[0])
- m.pointer_texcoord[0] = mesh->texcoordtexture2f;
- // LordHavoc: this is not caching at all (difficult to
- // cache fogging information), it's just (ab)using the
- // cache system to get some memory
- request.data_size = mesh->numverts * sizeof(float[4]);
- request.id_pointer1 = ent;
- request.id_pointer2 = mesh;
- request.id_number1 = r_framecount;
- if (R_Mesh_CacheArray(&request))
- RSurf_FoggedColors_Vertex3f_Color4f(mesh->vertex3f, request.data, 1, 1, 1, currentalpha, r_colorscale, mesh->numverts, modelorg);
- m.pointer_color = request.data;
- R_Mesh_State(&m);
- }
+ GL_VertexPointer(mesh->vertex3f);
+ if (m.tex[0])
+ m.pointer_texcoord[0] = mesh->texcoordtexture2f;
+ R_Mesh_State_Texture(&m);
+ RSurf_FoggedColors_Vertex3f_Color4f(mesh->vertex3f, varray_color4f, 1, 1, 1, currentalpha, r_colorscale, mesh->numverts, modelorg);
R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->element3i);
}
}
{
const surfmesh_t *mesh;
rmeshstate_t m;
- rcachearrayrequest_t request;
float modelorg[3];
Matrix4x4_Transform(&ent->inversematrix, r_origin, modelorg);
- memset(&request, 0, sizeof(request));
memset(&m, 0, sizeof(m));
- m.blendfunc1 = GL_SRC_ALPHA;
- m.blendfunc2 = GL_ONE;
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
+ GL_DepthMask(false);
+ GL_DepthTest(true);
m.tex[0] = R_GetTexture(texture->skin.fog);
- R_Mesh_State(&m);
- GL_UseColorArray();
+ GL_ColorPointer(varray_color4f);
for (mesh = surf->mesh;mesh;mesh = mesh->chain)
{
- if (gl_mesh_copyarrays.integer)
- {
- R_Mesh_GetSpace(mesh->numverts);
- R_Mesh_CopyVertex3f(mesh->vertex3f, mesh->numverts);
- if (m.tex[0])
- R_Mesh_CopyTexCoord2f(0, mesh->texcoordtexture2f, mesh->numverts);
- RSurf_FogPassColors_Vertex3f_Color4f(mesh->vertex3f, varray_color4f, fogcolor[0], fogcolor[1], fogcolor[2], currentalpha, r_colorscale, mesh->numverts, modelorg);
- }
- else
- {
- m.pointervertexcount = mesh->numverts;
- m.pointer_vertex = mesh->vertex3f;
- if (m.tex[0])
- m.pointer_texcoord[0] = mesh->texcoordtexture2f;
- // LordHavoc: this is not caching at all (difficult to
- // cache fogging information), it's just (ab)using the
- // cache system to get some memory
- request.data_size = mesh->numverts * sizeof(float[4]);
- request.id_pointer1 = ent;
- request.id_pointer2 = mesh;
- request.id_number1 = r_framecount;
- if (R_Mesh_CacheArray(&request))
- RSurf_FogPassColors_Vertex3f_Color4f(mesh->vertex3f, request.data, fogcolor[0], fogcolor[1], fogcolor[2], currentalpha, r_colorscale, mesh->numverts, modelorg);
- m.pointer_color = request.data;
- R_Mesh_State(&m);
- }
+ GL_VertexPointer(mesh->vertex3f);
+ if (m.tex[0])
+ m.pointer_texcoord[0] = mesh->texcoordtexture2f;
+ R_Mesh_State_Texture(&m);
+ RSurf_FogPassColors_Vertex3f_Color4f(mesh->vertex3f, varray_color4f, fogcolor[0], fogcolor[1], fogcolor[2], currentalpha, r_colorscale, mesh->numverts, modelorg);
R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->element3i);
}
}
int lightmaptexturenum;
float cl;
memset(&m, 0, sizeof(m));
- m.blendfunc1 = GL_ONE;
- m.blendfunc2 = GL_ZERO;
+ GL_BlendFunc(GL_ONE, GL_ZERO);
+ GL_DepthMask(true);
+ GL_DepthTest(true);
m.tex[0] = R_GetTexture(texture->skin.base);
m.tex[1] = R_GetTexture((**surfchain).lightmaptexture);
m.tex[2] = R_GetTexture(texture->skin.detail);
m.texrgbscale[0] = 1;
m.texrgbscale[1] = 4;
m.texrgbscale[2] = 2;
- R_Mesh_State(&m);
cl = (float) (1 << r_lightmapscalebit) * r_colorscale;
GL_Color(cl, cl, cl, 1);
if (surf->visframe == r_framecount)
{
lightmaptexturenum = R_GetTexture(surf->lightmaptexture);
- if (m.tex[1] != lightmaptexturenum)
- {
+ //if (m.tex[1] != lightmaptexturenum)
+ //{
m.tex[1] = lightmaptexturenum;
- if (gl_mesh_copyarrays.integer)
- R_Mesh_State(&m);
- }
+ // R_Mesh_State_Texture(&m);
+ //}
for (mesh = surf->mesh;mesh;mesh = mesh->chain)
{
- if (gl_mesh_copyarrays.integer)
- {
- R_Mesh_GetSpace(mesh->numverts);
- R_Mesh_CopyVertex3f(mesh->vertex3f, mesh->numverts);
- R_Mesh_CopyTexCoord2f(0, mesh->texcoordtexture2f, mesh->numverts);
- R_Mesh_CopyTexCoord2f(1, mesh->texcoordlightmap2f, mesh->numverts);
- R_Mesh_CopyTexCoord2f(2, mesh->texcoorddetail2f, mesh->numverts);
- }
- else
- {
- m.pointervertexcount = mesh->numverts;
- m.pointer_vertex = mesh->vertex3f;
- m.pointer_texcoord[0] = mesh->texcoordtexture2f;
- m.pointer_texcoord[1] = mesh->texcoordlightmap2f;
- m.pointer_texcoord[2] = mesh->texcoorddetail2f;
- R_Mesh_State(&m);
- }
+ GL_VertexPointer(mesh->vertex3f);
+ m.pointer_texcoord[0] = mesh->texcoordtexture2f;
+ m.pointer_texcoord[1] = mesh->texcoordlightmap2f;
+ m.pointer_texcoord[2] = mesh->texcoorddetail2f;
+ R_Mesh_State_Texture(&m);
R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->element3i);
}
}
rmeshstate_t m;
int lightmaptexturenum;
memset(&m, 0, sizeof(m));
- m.blendfunc1 = GL_ONE;
- m.blendfunc2 = GL_ZERO;
+ GL_BlendFunc(GL_ONE, GL_ZERO);
+ GL_DepthMask(true);
+ GL_DepthTest(true);
m.tex[0] = R_GetTexture(texture->skin.base);
m.tex[1] = R_GetTexture((**surfchain).lightmaptexture);
if (gl_combine.integer)
m.texrgbscale[1] = 4;
- R_Mesh_State(&m);
GL_Color(r_colorscale, r_colorscale, r_colorscale, 1);
while((surf = *surfchain++) != NULL)
{
if (surf->visframe == r_framecount)
{
lightmaptexturenum = R_GetTexture(surf->lightmaptexture);
- if (m.tex[1] != lightmaptexturenum)
- {
+ //if (m.tex[1] != lightmaptexturenum)
+ //{
m.tex[1] = lightmaptexturenum;
- R_Mesh_State(&m);
- }
+ // R_Mesh_State_Texture(&m);
+ //}
for (mesh = surf->mesh;mesh;mesh = mesh->chain)
{
- if (gl_mesh_copyarrays.integer)
- {
- R_Mesh_GetSpace(mesh->numverts);
- R_Mesh_CopyVertex3f(mesh->vertex3f, mesh->numverts);
- R_Mesh_CopyTexCoord2f(0, mesh->texcoordtexture2f, mesh->numverts);
- R_Mesh_CopyTexCoord2f(1, mesh->texcoordlightmap2f, mesh->numverts);
- }
- else
- {
- m.pointervertexcount = mesh->numverts;
- m.pointer_vertex = mesh->vertex3f;
- m.pointer_texcoord[0] = mesh->texcoordtexture2f;
- m.pointer_texcoord[1] = mesh->texcoordlightmap2f;
- R_Mesh_State(&m);
- }
+ GL_VertexPointer(mesh->vertex3f);
+ m.pointer_texcoord[0] = mesh->texcoordtexture2f;
+ m.pointer_texcoord[1] = mesh->texcoordlightmap2f;
+ R_Mesh_State_Texture(&m);
R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->element3i);
}
}
const surfmesh_t *mesh;
rmeshstate_t m;
memset(&m, 0, sizeof(m));
- m.blendfunc1 = GL_ONE;
- m.blendfunc2 = GL_ZERO;
+ GL_DepthMask(true);
+ GL_DepthTest(true);
+ GL_BlendFunc(GL_ONE, GL_ZERO);
m.tex[0] = R_GetTexture(texture->skin.base);
- R_Mesh_State(&m);
GL_Color(1, 1, 1, 1);
while((surf = *surfchain++) != NULL)
{
{
for (mesh = surf->mesh;mesh;mesh = mesh->chain)
{
- if (gl_mesh_copyarrays.integer)
- {
- R_Mesh_GetSpace(mesh->numverts);
- R_Mesh_CopyVertex3f(mesh->vertex3f, mesh->numverts);
- R_Mesh_CopyTexCoord2f(0, mesh->texcoordtexture2f, mesh->numverts);
- }
- else
- {
- m.pointervertexcount = mesh->numverts;
- m.pointer_vertex = mesh->vertex3f;
- m.pointer_texcoord[0] = mesh->texcoordtexture2f;
- R_Mesh_State(&m);
- }
+ GL_VertexPointer(mesh->vertex3f);
+ m.pointer_texcoord[0] = mesh->texcoordtexture2f;
+ R_Mesh_State_Texture(&m);
R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->element3i);
}
}
rmeshstate_t m;
int lightmaptexturenum;
memset(&m, 0, sizeof(m));
- m.blendfunc1 = GL_ZERO;
- m.blendfunc2 = GL_SRC_COLOR;
+ GL_BlendFunc(GL_ZERO, GL_SRC_COLOR);
+ GL_DepthMask(false);
+ GL_DepthTest(true);
m.tex[0] = R_GetTexture((**surfchain).lightmaptexture);
if (gl_combine.integer)
m.texrgbscale[0] = 4;
- R_Mesh_State(&m);
GL_Color(r_colorscale, r_colorscale, r_colorscale, 1);
while((surf = *surfchain++) != NULL)
{
if (surf->visframe == r_framecount)
{
lightmaptexturenum = R_GetTexture(surf->lightmaptexture);
- if (m.tex[0] != lightmaptexturenum)
- {
+ //if (m.tex[0] != lightmaptexturenum)
+ //{
m.tex[0] = lightmaptexturenum;
- R_Mesh_State(&m);
- }
+ // R_Mesh_State_Texture(&m);
+ //}
for (mesh = surf->mesh;mesh;mesh = mesh->chain)
{
- if (gl_mesh_copyarrays.integer)
- {
- R_Mesh_GetSpace(mesh->numverts);
- R_Mesh_CopyVertex3f(mesh->vertex3f, mesh->numverts);
- R_Mesh_CopyTexCoord2f(0, mesh->texcoordlightmap2f, mesh->numverts);
- }
- else
- {
- m.pointervertexcount = mesh->numverts;
- m.pointer_vertex = mesh->vertex3f;
- m.pointer_texcoord[0] = mesh->texcoordlightmap2f;
- R_Mesh_State(&m);
- }
+ GL_VertexPointer(mesh->vertex3f);
+ m.pointer_texcoord[0] = mesh->texcoordlightmap2f;
+ R_Mesh_State_Texture(&m);
R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->element3i);
}
}
const msurface_t *surf;
const surfmesh_t *mesh;
float colorscale;
- rcachearrayrequest_t request;
rmeshstate_t m;
- memset(&request, 0, sizeof(request));
memset(&m, 0, sizeof(m));
- m.blendfunc1 = GL_SRC_ALPHA;
- m.blendfunc2 = GL_ONE;
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
+ GL_DepthMask(false);
+ GL_DepthTest(true);
m.tex[0] = R_GetTexture(texture->skin.base);
colorscale = r_colorscale;
if (gl_combine.integer)
m.texrgbscale[0] = 4;
colorscale *= 0.25f;
}
- R_Mesh_State(&m);
- GL_UseColorArray();
+ GL_ColorPointer(varray_color4f);
while((surf = *surfchain++) != NULL)
{
if (surf->visframe == r_framecount && surf->dlightframe == r_framecount)
{
if (RSurf_LightCheck(&ent->inversematrix, surf->dlightbits, mesh))
{
- if (gl_mesh_copyarrays.integer)
- {
- R_Mesh_GetSpace(mesh->numverts);
- R_Mesh_CopyVertex3f(mesh->vertex3f, mesh->numverts);
- R_Mesh_CopyTexCoord2f(0, mesh->texcoordtexture2f, mesh->numverts);
- R_FillColors(varray_color4f, mesh->numverts, 0, 0, 0, 1);
- RSurf_LightSeparate_Vertex3f_Color4f(&ent->inversematrix, surf->dlightbits, mesh->numverts, mesh->vertex3f, varray_color4f, colorscale);
- }
- else
- {
- m.pointervertexcount = mesh->numverts;
- m.pointer_vertex = mesh->vertex3f;
- m.pointer_texcoord[0] = mesh->texcoordtexture2f;
- // LordHavoc: this is not caching at all (difficult to
- // cache lighting information), it's just (ab)using the
- // cache system to get some memory
- request.data_size = mesh->numverts * sizeof(float[4]);
- request.id_pointer1 = ent;
- request.id_pointer2 = mesh;
- request.id_number1 = r_framecount;
- if (R_Mesh_CacheArray(&request))
- {
- R_FillColors(request.data, mesh->numverts, 0, 0, 0, 1);
- RSurf_LightSeparate_Vertex3f_Color4f(&ent->inversematrix, surf->dlightbits, mesh->numverts, mesh->vertex3f, request.data, colorscale);
- }
- m.pointer_color = request.data;
- R_Mesh_State(&m);
- }
+ GL_VertexPointer(mesh->vertex3f);
+ m.pointer_texcoord[0] = mesh->texcoordtexture2f;
+ R_FillColors(varray_color4f, mesh->numverts, 0, 0, 0, 1);
+ R_Mesh_State_Texture(&m);
+ RSurf_LightSeparate_Vertex3f_Color4f(&ent->inversematrix, surf->dlightbits, mesh->numverts, mesh->vertex3f, varray_color4f, colorscale);
R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->element3i);
}
}
{
const msurface_t *surf;
const surfmesh_t *mesh;
- rcachearrayrequest_t request;
rmeshstate_t m;
float modelorg[3];
Matrix4x4_Transform(&ent->inversematrix, r_origin, modelorg);
- memset(&request, 0, sizeof(request));
memset(&m, 0, sizeof(m));
- m.blendfunc1 = GL_SRC_ALPHA;
- m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
- R_Mesh_State(&m);
- GL_UseColorArray();
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ GL_DepthMask(false);
+ GL_DepthTest(true);
+ GL_ColorPointer(varray_color4f);
while((surf = *surfchain++) != NULL)
{
if (surf->visframe == r_framecount)
{
for (mesh = surf->mesh;mesh;mesh = mesh->chain)
{
- if (gl_mesh_copyarrays.integer)
- {
- R_Mesh_GetSpace(mesh->numverts);
- R_Mesh_CopyVertex3f(mesh->vertex3f, mesh->numverts);
- if (m.tex[0])
- R_Mesh_CopyTexCoord2f(0, mesh->texcoordtexture2f, mesh->numverts);
- RSurf_FogPassColors_Vertex3f_Color4f(mesh->vertex3f, varray_color4f, fogcolor[0], fogcolor[1], fogcolor[2], 1, r_colorscale, mesh->numverts, modelorg);
- }
- else
- {
- m.pointervertexcount = mesh->numverts;
- m.pointer_vertex = mesh->vertex3f;
- if (m.tex[0])
- m.pointer_texcoord[0] = mesh->texcoordtexture2f;
- // LordHavoc: this is not caching at all (difficult to
- // cache fogging information), it's just (ab)using the
- // cache system to get some memory
- request.data_size = mesh->numverts * sizeof(float[4]);
- request.id_pointer1 = ent;
- request.id_pointer2 = mesh;
- request.id_number1 = r_framecount;
- if (R_Mesh_CacheArray(&request))
- RSurf_FogPassColors_Vertex3f_Color4f(mesh->vertex3f, request.data, fogcolor[0], fogcolor[1], fogcolor[2], 1, r_colorscale, mesh->numverts, modelorg);
- m.pointer_color = request.data;
- R_Mesh_State(&m);
- }
+ GL_VertexPointer(mesh->vertex3f);
+ if (m.tex[0])
+ m.pointer_texcoord[0] = mesh->texcoordtexture2f;
+ R_Mesh_State_Texture(&m);
+ RSurf_FogPassColors_Vertex3f_Color4f(mesh->vertex3f, varray_color4f, fogcolor[0], fogcolor[1], fogcolor[2], 1, r_colorscale, mesh->numverts, modelorg);
R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->element3i);
}
}
const surfmesh_t *mesh;
rmeshstate_t m;
memset(&m, 0, sizeof(m));
- m.blendfunc1 = GL_DST_COLOR;
- m.blendfunc2 = GL_SRC_COLOR;
+ GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
+ GL_DepthMask(false);
+ GL_DepthTest(true);
m.tex[0] = R_GetTexture(texture->skin.detail);
- R_Mesh_State(&m);
GL_Color(1, 1, 1, 1);
while((surf = *surfchain++) != NULL)
{
{
for (mesh = surf->mesh;mesh;mesh = mesh->chain)
{
- if (gl_mesh_copyarrays.integer)
- {
- R_Mesh_GetSpace(mesh->numverts);
- R_Mesh_CopyVertex3f(mesh->vertex3f, mesh->numverts);
- R_Mesh_CopyTexCoord2f(0, mesh->texcoorddetail2f, mesh->numverts);
- }
- else
- {
- m.pointervertexcount = mesh->numverts;
- m.pointer_vertex = mesh->vertex3f;
- m.pointer_texcoord[0] = mesh->texcoorddetail2f;
- R_Mesh_State(&m);
- }
+ GL_VertexPointer(mesh->vertex3f);
+ m.pointer_texcoord[0] = mesh->texcoorddetail2f;
+ R_Mesh_State_Texture(&m);
R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->element3i);
}
}
const surfmesh_t *mesh;
rmeshstate_t m;
memset(&m, 0, sizeof(m));
- m.blendfunc1 = GL_SRC_ALPHA;
- m.blendfunc2 = GL_ONE;
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
+ GL_DepthMask(false);
+ GL_DepthTest(true);
m.tex[0] = R_GetTexture(texture->skin.glow);
- R_Mesh_State(&m);
GL_Color(r_colorscale, r_colorscale, r_colorscale, 1);
while((surf = *surfchain++) != NULL)
{
{
for (mesh = surf->mesh;mesh;mesh = mesh->chain)
{
- if (gl_mesh_copyarrays.integer)
- {
- R_Mesh_GetSpace(mesh->numverts);
- R_Mesh_CopyVertex3f(mesh->vertex3f, mesh->numverts);
- R_Mesh_CopyTexCoord2f(0, mesh->texcoordtexture2f, mesh->numverts);
- }
- else
- {
- m.pointervertexcount = mesh->numverts;
- m.pointer_vertex = mesh->vertex3f;
- m.pointer_texcoord[0] = mesh->texcoordtexture2f;
- R_Mesh_State(&m);
- }
+ GL_VertexPointer(mesh->vertex3f);
+ m.pointer_texcoord[0] = mesh->texcoordtexture2f;
+ R_Mesh_State_Texture(&m);
R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->element3i);
}
}
const surfmesh_t *mesh;
rmeshstate_t m;
memset(&m, 0, sizeof(m));
- m.blendfunc1 = GL_SRC_ALPHA;
- m.blendfunc2 = GL_ZERO;
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ZERO);
+ GL_DepthMask(true);
m.tex[0] = R_GetTexture(texture->skin.glow);
- R_Mesh_State(&m);
if (m.tex[0])
GL_Color(r_colorscale, r_colorscale, r_colorscale, 1);
else
{
for (mesh = surf->mesh;mesh;mesh = mesh->chain)
{
- if (gl_mesh_copyarrays.integer)
- {
- R_Mesh_GetSpace(mesh->numverts);
- R_Mesh_CopyVertex3f(mesh->vertex3f, mesh->numverts);
- R_Mesh_CopyTexCoord2f(0, mesh->texcoordtexture2f, mesh->numverts);
- }
- else
- {
- m.pointervertexcount = mesh->numverts;
- m.pointer_vertex = mesh->vertex3f;
- m.pointer_texcoord[0] = mesh->texcoordtexture2f;
- R_Mesh_State(&m);
- }
+ GL_VertexPointer(mesh->vertex3f);
+ m.pointer_texcoord[0] = mesh->texcoordtexture2f;
+ R_Mesh_State_Texture(&m);
R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->element3i);
}
}
rmeshstate_t m;
const entity_render_t *ent = calldata1;
const mportal_t *portal = ent->model->portals + calldata2;
- memset(&m, 0, sizeof(m));
- m.blendfunc1 = GL_SRC_ALPHA;
- m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ GL_DepthMask(false);
+ GL_DepthTest(true);
R_Mesh_Matrix(&ent->matrix);
- R_Mesh_State(&m);
- R_Mesh_GetSpace(portal->numpoints);
+ GL_VertexPointer(varray_vertex3f);
+
+ memset(&m, 0, sizeof(m));
+ R_Mesh_State_Texture(&m);
+
i = portal - ent->model->portals;
GL_Color(((i & 0x0007) >> 0) * (1.0f / 7.0f) * r_colorscale,
((i & 0x0038) >> 3) * (1.0f / 7.0f) * r_colorscale,
temp[1] = bound(surf->poly_mins[1], relativelightorigin[1], surf->poly_maxs[1]) - relativelightorigin[1];
temp[2] = bound(surf->poly_mins[2], relativelightorigin[2], surf->poly_maxs[2]) - relativelightorigin[2];
if (DotProduct(temp, temp) < lightradius2)
- {
for (mesh = surf->mesh;mesh;mesh = mesh->chain)
- {
- R_Mesh_GetSpace(mesh->numverts);
- R_Mesh_CopyVertex3f(mesh->vertex3f, mesh->numverts);
- R_Shadow_Volume(mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->neighbor3i, relativelightorigin, lightradius, projectdistance);
- }
- }
+ R_Shadow_Volume(mesh->numverts, mesh->numtriangles, mesh->vertex3f, mesh->element3i, mesh->neighbor3i, relativelightorigin, lightradius, projectdistance);
}
}
}
lightmaxs[1] = relativelightorigin[1] + lightradius;
lightmaxs[2] = relativelightorigin[2] + lightradius;
R_UpdateTextureInfo(ent);
- if (ent != &cl_entities[0].render)
+ for (surfnum = 0, surf = ent->model->surfaces + ent->model->firstmodelsurface;surfnum < ent->model->nummodelsurfaces;surfnum++, surf++)
{
- // bmodel, cull crudely to view and light
- for (surfnum = 0, surf = ent->model->surfaces + ent->model->firstmodelsurface;surfnum < ent->model->nummodelsurfaces;surfnum++, surf++)
+ if ((ent != &cl_entities[0].render || surf->visframe == r_framecount) && BoxesOverlap(surf->poly_mins, surf->poly_maxs, lightmins, lightmaxs))
{
- if (BoxesOverlap(surf->poly_mins, surf->poly_maxs, lightmins, lightmaxs))
- {
- f = PlaneDiff(relativelightorigin, surf->plane);
- if (surf->flags & SURF_PLANEBACK)
- f = -f;
- if (f >= -0.1 && f < lightradius)
- {
- f = PlaneDiff(relativeeyeorigin, surf->plane);
- if (surf->flags & SURF_PLANEBACK)
- f = -f;
- if (f > 0)
- {
- t = surf->texinfo->texture->currentframe;
- if (t->rendertype == SURFRENDER_OPAQUE && t->flags & SURF_SHADOWLIGHT)
- {
- for (mesh = surf->mesh;mesh;mesh = mesh->chain)
- {
- R_Shadow_DiffuseLighting(mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->vertex3f, mesh->svector3f, mesh->tvector3f, mesh->normal3f, mesh->texcoordtexture2f, relativelightorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.base, t->skin.nmap, NULL);
- R_Shadow_SpecularLighting(mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->vertex3f, mesh->svector3f, mesh->tvector3f, mesh->normal3f, mesh->texcoordtexture2f, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.gloss, t->skin.nmap, NULL);
- }
- }
- }
- }
- }
- }
- }
- else
- {
- // world, already culled to view, just cull to light
- for (surfnum = 0, surf = ent->model->surfaces + ent->model->firstmodelsurface;surfnum < ent->model->nummodelsurfaces;surfnum++, surf++)
- {
- if (surf->visframe == r_framecount && BoxesOverlap(surf->poly_mins, surf->poly_maxs, lightmins, lightmaxs))
+ f = PlaneDiff(relativelightorigin, surf->plane);
+ if (surf->flags & SURF_PLANEBACK)
+ f = -f;
+ if (f >= -0.1 && f < lightradius)
{
- f = PlaneDiff(relativelightorigin, surf->plane);
- if (surf->flags & SURF_PLANEBACK)
- f = -f;
- if (f >= -0.1 && f < lightradius)
+ t = surf->texinfo->texture->currentframe;
+ if (t->rendertype == SURFRENDER_OPAQUE && t->flags & SURF_SHADOWLIGHT)
{
- t = surf->texinfo->texture->currentframe;
- if (t->rendertype == SURFRENDER_OPAQUE && t->flags & SURF_SHADOWLIGHT)
+ for (mesh = surf->mesh;mesh;mesh = mesh->chain)
{
- for (mesh = surf->mesh;mesh;mesh = mesh->chain)
- {
- R_Shadow_DiffuseLighting(mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->vertex3f, mesh->svector3f, mesh->tvector3f, mesh->normal3f, mesh->texcoordtexture2f, relativelightorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.base, t->skin.nmap, NULL);
- R_Shadow_SpecularLighting(mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->vertex3f, mesh->svector3f, mesh->tvector3f, mesh->normal3f, mesh->texcoordtexture2f, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.gloss, t->skin.nmap, NULL);
- }
+ R_Shadow_DiffuseLighting(mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->vertex3f, mesh->svector3f, mesh->tvector3f, mesh->normal3f, mesh->texcoordtexture2f, relativelightorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.base, t->skin.nmap, NULL);
+ R_Shadow_SpecularLighting(mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->vertex3f, mesh->svector3f, mesh->tvector3f, mesh->normal3f, mesh->texcoordtexture2f, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.gloss, t->skin.nmap, NULL);
}
}
}
#define GLTEXTURETYPE_CUBEMAP 3
static int gltexturetypeenums[4] = {GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D, GL_TEXTURE_CUBE_MAP_ARB};
+static int gltexturetypebindingenums[4] = {GL_TEXTURE_BINDING_1D, GL_TEXTURE_BINDING_2D, GL_TEXTURE_BINDING_3D, GL_TEXTURE_BINDING_CUBE_MAP_ARB};
static int gltexturetypedimensions[4] = {1, 2, 3, 2};
static int cubemapside[6] =
{
{"GL_LINEAR_MIPMAP_LINEAR", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR}
};
-extern int gl_backend_rebindtextures;
-
static void GL_TextureMode_f (void)
{
int i;
+ GLint oldbindtexnum;
gltextureimage_t *image;
gltexturepool_t *pool;
// only update already uploaded images
if (!(image->flags & GLTEXF_UPLOAD))
{
- qglBindTexture(GL_TEXTURE_2D, image->texnum);
+ qglGetIntegerv(gltexturetypebindingenums[image->texturetype], &oldbindtexnum);
+ qglBindTexture(gltexturetypeenums[image->texturetype], image->texnum);
if (image->flags & TEXF_MIPMAP)
- qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
+ qglTexParameteri(gltexturetypeenums[image->texturetype], GL_TEXTURE_MIN_FILTER, gl_filter_min);
else
- qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_mag);
- qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_mag);
+ qglTexParameteri(gltexturetypeenums[image->texturetype], GL_TEXTURE_MIN_FILTER, gl_filter_mag);
+ qglTexParameteri(gltexturetypeenums[image->texturetype], GL_TEXTURE_MAG_FILTER, gl_filter_mag);
+ qglBindTexture(gltexturetypeenums[image->texturetype], oldbindtexnum);
}
}
}
static void R_Upload(gltexture_t *glt, qbyte *data)
{
- int i, mip, width, height, depth, internalformat;
+ int i, mip, width, height, depth;
+ GLint oldbindtexnum;
qbyte *prevbuffer;
prevbuffer = data;
- R_Mesh_EndBatch();
-
CHECKGLERROR
glt->texnum = glt->image->texnum;
+ // we need to restore the texture binding after finishing the upload
+ qglGetIntegerv(gltexturetypebindingenums[glt->image->texturetype], &oldbindtexnum);
qglBindTexture(gltexturetypeenums[glt->image->texturetype], glt->image->texnum);
CHECKGLERROR
glt->flags &= ~GLTEXF_UPLOAD;
- gl_backend_rebindtextures = true;
if (glt->flags & TEXF_FRAGMENT)
{
Host_Error("R_Upload: fragment texture of type other than 1D, 2D, or 3D\n");
break;
}
- glt->texnum = glt->image->texnum;
- return;
- }
-
- glt->image->flags &= ~GLTEXF_UPLOAD;
-
- // these are rounded up versions of the size to do better resampling
- for (width = 1;width < glt->width ;width <<= 1);
- for (height = 1;height < glt->height;height <<= 1);
- for (depth = 1;depth < glt->depth ;depth <<= 1);
-
- R_MakeResizeBufferBigger(width * height * depth * glt->image->sides * glt->image->bytesperpixel);
-
- if (prevbuffer == NULL)
- {
- width = glt->image->width;
- height = glt->image->height;
- depth = glt->image->depth;
- memset(resizebuffer, 255, width * height * depth * glt->image->bytesperpixel);
- prevbuffer = resizebuffer;
}
else
{
- if (glt->textype->textype == TEXTYPE_PALETTE)
- {
- // promote paletted to RGBA, so we only have to worry about RGB and
- // RGBA in the rest of this code
- Image_Copy8bitRGBA(prevbuffer, colorconvertbuffer, glt->width * glt->height * glt->depth * glt->image->sides, glt->palette);
- prevbuffer = colorconvertbuffer;
- }
- }
+ glt->image->flags &= ~GLTEXF_UPLOAD;
- // 3 and 4 are converted by the driver to it's preferred format for the current display mode
- internalformat = 3;
- if (glt->flags & TEXF_ALPHA)
- internalformat = 4;
+ // these are rounded up versions of the size to do better resampling
+ for (width = 1;width < glt->width ;width <<= 1);
+ for (height = 1;height < glt->height;height <<= 1);
+ for (depth = 1;depth < glt->depth ;depth <<= 1);
- // cubemaps contain multiple images and thus get processed a bit differently
- if (glt->image->texturetype != GLTEXTURETYPE_CUBEMAP)
- {
- if (glt->width != width || glt->height != height || glt->depth != depth)
- {
- Image_Resample(prevbuffer, glt->width, glt->height, glt->depth, resizebuffer, width, height, depth, glt->image->bytesperpixel, r_lerpimages.integer);
- prevbuffer = resizebuffer;
- }
- // picmip/max_size
- while (width > glt->image->width || height > glt->image->height || depth > glt->image->depth)
+ R_MakeResizeBufferBigger(width * height * depth * glt->image->sides * glt->image->bytesperpixel);
+
+ if (prevbuffer == NULL)
{
- Image_MipReduce(prevbuffer, resizebuffer, &width, &height, &depth, glt->image->width, glt->image->height, glt->image->depth, glt->image->bytesperpixel);
+ width = glt->image->width;
+ height = glt->image->height;
+ depth = glt->image->depth;
+ memset(resizebuffer, 255, width * height * depth * glt->image->bytesperpixel);
prevbuffer = resizebuffer;
}
- }
- mip = 0;
- switch(glt->image->texturetype)
- {
- case GLTEXTURETYPE_1D:
- qglTexImage1D(GL_TEXTURE_1D, mip++, internalformat, width, 0, glt->image->glformat, GL_UNSIGNED_BYTE, prevbuffer);
- CHECKGLERROR
- if (glt->flags & TEXF_MIPMAP)
+ else
{
- while (width > 1 || height > 1 || depth > 1)
+ if (glt->textype->textype == TEXTYPE_PALETTE)
{
- Image_MipReduce(prevbuffer, resizebuffer, &width, &height, &depth, 1, 1, 1, glt->image->bytesperpixel);
- prevbuffer = resizebuffer;
- qglTexImage1D(GL_TEXTURE_1D, mip++, internalformat, width, 0, glt->image->glformat, GL_UNSIGNED_BYTE, prevbuffer);
- CHECKGLERROR
+ // promote paletted to RGBA, so we only have to worry about RGB and
+ // RGBA in the rest of this code
+ Image_Copy8bitRGBA(prevbuffer, colorconvertbuffer, glt->width * glt->height * glt->depth * glt->image->sides, glt->palette);
+ prevbuffer = colorconvertbuffer;
}
}
- break;
- case GLTEXTURETYPE_2D:
- qglTexImage2D(GL_TEXTURE_2D, mip++, internalformat, width, height, 0, glt->image->glformat, GL_UNSIGNED_BYTE, prevbuffer);
- CHECKGLERROR
- if (glt->flags & TEXF_MIPMAP)
+
+ // cubemaps contain multiple images and thus get processed a bit differently
+ if (glt->image->texturetype != GLTEXTURETYPE_CUBEMAP)
{
- while (width > 1 || height > 1 || depth > 1)
+ if (glt->width != width || glt->height != height || glt->depth != depth)
{
- Image_MipReduce(prevbuffer, resizebuffer, &width, &height, &depth, 1, 1, 1, glt->image->bytesperpixel);
+ Image_Resample(prevbuffer, glt->width, glt->height, glt->depth, resizebuffer, width, height, depth, glt->image->bytesperpixel, r_lerpimages.integer);
prevbuffer = resizebuffer;
- qglTexImage2D(GL_TEXTURE_2D, mip++, internalformat, width, height, 0, glt->image->glformat, GL_UNSIGNED_BYTE, prevbuffer);
- CHECKGLERROR
}
- }
- break;
- case GLTEXTURETYPE_3D:
- qglTexImage3D(GL_TEXTURE_3D, mip++, internalformat, width, height, depth, 0, glt->image->glformat, GL_UNSIGNED_BYTE, prevbuffer);
- CHECKGLERROR
- if (glt->flags & TEXF_MIPMAP)
- {
- while (width > 1 || height > 1 || depth > 1)
+ // picmip/max_size
+ while (width > glt->image->width || height > glt->image->height || depth > glt->image->depth)
{
- Image_MipReduce(prevbuffer, resizebuffer, &width, &height, &depth, 1, 1, 1, glt->image->bytesperpixel);
+ Image_MipReduce(prevbuffer, resizebuffer, &width, &height, &depth, glt->image->width, glt->image->height, glt->image->depth, glt->image->bytesperpixel);
prevbuffer = resizebuffer;
- qglTexImage3D(GL_TEXTURE_3D, mip++, internalformat, width, height, depth, 0, glt->image->glformat, GL_UNSIGNED_BYTE, prevbuffer);
- CHECKGLERROR
}
}
- break;
- case GLTEXTURETYPE_CUBEMAP:
- // convert and upload each side in turn,
- // from a continuous block of input texels
- texturebuffer = prevbuffer;
- for (i = 0;i < 6;i++)
+ mip = 0;
+ switch(glt->image->texturetype)
{
- prevbuffer = texturebuffer;
- texturebuffer += width * height * depth * glt->textype->inputbytesperpixel;
- if (glt->width != width || glt->height != height || glt->depth != depth)
+ case GLTEXTURETYPE_1D:
+ qglTexImage1D(GL_TEXTURE_1D, mip++, glt->image->glinternalformat, width, 0, glt->image->glformat, GL_UNSIGNED_BYTE, prevbuffer);
+ CHECKGLERROR
+ if (glt->flags & TEXF_MIPMAP)
{
- Image_Resample(prevbuffer, glt->width, glt->height, glt->depth, resizebuffer, width, height, depth, glt->image->bytesperpixel, r_lerpimages.integer);
- prevbuffer = resizebuffer;
+ while (width > 1 || height > 1 || depth > 1)
+ {
+ Image_MipReduce(prevbuffer, resizebuffer, &width, &height, &depth, 1, 1, 1, glt->image->bytesperpixel);
+ prevbuffer = resizebuffer;
+ qglTexImage1D(GL_TEXTURE_1D, mip++, glt->image->glinternalformat, width, 0, glt->image->glformat, GL_UNSIGNED_BYTE, prevbuffer);
+ CHECKGLERROR
+ }
}
- // picmip/max_size
- while (width > glt->image->width || height > glt->image->height || depth > glt->image->depth)
+ break;
+ case GLTEXTURETYPE_2D:
+ qglTexImage2D(GL_TEXTURE_2D, mip++, glt->image->glinternalformat, width, height, 0, glt->image->glformat, GL_UNSIGNED_BYTE, prevbuffer);
+ CHECKGLERROR
+ if (glt->flags & TEXF_MIPMAP)
{
- Image_MipReduce(prevbuffer, resizebuffer, &width, &height, &depth, glt->image->width, glt->image->height, glt->image->depth, glt->image->bytesperpixel);
- prevbuffer = resizebuffer;
+ while (width > 1 || height > 1 || depth > 1)
+ {
+ Image_MipReduce(prevbuffer, resizebuffer, &width, &height, &depth, 1, 1, 1, glt->image->bytesperpixel);
+ prevbuffer = resizebuffer;
+ qglTexImage2D(GL_TEXTURE_2D, mip++, glt->image->glinternalformat, width, height, 0, glt->image->glformat, GL_UNSIGNED_BYTE, prevbuffer);
+ CHECKGLERROR
+ }
}
- mip = 0;
- qglTexImage2D(cubemapside[i], mip++, internalformat, width, height, 0, glt->image->glformat, GL_UNSIGNED_BYTE, prevbuffer);
+ break;
+ case GLTEXTURETYPE_3D:
+ qglTexImage3D(GL_TEXTURE_3D, mip++, glt->image->glinternalformat, width, height, depth, 0, glt->image->glformat, GL_UNSIGNED_BYTE, prevbuffer);
CHECKGLERROR
if (glt->flags & TEXF_MIPMAP)
{
{
Image_MipReduce(prevbuffer, resizebuffer, &width, &height, &depth, 1, 1, 1, glt->image->bytesperpixel);
prevbuffer = resizebuffer;
- qglTexImage2D(cubemapside[i], mip++, internalformat, width, height, 0, glt->image->glformat, GL_UNSIGNED_BYTE, prevbuffer);
+ qglTexImage3D(GL_TEXTURE_3D, mip++, glt->image->glinternalformat, width, height, depth, 0, glt->image->glformat, GL_UNSIGNED_BYTE, prevbuffer);
CHECKGLERROR
}
}
+ break;
+ case GLTEXTURETYPE_CUBEMAP:
+ // convert and upload each side in turn,
+ // from a continuous block of input texels
+ texturebuffer = prevbuffer;
+ for (i = 0;i < 6;i++)
+ {
+ prevbuffer = texturebuffer;
+ texturebuffer += width * height * depth * glt->textype->inputbytesperpixel;
+ if (glt->width != width || glt->height != height || glt->depth != depth)
+ {
+ Image_Resample(prevbuffer, glt->width, glt->height, glt->depth, resizebuffer, width, height, depth, glt->image->bytesperpixel, r_lerpimages.integer);
+ prevbuffer = resizebuffer;
+ }
+ // picmip/max_size
+ while (width > glt->image->width || height > glt->image->height || depth > glt->image->depth)
+ {
+ Image_MipReduce(prevbuffer, resizebuffer, &width, &height, &depth, glt->image->width, glt->image->height, glt->image->depth, glt->image->bytesperpixel);
+ prevbuffer = resizebuffer;
+ }
+ mip = 0;
+ qglTexImage2D(cubemapside[i], mip++, glt->image->glinternalformat, width, height, 0, glt->image->glformat, GL_UNSIGNED_BYTE, prevbuffer);
+ CHECKGLERROR
+ if (glt->flags & TEXF_MIPMAP)
+ {
+ while (width > 1 || height > 1 || depth > 1)
+ {
+ Image_MipReduce(prevbuffer, resizebuffer, &width, &height, &depth, 1, 1, 1, glt->image->bytesperpixel);
+ prevbuffer = resizebuffer;
+ qglTexImage2D(cubemapside[i], mip++, glt->image->glinternalformat, width, height, 0, glt->image->glformat, GL_UNSIGNED_BYTE, prevbuffer);
+ CHECKGLERROR
+ }
+ }
+ }
+ break;
}
- break;
+ GL_SetupTextureParameters(glt->image->flags, glt->image->texturetype);
}
- GL_SetupTextureParameters(glt->image->flags, glt->image->texturetype);
+ qglBindTexture(gltexturetypeenums[glt->image->texturetype], oldbindtexnum);
}
static void R_FindImageForTexture(gltexture_t *glt)
#define GL_TEXTURE_MAG_FILTER 0x2800
#define GL_TEXTURE_MIN_FILTER 0x2801
#define GL_UNPACK_ALIGNMENT 0x0CF5
+#define GL_TEXTURE_BINDING_1D 0x8068
+#define GL_TEXTURE_BINDING_2D 0x8069
#define GL_NEAREST 0x2600
#define GL_LINEAR 0x2601
// GL_ARB_multitexture
extern int gl_textureunits;
extern void (GLAPIENTRY *qglMultiTexCoord2f) (GLenum, GLfloat, GLfloat);
+extern void (GLAPIENTRY *qglMultiTexCoord3f) (GLenum, GLfloat, GLfloat, GLfloat);
extern void (GLAPIENTRY *qglActiveTexture) (GLenum);
extern void (GLAPIENTRY *qglClientActiveTexture) (GLenum);
#ifndef GL_ACTIVE_TEXTURE_ARB
//extern void (GLAPIENTRY *qglReadBuffer)(GLenum mode);
extern void (GLAPIENTRY *qglEnable)(GLenum cap);
extern void (GLAPIENTRY *qglDisable)(GLenum cap);
-//extern GLboolean GLAPIENTRY *qglIsEnabled)(GLenum cap);
+extern GLboolean (GLAPIENTRY *qglIsEnabled)(GLenum cap);
extern void (GLAPIENTRY *qglEnableClientState)(GLenum cap);
extern void (GLAPIENTRY *qglDisableClientState)(GLenum cap);
extern void (GLAPIENTRY *qglClearDepth)(GLclampd depth);
extern void (GLAPIENTRY *qglDepthFunc)(GLenum func);
extern void (GLAPIENTRY *qglDepthMask)(GLboolean flag);
-//extern void (GLAPIENTRY *qglDepthRange)(GLclampd near_val, GLclampd far_val);
+extern void (GLAPIENTRY *qglDepthRange)(GLclampd near_val, GLclampd far_val);
extern void (GLAPIENTRY *qglColorMask)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
extern void (GLAPIENTRY *qglDrawRangeElements)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
extern void (GLAPIENTRY *qglDrawElements)(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);
extern void (GLAPIENTRY *qglVertexPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr);
-//extern void (GLAPIENTRY *qglNormalPointer)(GLenum type, GLsizei stride, const GLvoid *ptr);
+extern void (GLAPIENTRY *qglNormalPointer)(GLenum type, GLsizei stride, const GLvoid *ptr);
extern void (GLAPIENTRY *qglColorPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr);
extern void (GLAPIENTRY *qglTexCoordPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr);
-//extern void (GLAPIENTRY *qglArrayElement)(GLint i);
+extern void (GLAPIENTRY *qglArrayElement)(GLint i);
extern void (GLAPIENTRY *qglColor4f)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
-//extern void (GLAPIENTRY *qglTexCoord2f)(GLfloat s, GLfloat t);
-//extern void (GLAPIENTRY *qglVertex2f)(GLfloat x, GLfloat y);
-//extern void (GLAPIENTRY *qglVertex3f)(GLfloat x, GLfloat y, GLfloat z);
-//extern void (GLAPIENTRY *qglBegin)(GLenum mode);
-//extern void (GLAPIENTRY *qglEnd)(void);
+extern void (GLAPIENTRY *qglTexCoord2f)(GLfloat s, GLfloat t);
+extern void (GLAPIENTRY *qglTexCoord3f)(GLfloat s, GLfloat t, GLfloat r);
+extern void (GLAPIENTRY *qglVertex2f)(GLfloat x, GLfloat y);
+extern void (GLAPIENTRY *qglVertex3f)(GLfloat x, GLfloat y, GLfloat z);
+extern void (GLAPIENTRY *qglBegin)(GLenum mode);
+extern void (GLAPIENTRY *qglEnd)(void);
extern void (GLAPIENTRY *qglMatrixMode)(GLenum mode);
extern void (GLAPIENTRY *qglOrtho)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val);
#define DEBUGGL
#ifdef DEBUGGL
-#define CHECKGLERROR if ((errornumber = qglGetError())) GL_PrintError(errornumber, __FILE__, __LINE__);
+#define CHECKGLERROR {if (gl_printcheckerror.integer) Con_Printf("CHECKGLERROR at %s:%d\n", __FILE__, __LINE__);if (gl_paranoid.integer && (errornumber = qglGetError())) GL_PrintError(errornumber, __FILE__, __LINE__);}
extern int errornumber;
void GL_PrintError(int errornumber, char *filename, int linenumber);
#else
*/
}
-void Mod_ShadowMesh_AddMesh(mempool_t *mempool, shadowmesh_t *mesh, int numverts, float *verts, int numtris, int *elements)
+void Mod_ShadowMesh_AddMesh(mempool_t *mempool, shadowmesh_t *mesh, float *verts, int numtris, int *elements)
{
int i;
for (i = 0;i < numtris;i++, elements += 3)
int Mod_ShadowMesh_AddVertex(shadowmesh_t *mesh, float *v);
void Mod_ShadowMesh_AddTriangle(mempool_t *mempool, shadowmesh_t *mesh, float *vert0, float *vert1, float *vert2);
void Mod_ShadowMesh_AddPolygon(mempool_t *mempool, shadowmesh_t *mesh, int numverts, float *verts);
-void Mod_ShadowMesh_AddMesh(mempool_t *mempool, shadowmesh_t *mesh, int numverts, float *verts, int numtris, int *elements);
+void Mod_ShadowMesh_AddMesh(mempool_t *mempool, shadowmesh_t *mesh, float *verts, int numtris, int *elements);
shadowmesh_t *Mod_ShadowMesh_Begin(mempool_t *mempool, int initialnumtriangles);
shadowmesh_t *Mod_ShadowMesh_Finish(mempool_t *mempool, shadowmesh_t *firstmesh);
void Mod_ShadowMesh_CalcBBox(shadowmesh_t *firstmesh, vec3_t mins, vec3_t maxs, vec3_t center, float *radius);
Cvar_RegisterVariable(&crosshair_static);
}
-void R_DrawCrosshairSprite(rtexture_t *texture, vec3_t origin, vec_t scale, float cr, float cg, float cb, float ca)
-{
- rmeshstate_t m;
- float diff[3];
-
- if (fogenabled)
- {
- VectorSubtract(origin, r_origin, diff);
- ca *= 1 - exp(fogdensity/DotProduct(diff,diff));
- }
-
- memset(&m, 0, sizeof(m));
- m.blendfunc1 = GL_SRC_ALPHA;
- m.blendfunc2 = GL_ONE;
- m.depthdisable = true;
- m.tex[0] = R_GetTexture(texture);
- R_Mesh_Matrix(&r_identitymatrix);
- R_Mesh_State(&m);
-
- GL_Color(cr * r_colorscale, cg * r_colorscale, cb * r_colorscale, ca);
- R_DrawSpriteMesh(origin, vright, vup, scale, -scale, -scale, scale);
-}
-
void R_GetCrosshairColor(float *out)
{
int i;
spritescale = CL_TraceLine(v1, v2, spriteorigin, NULL, 0, true, NULL) * (8192.0f / 40.0f) * crosshair_size.value;
// draw the sprite
- R_DrawCrosshairSprite(pic->tex, spriteorigin, spritescale, color[0], color[1], color[2], color[3]);
+ R_DrawSprite(GL_SRC_ALPHA, GL_ONE, pic->tex, true, spriteorigin, vright, vup, spritescale, -spritescale, -spritescale, spritescale, color[0], color[1], color[2], color[3]);
}
void R_Draw2DCrosshair(void)
const explosion_t *e;
e = calldata1;
- memset(&m, 0, sizeof(m));
- m.blendfunc1 = GL_SRC_ALPHA;
- m.blendfunc2 = GL_ONE;
- m.tex[0] = R_GetTexture(explosiontexture);
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
+ GL_DepthMask(false);
+ GL_DepthTest(true);
R_Mesh_Matrix(&r_identitymatrix);
numtriangles = EXPLOSIONTRIS;
numverts = EXPLOSIONVERTS;
alpha = e->alpha * r_colorscale;
GL_Color(alpha, alpha, alpha, 1);
- if (gl_mesh_copyarrays.integer)
- {
- R_Mesh_State(&m);
- R_Mesh_GetSpace(numverts);
- R_Mesh_CopyVertex3f(e->vert[0], numverts);
- R_Mesh_CopyTexCoord2f(0, explosiontexcoord2f[0], numverts);
- }
- else
- {
- m.pointervertexcount = numverts;
- m.pointer_vertex = e->vert[0];
- m.pointer_texcoord[0] = explosiontexcoord2f[0];
- R_Mesh_State(&m);
- }
+ GL_VertexPointer(e->vert[0]);
+
+ memset(&m, 0, sizeof(m));
+ m.tex[0] = R_GetTexture(explosiontexture);
+ m.pointer_texcoord[0] = explosiontexcoord2f[0];
+ R_Mesh_State_Texture(&m);
+
R_Mesh_Draw(numverts, numtriangles, explosiontris[0]);
}
void R_DrawCoronas(void)
{
int i;
- rmeshstate_t m;
- float scale, viewdist, diff[3], dist;
+ float cscale, scale, viewdist, dist;
rdlight_t *rd;
if (!r_coronas.integer)
return;
- memset(&m, 0, sizeof(m));
- m.blendfunc1 = GL_ONE;
- m.blendfunc2 = GL_ONE;
- m.depthdisable = true; // magic
- m.tex[0] = R_GetTexture(lightcorona);
R_Mesh_Matrix(&r_identitymatrix);
- R_Mesh_State(&m);
viewdist = DotProduct(r_origin, vpn);
for (i = 0;i < r_numdlights;i++)
{
dist = (DotProduct(rd->origin, vpn) - viewdist);
if (dist >= 24.0f && CL_TraceLine(rd->origin, r_origin, NULL, NULL, 0, true, NULL) == 1)
{
- scale = r_colorscale * (1.0f / 131072.0f);
- if (gl_flashblend.integer)
- scale *= 4.0f;
- if (fogenabled)
- {
- VectorSubtract(rd->origin, r_origin, diff);
- scale *= 1 - exp(fogdensity/DotProduct(diff,diff));
- }
- GL_Color(rd->light[0] * scale, rd->light[1] * scale, rd->light[2] * scale, 1);
+ cscale = (1.0f / 131072.0f);
scale = rd->cullradius * 0.25f;
if (gl_flashblend.integer)
+ {
+ cscale *= 4.0f;
scale *= 2.0f;
- R_DrawSpriteMesh(rd->origin, vright, vup, scale, -scale, -scale, scale);
+ }
+ R_DrawSprite(GL_ONE, GL_ONE, lightcorona, true, rd->origin, vright, vup, scale, -scale, -scale, scale, rd->light[0] * cscale, rd->light[1] * cscale, rd->light[2] * cscale, 1);
}
}
}
+/*
+Terminology: Stencil Shadow Volume (sometimes called Stencil Shadows)
+An extrusion of the lit faces, beginning at the original geometry and ending
+further from the light source than the original geometry (presumably at least
+as far as the light's radius, if the light has a radius at all), capped at
+both front and back to avoid any problems (extrusion from dark faces also
+works but has a different set of problems)
+
+This is rendered using Carmack's Reverse technique, in which backfaces behind
+zbuffer (zfail) increment the stencil, and frontfaces behind zbuffer (zfail)
+decrement the stencil, the result is a stencil value of zero where shadows
+did not intersect the visible geometry, suitable as a stencil mask for
+rendering lighting everywhere but shadow.
+
+In our case we use a biased stencil clear of 128 to avoid requiring the
+stencil wrap extension (but probably should support it).
+
+
+
+Terminology: Stencil Light Volume (sometimes called Light Volumes)
+Similar to a Stencil Shadow Volume, but inverted; rather than containing the
+areas in shadow it contanis the areas in light, this can only be built
+quickly for certain limited cases (such as portal visibility from a point),
+but is quite useful for some effects (sunlight coming from sky polygons is
+one possible example, translucent occluders is another example).
+
+
+
+Terminology: Optimized Stencil Shadow Volume
+A Stencil Shadow Volume that has been processed sufficiently to ensure it has
+no duplicate coverage of areas (no need to shadow an area twice), often this
+greatly improves performance but is an operation too costly to use on moving
+lights (however completely optimal Stencil Light Volumes can be constructed
+in some ideal cases).
+
+
+
+Terminology: Per Pixel Lighting (sometimes abbreviated PPL)
+Per pixel evaluation of lighting equations, at a bare minimum this involves
+DOT3 shading of diffuse lighting (per pixel dotproduct of negated incidence
+vector and surface normal, using a texture of the surface bumps, called a
+NormalMap) if supported by hardware; in our case there is support for cards
+which are incapable of DOT3, the quality is quite poor however. Additionally
+it is desirable to have specular evaluation per pixel, per vertex
+normalization of specular halfangle vectors causes noticable distortion but
+is unavoidable on hardware without GL_ARB_fragment_program.
+
+
+
+Terminology: Normalization CubeMap
+A cubemap containing normalized dot3-encoded (vectors of length 1 or less
+encoded as RGB colors) for any possible direction, this technique allows per
+pixel calculation of incidence vector for per pixel lighting purposes, which
+would not otherwise be possible per pixel without GL_ARB_fragment_program.
+
+
+
+Terminology: 2D Attenuation Texturing
+A very crude approximation of light attenuation with distance which results
+in cylindrical light shapes which fade vertically as a streak (some games
+such as Doom3 allow this to be rotated to be less noticable in specific
+cases), the technique is simply modulating lighting by two 2D textures (which
+can be the same) on different axes of projection (XY and Z, typically), this
+is the best technique available without 3D Attenuation Texturing or
+GL_ARB_fragment_program technology.
+
+
+
+Terminology: 3D Attenuation Texturing
+A slightly crude approximation of light attenuation with distance, its flaws
+are limited radius and resolution (performance tradeoffs).
+
+
+
+Terminology: 3D Attenuation-Normalization Texturing
+A 3D Attenuation Texture merged with a Normalization CubeMap, by making the
+vectors shorter the lighting becomes darker, a very effective optimization of
+diffuse lighting if 3D Attenuation Textures are already used.
+
+
+
+Terminology: Light Cubemap Filtering
+A technique for modeling non-uniform light distribution according to
+direction, for example projecting a stained glass window image onto a wall,
+this is done by texturing the lighting with a cubemap.
+
+
+
+Terminology: Light Projection Filtering
+A technique for modeling shadowing of light passing through translucent
+surfaces, allowing stained glass windows and other effects to be done more
+elegantly than possible with Light Cubemap Filtering by applying an occluder
+texture to the lighting combined with a stencil light volume to limit the lit
+area (this allows evaluating multiple translucent occluders in a scene).
+
+
+
+Terminology: Doom3 Lighting
+A combination of Stencil Shadow Volume, Per Pixel Lighting, Normalization
+CubeMap, 2D Attenuation Texturing, and Light Filtering, as demonstrated by
+the (currently upcoming) game Doom3.
+*/
+
#include "quakedef.h"
#include "r_shadow.h"
#include "cl_collision.h"
int maxvertexupdate;
int *vertexupdate;
+int *vertexremap;
int vertexupdatenum;
rtexturepool_t *r_shadow_texturepool;
cvar_t r_shadow_scissor = {0, "r_shadow_scissor", "1"};
cvar_t r_shadow_bumpscale_bumpmap = {0, "r_shadow_bumpscale_bumpmap", "4"};
cvar_t r_shadow_bumpscale_basetexture = {0, "r_shadow_bumpscale_basetexture", "0"};
-cvar_t r_shadow_polygonoffset = {0, "r_shadow_polygonoffset", "-1"};
+cvar_t r_shadow_polygonoffset = {0, "r_shadow_polygonoffset", "0"};
cvar_t r_shadow_portallight = {0, "r_shadow_portallight", "1"};
-cvar_t r_shadow_projectdistance = {0, "r_shadow_projectdistance", "100000"};
+cvar_t r_shadow_projectdistance = {0, "r_shadow_projectdistance", "10000"};
cvar_t r_shadow_texture3d = {0, "r_shadow_texture3d", "1"};
+cvar_t r_shadow_singlepassvolumegeneration = {0, "r_shadow_singlepassvolumegeneration", "1"};
int c_rt_lights, c_rt_clears, c_rt_scissored;
int c_rt_shadowmeshes, c_rt_shadowtris, c_rt_lightmeshes, c_rt_lighttris;
shadowelements = NULL;
maxvertexupdate = 0;
vertexupdate = NULL;
+ vertexremap = NULL;
vertexupdatenum = 0;
maxtrianglefacinglight = 0;
trianglefacinglight = NULL;
shadowelements = NULL;
maxvertexupdate = 0;
vertexupdate = NULL;
+ vertexremap = NULL;
vertexupdatenum = 0;
maxtrianglefacinglight = 0;
trianglefacinglight = NULL;
Cvar_RegisterVariable(&r_shadow_portallight);
Cvar_RegisterVariable(&r_shadow_projectdistance);
Cvar_RegisterVariable(&r_shadow_texture3d);
+ Cvar_RegisterVariable(&r_shadow_singlepassvolumegeneration);
R_Shadow_EditLights_Init();
R_RegisterModule("R_Shadow", r_shadow_start, r_shadow_shutdown, r_shadow_newmap);
}
-int R_Shadow_MakeTriangleShadowFlags_Vertex3f(const int *elements, const float *vertex, int numtris, qbyte *facing, int *list, const float *relativelightorigin)
-{
- int i, tris = 0;
- const float *v0, *v1, *v2;
- for (i = 0;i < numtris;i++, elements += 3)
- {
- // calculate triangle facing flag
- v0 = vertex + elements[0] * 3;
- v1 = vertex + elements[1] * 3;
- v2 = vertex + elements[2] * 3;
- if(PointInfrontOfTriangle(relativelightorigin, v0, v1, v2))
- {
- facing[i] = true;
- list[tris++] = i;
- }
- else
- facing[i] = false;
- }
- return tris;
-}
-
-int R_Shadow_BuildShadowVolume(const int *elements, const int *neighbors, int numverts, const qbyte *facing, const int *facinglist, int numfacing, int *out, float *vertices, const float *relativelightorigin, float projectdistance)
-{
- int i, j, tris, vertexpointeradjust = numverts * 3;
- const int *e, *n;
- float *vin, *vout;
-
- if (maxvertexupdate < numverts)
- {
- maxvertexupdate = numverts;
- if (vertexupdate)
- Mem_Free(vertexupdate);
- vertexupdate = Mem_Alloc(r_shadow_mempool, maxvertexupdate * sizeof(int));
- }
- vertexupdatenum++;
-
- // check each frontface for bordering backfaces,
- // and cast shadow polygons from those edges,
- // also create front and back caps for shadow volume
- tris = numfacing * 2;
- // output front caps
- for (i = 0;i < numfacing;i++)
- {
- e = elements + facinglist[i] * 3;
- out[0] = e[0];
- out[1] = e[1];
- out[2] = e[2];
- out += 3;
- }
- // output back caps
- for (i = 0;i < numfacing;i++)
- {
- e = elements + facinglist[i] * 3;
- // generate vertices if needed
- for (j = 0;j < 3;j++)
- {
- if (vertexupdate[e[j]] != vertexupdatenum)
- {
- vertexupdate[e[j]] = vertexupdatenum;
- vin = vertices + e[j] * 3;
- vout = vin + vertexpointeradjust;
- vout[0] = relativelightorigin[0] + projectdistance * (vin[0] - relativelightorigin[0]);
- vout[1] = relativelightorigin[1] + projectdistance * (vin[1] - relativelightorigin[1]);
- vout[2] = relativelightorigin[2] + projectdistance * (vin[2] - relativelightorigin[2]);
- }
- }
- out[0] = e[2] + numverts;
- out[1] = e[1] + numverts;
- out[2] = e[0] + numverts;
- out += 3;
- }
- // output sides around frontfaces
- for (i = 0;i < numfacing;i++)
- {
- n = neighbors + facinglist[i] * 3;
- // check the edges
- if (n[0] < 0 || !facing[n[0]])
- {
- e = elements + facinglist[i] * 3;
- out[0] = e[1];
- out[1] = e[0];
- out[2] = e[0] + numverts;
- out[3] = e[1];
- out[4] = e[0] + numverts;
- out[5] = e[1] + numverts;
- out += 6;
- tris += 2;
- }
- if (n[1] < 0 || !facing[n[1]])
- {
- e = elements + facinglist[i] * 3;
- out[0] = e[2];
- out[1] = e[1];
- out[2] = e[1] + numverts;
- out[3] = e[2];
- out[4] = e[1] + numverts;
- out[5] = e[2] + numverts;
- out += 6;
- tris += 2;
- }
- if (n[2] < 0 || !facing[n[2]])
- {
- e = elements + facinglist[i] * 3;
- out[0] = e[0];
- out[1] = e[2];
- out[2] = e[2] + numverts;
- out[3] = e[0];
- out[4] = e[2] + numverts;
- out[5] = e[0] + numverts;
- out += 6;
- tris += 2;
- }
- }
- return tris;
-}
-
void R_Shadow_ResizeTriangleFacingLight(int numtris)
{
// make sure trianglefacinglight is big enough for this volume
return shadowelements;
}
-void R_Shadow_Volume(int numverts, int numtris, int *elements, int *neighbors, vec3_t relativelightorigin, float lightradius, float projectdistance)
+int R_Shadow_ConstructShadowVolume(int innumvertices, int trianglerange_start, int trianglerange_end, const int *inelement3i, const int *inneighbor3i, const float *invertex3f, int *outnumvertices, int *outelement3i, float *outvertex3f, const float *relativelightorigin, float projectdistance)
+{
+ int i, j, tris = 0, numfacing = 0, vr[3], t, outvertices = 0;
+ const float *v[3];
+ const int *e, *n, *te;
+ float f, temp[3];
+
+ // make sure trianglefacinglight is big enough for this volume
+ if (maxtrianglefacinglight < trianglerange_end)
+ R_Shadow_ResizeTriangleFacingLight(trianglerange_end);
+
+ if (maxvertexupdate < innumvertices)
+ {
+ maxvertexupdate = innumvertices;
+ if (vertexupdate)
+ Mem_Free(vertexupdate);
+ if (vertexremap)
+ Mem_Free(vertexremap);
+ vertexupdate = Mem_Alloc(r_shadow_mempool, maxvertexupdate * sizeof(int));
+ vertexremap = Mem_Alloc(r_shadow_mempool, maxvertexupdate * sizeof(int));
+ }
+ vertexupdatenum++;
+
+ if (r_shadow_singlepassvolumegeneration.integer)
+ {
+ // one pass approach (identify lit/dark faces and generate sides while doing so)
+ for (i = trianglerange_start, e = inelement3i + i * 3, n = inneighbor3i + i * 3;i < trianglerange_end;i++, e += 3, n += 3)
+ {
+ // calculate triangle facing flag
+ v[0] = invertex3f + e[0] * 3;
+ v[1] = invertex3f + e[1] * 3;
+ v[2] = invertex3f + e[2] * 3;
+ if((trianglefacinglight[i] = PointInfrontOfTriangle(relativelightorigin, v[0], v[1], v[2])))
+ {
+ // make sure the vertices are created
+ for (j = 0;j < 3;j++)
+ {
+ if (vertexupdate[e[j]] != vertexupdatenum)
+ {
+ vertexupdate[e[j]] = vertexupdatenum;
+ vertexremap[e[j]] = outvertices;
+ VectorCopy(v[j], outvertex3f);
+ VectorSubtract(v[j], relativelightorigin, temp);
+ f = projectdistance / VectorLength(temp);
+ VectorMA(relativelightorigin, f, temp, (outvertex3f + 3));
+ outvertex3f += 6;
+ outvertices += 2;
+ }
+ }
+ // output the front and back triangles
+ vr[0] = vertexremap[e[0]];
+ vr[1] = vertexremap[e[1]];
+ vr[2] = vertexremap[e[2]];
+ outelement3i[0] = vr[0];
+ outelement3i[1] = vr[1];
+ outelement3i[2] = vr[2];
+ outelement3i[3] = vr[2] + 1;
+ outelement3i[4] = vr[1] + 1;
+ outelement3i[5] = vr[0] + 1;
+ outelement3i += 6;
+ tris += 2;
+ // output the sides (facing outward from this triangle)
+ t = n[0];
+ if ((t >= trianglerange_start && t < trianglerange_end) ? (t < i && !trianglefacinglight[t]) : (t < 0 || (te = inelement3i + t * 3, v[0] = invertex3f + te[0] * 3, v[1] = invertex3f + te[1] * 3, v[2] = invertex3f + te[2] * 3, !PointInfrontOfTriangle(relativelightorigin, v[0], v[1], v[2]))))
+ {
+ outelement3i[0] = vr[1];
+ outelement3i[1] = vr[0];
+ outelement3i[2] = vr[0] + 1;
+ outelement3i[3] = vr[1];
+ outelement3i[4] = vr[0] + 1;
+ outelement3i[5] = vr[1] + 1;
+ outelement3i += 6;
+ tris += 2;
+ }
+ t = n[1];
+ if ((t >= trianglerange_start && t < trianglerange_end) ? (t < i && !trianglefacinglight[t]) : (t < 0 || (te = inelement3i + t * 3, v[0] = invertex3f + te[0] * 3, v[1] = invertex3f + te[1] * 3, v[2] = invertex3f + te[2] * 3, !PointInfrontOfTriangle(relativelightorigin, v[0], v[1], v[2]))))
+ {
+ outelement3i[0] = vr[2];
+ outelement3i[1] = vr[1];
+ outelement3i[2] = vr[1] + 1;
+ outelement3i[3] = vr[2];
+ outelement3i[4] = vr[1] + 1;
+ outelement3i[5] = vr[2] + 1;
+ outelement3i += 6;
+ tris += 2;
+ }
+ t = n[2];
+ if ((t >= trianglerange_start && t < trianglerange_end) ? (t < i && !trianglefacinglight[t]) : (t < 0 || (te = inelement3i + t * 3, v[0] = invertex3f + te[0] * 3, v[1] = invertex3f + te[1] * 3, v[2] = invertex3f + te[2] * 3, !PointInfrontOfTriangle(relativelightorigin, v[0], v[1], v[2]))))
+ {
+ outelement3i[0] = vr[0];
+ outelement3i[1] = vr[2];
+ outelement3i[2] = vr[2] + 1;
+ outelement3i[3] = vr[0];
+ outelement3i[4] = vr[2] + 1;
+ outelement3i[5] = vr[0] + 1;
+ outelement3i += 6;
+ tris += 2;
+ }
+ }
+ else
+ {
+ // this triangle is not facing the light
+ // output the sides (facing inward to this triangle)
+ t = n[0];
+ if (t < i && t >= trianglerange_start && t < trianglerange_end && trianglefacinglight[t])
+ {
+ vr[0] = vertexremap[e[0]];
+ vr[1] = vertexremap[e[1]];
+ outelement3i[0] = vr[1];
+ outelement3i[1] = vr[0] + 1;
+ outelement3i[2] = vr[0];
+ outelement3i[3] = vr[1];
+ outelement3i[4] = vr[1] + 1;
+ outelement3i[5] = vr[0] + 1;
+ outelement3i += 6;
+ tris += 2;
+ }
+ t = n[1];
+ if (t < i && t >= trianglerange_start && t < trianglerange_end && trianglefacinglight[t])
+ {
+ vr[1] = vertexremap[e[1]];
+ vr[2] = vertexremap[e[2]];
+ outelement3i[0] = vr[2];
+ outelement3i[1] = vr[1] + 1;
+ outelement3i[2] = vr[1];
+ outelement3i[3] = vr[2];
+ outelement3i[4] = vr[2] + 1;
+ outelement3i[5] = vr[1] + 1;
+ outelement3i += 6;
+ tris += 2;
+ }
+ t = n[2];
+ if (t < i && t >= trianglerange_start && t < trianglerange_end && trianglefacinglight[t])
+ {
+ vr[0] = vertexremap[e[0]];
+ vr[2] = vertexremap[e[2]];
+ outelement3i[0] = vr[0];
+ outelement3i[1] = vr[2] + 1;
+ outelement3i[2] = vr[2];
+ outelement3i[3] = vr[0];
+ outelement3i[4] = vr[0] + 1;
+ outelement3i[5] = vr[2] + 1;
+ outelement3i += 6;
+ tris += 2;
+ }
+ }
+ }
+ }
+ else
+ {
+ // two pass approach (identify lit/dark faces and then generate sides)
+ for (i = trianglerange_start, e = inelement3i + i * 3, numfacing = 0;i < trianglerange_end;i++, e += 3)
+ {
+ // calculate triangle facing flag
+ v[0] = invertex3f + e[0] * 3;
+ v[1] = invertex3f + e[1] * 3;
+ v[2] = invertex3f + e[2] * 3;
+ if((trianglefacinglight[i] = PointInfrontOfTriangle(relativelightorigin, v[0], v[1], v[2])))
+ {
+ trianglefacinglightlist[numfacing++] = i;
+ // make sure the vertices are created
+ for (j = 0;j < 3;j++)
+ {
+ if (vertexupdate[e[j]] != vertexupdatenum)
+ {
+ vertexupdate[e[j]] = vertexupdatenum;
+ vertexremap[e[j]] = outvertices;
+ VectorSubtract(v[j], relativelightorigin, temp);
+ f = projectdistance / VectorLength(temp);
+ VectorCopy(v[j], outvertex3f);
+ VectorMA(relativelightorigin, f, temp, (outvertex3f + 3));
+ outvertex3f += 6;
+ outvertices += 2;
+ }
+ }
+ // output the front and back triangles
+ outelement3i[3] = vertexremap[e[0]];
+ outelement3i[4] = vertexremap[e[1]];
+ outelement3i[5] = vertexremap[e[2]];
+ outelement3i[0] = vertexremap[e[2]] + 1;
+ outelement3i[1] = vertexremap[e[1]] + 1;
+ outelement3i[2] = vertexremap[e[0]] + 1;
+ outelement3i += 6;
+ tris += 2;
+ }
+ }
+ for (i = 0;i < numfacing;i++)
+ {
+ t = trianglefacinglightlist[i];
+ e = inelement3i + t * 3;
+ n = inneighbor3i + t * 3;
+ // output the sides (facing outward from this triangle)
+ t = n[0];
+ if ((t >= trianglerange_start && t < trianglerange_end) ? (!trianglefacinglight[t]) : (t < 0 || (te = inelement3i + t * 3, v[0] = invertex3f + te[0] * 3, v[1] = invertex3f + te[1] * 3, v[2] = invertex3f + te[2] * 3, !PointInfrontOfTriangle(relativelightorigin, v[0], v[1], v[2]))))
+ {
+ vr[0] = vertexremap[e[0]];
+ vr[1] = vertexremap[e[1]];
+ outelement3i[0] = vr[1];
+ outelement3i[1] = vr[0];
+ outelement3i[2] = vr[0] + 1;
+ outelement3i[3] = vr[1];
+ outelement3i[4] = vr[0] + 1;
+ outelement3i[5] = vr[1] + 1;
+ outelement3i += 6;
+ tris += 2;
+ }
+ t = n[1];
+ if ((t >= trianglerange_start && t < trianglerange_end) ? (!trianglefacinglight[t]) : (t < 0 || (te = inelement3i + t * 3, v[0] = invertex3f + te[0] * 3, v[1] = invertex3f + te[1] * 3, v[2] = invertex3f + te[2] * 3, !PointInfrontOfTriangle(relativelightorigin, v[0], v[1], v[2]))))
+ {
+ vr[1] = vertexremap[e[1]];
+ vr[2] = vertexremap[e[2]];
+ outelement3i[0] = vr[2];
+ outelement3i[1] = vr[1];
+ outelement3i[2] = vr[1] + 1;
+ outelement3i[3] = vr[2];
+ outelement3i[4] = vr[1] + 1;
+ outelement3i[5] = vr[2] + 1;
+ outelement3i += 6;
+ tris += 2;
+ }
+ t = n[2];
+ if ((t >= trianglerange_start && t < trianglerange_end) ? (!trianglefacinglight[t]) : (t < 0 || (te = inelement3i + t * 3, v[0] = invertex3f + te[0] * 3, v[1] = invertex3f + te[1] * 3, v[2] = invertex3f + te[2] * 3, !PointInfrontOfTriangle(relativelightorigin, v[0], v[1], v[2]))))
+ {
+ vr[0] = vertexremap[e[0]];
+ vr[2] = vertexremap[e[2]];
+ outelement3i[0] = vr[0];
+ outelement3i[1] = vr[2];
+ outelement3i[2] = vr[2] + 1;
+ outelement3i[3] = vr[0];
+ outelement3i[4] = vr[2] + 1;
+ outelement3i[5] = vr[0] + 1;
+ outelement3i += 6;
+ tris += 2;
+ }
+ }
+ }
+ if (outnumvertices)
+ *outnumvertices = outvertices;
+ return tris;
+}
+
+float varray_vertex3f2[65536*3];
+
+void R_Shadow_Volume(int numverts, int numtris, const float *invertex3f, int *elements, int *neighbors, vec3_t relativelightorigin, float lightradius, float projectdistance)
{
- int tris;
+ int tris, outverts;
if (projectdistance < 0.1)
{
Con_Printf("R_Shadow_Volume: projectdistance %f\n");
}
if (!numverts)
return;
-// terminology:
-//
-// frontface:
-// a triangle facing the light source
-//
-// backface:
-// a triangle not facing the light source
-//
-// shadow volume:
-// an extrusion of the frontfaces, beginning at the original geometry and
-// ending further from the light source than the original geometry
-// (presumably at least as far as the light's radius, if the light has a
-// radius at all), capped at both front and back to avoid any problems
-//
-// description:
-// draws the shadow volumes of the model.
-// requirements:
-// vertex locations must already be in varray_vertex3f before use.
-// varray_vertex3f must have capacity for numverts * 2.
-
- // make sure trianglefacinglight is big enough for this volume
- if (maxtrianglefacinglight < numtris)
- R_Shadow_ResizeTriangleFacingLight(numtris);
// make sure shadowelements is big enough for this volume
if (maxshadowelements < numtris * 24)
R_Shadow_ResizeShadowElements(numtris);
- // check which triangles are facing the light
- tris = R_Shadow_MakeTriangleShadowFlags_Vertex3f(elements, varray_vertex3f, numtris, trianglefacinglight, trianglefacinglightlist, relativelightorigin);
- if (!tris)
- return;
-
- // by clever use of elements we can construct the whole shadow from
- // the unprojected vertices and the projected vertices
-
- // output triangle elements and vertices
- tris = R_Shadow_BuildShadowVolume(elements, neighbors, numverts, trianglefacinglight, trianglefacinglightlist, tris, shadowelements, varray_vertex3f, relativelightorigin, projectdistance);
- if (!tris)
- return;
-
- if (r_shadowstage == SHADOWSTAGE_STENCIL)
+ // check which triangles are facing the light, and then output
+ // triangle elements and vertices... by clever use of elements we
+ // can construct the whole shadow from the unprojected vertices and
+ // the projected vertices
+ if ((tris = R_Shadow_ConstructShadowVolume(numverts, 0, numtris, elements, neighbors, invertex3f, &outverts, shadowelements, varray_vertex3f2, relativelightorigin, projectdistance)))
{
- // increment stencil if backface is behind depthbuffer
- //R_Mesh_EndBatch();
- qglCullFace(GL_BACK); // quake is backwards, this culls front faces
- qglStencilOp(GL_KEEP, GL_INCR, GL_KEEP);
- R_Mesh_Draw_NoBatching(numverts * 2, tris, shadowelements);
+ GL_VertexPointer(varray_vertex3f2);
+ if (r_shadowstage == SHADOWSTAGE_STENCIL)
+ {
+ // increment stencil if backface is behind depthbuffer
+ qglCullFace(GL_BACK); // quake is backwards, this culls front faces
+ qglStencilOp(GL_KEEP, GL_INCR, GL_KEEP);
+ R_Mesh_Draw(outverts, tris, shadowelements);
+ c_rt_shadowmeshes++;
+ c_rt_shadowtris += numtris;
+ // decrement stencil if frontface is behind depthbuffer
+ qglCullFace(GL_FRONT); // quake is backwards, this culls back faces
+ qglStencilOp(GL_KEEP, GL_DECR, GL_KEEP);
+ }
+ R_Mesh_Draw(outverts, tris, shadowelements);
c_rt_shadowmeshes++;
c_rt_shadowtris += numtris;
- // decrement stencil if frontface is behind depthbuffer
- //R_Mesh_EndBatch();
- qglCullFace(GL_FRONT); // quake is backwards, this culls back faces
- qglStencilOp(GL_KEEP, GL_DECR, GL_KEEP);
}
- R_Mesh_Draw_NoBatching(numverts * 2, tris, shadowelements);
- c_rt_shadowmeshes++;
- c_rt_shadowtris += numtris;
}
void R_Shadow_RenderShadowMeshVolume(shadowmesh_t *firstmesh)
{
shadowmesh_t *mesh;
+ rmeshstate_t m;
+ memset(&m, 0, sizeof(m));
if (r_shadowstage == SHADOWSTAGE_STENCIL)
{
// increment stencil if backface is behind depthbuffer
- //R_Mesh_EndBatch();
qglCullFace(GL_BACK); // quake is backwards, this culls front faces
qglStencilOp(GL_KEEP, GL_INCR, GL_KEEP);
for (mesh = firstmesh;mesh;mesh = mesh->next)
{
- R_Mesh_GetSpace(mesh->numverts);
- R_Mesh_CopyVertex3f(mesh->vertex3f, mesh->numverts);
- R_Mesh_Draw_NoBatching(mesh->numverts, mesh->numtriangles, mesh->element3i);
+ GL_VertexPointer(mesh->vertex3f);
+ R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->element3i);
c_rtcached_shadowmeshes++;
c_rtcached_shadowtris += mesh->numtriangles;
}
// decrement stencil if frontface is behind depthbuffer
- //R_Mesh_EndBatch();
qglCullFace(GL_FRONT); // quake is backwards, this culls back faces
qglStencilOp(GL_KEEP, GL_DECR, GL_KEEP);
}
for (mesh = firstmesh;mesh;mesh = mesh->next)
{
- R_Mesh_GetSpace(mesh->numverts);
- R_Mesh_CopyVertex3f(mesh->vertex3f, mesh->numverts);
- R_Mesh_Draw_NoBatching(mesh->numverts, mesh->numtriangles, mesh->element3i);
+ GL_VertexPointer(mesh->vertex3f);
+ R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->element3i);
c_rtcached_shadowmeshes++;
c_rtcached_shadowtris += mesh->numtriangles;
}
|| r_shadow_lightattenuationscale.value != r_shadow_attenscale)
R_Shadow_MakeTextures();
- R_Mesh_EndBatch();
- memset(&m, 0, sizeof(m));
- m.blendfunc1 = GL_ONE;
- m.blendfunc2 = GL_ZERO;
- R_Mesh_State(&m);
+ GL_BlendFunc(GL_ONE, GL_ZERO);
+ GL_DepthMask(false);
+ GL_DepthTest(true);
GL_Color(0, 0, 0, 1);
+
+ memset(&m, 0, sizeof(m));
+ R_Mesh_State_Texture(&m);
+
qglDisable(GL_SCISSOR_TEST);
r_shadowstage = SHADOWSTAGE_NONE;
void R_Shadow_Stage_ShadowVolumes(void)
{
rmeshstate_t m;
- //R_Mesh_EndBatch();
+
memset(&m, 0, sizeof(m));
- R_Mesh_TextureState(&m);
+ R_Mesh_State_Texture(&m);
+
GL_Color(1, 1, 1, 1);
+ GL_BlendFunc(GL_ONE, GL_ZERO);
+ GL_DepthMask(false);
+ GL_DepthTest(true);
+
+ if (r_shadow_polygonoffset.value != 0)
+ {
+ qglPolygonOffset(1.0f, r_shadow_polygonoffset.value);
+ qglEnable(GL_POLYGON_OFFSET_FILL);
+ }
+ else
+ qglDisable(GL_POLYGON_OFFSET_FILL);
qglColorMask(0, 0, 0, 0);
- qglDisable(GL_BLEND);
- qglDepthMask(0);
qglDepthFunc(GL_LESS);
qglEnable(GL_STENCIL_TEST);
qglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
qglStencilFunc(GL_ALWAYS, 128, 0xFF);
- qglEnable(GL_CULL_FACE);
- qglEnable(GL_DEPTH_TEST);
r_shadowstage = SHADOWSTAGE_STENCIL;
+
qglClear(GL_STENCIL_BUFFER_BIT);
c_rt_clears++;
// LordHavoc note: many shadow volumes reside entirely inside the world
void R_Shadow_Stage_LightWithoutShadows(void)
{
rmeshstate_t m;
- //R_Mesh_EndBatch();
+
memset(&m, 0, sizeof(m));
- R_Mesh_TextureState(&m);
- qglActiveTexture(GL_TEXTURE0_ARB);
+ R_Mesh_State_Texture(&m);
- qglEnable(GL_BLEND);
- qglBlendFunc(GL_ONE, GL_ONE);
GL_Color(1, 1, 1, 1);
+ GL_BlendFunc(GL_ONE, GL_ONE);
+ GL_DepthMask(false);
+ GL_DepthTest(true);
+ qglDisable(GL_POLYGON_OFFSET_FILL);
+
+ //GL_DepthTest(false);
+
qglColorMask(1, 1, 1, 1);
- qglDepthMask(0);
- qglDepthFunc(GL_EQUAL);
+ qglDepthFunc(GL_LEQUAL);
qglDisable(GL_STENCIL_TEST);
qglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
qglStencilFunc(GL_EQUAL, 128, 0xFF);
- qglEnable(GL_CULL_FACE);
- qglEnable(GL_DEPTH_TEST);
+
r_shadowstage = SHADOWSTAGE_LIGHT;
c_rt_lights++;
}
void R_Shadow_Stage_LightWithShadows(void)
{
rmeshstate_t m;
- //R_Mesh_EndBatch();
+
memset(&m, 0, sizeof(m));
- R_Mesh_TextureState(&m);
- qglActiveTexture(GL_TEXTURE0_ARB);
+ R_Mesh_State_Texture(&m);
- qglEnable(GL_BLEND);
- qglBlendFunc(GL_ONE, GL_ONE);
GL_Color(1, 1, 1, 1);
+ GL_BlendFunc(GL_ONE, GL_ONE);
+ GL_DepthMask(false);
+ GL_DepthTest(true);
+ qglDisable(GL_POLYGON_OFFSET_FILL);
+
+ //GL_DepthTest(false);
+
qglColorMask(1, 1, 1, 1);
- qglDepthMask(0);
- qglDepthFunc(GL_EQUAL);
+ qglDepthFunc(GL_LEQUAL);
qglEnable(GL_STENCIL_TEST);
qglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
// only draw light where this geometry was already rendered AND the
// stencil is 128 (values other than this mean shadow)
qglStencilFunc(GL_EQUAL, 128, 0xFF);
- qglEnable(GL_CULL_FACE);
- qglEnable(GL_DEPTH_TEST);
+
r_shadowstage = SHADOWSTAGE_LIGHT;
c_rt_lights++;
}
void R_Shadow_Stage_End(void)
{
rmeshstate_t m;
- //R_Mesh_EndBatch();
- // attempt to restore state to what Mesh_State thinks it is
- qglDisable(GL_BLEND);
- qglBlendFunc(GL_ONE, GL_ZERO);
- qglDepthMask(1);
- // now restore the rest of the state to normal
+
+ memset(&m, 0, sizeof(m));
+ R_Mesh_State_Texture(&m);
+
GL_Color(1, 1, 1, 1);
+ GL_BlendFunc(GL_ONE, GL_ZERO);
+ GL_DepthMask(true);
+ GL_DepthTest(true);
+ qglDisable(GL_POLYGON_OFFSET_FILL);
+
qglColorMask(1, 1, 1, 1);
qglDisable(GL_SCISSOR_TEST);
qglDepthFunc(GL_LEQUAL);
qglDisable(GL_STENCIL_TEST);
qglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
qglStencilFunc(GL_ALWAYS, 128, 0xFF);
- qglEnable(GL_CULL_FACE);
- qglEnable(GL_DEPTH_TEST);
- // force mesh state to reset by using various combinations of features
- memset(&m, 0, sizeof(m));
- m.blendfunc1 = GL_SRC_ALPHA;
- m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
- R_Mesh_State(&m);
- m.blendfunc1 = GL_ONE;
- m.blendfunc2 = GL_ZERO;
- R_Mesh_State(&m);
+
r_shadowstage = SHADOWSTAGE_NONE;
}
&& r_origin[1] >= mins[1] && r_origin[1] <= maxs[1]
&& r_origin[2] >= mins[2] && r_origin[2] <= maxs[2])
{
- //R_Mesh_EndBatch();
qglDisable(GL_SCISSOR_TEST);
return false;
}
VectorSubtract(r_origin, origin, v);
if (DotProduct(v, v) < radius * radius)
{
- //R_Mesh_EndBatch();
qglDisable(GL_SCISSOR_TEST);
return false;
}
if (ix2 <= ix1 || iy2 <= iy1)
return true;
// set up the scissor rectangle
- //R_Mesh_EndBatch();
qglScissor(ix1, iy1, ix2 - ix1, iy2 - iy1);
qglEnable(GL_SCISSOR_TEST);
c_rt_scissored++;
// (?!? seems like a driver bug) so abort if gl_stencil is false
if (!gl_stencil || BoxesOverlap(r_origin, r_origin, mins, maxs))
{
- //R_Mesh_EndBatch();
qglDisable(GL_SCISSOR_TEST);
return false;
}
if (ix2 <= ix1 || iy2 <= iy1)
return true;
// set up the scissor rectangle
- //R_Mesh_EndBatch();
qglScissor(ix1, iy1, ix2 - ix1, iy2 - iy1);
qglEnable(GL_SCISSOR_TEST);
c_rt_scissored++;
int renders;
float color[3], color2[3];
rmeshstate_t m;
- memset(&m, 0, sizeof(m));
+ GL_VertexPointer(vertex3f);
if (gl_dot3arb && gl_texturecubemap && gl_combine.integer && gl_stencil)
{
if (!bumptexture)
bumptexture = r_shadow_blankbumptexture;
+ GL_Color(1,1,1,1);
// colorscale accounts for how much we multiply the brightness during combine
// mult is how many times the final pass of the lighting will be
// performed to get more brightness than otherwise possible
if (r_shadow_texture3d.integer && r_textureunits.integer >= 4)
{
// 3/2 3D combine path (Geforce3, Radeon 8500)
- //R_Mesh_EndBatch();
+ memset(&m, 0, sizeof(m));
m.tex[0] = R_GetTexture(bumptexture);
m.texcubemap[1] = R_GetTexture(r_shadow_normalcubetexture);
m.tex3d[2] = R_GetTexture(r_shadow_attenuation3dtexture);
m.texcombinergb[0] = GL_REPLACE;
m.texcombinergb[1] = GL_DOT3_RGBA_ARB;
- R_Mesh_TextureState(&m);
+ m.pointer_texcoord[0] = texcoord2f;
+ m.pointer_texcoord[1] = varray_texcoord3f[1];
+ m.pointer_texcoord[2] = varray_texcoord3f[2];
+ R_Mesh_State_Texture(&m);
qglColorMask(0,0,0,1);
- qglDisable(GL_BLEND);
- GL_Color(1,1,1,1);
- R_Mesh_GetSpace(numverts);
- R_Mesh_CopyVertex3f(vertex3f, numverts);
- R_Mesh_CopyTexCoord2f(0, texcoord2f, numverts);
+ GL_BlendFunc(GL_ONE, GL_ZERO);
R_Shadow_GenTexCoords_Diffuse_NormalCubeMap(varray_texcoord3f[1], numverts, vertex3f, svector3f, tvector3f, normal3f, relativelightorigin);
R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[2], numverts, vertex3f, matrix_modeltoattenuationxyz);
- R_Mesh_Draw_NoBatching(numverts, numtriangles, elements);
+ R_Mesh_Draw(numverts, numtriangles, elements);
c_rt_lightmeshes++;
c_rt_lighttris += numtriangles;
- //R_Mesh_EndBatch();
+ memset(&m, 0, sizeof(m));
m.tex[0] = R_GetTexture(basetexture);
- m.tex[1] = 0;
m.texcubemap[1] = R_GetTexture(lightcubemap);
- m.tex3d[2] = 0;
- m.texcombinergb[0] = GL_MODULATE;
- m.texcombinergb[1] = GL_MODULATE;
- R_Mesh_TextureState(&m);
+ m.pointer_texcoord[0] = texcoord2f;
+ m.pointer_texcoord[1] = lightcubemap ? varray_texcoord3f[1] : NULL;
+ R_Mesh_State_Texture(&m);
qglColorMask(1,1,1,0);
- qglBlendFunc(GL_DST_ALPHA, GL_ONE);
- qglEnable(GL_BLEND);
- R_Mesh_GetSpace(numverts);
- R_Mesh_CopyVertex3f(vertex3f, numverts);
- R_Mesh_CopyTexCoord2f(0, texcoord2f, numverts);
+ GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
if (lightcubemap)
R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltofilter);
VectorScale(lightcolor, r_colorscale * r_shadow_lightintensityscale.value, color2);
color[1] = bound(0, color2[1], 1);
color[2] = bound(0, color2[2], 1);
GL_Color(color[0], color[1], color[2], 1);
- R_Mesh_Draw_NoBatching(numverts, numtriangles, elements);
+ R_Mesh_Draw(numverts, numtriangles, elements);
c_rt_lightmeshes++;
c_rt_lighttris += numtriangles;
}
else if (r_shadow_texture3d.integer && r_textureunits.integer >= 2 && lightcubemap)
{
// 1/2/2 3D combine path (original Radeon)
- //R_Mesh_EndBatch();
+ memset(&m, 0, sizeof(m));
m.tex3d[0] = R_GetTexture(r_shadow_attenuation3dtexture);
- R_Mesh_TextureState(&m);
+ m.pointer_texcoord[0] = varray_texcoord3f[0];
+ R_Mesh_State_Texture(&m);
qglColorMask(0,0,0,1);
- qglDisable(GL_BLEND);
- GL_Color(1,1,1,1);
- R_Mesh_GetSpace(numverts);
- R_Mesh_CopyVertex3f(vertex3f, numverts);
+ GL_BlendFunc(GL_ONE, GL_ZERO);
R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[0], numverts, vertex3f, matrix_modeltoattenuationxyz);
- R_Mesh_Draw_NoBatching(numverts, numtriangles, elements);
+ R_Mesh_Draw(numverts, numtriangles, elements);
c_rt_lightmeshes++;
c_rt_lighttris += numtriangles;
- //R_Mesh_EndBatch();
+ memset(&m, 0, sizeof(m));
m.tex[0] = R_GetTexture(bumptexture);
- m.tex3d[0] = 0;
m.texcubemap[1] = R_GetTexture(r_shadow_normalcubetexture);
m.texcombinergb[0] = GL_REPLACE;
m.texcombinergb[1] = GL_DOT3_RGBA_ARB;
- R_Mesh_TextureState(&m);
- qglBlendFunc(GL_DST_ALPHA, GL_ZERO);
- qglEnable(GL_BLEND);
- R_Mesh_GetSpace(numverts);
- R_Mesh_CopyVertex3f(vertex3f, numverts);
- R_Mesh_CopyTexCoord2f(0, texcoord2f, numverts);
+ m.pointer_texcoord[0] = texcoord2f;
+ m.pointer_texcoord[1] = varray_texcoord3f[1];
+ R_Mesh_State_Texture(&m);
+ GL_BlendFunc(GL_DST_ALPHA, GL_ZERO);
R_Shadow_GenTexCoords_Diffuse_NormalCubeMap(varray_texcoord3f[1], numverts, vertex3f, svector3f, tvector3f, normal3f, relativelightorigin);
- R_Mesh_Draw_NoBatching(numverts, numtriangles, elements);
+ R_Mesh_Draw(numverts, numtriangles, elements);
c_rt_lightmeshes++;
c_rt_lighttris += numtriangles;
- //R_Mesh_EndBatch();
+ memset(&m, 0, sizeof(m));
m.tex[0] = R_GetTexture(basetexture);
m.texcubemap[1] = R_GetTexture(lightcubemap);
- m.texcombinergb[0] = GL_MODULATE;
- m.texcombinergb[1] = GL_MODULATE;
- R_Mesh_TextureState(&m);
+ m.pointer_texcoord[0] = texcoord2f;
+ m.pointer_texcoord[1] = lightcubemap ? varray_texcoord3f[1] : NULL;
+ R_Mesh_State_Texture(&m);
qglColorMask(1,1,1,0);
- qglBlendFunc(GL_DST_ALPHA, GL_ONE);
- R_Mesh_GetSpace(numverts);
- R_Mesh_CopyVertex3f(vertex3f, numverts);
- R_Mesh_CopyTexCoord2f(0, texcoord2f, numverts);
+ GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
if (lightcubemap)
R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltofilter);
VectorScale(lightcolor, r_colorscale * r_shadow_lightintensityscale.value, color2);
color[1] = bound(0, color2[1], 1);
color[2] = bound(0, color2[2], 1);
GL_Color(color[0], color[1], color[2], 1);
- R_Mesh_Draw_NoBatching(numverts, numtriangles, elements);
+ R_Mesh_Draw(numverts, numtriangles, elements);
c_rt_lightmeshes++;
c_rt_lighttris += numtriangles;
}
else if (r_shadow_texture3d.integer && r_textureunits.integer >= 2 && !lightcubemap)
{
// 2/2 3D combine path (original Radeon)
- //R_Mesh_EndBatch();
+ memset(&m, 0, sizeof(m));
m.tex[0] = R_GetTexture(bumptexture);
m.texcubemap[1] = R_GetTexture(r_shadow_normalcubetexture);
m.texcombinergb[0] = GL_REPLACE;
m.texcombinergb[1] = GL_DOT3_RGBA_ARB;
- R_Mesh_TextureState(&m);
- GL_Color(1,1,1,1);
+ m.pointer_texcoord[0] = texcoord2f;
+ m.pointer_texcoord[1] = varray_texcoord3f[1];
+ R_Mesh_State_Texture(&m);
qglColorMask(0,0,0,1);
- qglDisable(GL_BLEND);
- R_Mesh_GetSpace(numverts);
- R_Mesh_CopyVertex3f(vertex3f, numverts);
- R_Mesh_CopyTexCoord2f(0, texcoord2f, numverts);
+ GL_BlendFunc(GL_ONE, GL_ZERO);
R_Shadow_GenTexCoords_Diffuse_NormalCubeMap(varray_texcoord3f[1], numverts, vertex3f, svector3f, tvector3f, normal3f, relativelightorigin);
- R_Mesh_Draw_NoBatching(numverts, numtriangles, elements);
+ R_Mesh_Draw(numverts, numtriangles, elements);
c_rt_lightmeshes++;
c_rt_lighttris += numtriangles;
- //R_Mesh_EndBatch();
+ memset(&m, 0, sizeof(m));
m.tex[0] = R_GetTexture(basetexture);
m.tex3d[1] = R_GetTexture(r_shadow_attenuation3dtexture);
- m.texcubemap[1] = 0;
- m.texcombinergb[0] = GL_MODULATE;
- m.texcombinergb[1] = GL_MODULATE;
- R_Mesh_TextureState(&m);
- R_Mesh_GetSpace(numverts);
+ m.pointer_texcoord[0] = texcoord2f;
+ m.pointer_texcoord[1] = varray_texcoord3f[1];
+ R_Mesh_State_Texture(&m);
qglColorMask(1,1,1,0);
- qglBlendFunc(GL_DST_ALPHA, GL_ONE);
- qglEnable(GL_BLEND);
- R_Mesh_GetSpace(numverts);
- R_Mesh_CopyVertex3f(vertex3f, numverts);
- R_Mesh_CopyTexCoord2f(0, texcoord2f, numverts);
+ GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltoattenuationxyz);
VectorScale(lightcolor, r_colorscale * r_shadow_lightintensityscale.value, color2);
for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--)
color[1] = bound(0, color2[1], 1);
color[2] = bound(0, color2[2], 1);
GL_Color(color[0], color[1], color[2], 1);
- R_Mesh_Draw_NoBatching(numverts, numtriangles, elements);
+ R_Mesh_Draw(numverts, numtriangles, elements);
c_rt_lightmeshes++;
c_rt_lighttris += numtriangles;
}
else if (r_textureunits.integer >= 4)
{
// 4/2 2D combine path (Geforce3, Radeon 8500)
- //R_Mesh_EndBatch();
+ memset(&m, 0, sizeof(m));
m.tex[0] = R_GetTexture(bumptexture);
m.texcubemap[1] = R_GetTexture(r_shadow_normalcubetexture);
m.texcombinergb[0] = GL_REPLACE;
m.texcombinergb[1] = GL_DOT3_RGBA_ARB;
m.tex[2] = R_GetTexture(r_shadow_attenuation2dtexture);
m.tex[3] = R_GetTexture(r_shadow_attenuation2dtexture);
- R_Mesh_TextureState(&m);
+ m.pointer_texcoord[0] = texcoord2f;
+ m.pointer_texcoord[1] = varray_texcoord3f[1];
+ m.pointer_texcoord[2] = varray_texcoord2f[2];
+ m.pointer_texcoord[3] = varray_texcoord2f[3];
+ R_Mesh_State_Texture(&m);
qglColorMask(0,0,0,1);
- qglDisable(GL_BLEND);
- GL_Color(1,1,1,1);
- R_Mesh_GetSpace(numverts);
- R_Mesh_CopyVertex3f(vertex3f, numverts);
- R_Mesh_CopyTexCoord2f(0, texcoord2f, numverts);
+ GL_BlendFunc(GL_ONE, GL_ZERO);
R_Shadow_GenTexCoords_Diffuse_NormalCubeMap(varray_texcoord3f[1], numverts, vertex3f, svector3f, tvector3f, normal3f, relativelightorigin);
R_Shadow_Transform_Vertex3f_TexCoord2f(varray_texcoord2f[2], numverts, vertex3f, matrix_modeltoattenuationxyz);
R_Shadow_Transform_Vertex3f_TexCoord2f(varray_texcoord2f[3], numverts, vertex3f, matrix_modeltoattenuationz);
- R_Mesh_Draw_NoBatching(numverts, numtriangles, elements);
+ R_Mesh_Draw(numverts, numtriangles, elements);
c_rt_lightmeshes++;
c_rt_lighttris += numtriangles;
- //R_Mesh_EndBatch();
+ memset(&m, 0, sizeof(m));
m.tex[0] = R_GetTexture(basetexture);
m.texcubemap[1] = R_GetTexture(lightcubemap);
- m.texcombinergb[0] = GL_MODULATE;
- m.texcombinergb[1] = GL_MODULATE;
- m.tex[2] = 0;
- m.tex[3] = 0;
- R_Mesh_TextureState(&m);
+ m.pointer_texcoord[0] = texcoord2f;
+ m.pointer_texcoord[1] = lightcubemap ? varray_texcoord3f[1] : NULL;
+ R_Mesh_State_Texture(&m);
qglColorMask(1,1,1,0);
- qglBlendFunc(GL_DST_ALPHA, GL_ONE);
- qglEnable(GL_BLEND);
- R_Mesh_GetSpace(numverts);
- R_Mesh_CopyVertex3f(vertex3f, numverts);
- R_Mesh_CopyTexCoord2f(0, texcoord2f, numverts);
+ GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
if (lightcubemap)
R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltofilter);
VectorScale(lightcolor, r_colorscale * r_shadow_lightintensityscale.value, color2);
color[1] = bound(0, color2[1], 1);
color[2] = bound(0, color2[2], 1);
GL_Color(color[0], color[1], color[2], 1);
- R_Mesh_Draw_NoBatching(numverts, numtriangles, elements);
+ R_Mesh_Draw(numverts, numtriangles, elements);
c_rt_lightmeshes++;
c_rt_lighttris += numtriangles;
}
else
{
// 2/2/2 2D combine path (any dot3 card)
- //R_Mesh_EndBatch();
+ memset(&m, 0, sizeof(m));
m.tex[0] = R_GetTexture(r_shadow_attenuation2dtexture);
m.tex[1] = R_GetTexture(r_shadow_attenuation2dtexture);
- R_Mesh_TextureState(&m);
+ m.pointer_texcoord[0] = varray_texcoord2f[0];
+ m.pointer_texcoord[1] = varray_texcoord2f[1];
+ R_Mesh_State_Texture(&m);
qglColorMask(0,0,0,1);
- qglDisable(GL_BLEND);
- GL_Color(1,1,1,1);
- R_Mesh_GetSpace(numverts);
- R_Mesh_CopyVertex3f(vertex3f, numverts);
+ GL_BlendFunc(GL_ONE, GL_ZERO);
R_Shadow_Transform_Vertex3f_TexCoord2f(varray_texcoord2f[0], numverts, vertex3f, matrix_modeltoattenuationxyz);
R_Shadow_Transform_Vertex3f_TexCoord2f(varray_texcoord2f[1], numverts, vertex3f, matrix_modeltoattenuationz);
- R_Mesh_Draw_NoBatching(numverts, numtriangles, elements);
+ R_Mesh_Draw(numverts, numtriangles, elements);
c_rt_lightmeshes++;
c_rt_lighttris += numtriangles;
- //R_Mesh_EndBatch();
+ memset(&m, 0, sizeof(m));
m.tex[0] = R_GetTexture(bumptexture);
- m.tex[1] = 0;
m.texcubemap[1] = R_GetTexture(r_shadow_normalcubetexture);
m.texcombinergb[0] = GL_REPLACE;
m.texcombinergb[1] = GL_DOT3_RGBA_ARB;
- R_Mesh_TextureState(&m);
- qglBlendFunc(GL_DST_ALPHA, GL_ZERO);
- qglEnable(GL_BLEND);
- R_Mesh_GetSpace(numverts);
- R_Mesh_CopyVertex3f(vertex3f, numverts);
- R_Mesh_CopyTexCoord2f(0, texcoord2f, numverts);
+ m.pointer_texcoord[0] = texcoord2f;
+ m.pointer_texcoord[1] = varray_texcoord3f[1];
+ R_Mesh_State_Texture(&m);
+ GL_BlendFunc(GL_DST_ALPHA, GL_ZERO);
R_Shadow_GenTexCoords_Diffuse_NormalCubeMap(varray_texcoord3f[1], numverts, vertex3f, svector3f, tvector3f, normal3f, relativelightorigin);
- R_Mesh_Draw_NoBatching(numverts, numtriangles, elements);
+ R_Mesh_Draw(numverts, numtriangles, elements);
c_rt_lightmeshes++;
c_rt_lighttris += numtriangles;
- //R_Mesh_EndBatch();
+ memset(&m, 0, sizeof(m));
m.tex[0] = R_GetTexture(basetexture);
m.texcubemap[1] = R_GetTexture(lightcubemap);
- m.texcombinergb[0] = GL_MODULATE;
- m.texcombinergb[1] = GL_MODULATE;
- R_Mesh_TextureState(&m);
+ m.pointer_texcoord[0] = texcoord2f;
+ m.pointer_texcoord[1] = lightcubemap ? varray_texcoord3f[1] : NULL;
+ R_Mesh_State_Texture(&m);
qglColorMask(1,1,1,0);
- qglBlendFunc(GL_DST_ALPHA, GL_ONE);
- R_Mesh_GetSpace(numverts);
- R_Mesh_CopyVertex3f(vertex3f, numverts);
- R_Mesh_CopyTexCoord2f(0, texcoord2f, numverts);
+ GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
if (lightcubemap)
R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltofilter);
VectorScale(lightcolor, r_colorscale * r_shadow_lightintensityscale.value, color2);
color[1] = bound(0, color2[1], 1);
color[2] = bound(0, color2[2], 1);
GL_Color(color[0], color[1], color[2], 1);
- R_Mesh_Draw_NoBatching(numverts, numtriangles, elements);
+ R_Mesh_Draw(numverts, numtriangles, elements);
c_rt_lightmeshes++;
c_rt_lighttris += numtriangles;
}
}
else
{
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
+ GL_DepthMask(false);
+ GL_DepthTest(true);
+ GL_ColorPointer(varray_color4f);
+ VectorScale(lightcolor, r_colorscale * r_shadow_lightintensityscale.value, color2);
+ memset(&m, 0, sizeof(m));
+ m.tex[0] = R_GetTexture(basetexture);
+ m.pointer_texcoord[0] = texcoord2f;
if (r_textureunits.integer >= 2)
{
// voodoo2
- //R_Mesh_EndBatch();
-#if 1
- m.tex[0] = R_GetTexture(basetexture);
- m.tex[1] = R_GetTexture(r_shadow_attenuation2dtexture);
- R_Mesh_TextureState(&m);
- qglBlendFunc(GL_SRC_ALPHA, GL_ONE);
- qglEnable(GL_BLEND);
-#else
- m.tex[0] = R_GetTexture(basetexture);
m.tex[1] = R_GetTexture(r_shadow_attenuation2dtexture);
- m.blendfunc1 = GL_SRC_ALPHA;
- m.blendfunc2 = GL_ONE;
- R_Mesh_State(&m);
-#endif
- VectorScale(lightcolor, r_colorscale * r_shadow_lightintensityscale.value, color2);
- for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--)
- {
- color[0] = bound(0, color2[0], 1);
- color[1] = bound(0, color2[1], 1);
- color[2] = bound(0, color2[2], 1);
- GL_UseColorArray();
- R_Mesh_GetSpace(numverts);
- R_Mesh_CopyVertex3f(vertex3f, numverts);
- R_Mesh_CopyTexCoord2f(0, texcoord2f, numverts);
- R_Shadow_Transform_Vertex3f_TexCoord2f(varray_texcoord2f[1], numverts, vertex3f, matrix_modeltoattenuationxyz);
- R_Shadow_VertexLightingWithXYAttenuationTexture(numverts, vertex3f, normal3f, color, matrix_modeltofilter);
- R_Mesh_Draw_NoBatching(numverts, numtriangles, elements);
- c_rt_lightmeshes++;
- c_rt_lighttris += numtriangles;
- }
+ m.pointer_texcoord[1] = varray_texcoord2f[1];
+ R_Shadow_Transform_Vertex3f_TexCoord2f(varray_texcoord2f[1], numverts, vertex3f, matrix_modeltoattenuationxyz);
}
- else
+ R_Mesh_State_Texture(&m);
+ for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--)
{
- // voodoo1
- //R_Mesh_EndBatch();
-#if 1
- m.tex[0] = R_GetTexture(basetexture);
- R_Mesh_TextureState(&m);
- qglBlendFunc(GL_SRC_ALPHA, GL_ONE);
- qglEnable(GL_BLEND);
-#else
- m.tex[0] = R_GetTexture(basetexture);
- m.blendfunc1 = GL_SRC_ALPHA;
- m.blendfunc2 = GL_ONE;
- R_Mesh_State(&m);
-#endif
- VectorScale(lightcolor, r_colorscale * r_shadow_lightintensityscale.value, color2);
- for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--)
- {
- color[0] = bound(0, color2[0], 1);
- color[1] = bound(0, color2[1], 1);
- color[2] = bound(0, color2[2], 1);
- GL_UseColorArray();
- R_Mesh_GetSpace(numverts);
- R_Mesh_CopyVertex3f(vertex3f, numverts);
- R_Mesh_CopyTexCoord2f(0, texcoord2f, numverts);
+ color[0] = bound(0, color2[0], 1);
+ color[1] = bound(0, color2[1], 1);
+ color[2] = bound(0, color2[2], 1);
+ if (r_textureunits.integer >= 2)
+ R_Shadow_VertexLightingWithXYAttenuationTexture(numverts, vertex3f, normal3f, color, matrix_modeltofilter);
+ else
R_Shadow_VertexLighting(numverts, vertex3f, normal3f, color, matrix_modeltofilter);
- R_Mesh_Draw_NoBatching(numverts, numtriangles, elements);
- c_rt_lightmeshes++;
- c_rt_lighttris += numtriangles;
- }
+ R_Mesh_Draw(numverts, numtriangles, elements);
+ c_rt_lightmeshes++;
+ c_rt_lighttris += numtriangles;
}
}
}
rmeshstate_t m;
if (!gl_dot3arb || !gl_texturecubemap || !gl_combine.integer || !gl_stencil)
return;
- memset(&m, 0, sizeof(m));
if (!bumptexture)
bumptexture = r_shadow_blankbumptexture;
if (!glosstexture)
glosstexture = r_shadow_blankglosstexture;
if (r_shadow_gloss.integer >= 2 || (r_shadow_gloss.integer >= 1 && glosstexture != r_shadow_blankglosstexture))
{
+ GL_VertexPointer(vertex3f);
+ GL_Color(1,1,1,1);
if (r_shadow_texture3d.integer && r_textureunits.integer >= 2 && lightcubemap /*&& gl_support_blendsquare*/) // FIXME: detect blendsquare!
{
// 2/0/0/1/2 3D combine blendsquare path
- //R_Mesh_EndBatch();
+ memset(&m, 0, sizeof(m));
m.tex[0] = R_GetTexture(bumptexture);
m.texcubemap[1] = R_GetTexture(r_shadow_normalcubetexture);
m.texcombinergb[1] = GL_DOT3_RGBA_ARB;
- R_Mesh_TextureState(&m);
+ m.pointer_texcoord[0] = texcoord2f;
+ m.pointer_texcoord[1] = varray_texcoord3f[1];
+ R_Mesh_State_Texture(&m);
qglColorMask(0,0,0,1);
// this squares the result
- qglEnable(GL_BLEND);
- qglBlendFunc(GL_SRC_ALPHA, GL_ZERO);
- GL_Color(1,1,1,1);
- R_Mesh_GetSpace(numverts);
- R_Mesh_CopyVertex3f(vertex3f, numverts);
- R_Mesh_CopyTexCoord2f(0, texcoord2f, numverts);
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ZERO);
R_Shadow_GenTexCoords_Specular_NormalCubeMap(varray_texcoord3f[1], numverts, vertex3f, svector3f, tvector3f, normal3f, relativelightorigin, relativeeyeorigin);
- R_Mesh_Draw_NoBatching(numverts, numtriangles, elements);
+ R_Mesh_Draw(numverts, numtriangles, elements);
c_rt_lightmeshes++;
c_rt_lighttris += numtriangles;
- //R_Mesh_EndBatch();
- m.tex[0] = 0;
- m.texcubemap[1] = 0;
- m.texcombinergb[1] = GL_MODULATE;
- R_Mesh_TextureState(&m);
+ memset(&m, 0, sizeof(m));
+ R_Mesh_State_Texture(&m);
// square alpha in framebuffer a few times to make it shiny
- qglBlendFunc(GL_ZERO, GL_DST_ALPHA);
+ GL_BlendFunc(GL_ZERO, GL_DST_ALPHA);
// these comments are a test run through this math for intensity 0.5
// 0.5 * 0.5 = 0.25 (done by the BlendFunc earlier)
// 0.25 * 0.25 = 0.0625 (this is another pass)
// 0.0625 * 0.0625 = 0.00390625 (this is another pass)
- R_Mesh_GetSpace(numverts);
- R_Mesh_CopyVertex3f(vertex3f, numverts);
- R_Mesh_Draw_NoBatching(numverts, numtriangles, elements);
+ R_Mesh_Draw(numverts, numtriangles, elements);
c_rt_lightmeshes++;
c_rt_lighttris += numtriangles;
- R_Mesh_Draw_NoBatching(numverts, numtriangles, elements);
+ R_Mesh_Draw(numverts, numtriangles, elements);
c_rt_lightmeshes++;
c_rt_lighttris += numtriangles;
- //R_Mesh_EndBatch();
+ memset(&m, 0, sizeof(m));
m.tex3d[0] = R_GetTexture(r_shadow_attenuation3dtexture);
- R_Mesh_TextureState(&m);
- qglBlendFunc(GL_DST_ALPHA, GL_ZERO);
- R_Mesh_GetSpace(numverts);
- R_Mesh_CopyVertex3f(vertex3f, numverts);
+ m.pointer_texcoord[0] = varray_texcoord3f[0];
+ R_Mesh_State_Texture(&m);
+ GL_BlendFunc(GL_DST_ALPHA, GL_ZERO);
R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[0], numverts, vertex3f, matrix_modeltoattenuationxyz);
- R_Mesh_Draw_NoBatching(numverts, numtriangles, elements);
+ R_Mesh_Draw(numverts, numtriangles, elements);
c_rt_lightmeshes++;
c_rt_lighttris += numtriangles;
- //R_Mesh_EndBatch();
- m.tex3d[0] = 0;
+ memset(&m, 0, sizeof(m));
m.tex[0] = R_GetTexture(glosstexture);
m.texcubemap[1] = R_GetTexture(lightcubemap);
- R_Mesh_TextureState(&m);
+ m.pointer_texcoord[0] = texcoord2f;
+ m.pointer_texcoord[1] = lightcubemap ? varray_texcoord3f[1] : NULL;
+ R_Mesh_State_Texture(&m);
qglColorMask(1,1,1,0);
- qglBlendFunc(GL_DST_ALPHA, GL_ONE);
- R_Mesh_GetSpace(numverts);
- R_Mesh_CopyVertex3f(vertex3f, numverts);
- R_Mesh_CopyTexCoord2f(0, texcoord2f, numverts);
+ GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
if (lightcubemap)
R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltofilter);
VectorScale(lightcolor, r_colorscale * r_shadow_lightintensityscale.value * 0.25f, color2);
color[1] = bound(0, color2[1], 1);
color[2] = bound(0, color2[2], 1);
GL_Color(color[0], color[1], color[2], 1);
- R_Mesh_Draw_NoBatching(numverts, numtriangles, elements);
+ R_Mesh_Draw(numverts, numtriangles, elements);
c_rt_lightmeshes++;
c_rt_lighttris += numtriangles;
}
else if (r_shadow_texture3d.integer && r_textureunits.integer >= 2 && !lightcubemap /*&& gl_support_blendsquare*/) // FIXME: detect blendsquare!
{
// 2/0/0/2 3D combine blendsquare path
- //R_Mesh_EndBatch();
+ memset(&m, 0, sizeof(m));
m.tex[0] = R_GetTexture(bumptexture);
m.texcubemap[1] = R_GetTexture(r_shadow_normalcubetexture);
m.texcombinergb[1] = GL_DOT3_RGBA_ARB;
- R_Mesh_TextureState(&m);
+ m.pointer_texcoord[0] = texcoord2f;
+ m.pointer_texcoord[1] = varray_texcoord3f[1];
+ R_Mesh_State_Texture(&m);
qglColorMask(0,0,0,1);
// this squares the result
- qglEnable(GL_BLEND);
- qglBlendFunc(GL_SRC_ALPHA, GL_ZERO);
- GL_Color(1,1,1,1);
- R_Mesh_GetSpace(numverts);
- R_Mesh_CopyVertex3f(vertex3f, numverts);
- R_Mesh_CopyTexCoord2f(0, texcoord2f, numverts);
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ZERO);
R_Shadow_GenTexCoords_Specular_NormalCubeMap(varray_texcoord3f[1], numverts, vertex3f, svector3f, tvector3f, normal3f, relativelightorigin, relativeeyeorigin);
- R_Mesh_Draw_NoBatching(numverts, numtriangles, elements);
+ R_Mesh_Draw(numverts, numtriangles, elements);
c_rt_lightmeshes++;
c_rt_lighttris += numtriangles;
- //R_Mesh_EndBatch();
- m.tex[0] = 0;
- m.texcubemap[1] = 0;
- m.texcombinergb[1] = GL_MODULATE;
- R_Mesh_TextureState(&m);
+ memset(&m, 0, sizeof(m));
+ R_Mesh_State_Texture(&m);
// square alpha in framebuffer a few times to make it shiny
- qglBlendFunc(GL_ZERO, GL_DST_ALPHA);
+ GL_BlendFunc(GL_ZERO, GL_DST_ALPHA);
// these comments are a test run through this math for intensity 0.5
// 0.5 * 0.5 = 0.25 (done by the BlendFunc earlier)
// 0.25 * 0.25 = 0.0625 (this is another pass)
// 0.0625 * 0.0625 = 0.00390625 (this is another pass)
- R_Mesh_GetSpace(numverts);
- R_Mesh_CopyVertex3f(vertex3f, numverts);
- R_Mesh_Draw_NoBatching(numverts, numtriangles, elements);
+ R_Mesh_Draw(numverts, numtriangles, elements);
c_rt_lightmeshes++;
c_rt_lighttris += numtriangles;
- R_Mesh_Draw_NoBatching(numverts, numtriangles, elements);
+ R_Mesh_Draw(numverts, numtriangles, elements);
c_rt_lightmeshes++;
c_rt_lighttris += numtriangles;
- //R_Mesh_EndBatch();
- R_Mesh_GetSpace(numverts);
- R_Mesh_CopyVertex3f(vertex3f, numverts);
- R_Mesh_CopyTexCoord2f(0, texcoord2f, numverts);
+ memset(&m, 0, sizeof(m));
m.tex[0] = R_GetTexture(glosstexture);
m.tex3d[1] = R_GetTexture(r_shadow_attenuation3dtexture);
- R_Mesh_TextureState(&m);
+ m.pointer_texcoord[0] = texcoord2f;
+ m.pointer_texcoord[1] = varray_texcoord3f[1];
+ R_Mesh_State_Texture(&m);
qglColorMask(1,1,1,0);
- qglBlendFunc(GL_DST_ALPHA, GL_ONE);
- R_Mesh_GetSpace(numverts);
- R_Mesh_CopyVertex3f(vertex3f, numverts);
- R_Mesh_CopyTexCoord2f(0, texcoord2f, numverts);
+ GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltoattenuationxyz);
VectorScale(lightcolor, r_colorscale * r_shadow_lightintensityscale.value * 0.25f, color2);
for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--)
color[1] = bound(0, color2[1], 1);
color[2] = bound(0, color2[2], 1);
GL_Color(color[0], color[1], color[2], 1);
- R_Mesh_Draw_NoBatching(numverts, numtriangles, elements);
+ R_Mesh_Draw(numverts, numtriangles, elements);
c_rt_lightmeshes++;
c_rt_lighttris += numtriangles;
}
else if (r_textureunits.integer >= 2 /*&& gl_support_blendsquare*/) // FIXME: detect blendsquare!
{
// 2/0/0/2/2 2D combine blendsquare path
- //R_Mesh_EndBatch();
+ memset(&m, 0, sizeof(m));
m.tex[0] = R_GetTexture(bumptexture);
m.texcubemap[1] = R_GetTexture(r_shadow_normalcubetexture);
m.texcombinergb[1] = GL_DOT3_RGBA_ARB;
- R_Mesh_TextureState(&m);
+ m.pointer_texcoord[0] = texcoord2f;
+ m.pointer_texcoord[1] = varray_texcoord3f[1];
+ R_Mesh_State_Texture(&m);
qglColorMask(0,0,0,1);
// this squares the result
- qglEnable(GL_BLEND);
- qglBlendFunc(GL_SRC_ALPHA, GL_ZERO);
- GL_Color(1,1,1,1);
- R_Mesh_GetSpace(numverts);
- R_Mesh_CopyVertex3f(vertex3f, numverts);
- R_Mesh_CopyTexCoord2f(0, texcoord2f, numverts);
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ZERO);
R_Shadow_GenTexCoords_Specular_NormalCubeMap(varray_texcoord3f[1], numverts, vertex3f, svector3f, tvector3f, normal3f, relativelightorigin, relativeeyeorigin);
- R_Mesh_Draw_NoBatching(numverts, numtriangles, elements);
+ R_Mesh_Draw(numverts, numtriangles, elements);
c_rt_lightmeshes++;
c_rt_lighttris += numtriangles;
- //R_Mesh_EndBatch();
- m.tex[0] = 0;
- m.texcubemap[1] = 0;
- m.texcombinergb[1] = GL_MODULATE;
- R_Mesh_TextureState(&m);
+ memset(&m, 0, sizeof(m));
+ R_Mesh_State_Texture(&m);
// square alpha in framebuffer a few times to make it shiny
- qglBlendFunc(GL_ZERO, GL_DST_ALPHA);
+ GL_BlendFunc(GL_ZERO, GL_DST_ALPHA);
// these comments are a test run through this math for intensity 0.5
// 0.5 * 0.5 = 0.25 (done by the BlendFunc earlier)
// 0.25 * 0.25 = 0.0625 (this is another pass)
// 0.0625 * 0.0625 = 0.00390625 (this is another pass)
- R_Mesh_GetSpace(numverts);
- R_Mesh_CopyVertex3f(vertex3f, numverts);
- R_Mesh_Draw_NoBatching(numverts, numtriangles, elements);
+ R_Mesh_Draw(numverts, numtriangles, elements);
c_rt_lightmeshes++;
c_rt_lighttris += numtriangles;
- R_Mesh_Draw_NoBatching(numverts, numtriangles, elements);
+ R_Mesh_Draw(numverts, numtriangles, elements);
c_rt_lightmeshes++;
c_rt_lighttris += numtriangles;
- //R_Mesh_EndBatch();
+ memset(&m, 0, sizeof(m));
m.tex[0] = R_GetTexture(r_shadow_attenuation2dtexture);
m.tex[1] = R_GetTexture(r_shadow_attenuation2dtexture);
- R_Mesh_TextureState(&m);
- qglBlendFunc(GL_DST_ALPHA, GL_ZERO);
- R_Mesh_GetSpace(numverts);
- R_Mesh_CopyVertex3f(vertex3f, numverts);
+ m.pointer_texcoord[0] = varray_texcoord2f[0];
+ m.pointer_texcoord[1] = varray_texcoord2f[1];
+ R_Mesh_State_Texture(&m);
+ GL_BlendFunc(GL_DST_ALPHA, GL_ZERO);
R_Shadow_Transform_Vertex3f_TexCoord2f(varray_texcoord2f[0], numverts, vertex3f, matrix_modeltoattenuationxyz);
R_Shadow_Transform_Vertex3f_TexCoord2f(varray_texcoord2f[1], numverts, vertex3f, matrix_modeltoattenuationz);
- R_Mesh_Draw_NoBatching(numverts, numtriangles, elements);
+ R_Mesh_Draw(numverts, numtriangles, elements);
c_rt_lightmeshes++;
c_rt_lighttris += numtriangles;
- //R_Mesh_EndBatch();
+ memset(&m, 0, sizeof(m));
m.tex[0] = R_GetTexture(glosstexture);
m.texcubemap[1] = R_GetTexture(lightcubemap);
- R_Mesh_TextureState(&m);
+ m.pointer_texcoord[0] = texcoord2f;
+ m.pointer_texcoord[1] = lightcubemap ? varray_texcoord3f[1] : NULL;
+ R_Mesh_State_Texture(&m);
qglColorMask(1,1,1,0);
- qglBlendFunc(GL_DST_ALPHA, GL_ONE);
- R_Mesh_GetSpace(numverts);
- R_Mesh_CopyVertex3f(vertex3f, numverts);
- R_Mesh_CopyTexCoord2f(0, texcoord2f, numverts);
+ GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
if (lightcubemap)
R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltofilter);
VectorScale(lightcolor, r_colorscale * r_shadow_lightintensityscale.value * 0.25f, color2);
color[1] = bound(0, color2[1], 1);
color[2] = bound(0, color2[2], 1);
GL_Color(color[0], color[1], color[2], 1);
- R_Mesh_Draw_NoBatching(numverts, numtriangles, elements);
+ R_Mesh_Draw(numverts, numtriangles, elements);
c_rt_lightmeshes++;
c_rt_lighttris += numtriangles;
}
for (j = 0;j < e->numsurfaces;j++)
if (e->surfaces[j]->castshadow == castshadowcount)
for (surfmesh = e->surfaces[j]->mesh;surfmesh;surfmesh = surfmesh->chain)
- Mod_ShadowMesh_AddMesh(r_shadow_mempool, castmesh, surfmesh->numverts, surfmesh->vertex3f, surfmesh->numtriangles, surfmesh->element3i);
+ Mod_ShadowMesh_AddMesh(r_shadow_mempool, castmesh, surfmesh->vertex3f, surfmesh->numtriangles, surfmesh->element3i);
castmesh = Mod_ShadowMesh_Finish(r_shadow_mempool, castmesh);
// cast shadow volume from castmesh
for (mesh = castmesh;mesh;mesh = mesh->next)
{
- R_Shadow_ResizeTriangleFacingLight(castmesh->numtriangles);
R_Shadow_ResizeShadowElements(castmesh->numtriangles);
if (maxverts < castmesh->numverts * 2)
if (vertex3f == NULL && maxverts > 0)
vertex3f = Mem_Alloc(r_shadow_mempool, maxverts * sizeof(float[3]));
- // now that we have the buffers big enough, construct shadow volume mesh
- memcpy(vertex3f, castmesh->vertex3f, castmesh->numverts * sizeof(float[3]));
- tris = R_Shadow_MakeTriangleShadowFlags_Vertex3f(castmesh->element3i, vertex3f, castmesh->numtriangles, trianglefacinglight, trianglefacinglightlist, e->origin);
- tris = R_Shadow_BuildShadowVolume(castmesh->element3i, castmesh->neighbor3i, castmesh->numverts, trianglefacinglight, trianglefacinglightlist, tris, shadowelements, vertex3f, e->origin, r_shadow_projectdistance.value);
- // add the constructed shadow volume mesh
- Mod_ShadowMesh_AddMesh(r_shadow_mempool, e->shadowvolume, castmesh->numverts, vertex3f, tris, shadowelements);
+ // now that we have the buffers big enough, construct and add
+ // the shadow volume mesh
+ if ((tris = R_Shadow_ConstructShadowVolume(castmesh->numverts, 0, castmesh->numtriangles, castmesh->element3i, castmesh->neighbor3i, castmesh->vertex3f, NULL, shadowelements, vertex3f, e->origin, r_shadow_projectdistance.value)))
+ Mod_ShadowMesh_AddMesh(r_shadow_mempool, e->shadowvolume, vertex3f, tris, shadowelements);
}
if (vertex3f)
Mem_Free(vertex3f);
r_shadow_selectedlight->selected = true;
}
-
-void R_DrawLightSprite(int texnum, const vec3_t origin, vec_t scale, float cr, float cg, float cb, float ca)
-{
- rmeshstate_t m;
- float diff[3];
-
- if (fogenabled)
- {
- VectorSubtract(origin, r_origin, diff);
- ca *= 1 - exp(fogdensity/DotProduct(diff,diff));
- }
-
- memset(&m, 0, sizeof(m));
- m.blendfunc1 = GL_SRC_ALPHA;
- m.blendfunc2 = GL_ONE;
- m.tex[0] = texnum;
- R_Mesh_Matrix(&r_identitymatrix);
- R_Mesh_State(&m);
-
- GL_Color(cr * r_colorscale, cg * r_colorscale, cb * r_colorscale, ca);
- R_DrawSpriteMesh(origin, vright, vup, scale, -scale, -scale, scale);
-}
+rtexture_t *lighttextures[5];
void R_Shadow_DrawCursorCallback(const void *calldata1, int calldata2)
{
- cachepic_t *pic;
- pic = Draw_CachePic("gfx/crosshair1.tga");
- if (pic)
- R_DrawLightSprite(R_GetTexture(pic->tex), r_editlights_cursorlocation, r_editlights_cursorgrid.value * 0.5f, 1, 1, 1, 0.5);
+ float scale = r_editlights_cursorgrid.value * 0.5f;
+ R_DrawSprite(GL_SRC_ALPHA, GL_ONE, lighttextures[0], false, r_editlights_cursorlocation, vright, vup, scale, -scale, -scale, scale, 1, 1, 1, 0.5f);
}
void R_Shadow_DrawLightSpriteCallback(const void *calldata1, int calldata2)
intensity = 0.5;
if (light->selected)
intensity = 0.75 + 0.25 * sin(realtime * M_PI * 4.0);
- if (light->shadowvolume)
- R_DrawLightSprite(calldata2, light->origin, 8, intensity, intensity, intensity, 0.5);
- else
- R_DrawLightSprite(calldata2, light->origin, 8, intensity * 0.5, intensity * 0.5, intensity * 0.5, 0.5);
+ if (!light->shadowvolume)
+ intensity *= 0.5f;
+ R_DrawSprite(GL_SRC_ALPHA, GL_ONE, lighttextures[calldata2], false, light->origin, vright, vup, 8, -8, -8, 8, intensity, intensity, intensity, 0.5);
}
void R_Shadow_DrawLightSprites(void)
{
- int i, texnums[5];
+ int i;
cachepic_t *pic;
worldlight_t *light;
for (i = 0;i < 5;i++)
{
- pic = Draw_CachePic(va("gfx/crosshair%i.tga", i + 1));
- if (pic)
- texnums[i] = R_GetTexture(pic->tex);
- else
- texnums[i] = 0;
+ lighttextures[i] = NULL;
+ if ((pic = Draw_CachePic(va("gfx/crosshair%i.tga", i + 1))))
+ lighttextures[i] = pic->tex;
}
for (light = r_shadow_worldlightchain;light;light = light->next)
- R_MeshQueue_AddTransparent(light->origin, R_Shadow_DrawLightSpriteCallback, light, texnums[((int) light) % 5]);
+ R_MeshQueue_AddTransparent(light->origin, R_Shadow_DrawLightSpriteCallback, light, ((int) light) % 5);
R_MeshQueue_AddTransparent(r_editlights_cursorlocation, R_Shadow_DrawCursorCallback, NULL, 0);
}
extern cvar_t r_shadow_bumpscale_basetexture;
void R_Shadow_Init(void);
-void R_Shadow_Volume(int numverts, int numtris, int *elements, int *neighbors, vec3_t relativelightorigin, float lightradius, float projectdistance);
+void R_Shadow_Volume(int numverts, int numtris, const float *invertex3f, int *elements, int *neighbors, vec3_t relativelightorigin, float lightradius, float projectdistance);
void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *elements, const float *vertices, const float *svectors, const float *tvectors, const float *normals, const float *texcoords, const float *relativelightorigin, float lightradius, const float *lightcolor, const matrix4x4_t *matrix_worldtofilter, const matrix4x4_t *matrix_worldtoattenuationxyz, const matrix4x4_t *matrix_worldtoattenuationz, rtexture_t *basetexture, rtexture_t *bumptexture, rtexture_t *lightcubemap);
void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elements, const float *vertices, const float *svectors, const float *tvectors, const float *normals, const float *texcoords, const float *relativelightorigin, const float *relativeeyeorigin, float lightradius, const float *lightcolor, const matrix4x4_t *matrix_worldtofilter, const matrix4x4_t *matrix_worldtoattenuationxyz, const matrix4x4_t *matrix_worldtoattenuationz, rtexture_t *glosstexture, rtexture_t *bumptexture, rtexture_t *lightcubemap);
void R_Shadow_ClearStencil(void);
}
}
+float skyboxvertex3f[6*4*3] =
+{
+ // skyside[0]
+ 16, 16, 16,
+ 16, 16, -16,
+ -16, 16, -16,
+ -16, 16, 16,
+ // skyside[1]
+ -16, 16, 16,
+ -16, 16, -16,
+ -16, -16, -16,
+ -16, -16, 16,
+ // skyside[2]
+ -16, -16, 16,
+ -16, -16, -16,
+ 16, -16, -16,
+ 16, -16, 16,
+ // skyside[3]
+ 16, -16, 16,
+ 16, -16, -16,
+ 16, 16, -16,
+ 16, 16, 16,
+ // skyside[4]
+ 16, -16, 16,
+ 16, 16, 16,
+ -16, 16, 16,
+ -16, -16, 16,
+ // skyside[5]
+ 16, 16, -16,
+ 16, -16, -16,
+ -16, -16, -16,
+ -16, 16, -16
+};
+
+float skyboxtexcoord2f[6*4*2] =
+{
+ // skyside[0]
+ 1, 0,
+ 1, 1,
+ 0, 1,
+ 0, 0,
+ // skyside[1]
+ 1, 0,
+ 1, 1,
+ 0, 1,
+ 0, 0,
+ // skyside[2]
+ 1, 0,
+ 1, 1,
+ 0, 1,
+ 0, 0,
+ // skyside[3]
+ 1, 0,
+ 1, 1,
+ 0, 1,
+ 0, 0,
+ // skyside[4]
+ 1, 0,
+ 1, 1,
+ 0, 1,
+ 0, 0,
+ // skyside[5]
+ 1, 0,
+ 1, 1,
+ 0, 1,
+ 0, 0
+};
+
+int skyboxelements[6*2*3] =
+{
+ // skyside[0]
+ 8, 9, 10,
+ 8, 10, 11,
+ // skyside[1]
+ 4, 5, 6,
+ 4, 6, 7,
+ // skyside[2]
+ 12, 13, 14,
+ 12, 14, 15,
+ // skyside[3]
+ 0, 1, 2,
+ 0, 2, 3,
+ // skyside[4]
+ 16, 17, 18,
+ 16, 18, 19,
+ // skyside[5]
+ 20, 21, 22,
+ 20, 22, 23
+};
+
static void R_SkyBox(void)
{
+ int i;
rmeshstate_t m;
-
-#define R_SkyBoxPolyVec(i,s,t,x,y,z) \
- varray_vertex3f[i * 3 + 0] = (x) * 16.0f;\
- varray_vertex3f[i * 3 + 1] = (y) * 16.0f;\
- varray_vertex3f[i * 3 + 2] = (z) * 16.0f;\
- varray_texcoord2f[0][i * 2 + 0] = (s);\
- varray_texcoord2f[0][i * 2 + 1] = (t);
-
GL_Color(r_colorscale, r_colorscale, r_colorscale, 1);
-
memset(&m, 0, sizeof(m));
- m.blendfunc1 = GL_ONE;
- m.blendfunc2 = GL_ZERO;
- m.depthdisable = true; // don't modify or read zbuffer
-
- m.tex[0] = R_GetTexture(skyboxside[3]); // front
- R_Mesh_State(&m);
- R_Mesh_GetSpace(4);
- R_SkyBoxPolyVec(0, 1, 0, 1, -1, 1);
- R_SkyBoxPolyVec(1, 1, 1, 1, -1, -1);
- R_SkyBoxPolyVec(2, 0, 1, 1, 1, -1);
- R_SkyBoxPolyVec(3, 0, 0, 1, 1, 1);
- R_Mesh_Draw(4, 2, polygonelements);
-
- m.tex[0] = R_GetTexture(skyboxside[1]); // back
- R_Mesh_TextureState(&m);
- R_Mesh_GetSpace(4);
- R_SkyBoxPolyVec(0, 1, 0, -1, 1, 1);
- R_SkyBoxPolyVec(1, 1, 1, -1, 1, -1);
- R_SkyBoxPolyVec(2, 0, 1, -1, -1, -1);
- R_SkyBoxPolyVec(3, 0, 0, -1, -1, 1);
- R_Mesh_Draw(4, 2, polygonelements);
-
- m.tex[0] = R_GetTexture(skyboxside[0]); // right
- R_Mesh_TextureState(&m);
- R_Mesh_GetSpace(4);
- R_SkyBoxPolyVec(0, 1, 0, 1, 1, 1);
- R_SkyBoxPolyVec(1, 1, 1, 1, 1, -1);
- R_SkyBoxPolyVec(2, 0, 1, -1, 1, -1);
- R_SkyBoxPolyVec(3, 0, 0, -1, 1, 1);
- R_Mesh_Draw(4, 2, polygonelements);
-
- m.tex[0] = R_GetTexture(skyboxside[2]); // left
- R_Mesh_TextureState(&m);
- R_Mesh_GetSpace(4);
- R_SkyBoxPolyVec(0, 1, 0, -1, -1, 1);
- R_SkyBoxPolyVec(1, 1, 1, -1, -1, -1);
- R_SkyBoxPolyVec(2, 0, 1, 1, -1, -1);
- R_SkyBoxPolyVec(3, 0, 0, 1, -1, 1);
- R_Mesh_Draw(4, 2, polygonelements);
-
- m.tex[0] = R_GetTexture(skyboxside[4]); // up
- R_Mesh_TextureState(&m);
- R_Mesh_GetSpace(4);
- R_SkyBoxPolyVec(0, 1, 0, 1, -1, 1);
- R_SkyBoxPolyVec(1, 1, 1, 1, 1, 1);
- R_SkyBoxPolyVec(2, 0, 1, -1, 1, 1);
- R_SkyBoxPolyVec(3, 0, 0, -1, -1, 1);
- R_Mesh_Draw(4, 2, polygonelements);
-
- m.tex[0] = R_GetTexture(skyboxside[5]); // down
- R_Mesh_TextureState(&m);
- R_Mesh_GetSpace(4);
- R_SkyBoxPolyVec(0, 1, 0, 1, 1, -1);
- R_SkyBoxPolyVec(1, 1, 1, 1, -1, -1);
- R_SkyBoxPolyVec(2, 0, 1, -1, -1, -1);
- R_SkyBoxPolyVec(3, 0, 0, -1, 1, -1);
- R_Mesh_Draw(4, 2, polygonelements);
+ GL_BlendFunc(GL_ONE, GL_ZERO);
+ GL_DepthMask(true);
+ GL_DepthTest(false); // don't modify or read zbuffer
+ GL_VertexPointer(skyboxvertex3f);
+ m.pointer_texcoord[0] = skyboxtexcoord2f;
+ for (i = 0;i < 6;i++)
+ {
+ m.tex[0] = R_GetTexture(skyboxside[i]);
+ R_Mesh_State_Texture(&m);
+ R_Mesh_Draw(4, 2, skyboxelements + i * 6);
+ }
}
#define skygridx 32
float speedscale;
static qboolean skysphereinitialized = false;
rmeshstate_t m;
- rcachearrayrequest_t request;
+ matrix4x4_t scroll1matrix, scroll2matrix, identitymatrix;
if (!skysphereinitialized)
{
skysphereinitialized = true;
// wrap the scroll just to be extra kind to float accuracy
speedscale -= (int)speedscale;
+ // scroll the lower cloud layer twice as fast (just like quake did)
+ Matrix4x4_CreateTranslate(&scroll1matrix, speedscale, speedscale, 0);
+ Matrix4x4_CreateTranslate(&scroll2matrix, speedscale * 2, speedscale * 2, 0);
+ Matrix4x4_CreateIdentity(&identitymatrix);
+
+ GL_VertexPointer(skysphere_vertex3f);
+ GL_Color(r_colorscale, r_colorscale, r_colorscale, 1);
+ GL_BlendFunc(GL_ONE, GL_ZERO);
+ GL_DepthMask(true);
+ GL_DepthTest(false); // don't modify or read zbuffer
+ memset(&m, 0, sizeof(m));
+ m.tex[0] = R_GetTexture(solidskytexture);
+ m.pointer_texcoord[0] = skysphere_texcoord2f;
+ R_Mesh_TextureMatrix(0, &scroll1matrix);
if (r_colorscale == 1 && r_textureunits.integer >= 2)
{
// one pass using GL_DECAL or GL_INTERPOLATE_ARB for alpha layer
// LordHavoc: note that color is not set here because it does not
// matter with GL_REPLACE
- memset(&m, 0, sizeof(m));
- m.blendfunc1 = GL_ONE;
- m.blendfunc2 = GL_ZERO;
- m.depthdisable = true; // don't modify or read zbuffer
- m.tex[0] = R_GetTexture(solidskytexture);
m.tex[1] = R_GetTexture(alphaskytexture);
- m.texcombinergb[0] = GL_REPLACE;
m.texcombinergb[1] = gl_combine.integer ? GL_INTERPOLATE_ARB : GL_DECAL;
- if (gl_mesh_copyarrays.integer)
- {
- R_Mesh_State(&m);
- R_Mesh_GetSpace(skysphere_numverts);
- R_Mesh_CopyVertex3f(skysphere_vertex3f, skysphere_numverts);
- R_ScrollTexCoord2f(varray_texcoord2f[0], skysphere_texcoord2f, skysphere_numverts, speedscale, speedscale);
- R_ScrollTexCoord2f(varray_texcoord2f[1], skysphere_texcoord2f, skysphere_numverts, speedscale*2, speedscale*2);
- }
- else
- {
- m.pointervertexcount = skysphere_numverts;
- m.pointer_vertex = skysphere_vertex3f;
- memset(&request, 0, sizeof(request));
- request.data_size = skysphere_numverts * sizeof(float[2]);
- request.id_pointer1 = skysphere_texcoord2f;
- request.id_number1 = CRC_Block((void *)&speedscale, sizeof(speedscale));
- if (R_Mesh_CacheArray(&request))
- R_ScrollTexCoord2f(request.data, skysphere_texcoord2f, skysphere_numverts, speedscale, speedscale);
- m.pointer_texcoord[0] = request.data;
- speedscale *= 2;
- request.id_number1 = CRC_Block((void *)&speedscale, sizeof(speedscale));
- if (R_Mesh_CacheArray(&request))
- R_ScrollTexCoord2f(request.data, skysphere_texcoord2f, skysphere_numverts, speedscale, speedscale);
- m.pointer_texcoord[1] = request.data;
- R_Mesh_State(&m);
- }
+ m.pointer_texcoord[1] = skysphere_texcoord2f;
+ R_Mesh_State_Texture(&m);
+ R_Mesh_TextureMatrix(1, &scroll2matrix);
R_Mesh_Draw(skysphere_numverts, skysphere_numtriangles, skysphere_element3i);
+ R_Mesh_TextureMatrix(1, &identitymatrix);
}
else
{
// two pass
- GL_Color(r_colorscale, r_colorscale, r_colorscale, 1);
- memset(&m, 0, sizeof(m));
- m.blendfunc1 = GL_ONE;
- m.blendfunc2 = GL_ZERO;
- m.depthdisable = true; // don't modify or read zbuffer
- m.tex[0] = R_GetTexture(solidskytexture);
- if (gl_mesh_copyarrays.integer)
- {
- R_Mesh_State(&m);
- R_Mesh_GetSpace(skysphere_numverts);
- R_Mesh_CopyVertex3f(skysphere_vertex3f, skysphere_numverts);
- R_ScrollTexCoord2f(varray_texcoord2f[0], skysphere_texcoord2f, skysphere_numverts, speedscale, speedscale);
- }
- else
- {
- m.pointervertexcount = skysphere_numverts;
- m.pointer_vertex = skysphere_vertex3f;
- memset(&request, 0, sizeof(request));
- request.data_size = skysphere_numverts * sizeof(float[2]);
- request.id_pointer1 = skysphere_texcoord2f;
- request.id_number1 = CRC_Block((void *)&speedscale, sizeof(speedscale));
- if (R_Mesh_CacheArray(&request))
- R_ScrollTexCoord2f(request.data, skysphere_texcoord2f, skysphere_numverts, speedscale, speedscale);
- m.pointer_texcoord[0] = request.data;
- R_Mesh_State(&m);
- }
+ R_Mesh_State_Texture(&m);
R_Mesh_Draw(skysphere_numverts, skysphere_numtriangles, skysphere_element3i);
- // scroll the lower cloud layer twice as fast (just like quake did)
- speedscale *= 2;
-
- m.blendfunc1 = GL_SRC_ALPHA;
- m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
m.tex[0] = R_GetTexture(alphaskytexture);
- if (gl_mesh_copyarrays.integer)
- {
- R_Mesh_State(&m);
- R_Mesh_GetSpace(skysphere_numverts);
- R_Mesh_CopyVertex3f(skysphere_vertex3f, skysphere_numverts);
- R_ScrollTexCoord2f(varray_texcoord2f[0], skysphere_texcoord2f, skysphere_numverts, speedscale, speedscale);
- }
- else
- {
- m.pointervertexcount = skysphere_numverts;
- m.pointer_vertex = skysphere_vertex3f;
- request.data_size = skysphere_numverts * sizeof(float[2]);
- request.id_pointer1 = skysphere_texcoord2f;
- request.id_number1 = CRC_Block((void *)&speedscale, sizeof(speedscale));
- if (R_Mesh_CacheArray(&request))
- R_ScrollTexCoord2f(request.data, skysphere_texcoord2f, skysphere_numverts, speedscale, speedscale);
- m.pointer_texcoord[0] = request.data;
- R_Mesh_State(&m);
- }
+ R_Mesh_State_Texture(&m);
+ R_Mesh_TextureMatrix(0, &scroll2matrix);
R_Mesh_Draw(skysphere_numverts, skysphere_numtriangles, skysphere_element3i);
}
+ R_Mesh_TextureMatrix(0, &identitymatrix);
}
void R_Sky(void)
// this modifies the depth buffer so we have to clear it afterward
//R_SkyRoom();
// clear the depthbuffer that was used while rendering the skyroom
- //R_Mesh_EndBatch();
//qglClear(GL_DEPTH_BUFFER_BIT);
}
*/
Cvar_RegisterVariable (&r_sky);
R_RegisterModule("R_Sky", r_sky_start, r_sky_shutdown, r_sky_newmap);
}
+
return false;
}
-static void R_DrawSpriteImage (int additive, mspriteframe_t *frame, int texture, vec3_t origin, vec3_t up, vec3_t left, float red, float green, float blue, float alpha)
+static void R_DrawSpriteImage (int additive, mspriteframe_t *frame, rtexture_t *texture, vec3_t origin, vec3_t up, vec3_t left, float red, float green, float blue, float alpha)
{
- rmeshstate_t m;
- memset(&m, 0, sizeof(m));
- m.blendfunc1 = GL_SRC_ALPHA;
- m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
- if (additive)
- m.blendfunc2 = GL_ONE;
- m.tex[0] = texture;
- R_Mesh_State(&m);
-
- GL_Color(red * r_colorscale, green * r_colorscale, blue * r_colorscale, alpha);
// FIXME: negate left and right in loader
- R_DrawSpriteMesh(origin, left, up, frame->left, frame->right, frame->down, frame->up);
+ R_DrawSprite(GL_SRC_ALPHA, additive ? GL_ONE : GL_ONE_MINUS_SRC_ALPHA, texture, false, origin, left, up, frame->left, frame->right, frame->down, frame->up, red, green, blue, alpha);
}
void R_DrawSpriteModelCallback(const void *calldata1, int calldata2)
if (ent->frameblend[i].lerp >= 0.01f)
{
frame = ent->model->sprdata_frames + ent->frameblend[i].frame;
- R_DrawSpriteImage((ent->effects & EF_ADDITIVE) || (ent->model->flags & EF_ADDITIVE), frame, R_GetTexture(frame->texture), org, up, left, color[0] * ifog, color[1] * ifog, color[2] * ifog, ent->alpha * ent->frameblend[i].lerp);
+ R_DrawSpriteImage((ent->effects & EF_ADDITIVE) || (ent->model->flags & EF_ADDITIVE), frame, frame->texture, org, up, left, color[0] * ifog, color[1] * ifog, color[2] * ifog, ent->alpha * ent->frameblend[i].lerp);
if (fog * ent->frameblend[i].lerp >= 0.01f)
- R_DrawSpriteImage(true, frame, R_GetTexture(frame->fogtexture), org, up, left, fogcolor[0],fogcolor[1],fogcolor[2], fog * ent->alpha * ent->frameblend[i].lerp);
+ R_DrawSpriteImage(true, frame, frame->fogtexture, org, up, left, fogcolor[0],fogcolor[1],fogcolor[2], fog * ent->alpha * ent->frameblend[i].lerp);
}
}
#else
for (i = 0;i < 4 && ent->frameblend[i].lerp;i++)
frame = ent->model->sprdata_frames + ent->frameblend[i].frame;
- R_DrawSpriteImage((ent->effects & EF_ADDITIVE) || (ent->model->flags & EF_ADDITIVE), frame, R_GetTexture(frame->texture), org, up, left, color[0] * ifog, color[1] * ifog, color[2] * ifog, ent->alpha);
+ R_DrawSpriteImage((ent->effects & EF_ADDITIVE) || (ent->model->flags & EF_ADDITIVE), frame, frame->texture, org, up, left, color[0] * ifog, color[1] * ifog, color[2] * ifog, ent->alpha);
if (fog * ent->frameblend[i].lerp >= 0.01f)
- R_DrawSpriteImage(true, frame, R_GetTexture(frame->fogtexture), org, up, left, fogcolor[0],fogcolor[1],fogcolor[2], fog * ent->alpha);
+ R_DrawSpriteImage(true, frame, frame->fogtexture, org, up, left, fogcolor[0],fogcolor[1],fogcolor[2], fog * ent->alpha);
#endif
}
void R_TimeReport_End(void);
// r_stain
-void R_Stain (const vec3_t origin, float radius, int cr1, int cg1, int cb1, int ca1, int cr2, int cg2, int cb2, int ca2);
+void R_Stain(const vec3_t origin, float radius, int cr1, int cg1, int cb1, int ca1, int cr2, int cg2, int cb2, int ca2);
void R_DrawWorldCrosshair(void);
void R_Draw2DCrosshair(void);
-void R_CalcBeam_Vertex3f (float *vert, const vec3_t org1, const vec3_t org2, float width);
-void R_DrawSpriteMesh(const vec3_t origin, const vec3_t left, const vec3_t up, float scalex1, float scalex2, float scaley1, float scaley2);
+void R_CalcBeam_Vertex3f(float *vert, const vec3_t org1, const vec3_t org2, float width);
+void R_DrawSprite(int blendfunc1, int blendfunc2, rtexture_t *texture, int depthdisable, const vec3_t origin, const vec3_t left, const vec3_t up, float scalex1, float scalex2, float scaley1, float scaley2, float cr, float cg, float cb, float ca);
#endif
char gl_driver[256];
// GL_ARB_multitexture
-//void (GLAPIENTRY *qglMultiTexCoord2f) (GLenum, GLfloat, GLfloat);
+void (GLAPIENTRY *qglMultiTexCoord2f) (GLenum, GLfloat, GLfloat);
+void (GLAPIENTRY *qglMultiTexCoord3f) (GLenum, GLfloat, GLfloat, GLfloat);
void (GLAPIENTRY *qglActiveTexture) (GLenum);
void (GLAPIENTRY *qglClientActiveTexture) (GLenum);
//void (GLAPIENTRY *qglReadBuffer)(GLenum mode);
void (GLAPIENTRY *qglEnable)(GLenum cap);
void (GLAPIENTRY *qglDisable)(GLenum cap);
-//GLboolean GLAPIENTRY *qglIsEnabled)(GLenum cap);
+GLboolean (GLAPIENTRY *qglIsEnabled)(GLenum cap);
void (GLAPIENTRY *qglEnableClientState)(GLenum cap);
void (GLAPIENTRY *qglDisableClientState)(GLenum cap);
void (GLAPIENTRY *qglClearDepth)(GLclampd depth);
void (GLAPIENTRY *qglDepthFunc)(GLenum func);
void (GLAPIENTRY *qglDepthMask)(GLboolean flag);
-//void (GLAPIENTRY *qglDepthRange)(GLclampd near_val, GLclampd far_val);
+void (GLAPIENTRY *qglDepthRange)(GLclampd near_val, GLclampd far_val);
void (GLAPIENTRY *qglColorMask)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
void (GLAPIENTRY *qglDrawRangeElements)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
void (GLAPIENTRY *qglDrawElements)(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);
void (GLAPIENTRY *qglVertexPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr);
-//void (GLAPIENTRY *qglNormalPointer)(GLenum type, GLsizei stride, const GLvoid *ptr);
+void (GLAPIENTRY *qglNormalPointer)(GLenum type, GLsizei stride, const GLvoid *ptr);
void (GLAPIENTRY *qglColorPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr);
void (GLAPIENTRY *qglTexCoordPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr);
-//void (GLAPIENTRY *qglArrayElement)(GLint i);
+void (GLAPIENTRY *qglArrayElement)(GLint i);
void (GLAPIENTRY *qglColor4f)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
-//void (GLAPIENTRY *qglTexCoord2f)(GLfloat s, GLfloat t);
-//void (GLAPIENTRY *qglVertex2f)(GLfloat x, GLfloat y);
-//void (GLAPIENTRY *qglVertex3f)(GLfloat x, GLfloat y, GLfloat z);
-//void (GLAPIENTRY *qglBegin)(GLenum mode);
-//void (GLAPIENTRY *qglEnd)(void);
+void (GLAPIENTRY *qglTexCoord2f)(GLfloat s, GLfloat t);
+void (GLAPIENTRY *qglTexCoord2f)(GLfloat s, GLfloat t);
+void (GLAPIENTRY *qglTexCoord3f)(GLfloat s, GLfloat t, GLfloat r);
+void (GLAPIENTRY *qglVertex2f)(GLfloat x, GLfloat y);
+void (GLAPIENTRY *qglVertex3f)(GLfloat x, GLfloat y, GLfloat z);
+void (GLAPIENTRY *qglBegin)(GLenum mode);
+void (GLAPIENTRY *qglEnd)(void);
void (GLAPIENTRY *qglMatrixMode)(GLenum mode);
void (GLAPIENTRY *qglOrtho)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val);
// {"glReadBuffer", (void **) &qglReadBuffer},
{"glEnable", (void **) &qglEnable},
{"glDisable", (void **) &qglDisable},
-// {"glIsEnabled", (void **) &qglIsEnabled},
+ {"glIsEnabled", (void **) &qglIsEnabled},
{"glEnableClientState", (void **) &qglEnableClientState},
{"glDisableClientState", (void **) &qglDisableClientState},
// {"glGetBooleanv", (void **) &qglGetBooleanv},
{"glClearDepth", (void **) &qglClearDepth},
{"glDepthFunc", (void **) &qglDepthFunc},
{"glDepthMask", (void **) &qglDepthMask},
-// {"glDepthRange", (void **) &qglDepthRange},
+ {"glDepthRange", (void **) &qglDepthRange},
{"glDrawElements", (void **) &qglDrawElements},
{"glColorMask", (void **) &qglColorMask},
{"glVertexPointer", (void **) &qglVertexPointer},
-// {"glNormalPointer", (void **) &qglNormalPointer},
+ {"glNormalPointer", (void **) &qglNormalPointer},
{"glColorPointer", (void **) &qglColorPointer},
{"glTexCoordPointer", (void **) &qglTexCoordPointer},
-// {"glArrayElement", (void **) &qglArrayElement},
+ {"glArrayElement", (void **) &qglArrayElement},
{"glColor4f", (void **) &qglColor4f},
-// {"glTexCoord2f", (void **) &qglTexCoord2f},
-// {"glVertex2f", (void **) &qglVertex2f},
-// {"glVertex3f", (void **) &qglVertex3f},
-// {"glBegin", (void **) &qglBegin},
-// {"glEnd", (void **) &qglEnd},
+ {"glTexCoord2f", (void **) &qglTexCoord2f},
+ {"glTexCoord3f", (void **) &qglTexCoord3f},
+ {"glVertex2f", (void **) &qglVertex2f},
+ {"glVertex3f", (void **) &qglVertex3f},
+ {"glBegin", (void **) &qglBegin},
+ {"glEnd", (void **) &qglEnd},
{"glMatrixMode", (void **) &qglMatrixMode},
{"glOrtho", (void **) &qglOrtho},
{"glFrustum", (void **) &qglFrustum},
static dllfunction_t multitexturefuncs[] =
{
- //{"glMultiTexCoord2fARB", (void **) &qglMultiTexCoord2f},
+ {"glMultiTexCoord2fARB", (void **) &qglMultiTexCoord2f},
+ {"glMultiTexCoord3fARB", (void **) &qglMultiTexCoord3f},
{"glActiveTextureARB", (void **) &qglActiveTexture},
{"glClientActiveTextureARB", (void **) &qglClientActiveTexture},
{NULL, NULL}