int cl_traceline_endcontents;
-float CL_TraceLine (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal, int contents, int hitbmodels)
+float CL_TraceLine (const vec3_t start, const vec3_t end, vec3_t impact, vec3_t normal, int contents, int hitbmodels)
{
double maxfrac;
trace_t trace;
// (leafs matching contents are considered empty, others are solid)
extern int cl_traceline_endcontents; // set by TraceLine
-float CL_TraceLine (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal, int contents, int hitbmodels);
+float CL_TraceLine (const vec3_t start, const vec3_t end, vec3_t impact, vec3_t normal, int contents, int hitbmodels);
#endif
return;
dlightsetup:
+ //Con_Printf("dlight %i : %f %f %f : %f %f %f\n", i, org[0], org[1], org[2], red * radius, green * radius, blue * radius);
memset (dl, 0, sizeof(*dl));
//dl->ent = ent;
VectorCopy(org, dl->origin);
int partindexarray[6] = {0, 1, 2, 0, 2, 3};
-void R_DrawParticleCallback(void *calldata1, int calldata2)
+void R_DrawParticleCallback(const void *calldata1, int calldata2)
{
int lighting, dynlight, additive, texnum, orientation;
float org[3], up2[3], right2[3], v[3], right[3], up[3], fog, ifog, fogvec[3], cr, cg, cb, ca;
particletexture_t *tex;
mleaf_t *leaf;
rmeshbufferinfo_t m;
- particle_t *p;
-
- p = calldata1;
+ const particle_t *p = calldata1;
// LordHavoc: check if it's in a visible leaf
leaf = Mod_PointInLeaf(p->org, cl.worldmodel);
m.numtriangles = 2;
m.numverts = 4;
m.tex[0] = R_GetTexture(particlefonttexture);
+ Matrix4x4_CreateIdentity(&m.matrix);
if (R_Mesh_Draw_GetBuffer(&m, false))
{
m.index[0] = 0;
"org:'%+8.2f %+8.2f %+8.2f' ang:'%+4.0f %+4.0f %+4.0f' dir:'%+2.3f %+2.3f %+2.3f'\n"
"world:%6i faces%6i nodes%6i leafs%6i walls%6i dlitwalls\n"
"%5i models%5i bmodels%5i sprites%6i particles%4i dlights\n"
- "%6i modeltris%6i transmeshs%6i transtris%6i meshs%6i meshtris\n",
+ "%6i modeltris%6i meshs%6i meshtris\n",
r_refdef.vieworg[0], r_refdef.vieworg[1], r_refdef.vieworg[2], r_refdef.viewangles[0], r_refdef.viewangles[1], r_refdef.viewangles[2], vpn[0], vpn[1], vpn[2],
c_faces, c_nodes, c_leafs, c_brush_polys, c_light_polys,
c_models, c_bmodels, c_sprites, c_particles, c_dlights,
- c_alias_polys, c_transmeshs, c_transtris, c_meshs, c_meshtris);
+ c_alias_polys, c_meshs, c_meshtris);
c_brush_polys = 0;
c_alias_polys = 0;
#ifndef CLIENT_H
#define CLIENT_H
+#include "matrixlib.h"
+
// LordHavoc: 256 dynamic lights
#define MAX_DLIGHTS 256
// LordHavoc: this affects the lighting scale of the whole game
vec3_t origin;
// orientation
vec3_t angles;
+ // transform matrix for model to world
+ matrix4x4_t matrix;
+ // transform matrix for world to model
+ matrix4x4_t inversematrix;
// opacity (alpha) of the model
float alpha;
// size the model is shown
// caching results of static light traces (this is semi-persistent)
double entlightstime;
vec3_t entlightsorigin;
+ int entlightsframe;
int numentlights;
unsigned short entlights[MAXENTLIGHTS];
}
#include "quakedef.h"
cvar_t gl_mesh_maxtriangles = {0, "gl_mesh_maxtriangles", "1024"};
-cvar_t gl_mesh_transtriangles = {0, "gl_mesh_transtriangles", "16384"};
cvar_t gl_mesh_floatcolors = {0, "gl_mesh_floatcolors", "1"};
cvar_t gl_mesh_drawmode = {CVAR_SAVE, "gl_mesh_drawmode", "3"};
// this is used to increase gl_mesh_maxtriangles automatically if a mesh was
// too large for the buffers in the previous frame
int overflowedverts = 0;
-// increase transtriangles automatically too
-int overflowedtransverts = 0;
int gl_maxdrawrangeelementsvertices;
int gl_maxdrawrangeelementsindices;
// sign bits (true if negative) for vpn[] entries, so quick integer compares can be used instead of float compares
static int vpnbit0, vpnbit1, vpnbit2;
-int c_meshs, c_meshtris, c_transmeshs, c_transtris;
+int c_meshs, c_meshtris;
int lightscalebit;
float lightscale;
void SCR_ScreenShot_f (void);
static int max_meshs;
-static int max_transmeshs;
static int max_verts; // always max_meshs * 3
-static int max_transverts; // always max_transmeshs * 3
-#define TRANSDEPTHRES 4096
typedef struct buf_mesh_s
{
int triangles;
int firstvert;
int verts;
+ matrix4x4_t matrix;
struct buf_mesh_s *chain;
- struct buf_transtri_s *transchain;
}
buf_mesh_t;
-typedef struct buf_transtri_s
-{
- struct buf_transtri_s *next;
- struct buf_transtri_s *meshsortchain;
- buf_mesh_t *mesh;
- int index[3];
-}
-buf_transtri_t;
-
typedef struct buf_tri_s
{
int index[3];
}
buf_texcoord_t;
-static int currentmesh, currenttriangle, currentvertex, backendunits, backendactive, transranout;
+static int currentmesh, currenttriangle, currentvertex, backendunits, backendactive;
static buf_mesh_t *buf_mesh;
static buf_tri_t *buf_tri;
static buf_vertex_t *buf_vertex;
static buf_bcolor_t *buf_bcolor;
static buf_texcoord_t *buf_texcoord[MAX_TEXTUREUNITS];
-static int currenttransmesh, currenttransvertex, currenttranstriangle;
-static buf_mesh_t *buf_transmesh;
-static buf_transtri_t *buf_sorttranstri;
-static buf_transtri_t **buf_sorttranstri_list;
-static buf_tri_t *buf_transtri;
-static buf_vertex_t *buf_transvertex;
-static buf_fcolor_t *buf_transfcolor;
-static buf_texcoord_t *buf_transtexcoord[MAX_TEXTUREUNITS];
-
static mempool_t *gl_backend_mempool;
static int resizingbuffers = false;
qglGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &gl_maxdrawrangeelementsvertices);
qglGetIntegerv(GL_MAX_ELEMENTS_INDICES, &gl_maxdrawrangeelementsindices);
- Con_Printf("OpenGL Backend started with gl_mesh_maxtriangles %i, gl_mesh_transtriangles %i\n", gl_mesh_maxtriangles.integer, gl_mesh_transtriangles.integer);
+ Con_Printf("OpenGL Backend started with gl_mesh_maxtriangles %i\n", gl_mesh_maxtriangles.integer);
if (qglDrawRangeElements != NULL)
Con_Printf("glDrawRangeElements detected (max vertices %i, max indices %i)\n", gl_maxdrawrangeelementsvertices, gl_maxdrawrangeelementsindices);
if (strstr(gl_renderer, "3Dfx"))
Con_Printf("\n");
max_verts = max_meshs * 3;
- max_transverts = max_transmeshs * 3;
if (!gl_backend_mempool)
gl_backend_mempool = Mem_AllocPool("GL_Backend");
BACKENDALLOC(buf_fcolor, max_verts, buf_fcolor_t, "buf_fcolor")
BACKENDALLOC(buf_bcolor, max_verts, buf_bcolor_t, "buf_bcolor")
- BACKENDALLOC(buf_transmesh, max_transmeshs, buf_mesh_t, "buf_transmesh")
- BACKENDALLOC(buf_sorttranstri, max_transmeshs, buf_transtri_t, "buf_sorttranstri")
- BACKENDALLOC(buf_sorttranstri_list, TRANSDEPTHRES, buf_transtri_t *, "buf_sorttranstri_list")
- BACKENDALLOC(buf_transtri, max_transmeshs, buf_tri_t, "buf_transtri")
- BACKENDALLOC(buf_transvertex, max_transverts, buf_vertex_t, "buf_vertex")
- BACKENDALLOC(buf_transfcolor, max_transverts, buf_fcolor_t, "buf_fcolor")
-
for (i = 0;i < MAX_TEXTUREUNITS;i++)
{
// only allocate as many texcoord arrays as we need
if (i < gl_textureunits)
{
BACKENDALLOC(buf_texcoord[i], max_verts, buf_texcoord_t, va("buf_texcoord[%d]", i))
- BACKENDALLOC(buf_transtexcoord[i], max_transverts, buf_texcoord_t, va("buf_transtexcoord[%d]", i))
}
else
{
buf_texcoord[i] = NULL;
- buf_transtexcoord[i] = NULL;
}
}
backendunits = min(MAX_TEXTUREUNITS, gl_textureunits);
Cvar_SetValueQuick(&gl_mesh_maxtriangles, (int) ((overflowedverts + 2) / 3));
overflowedverts = 0;
- if (overflowedtransverts > gl_mesh_transtriangles.integer * 3)
- Cvar_SetValueQuick(&gl_mesh_transtriangles, (int) ((overflowedtransverts + 2) / 3));
- overflowedtransverts = 0;
-
if (gl_mesh_drawmode.integer < 0)
Cvar_SetValueQuick(&gl_mesh_drawmode, 0);
if (gl_mesh_drawmode.integer > 3)
if (gl_mesh_maxtriangles.integer > 21760)
Cvar_SetValueQuick(&gl_mesh_maxtriangles, 21760);
- if (gl_mesh_transtriangles.integer < 1024)
- Cvar_SetValueQuick(&gl_mesh_transtriangles, 1024);
- if (gl_mesh_transtriangles.integer > 65536)
- Cvar_SetValueQuick(&gl_mesh_transtriangles, 65536);
-
- if (max_meshs != gl_mesh_maxtriangles.integer || max_transmeshs != gl_mesh_transtriangles.integer)
+ if (max_meshs != gl_mesh_maxtriangles.integer)
{
max_meshs = gl_mesh_maxtriangles.integer;
- max_transmeshs = gl_mesh_transtriangles.integer;
if (!init)
{
#endif
Cvar_RegisterVariable(&gl_mesh_maxtriangles);
- Cvar_RegisterVariable(&gl_mesh_transtriangles);
Cvar_RegisterVariable(&gl_mesh_floatcolors);
Cvar_RegisterVariable(&gl_mesh_drawmode);
R_RegisterModule("GL_Backend", gl_backend_start, gl_backend_shutdown, gl_backend_newmap);
currentmesh = 0;
currenttriangle = 0;
currentvertex = 0;
- currenttransmesh = 0;
- currenttranstriangle = 0;
- currenttransvertex = 0;
- transranout = false;
r_mesh_farclip = farclip;
viewdist = DotProduct(r_origin, vpn);
vpnbit0 = vpn[0] < 0;
c_meshs = 0;
c_meshtris = 0;
- c_transmeshs = 0;
- c_transtris = 0;
GL_SetupFrame();
// renders mesh buffers, called to flush buffers when full
void R_Mesh_Render(void)
{
- int k;
+ int i, k;
+ float *v, tempv[4];
buf_mesh_t *mesh;
if (!backendactive)
}
GL_MeshState(buf_mesh);
+ for (k = 0, mesh = buf_mesh;k < currentmesh;k++, mesh++)
+ {
+ for (i = 0, v = buf_vertex[mesh->firstvert].v;i < mesh->verts;i++, v += 4)
+ {
+ VectorCopy(v, tempv);
+ Matrix4x4_Transform(&mesh->matrix, tempv, v);
+ }
+ }
GL_LockArray(0, currentvertex);
GL_DrawRangeElements(buf_mesh->firstvert, buf_mesh->firstvert + buf_mesh->verts, buf_mesh->triangles * 3, (unsigned int *)&buf_tri[buf_mesh->firsttriangle].index[0]);CHECKGLERROR
void R_Mesh_ClearDepth(void)
{
- if (currenttransmesh)
- R_Mesh_AddTransparent();
if (currentmesh)
R_Mesh_Render();
R_Mesh_Finish();
R_Mesh_Start(r_mesh_farclip);
}
-void R_Mesh_AddTransparent(void)
-{
- int i, j, k, *index;
- float viewdistcompare, centerscaler, dist1, dist2, dist3, center, maxdist;
- buf_vertex_t *vert1, *vert2, *vert3;
- buf_transtri_t *tri;
- buf_mesh_t *mesh, *transmesh;
-
- if (!currenttransmesh)
- return;
-
- // convert index data to transtris for sorting
- for (j = 0;j < currenttransmesh;j++)
- {
- mesh = buf_transmesh + j;
- k = mesh->firsttriangle;
- index = &buf_transtri[k].index[0];
- for (i = 0;i < mesh->triangles;i++)
- {
- tri = &buf_sorttranstri[k++];
- tri->mesh = mesh;
- tri->index[0] = *index++;
- tri->index[1] = *index++;
- tri->index[2] = *index++;
- }
- }
-
- // map farclip to 0-4095 list range
- centerscaler = (TRANSDEPTHRES / r_mesh_farclip) * (1.0f / 3.0f);
- viewdistcompare = viewdist + 4.0f;
-
- memset(buf_sorttranstri_list, 0, TRANSDEPTHRES * sizeof(buf_transtri_t *));
-
- k = 0;
- for (j = 0;j < currenttranstriangle;j++)
- {
- tri = &buf_sorttranstri[j];
- i = tri->mesh->firstvert;
-
- vert1 = &buf_transvertex[tri->index[0] + i];
- vert2 = &buf_transvertex[tri->index[1] + i];
- vert3 = &buf_transvertex[tri->index[2] + i];
-
- dist1 = DotProduct(vert1->v, vpn);
- dist2 = DotProduct(vert2->v, vpn);
- dist3 = DotProduct(vert3->v, vpn);
-
- maxdist = max(dist1, max(dist2, dist3));
- if (maxdist < viewdistcompare)
- continue;
-
- center = (dist1 + dist2 + dist3) * centerscaler - viewdist;
-#if SLOWMATH
- i = (int) center;
- i = bound(0, i, (TRANSDEPTHRES - 1));
-#else
- if (center < 0.0f)
- center = 0.0f;
- center += 8388608.0f;
- i = *((int *)¢er) & 0x7FFFFF;
- i = min(i, (TRANSDEPTHRES - 1));
-#endif
- tri->next = buf_sorttranstri_list[i];
- buf_sorttranstri_list[i] = tri;
- k++;
- }
-
- for (i = 0;i < currenttransmesh;i++)
- buf_transmesh[i].transchain = NULL;
- transmesh = NULL;
- for (j = 0;j < TRANSDEPTHRES;j++)
- {
- if ((tri = buf_sorttranstri_list[j]))
- {
- for (;tri;tri = tri->next)
- {
- if (!tri->mesh->transchain)
- {
- tri->mesh->chain = transmesh;
- transmesh = tri->mesh;
- }
- tri->meshsortchain = tri->mesh->transchain;
- tri->mesh->transchain = tri;
- }
- }
- }
-
- R_Mesh_Render();
- for (;transmesh;transmesh = transmesh->chain)
- {
- mesh = &buf_mesh[currentmesh++];
- *mesh = *transmesh; // copy mesh properties
-
- mesh->firstvert = currentvertex;
- memcpy(&buf_vertex[currentvertex], &buf_transvertex[transmesh->firstvert], transmesh->verts * sizeof(buf_vertex_t));
- memcpy(&buf_fcolor[currentvertex], &buf_transfcolor[transmesh->firstvert], transmesh->verts * sizeof(buf_fcolor_t));
- for (i = 0;i < backendunits && transmesh->textures[i];i++)
- memcpy(&buf_texcoord[i][currentvertex], &buf_transtexcoord[i][transmesh->firstvert], transmesh->verts * sizeof(buf_texcoord_t));
- currentvertex += mesh->verts;
-
- mesh->firsttriangle = currenttriangle;
- for (tri = transmesh->transchain;tri;tri = tri->meshsortchain)
- {
- buf_tri[currenttriangle].index[0] = tri->index[0];
- buf_tri[currenttriangle].index[1] = tri->index[1];
- buf_tri[currenttriangle].index[2] = tri->index[2];
- currenttriangle++;
- }
- mesh->triangles = currenttriangle - mesh->firsttriangle;
- R_Mesh_Render();
- }
-
- currenttransmesh = 0;
- currenttranstriangle = 0;
- currenttransvertex = 0;
-}
-
// allocates space in geometry buffers, and fills in pointers to the buffers in passsed struct
// (this is used for very high speed rendering, no copying)
int R_Mesh_Draw_GetBuffer(rmeshbufferinfo_t *m, int wantoverbright)
}
if (m->transparent)
- {
- overflowedtransverts += max(m->numtriangles * 3, m->numverts);
- if (currenttransmesh >= max_transmeshs || (currenttranstriangle + m->numtriangles) > max_transmeshs || (currenttransvertex + m->numverts) > max_transverts)
- {
- if (!transranout)
- {
- Con_Printf("R_Mesh_Draw_GetBuffer: ran out of room for transparent meshs\n");
- transranout = true;
- }
- return false;
- }
+ Con_Printf("R_Mesh_Draw_GetBuffer: m.transparent is no longer supported\n");
- c_transmeshs++;
- c_transtris += m->numtriangles;
- m->index = &buf_transtri[currenttranstriangle].index[0];
- m->vertex = &buf_transvertex[currenttransvertex].v[0];
- m->color = &buf_transfcolor[currenttransvertex].c[0];
- for (i = 0;i < backendunits;i++)
- m->texcoords[i] = &buf_transtexcoord[i][currenttransvertex].t[0];
-
- // transmesh is only for storage of transparent meshs until they
- // are inserted into the main mesh array
- mesh = &buf_transmesh[currenttransmesh++];
- mesh->firsttriangle = currenttranstriangle;
- mesh->firstvert = currenttransvertex;
- currenttranstriangle += m->numtriangles;
- currenttransvertex += m->numverts;
- }
- else
+ if (currentmesh)
{
- if (currentmesh)
- {
- R_Mesh_Render();
- Con_Printf("mesh queue not empty, flushing.\n");
- }
-
- c_meshs++;
- c_meshtris += m->numtriangles;
- m->index = &buf_tri[currenttriangle].index[0];
- m->vertex = &buf_vertex[currentvertex].v[0];
- m->color = &buf_fcolor[currentvertex].c[0];
- for (i = 0;i < backendunits;i++)
- m->texcoords[i] = &buf_texcoord[i][currentvertex].t[0];
-
- // opaque meshs are rendered directly
- mesh = &buf_mesh[currentmesh++];
- mesh->firsttriangle = currenttriangle;
- mesh->firstvert = currentvertex;
- currenttriangle += m->numtriangles;
- currentvertex += m->numverts;
+ R_Mesh_Render();
+ Con_Printf("mesh queue not empty, flushing.\n");
}
- // code shared for transparent and opaque meshs
+ c_meshs++;
+ c_meshtris += m->numtriangles;
+ m->index = &buf_tri[currenttriangle].index[0];
+ m->vertex = &buf_vertex[currentvertex].v[0];
+ m->color = &buf_fcolor[currentvertex].c[0];
+ for (i = 0;i < backendunits;i++)
+ m->texcoords[i] = &buf_texcoord[i][currentvertex].t[0];
+
+ // opaque meshs are rendered directly
+ mesh = &buf_mesh[currentmesh++];
+ mesh->firsttriangle = currenttriangle;
+ mesh->firstvert = currentvertex;
+ currenttriangle += m->numtriangles;
+ currentvertex += m->numverts;
+
mesh->blendfunc1 = m->blendfunc1;
mesh->blendfunc2 = m->blendfunc2;
mesh->depthmask = (m->blendfunc2 == GL_ZERO || m->depthwrite);
mesh->depthtest = !m->depthdisable;
mesh->triangles = m->numtriangles;
mesh->verts = m->numverts;
+ mesh->matrix = m->matrix; // this copies the struct
overbright = false;
scaler = 1;
extern int c_meshtris, c_meshs, c_transtris, c_transmeshs;
-typedef struct
-{
- int transparent;
- int depthwrite; // force depth writing enabled even if polygon is not opaque
- int depthdisable; // disable depth read/write entirely
- int blendfunc1;
- int blendfunc2;
- int numtriangles;
- int *index;
- int numverts;
- float *vertex;
- int vertexstep;
- float *color;
- int colorstep;
- float cr, cg, cb, ca; // if color is NULL, these are used for all vertices
- int tex[MAX_TEXTUREUNITS];
- float *texcoords[MAX_TEXTUREUNITS];
- int texcoordstep[MAX_TEXTUREUNITS];
- int texrgbscale[MAX_TEXTUREUNITS]; // used only if COMBINE is present
-}
-rmeshinfo_t;
-
typedef struct
{
//input to R_Mesh_Draw_GetBuffer
int numverts;
int tex[MAX_TEXTUREUNITS];
int texrgbscale[MAX_TEXTUREUNITS]; // used only if COMBINE is present
+ // model to world transform matrix
+ matrix4x4_t matrix;
// output
int *index;
R_RegisterModule("GL_Models", gl_models_start, gl_models_shutdown, gl_models_newmap);
}
+/*
void R_AliasTransformVerts(int vertcount)
{
vec3_t point;
vertcount--;
}
}
+*/
void R_AliasLerpVerts(int vertcount,
- float lerp1, trivertx_t *verts1, vec3_t fscale1, vec3_t translate1,
- float lerp2, trivertx_t *verts2, vec3_t fscale2, vec3_t translate2,
- float lerp3, trivertx_t *verts3, vec3_t fscale3, vec3_t translate3,
- float lerp4, trivertx_t *verts4, vec3_t fscale4, vec3_t translate4)
+ float lerp1, const trivertx_t *verts1, const vec3_t fscale1, const vec3_t translate1,
+ float lerp2, const trivertx_t *verts2, const vec3_t fscale2, const vec3_t translate2,
+ float lerp3, const trivertx_t *verts3, const vec3_t fscale3, const vec3_t translate3,
+ float lerp4, const trivertx_t *verts4, const vec3_t fscale4, const vec3_t translate4)
{
int i;
vec3_t scale1, scale2, scale3, scale4, translate;
- float *n1, *n2, *n3, *n4;
+ const float *n1, *n2, *n3, *n4;
float *av, *avn;
av = aliasvert;
avn = aliasvertnorm;
}
}
-skinframe_t *R_FetchSkinFrame(entity_render_t *ent)
+skinframe_t *R_FetchSkinFrame(const entity_render_t *ent)
{
model_t *model = ent->model;
if (model->skinscenes[ent->skinnum].framecount > 1)
return &model->skinframes[model->skinscenes[ent->skinnum].firstframe];
}
-void R_SetupMDLMD2Frames(entity_render_t *ent, float colorr, float colorg, float colorb)
+void R_SetupMDLMD2Frames(const entity_render_t *ent, float colorr, float colorg, float colorb)
{
- md2frame_t *frame1, *frame2, *frame3, *frame4;
- trivertx_t *frame1verts, *frame2verts, *frame3verts, *frame4verts;
- model_t *model;
- model = ent->model;
+ const md2frame_t *frame1, *frame2, *frame3, *frame4;
+ const trivertx_t *frame1verts, *frame2verts, *frame3verts, *frame4verts;
+ const model_t *model = ent->model;
frame1 = &model->mdlmd2data_frames[ent->frameblend[0].frame];
frame2 = &model->mdlmd2data_frames[ent->frameblend[1].frame];
R_LightModel(ent, model->numverts, colorr, colorg, colorb, false);
- R_AliasTransformVerts(model->numverts);
+ //R_AliasTransformVerts(model->numverts);
}
-void R_DrawQ1Q2AliasModelCallback (void *calldata1, int calldata2)
+void R_DrawQ1Q2AliasModelCallback (const void *calldata1, int calldata2)
{
int c, pantsfullbright, shirtfullbright, colormapped;
float pantscolor[3], shirtcolor[3];
rmeshbufferinfo_t m;
model_t *model;
skinframe_t *skinframe;
- entity_render_t *ent;
+ const entity_render_t *ent = calldata1;
- ent = calldata1;
- softwaretransformforentity(ent);
+// softwaretransformforentity(ent);
fog = 0;
if (fogenabled)
m.numtriangles = model->numtris;
m.numverts = model->numverts;
m.tex[0] = R_GetTexture(skinframe->merged);
+ m.matrix = ent->matrix;
c_alias_polys += m.numtriangles;
if (R_Mesh_Draw_GetBuffer(&m, true))
m.numtriangles = model->numtris;
m.numverts = model->numverts;
m.tex[0] = colormapped ? R_GetTexture(skinframe->base) : R_GetTexture(skinframe->merged);
+ m.matrix = ent->matrix;
if (R_Mesh_Draw_GetBuffer(&m, true))
{
c_alias_polys += m.numtriangles;
m.numtriangles = model->numtris;
m.numverts = model->numverts;
m.tex[0] = R_GetTexture(skinframe->pants);
+ m.matrix = ent->matrix;
if (R_Mesh_Draw_GetBuffer(&m, true))
{
c_alias_polys += m.numtriangles;
m.numtriangles = model->numtris;
m.numverts = model->numverts;
m.tex[0] = R_GetTexture(skinframe->shirt);
+ m.matrix = ent->matrix;
if (R_Mesh_Draw_GetBuffer(&m, true))
{
c_alias_polys += m.numtriangles;
m.numtriangles = model->numtris;
m.numverts = model->numverts;
m.tex[0] = R_GetTexture(skinframe->glow);
+ m.matrix = ent->matrix;
if (R_Mesh_Draw_GetBuffer(&m, true))
{
c_alias_polys += m.numtriangles;
m.numtriangles = model->numtris;
m.numverts = model->numverts;
m.tex[0] = R_GetTexture(skinframe->fog);
+ m.matrix = ent->matrix;
if (R_Mesh_Draw_GetBuffer(&m, false))
{
c_alias_polys += m.numtriangles;
}
}
-int ZymoticLerpBones(int count, zymbonematrix *bonebase, frameblend_t *blend, zymbone_t *bone)
+int ZymoticLerpBones(int count, const zymbonematrix *bonebase, const frameblend_t *blend, const zymbone_t *bone)
{
int i;
float lerp1, lerp2, lerp3, lerp4;
- zymbonematrix *out, rootmatrix, m, *bone1, *bone2, *bone3, *bone4;
+ zymbonematrix *out, rootmatrix, m;
+ const zymbonematrix *bone1, *bone2, *bone3, *bone4;
+ /*
// LordHavoc: combine transform from zym coordinate space to quake coordinate space with model to world transform matrix
rootmatrix.m[0][0] = softwaretransform_matrix[0][1];
rootmatrix.m[0][1] = -softwaretransform_matrix[0][0];
rootmatrix.m[2][1] = -softwaretransform_matrix[2][0];
rootmatrix.m[2][2] = softwaretransform_matrix[2][2];
rootmatrix.m[2][3] = softwaretransform_matrix[2][3];
+ */
+ rootmatrix.m[0][0] = 1;
+ rootmatrix.m[0][1] = 0;
+ rootmatrix.m[0][2] = 0;
+ rootmatrix.m[0][3] = 0;
+ rootmatrix.m[1][0] = 0;
+ rootmatrix.m[1][1] = 1;
+ rootmatrix.m[1][2] = 0;
+ rootmatrix.m[1][3] = 0;
+ rootmatrix.m[2][0] = 0;
+ rootmatrix.m[2][1] = 0;
+ rootmatrix.m[2][2] = 1;
+ rootmatrix.m[2][3] = 0;
bone1 = bonebase + blend[0].frame * count;
lerp1 = blend[0].lerp;
}
}
-void R_DrawZymoticModelMeshCallback (void *calldata1, int calldata2)
+void R_DrawZymoticModelMeshCallback (const void *calldata1, int calldata2)
{
float fog;
vec3_t diff;
zymtype1header_t *m;
rtexture_t *texture;
rmeshbufferinfo_t mbuf;
- entity_render_t *ent;
- int shadernum;
-
- ent = calldata1;
- shadernum = calldata2;
+ const entity_render_t *ent = calldata1;
+ int shadernum = calldata2;
// find the vertex index list and texture
m = ent->model->zymdata_header;
// 2. render fog as additive
}
- softwaretransformforentity(ent);
ZymoticLerpBones(m->numbones, (zymbonematrix *)(m->lump_poses.start + (int) m), ent->frameblend, (zymbone_t *)(m->lump_bones.start + (int) m));
ZymoticTransformVerts(m->numverts, (int *)(m->lump_vertbonecounts.start + (int) m), (zymvertex_t *)(m->lump_verts.start + (int) m));
ZymoticCalcNormals(m->numverts, m->numshaders, (int *)(m->lump_render.start + (int) m));
- R_LightModel(ent, m->numverts, 1 - fog, 1 - fog, 1 - fog, true);
+ R_LightModel(ent, m->numverts, 1 - fog, 1 - fog, 1 - fog, false);
memset(&mbuf, 0, sizeof(mbuf));
mbuf.numverts = m->numverts;
mbuf.blendfunc2 = GL_ZERO;
}
mbuf.tex[0] = R_GetTexture(texture);
+ mbuf.matrix = ent->matrix;
if (R_Mesh_Draw_GetBuffer(&mbuf, true))
{
c_alias_polys += mbuf.numtriangles;
mbuf.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
// FIXME: need alpha mask for fogging...
//mbuf.tex[0] = R_GetTexture(texture);
+ mbuf.matrix = ent->matrix;
if (R_Mesh_Draw_GetBuffer(&mbuf, false))
{
c_alias_polys += mbuf.numtriangles;
vec3_t v;
entity_render_t *ent;
+ ent = &cl_entities[0].render;
+ Matrix4x4_CreateIdentity(&ent->matrix);
+ Matrix4x4_CreateIdentity(&ent->inversematrix);
+
R_FarClip_Box(cl.worldmodel->normalmins, cl.worldmodel->normalmaxs);
if (!r_drawentities.integer)
if (R_VisibleCullBox(ent->mins, ent->maxs))
continue;
+ VectorCopy(ent->angles, v);
+ if (ent->model->type != mod_brush)
+ v[0] = -v[0];
+ Matrix4x4_CreateFromQuakeEntity(&ent->matrix, ent->origin[0], ent->origin[1], ent->origin[2], v[0], v[1], v[2], ent->scale);
+ Matrix4x4_Invert_Simple(&ent->inversematrix, &ent->matrix);
R_LerpAnimation(ent);
ent->visframe = r_framecount;
R_FarClip_Box(ent->mins, ent->maxs);
+
+ R_UpdateEntLights(ent);
}
}
m.depthdisable = true; // magic
m.numtriangles = 1;
m.numverts = 3;
+ Matrix4x4_CreateIdentity(&m.matrix);
if (R_Mesh_Draw_GetBuffer(&m, false))
{
m.index[0] = 0;
R_TimeReport("explosions");
R_MeshQueue_RenderTransparent();
-
- R_Mesh_AddTransparent();
R_TimeReport("addtrans");
R_DrawCoronas();
Combine and scale multiple lightmaps into the 8.8 format in blocklights
===============
*/
-static void R_BuildLightMap (entity_render_t *ent, msurface_t *surf, int dlightchanged)
+static void R_BuildLightMap (const entity_render_t *ent, msurface_t *surf, int dlightchanged)
{
if (!r_floatbuildlightmap.integer)
{
icolor[7] = ca2;
model = cl.worldmodel;
- softwaretransformidentity();
R_StainNode(model->nodes + model->hulls[0].firstclipnode, model, origin, radius, icolor);
// look for embedded bmodels
Mod_CheckLoaded(model);
if (model->type == mod_brush)
{
- softwaretransformforentity(ent);
- softwareuntransform(origin, org);
+ Matrix4x4_Transform(&ent->inversematrix, origin, org);
R_StainNode(model->nodes + model->hulls[0].firstclipnode, model, org, radius, icolor);
}
}
=============================================================
*/
-static void RSurfShader_Sky(entity_render_t *ent, msurface_t *firstsurf)
+static void RSurf_CopyXYZ(const surfvertex_t *in, float *out, int numverts)
{
- msurface_t *surf;
int i;
- surfvertex_t *v;
- surfmesh_t *mesh;
- rmeshbufferinfo_t m;
- float cr, cg, cb, ca;
- float *outv, *outc;
+ for (i = 0;i < numverts;i++, in++, out += 4)
+ {
+ VectorCopy(in->v, out);
+ out[3] = 1;
+ }
+}
- // LordHavoc: HalfLife maps have freaky skypolys...
- if (ent->model->ishlbsp)
- return;
+static void RSurf_CopyST(const surfvertex_t *in, float *out, int numverts)
+{
+ int i;
+ for (i = 0;i < numverts;i++, in++, out += 2)
+ {
+ out[0] = in->st[0];
+ out[1] = in->st[1];
+ }
+}
- if (skyrendernow)
+static void RSurf_CopyUV(const surfvertex_t *in, float *out, int numverts)
+{
+ int i;
+ for (i = 0;i < numverts;i++, in++, out += 2)
{
- skyrendernow = false;
- if (skyrendermasked)
- R_Sky();
+ out[0] = in->uv[0];
+ out[1] = in->uv[1];
}
- for (surf = firstsurf;surf;surf = surf->chain)
+}
+
+static void RSurf_CopyAB(const surfvertex_t *in, float *out, int numverts)
+{
+ int i;
+ for (i = 0;i < numverts;i++, in++, out += 2)
{
- // draw depth-only polys
- memset(&m, 0, sizeof(m));
- if (skyrendermasked)
- {
- m.blendfunc1 = GL_ZERO;
- m.blendfunc2 = GL_ONE;
- m.depthwrite = true;
- }
- else
- {
- m.blendfunc1 = GL_ONE;
- m.blendfunc2 = GL_ZERO;
- }
- for (mesh = surf->mesh;mesh;mesh = mesh->chain)
+ out[0] = in->ab[0];
+ out[1] = in->ab[1];
+ }
+}
+
+static void RSurf_AddLightmapToVertexColors(const surfvertex_t *in, float *c, int numverts, const qbyte *samples, int size3, const qbyte *styles)
+{
+ int i;
+ float scale;
+ const qbyte *lm;
+ if (styles[0] != 255)
+ {
+ for (i = 0;i < numverts;i++, in++, c += 4)
{
- m.numtriangles = mesh->numtriangles;
- m.numverts = mesh->numverts;
- if (R_Mesh_Draw_GetBuffer(&m, false))
+ lm = samples + in->lightmapoffset;
+ scale = d_lightstylevalue[styles[0]] * (1.0f / 32768.0f);
+ VectorMA(c, scale, lm, c);
+ if (styles[1] != 255)
{
- cr = fogcolor[0] * m.colorscale;
- cg = fogcolor[1] * m.colorscale;
- cb = fogcolor[2] * m.colorscale;
- ca = 1;
- memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
- for (i = 0, v = mesh->vertex, outv = m.vertex;i < m.numverts;i++, v++, outv += 4, outc += 4)
+ lm += size3;
+ scale = d_lightstylevalue[styles[1]] * (1.0f / 32768.0f);
+ VectorMA(c, scale, lm, c);
+ if (styles[2] != 255)
{
- softwaretransform(v->v, outv);
- }
- for (i = 0, outc = m.color;i < m.numverts;i++, outc += 4)
- {
- outc[0] = cr;
- outc[1] = cg;
- outc[2] = cb;
- outc[3] = ca;
+ lm += size3;
+ scale = d_lightstylevalue[styles[2]] * (1.0f / 32768.0f);
+ VectorMA(c, scale, lm, c);
+ if (styles[3] != 255)
+ {
+ lm += size3;
+ scale = d_lightstylevalue[styles[3]] * (1.0f / 32768.0f);
+ VectorMA(c, scale, lm, c);
+ }
}
- R_Mesh_Render();
}
}
}
}
-static int RSurf_LightSeparate(int *dlightbits, int numverts, float *vert, float *color)
+static void RSurf_FogColors(const float *v, float *c, float colorscale, int numverts, const float *modelorg)
+{
+ int i;
+ float diff[3], f;
+ if (fogenabled)
+ {
+ for (i = 0;i < numverts;i++, v += 4, c += 4)
+ {
+ VectorSubtract(v, modelorg, diff);
+ f = colorscale * (1 - exp(fogdensity/DotProduct(diff, diff)));
+ VectorScale(c, f, c);
+ }
+ }
+ else if (colorscale != 1)
+ for (i = 0;i < numverts;i++, c += 4)
+ VectorScale(c, colorscale, c);
+}
+
+static void RSurf_FoggedColors(const float *v, float *c, float r, float g, float b, float a, float colorscale, int numverts, const float *modelorg)
+{
+ int i;
+ float diff[3], f;
+ r *= colorscale;
+ g *= colorscale;
+ b *= colorscale;
+ if (fogenabled)
+ {
+ for (i = 0;i < numverts;i++, v += 4, c += 4)
+ {
+ VectorSubtract(v, modelorg, diff);
+ f = 1 - exp(fogdensity/DotProduct(diff, diff));
+ c[0] = r * f;
+ c[1] = g * f;
+ c[2] = b * f;
+ c[3] = a;
+ }
+ }
+ else
+ {
+ for (i = 0;i < numverts;i++, c += 4)
+ {
+ c[0] = r;
+ c[1] = g;
+ c[2] = b;
+ c[3] = a;
+ }
+ }
+}
+
+static void RSurf_FogPassColors(const float *v, float *c, float r, float g, float b, float a, float colorscale, int numverts, const float *modelorg)
{
- float f, *v, *c;
+ int i;
+ float diff[3], f;
+ r *= colorscale;
+ g *= colorscale;
+ b *= colorscale;
+ for (i = 0;i < numverts;i++, v += 4, c += 4)
+ {
+ VectorSubtract(v, modelorg, diff);
+ f = exp(fogdensity/DotProduct(diff, diff));
+ c[0] = r * f;
+ c[1] = g * f;
+ c[2] = b * f;
+ c[3] = a;
+ }
+}
+
+static void RSurf_ScaleColors(float *c, float scale, int numverts)
+{
+ int i;
+ if (scale != 1)
+ for (i = 0;i < numverts;i++, c += 4)
+ VectorScale(c, scale, c);
+}
+
+static int RSurf_LightSeparate(const matrix4x4_t *matrix, const int *dlightbits, int numverts, const float *vert, float *color)
+{
+ float f;
+ const float *v;
+ float *c;
int i, l, lit = false;
rdlight_t *rd;
vec3_t lightorigin;
if (dlightbits[l >> 5] & (1 << (l & 31)))
{
rd = &r_dlight[l];
- // FIXME: support softwareuntransform here and make bmodels use hardware transform?
- VectorCopy(rd->origin, lightorigin);
+ Matrix4x4_Transform(matrix, rd->origin, lightorigin);
for (i = 0, v = vert, c = color;i < numverts;i++, v += 4, c += 4)
{
f = VectorDistance2(v, lightorigin) + LIGHTOFFSET;
// note: this untransforms lights to do the checking,
// and takes surf->mesh->vertex data
-static int RSurf_LightCheck(int *dlightbits, surfmesh_t *mesh)
+static int RSurf_LightCheck(const int *dlightbits, surfmesh_t *mesh)
{
int i, l;
rdlight_t *rd;
return false;
}
-static void RSurfShader_Water_Callback(void *calldata1, int calldata2)
+static void RSurfShader_Sky(const entity_render_t *ent, const msurface_t *firstsurf)
+{
+ const msurface_t *surf;
+ surfmesh_t *mesh;
+ rmeshbufferinfo_t m;
+
+ // LordHavoc: HalfLife maps have freaky skypolys...
+ if (ent->model->ishlbsp)
+ return;
+
+ if (skyrendernow)
+ {
+ skyrendernow = false;
+ R_Sky();
+ }
+
+ // draw depth-only polys
+ memset(&m, 0, sizeof(m));
+ m.blendfunc1 = GL_ZERO;
+ m.blendfunc2 = GL_ONE;
+ m.depthwrite = true;
+ m.matrix = ent->matrix;
+ for (surf = firstsurf;surf;surf = surf->chain)
+ {
+ for (mesh = surf->mesh;mesh;mesh = mesh->chain)
+ {
+ m.numtriangles = mesh->numtriangles;
+ m.numverts = mesh->numverts;
+ if (R_Mesh_Draw_GetBuffer(&m, false))
+ {
+ memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
+ RSurf_CopyXYZ(mesh->vertex, m.vertex, m.numverts);
+ memset(m.color, 0, m.numverts * sizeof(float[4]));
+ R_Mesh_Render();
+ }
+ }
+ }
+}
+
+static void RSurfShader_Water_Callback(const void *calldata1, int calldata2)
{
- entity_render_t *ent = calldata1;
+ const entity_render_t *ent = calldata1;
msurface_t *surf = ent->model->surfaces + calldata2;
- int i, size3;
- surfvertex_t *v;
- float *outv, *outc, *outst, cl, diff[3];
- float base[3], scale, f;
- qbyte *lm;
+ float f;
surfmesh_t *mesh;
rmeshbufferinfo_t m;
float alpha = ent->alpha * (surf->flags & SURF_DRAWNOALPHA ? 1 : r_wateralpha.value);
+ float modelorg[3];
+ Matrix4x4_Transform(&ent->inversematrix, r_origin, modelorg);
- softwaretransformforentity(ent);
memset(&m, 0, sizeof(m));
if (ent->effects & EF_ADDITIVE)
{
m.blendfunc2 = GL_ZERO;
}
m.tex[0] = R_GetTexture(surf->currenttexture->texture);
- size3 = ((surf->extents[0]>>4)+1)*((surf->extents[1]>>4)+1)*3;
+ m.matrix = ent->matrix;
for (mesh = surf->mesh;mesh;mesh = mesh->chain)
{
m.numtriangles = mesh->numtriangles;
m.numverts = mesh->numverts;
if (R_Mesh_Draw_GetBuffer(&m, true))
{
- cl = m.colorscale;
memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
- for (i = 0, v = mesh->vertex, outv = m.vertex, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outst += 2)
- {
- softwaretransform(v->v, outv);
- outv[3] = 1;
- outst[0] = v->st[0];
- outst[1] = v->st[1];
- }
- base[0] = base[1] = base[2] = surf->flags & SURF_DRAWFULLBRIGHT ? 1.0f : ((surf->flags & SURF_LIGHTMAP) ? 0 : 0.5f);
- for (i = 0, outc = m.color;i < m.numverts;i++, outc += 4)
- {
- VectorCopy(base, outc);
- outc[3] = alpha;
- }
+ RSurf_CopyXYZ(mesh->vertex, m.vertex, m.numverts);
+ RSurf_CopyST(mesh->vertex, m.texcoords[0], m.numverts);
+ f = surf->flags & SURF_DRAWFULLBRIGHT ? 1.0f : ((surf->flags & SURF_LIGHTMAP) ? 0 : 0.5f);
+ R_FillColors(m.color, m.numverts, f, f, f, alpha);
if (!(surf->flags & SURF_DRAWFULLBRIGHT || ent->effects & EF_FULLBRIGHT))
{
if (surf->dlightframe == r_framecount)
- RSurf_LightSeparate(surf->dlightbits, m.numverts, m.vertex, m.color);
- for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color;i < m.numverts;i++, v++, outv += 4, outc += 4)
- {
- if (surf->flags & SURF_LIGHTMAP)
- if (surf->styles[0] != 255)
- {
- lm = surf->samples + v->lightmapoffset;
- scale = d_lightstylevalue[surf->styles[0]] * (1.0f / 32768.0f);
- VectorMA(outc, scale, lm, outc);
- if (surf->styles[1] != 255)
- {
- lm += size3;
- scale = d_lightstylevalue[surf->styles[1]] * (1.0f / 32768.0f);
- VectorMA(outc, scale, lm, outc);
- if (surf->styles[2] != 255)
- {
- lm += size3;
- scale = d_lightstylevalue[surf->styles[2]] * (1.0f / 32768.0f);
- VectorMA(outc, scale, lm, outc);
- if (surf->styles[3] != 255)
- {
- lm += size3;
- scale = d_lightstylevalue[surf->styles[3]] * (1.0f / 32768.0f);
- VectorMA(outc, scale, lm, outc);
- }
- }
- }
- }
- }
- }
- if (fogenabled)
- {
- for (i = 0, outv = m.vertex, outc = m.color;i < m.numverts;i++, outv += 4, outc += 4)
- {
- VectorSubtract(outv, r_origin, diff);
- f = m.colorscale * (1 - exp(fogdensity/DotProduct(diff, diff)));
- VectorScale(outc, f, outc);
- }
- }
- else if (m.colorscale != 1)
- {
- for (i = 0, outv = m.vertex, outc = m.color;i < m.numverts;i++, outv += 4, outc += 4)
- VectorScale(outc, m.colorscale, outc);
+ RSurf_LightSeparate(&ent->inversematrix, surf->dlightbits, m.numverts, m.vertex, m.color);
+ if (surf->flags & SURF_LIGHTMAP)
+ RSurf_AddLightmapToVertexColors(mesh->vertex, m.color, m.numverts, surf->samples, ((surf->extents[0]>>4)+1)*((surf->extents[1]>>4)+1)*3, surf->styles);
}
+ RSurf_FogColors(m.vertex, m.color, m.colorscale, m.numverts, modelorg);
R_Mesh_Render();
}
}
m.blendfunc1 = GL_SRC_ALPHA;
m.blendfunc2 = GL_ONE;
m.tex[0] = R_GetTexture(surf->currenttexture->fogtexture);
+ m.matrix = ent->matrix;
for (mesh = surf->mesh;mesh;mesh = mesh->chain)
{
m.numtriangles = mesh->numtriangles;
m.numverts = mesh->numverts;
if (R_Mesh_Draw_GetBuffer(&m, false))
{
- VectorScale(fogcolor, m.colorscale, base);
memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
- for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color;i < m.numverts;i++, v++, outv += 4, outc += 4)
- {
- softwaretransform(v->v, outv);
- outv[3] = 1;
- VectorSubtract(outv, r_origin, diff);
- f = exp(fogdensity/DotProduct(diff, diff));
- VectorScale(base, f, outc);
- outc[3] = alpha;
- }
+ RSurf_CopyXYZ(mesh->vertex, m.vertex, m.numverts);
if (m.tex[0])
- {
- for (i = 0, v = mesh->vertex, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outst += 2)
- {
- outst[0] = v->st[0];
- outst[1] = v->st[1];
- }
- }
+ RSurf_CopyST(mesh->vertex, m.texcoords[0], m.numverts);
+ RSurf_FogPassColors(m.vertex, m.color, fogcolor[0], fogcolor[1], fogcolor[2], alpha, m.colorscale, m.numverts, modelorg);
R_Mesh_Render();
}
}
}
}
-static void RSurfShader_Water(entity_render_t *ent, msurface_t *firstsurf)
+static void RSurfShader_Water(const entity_render_t *ent, const msurface_t *firstsurf)
{
- msurface_t *surf;
+ const msurface_t *surf;
for (surf = firstsurf;surf;surf = surf->chain)
{
if ((r_wateralpha.value < 1 && !(surf->flags & SURF_DRAWNOALPHA)) || ent->effects & EF_ADDITIVE || surf->currenttexture->fogtexture)
}
}
-static void RSurfShader_Wall_Pass_BaseVertex(entity_render_t *ent, msurface_t *surf)
+static void RSurfShader_Wall_Pass_BaseVertex(const entity_render_t *ent, const msurface_t *surf)
{
- int i, size3;
- surfvertex_t *v;
- float *outv, *outc, *outst, cl, ca, diff[3];
- float base[3], scale, f;
- qbyte *lm;
+ float base;
surfmesh_t *mesh;
rmeshbufferinfo_t m;
+ float modelorg[3];
+ Matrix4x4_Transform(&ent->inversematrix, r_origin, modelorg);
memset(&m, 0, sizeof(m));
if (ent->effects & EF_ADDITIVE)
{
m.blendfunc2 = GL_ZERO;
}
m.tex[0] = R_GetTexture(surf->currenttexture->texture);
-
- size3 = ((surf->extents[0]>>4)+1)*((surf->extents[1]>>4)+1)*3;
-
- base[0] = base[1] = base[2] = ent->effects & EF_FULLBRIGHT ? 2.0f : r_ambient.value * (1.0f / 64.0f);
-
- ca = ent->alpha;
+ base = ent->effects & EF_FULLBRIGHT ? 2.0f : r_ambient.value * (1.0f / 64.0f);
+ m.matrix = ent->matrix;
for (mesh = surf->mesh;mesh;mesh = mesh->chain)
{
m.numtriangles = mesh->numtriangles;
m.numverts = mesh->numverts;
-
if (R_Mesh_Draw_GetBuffer(&m, true))
{
- cl = m.colorscale;
memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
-
- if (ent->effects & EF_FULLBRIGHT)
- {
- for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2)
- {
- softwaretransform(v->v, outv);
- outv[3] = 1;
- VectorSubtract(outv, r_origin, diff);
- outc[0] = outc[1] = outc[2] = 2.0f * cl * (1 - exp(fogdensity/DotProduct(diff, diff)));
- outc[3] = ca;
- outst[0] = v->st[0];
- outst[1] = v->st[1];
- }
- }
- else
+ RSurf_CopyXYZ(mesh->vertex, m.vertex, m.numverts);
+ RSurf_CopyST(mesh->vertex, m.texcoords[0], m.numverts);
+ R_FillColors(m.color, m.numverts, base, base, base, ent->alpha);
+ if (!(ent->effects & EF_FULLBRIGHT))
{
- for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2)
- {
- softwaretransform(v->v, outv);
- outv[3] = 1;
- VectorCopy(base, outc);
- outc[3] = ca;
- outst[0] = v->st[0];
- outst[1] = v->st[1];
- }
-
if (surf->dlightframe == r_framecount)
- RSurf_LightSeparate(surf->dlightbits, m.numverts, m.vertex, m.color);
-
- for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color;i < m.numverts;i++, v++, outv += 4, outc += 4)
- {
- if (surf->styles[0] != 255)
- {
- lm = surf->samples + v->lightmapoffset;
- scale = d_lightstylevalue[surf->styles[0]] * (1.0f / 32768.0f);
- VectorMA(outc, scale, lm, outc);
- if (surf->styles[1] != 255)
- {
- lm += size3;
- scale = d_lightstylevalue[surf->styles[1]] * (1.0f / 32768.0f);
- VectorMA(outc, scale, lm, outc);
- if (surf->styles[2] != 255)
- {
- lm += size3;
- scale = d_lightstylevalue[surf->styles[2]] * (1.0f / 32768.0f);
- VectorMA(outc, scale, lm, outc);
- if (surf->styles[3] != 255)
- {
- lm += size3;
- scale = d_lightstylevalue[surf->styles[3]] * (1.0f / 32768.0f);
- VectorMA(outc, scale, lm, outc);
- }
- }
- }
- }
- if (fogenabled)
- {
- VectorSubtract(outv, r_origin, diff);
- f = cl * (1 - exp(fogdensity/DotProduct(diff, diff)));
- VectorScale(outc, f, outc);
- }
- else
- VectorScale(outc, cl, outc);
- }
+ RSurf_LightSeparate(&ent->inversematrix, surf->dlightbits, m.numverts, m.vertex, m.color);
+ if (surf->flags & SURF_LIGHTMAP)
+ RSurf_AddLightmapToVertexColors(mesh->vertex, m.color, m.numverts, surf->samples, ((surf->extents[0]>>4)+1)*((surf->extents[1]>>4)+1)*3, surf->styles);
}
+ RSurf_FogColors(m.vertex, m.color, m.colorscale, m.numverts, modelorg);
R_Mesh_Render();
}
}
}
-static void RSurfShader_Wall_Pass_BaseFullbright(entity_render_t *ent, msurface_t *surf)
+static void RSurfShader_Wall_Pass_BaseFullbright(const entity_render_t *ent, const msurface_t *surf)
{
- int i;
- surfvertex_t *v;
- float *outv, *outc, *outst, cl, ca, diff[3];
surfmesh_t *mesh;
rmeshbufferinfo_t m;
+ float modelorg[3];
+ Matrix4x4_Transform(&ent->inversematrix, r_origin, modelorg);
memset(&m, 0, sizeof(m));
if (ent->effects & EF_ADDITIVE)
{
m.blendfunc2 = GL_ZERO;
}
m.tex[0] = R_GetTexture(surf->currenttexture->texture);
- ca = ent->alpha;
+ m.matrix = ent->matrix;
for (mesh = surf->mesh;mesh;mesh = mesh->chain)
{
m.numtriangles = mesh->numtriangles;
m.numverts = mesh->numverts;
-
if (R_Mesh_Draw_GetBuffer(&m, false))
{
- cl = m.colorscale;
memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
- for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2)
- {
- softwaretransform(v->v, outv);
- outv[3] = 1;
- if (fogenabled)
- {
- VectorSubtract(outv, r_origin, diff);
- outc[0] = outc[1] = outc[2] = cl * (1 - exp(fogdensity/DotProduct(diff, diff)));
- }
- else
- outc[0] = outc[1] = outc[2] = cl;
- outc[3] = ca;
- outst[0] = v->st[0];
- outst[1] = v->st[1];
- }
+ RSurf_CopyXYZ(mesh->vertex, m.vertex, m.numverts);
+ RSurf_CopyST(mesh->vertex, m.texcoords[0], m.numverts);
+ RSurf_FoggedColors(m.vertex, m.color, 1, 1, 1, ent->alpha, m.colorscale, m.numverts, modelorg);
R_Mesh_Render();
}
}
}
-static void RSurfShader_Wall_Pass_Glow(entity_render_t *ent, msurface_t *surf)
+static void RSurfShader_Wall_Pass_Glow(const entity_render_t *ent, const msurface_t *surf)
{
- int i;
- surfvertex_t *v;
- float *outv, *outc, *outst, cl, ca, diff[3];
surfmesh_t *mesh;
rmeshbufferinfo_t m;
+ float modelorg[3];
+ Matrix4x4_Transform(&ent->inversematrix, r_origin, modelorg);
memset(&m, 0, sizeof(m));
m.transparent = ent->effects & EF_ADDITIVE || surf->currenttexture->fogtexture != NULL || ent->alpha != 1;
m.blendfunc1 = GL_SRC_ALPHA;
m.blendfunc2 = GL_ONE;
m.tex[0] = R_GetTexture(surf->currenttexture->glowtexture);
- ca = ent->alpha;
+ m.matrix = ent->matrix;
for (mesh = surf->mesh;mesh;mesh = mesh->chain)
{
m.numtriangles = mesh->numtriangles;
m.numverts = mesh->numverts;
-
if (R_Mesh_Draw_GetBuffer(&m, false))
{
- cl = m.colorscale;
memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
- for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2)
- {
- softwaretransform(v->v, outv);
- outv[3] = 1;
- if (fogenabled)
- {
- VectorSubtract(outv, r_origin, diff);
- outc[0] = outc[1] = outc[2] = cl * (1 - exp(fogdensity/DotProduct(diff, diff)));
- }
- else
- outc[0] = outc[1] = outc[2] = cl;
- outc[3] = ca;
- outst[0] = v->st[0];
- outst[1] = v->st[1];
- }
+ RSurf_CopyXYZ(mesh->vertex, m.vertex, m.numverts);
+ RSurf_CopyST(mesh->vertex, m.texcoords[0], m.numverts);
+ RSurf_FoggedColors(m.vertex, m.color, 1, 1, 1, ent->alpha, m.colorscale, m.numverts, modelorg);
R_Mesh_Render();
}
}
}
-static void RSurfShader_Wall_Pass_Fog(entity_render_t *ent, msurface_t *surf)
+static void RSurfShader_Wall_Pass_Fog(const entity_render_t *ent, const msurface_t *surf)
{
- int i;
- surfvertex_t *v;
- float *outv, *outc, *outst, cl, ca, diff[3], f;
surfmesh_t *mesh;
rmeshbufferinfo_t m;
+ float modelorg[3];
+ Matrix4x4_Transform(&ent->inversematrix, r_origin, modelorg);
memset(&m, 0, sizeof(m));
m.transparent = ent->effects & EF_ADDITIVE || surf->currenttexture->fogtexture != NULL || ent->alpha != 1;
m.blendfunc1 = GL_SRC_ALPHA;
m.blendfunc2 = GL_ONE;
- ca = ent->alpha;
+ m.matrix = ent->matrix;
+ m.tex[0] = R_GetTexture(surf->currenttexture->fogtexture);
for (mesh = surf->mesh;mesh;mesh = mesh->chain)
{
m.numtriangles = mesh->numtriangles;
m.numverts = mesh->numverts;
-
if (R_Mesh_Draw_GetBuffer(&m, false))
{
- cl = m.colorscale;
memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
- for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2)
- {
- softwaretransform(v->v, outv);
- outv[3] = 1;
- VectorSubtract(outv, r_origin, diff);
- f = cl * exp(fogdensity/DotProduct(diff, diff));
- VectorScale(fogcolor, f, outc);
- outc[3] = ca;
- outst[0] = v->st[0];
- outst[1] = v->st[1];
- }
+ RSurf_CopyXYZ(mesh->vertex, m.vertex, m.numverts);
+ if (m.tex[0])
+ RSurf_CopyST(mesh->vertex, m.texcoords[0], m.numverts);
+ RSurf_FogPassColors(m.vertex, m.color, fogcolor[0], fogcolor[1], fogcolor[2], ent->alpha, m.colorscale, m.numverts, modelorg);
R_Mesh_Render();
}
}
}
-static void RSurfShader_OpaqueWall_Pass_TripleTexCombine(entity_render_t *ent, msurface_t *surf)
+static void RSurfShader_OpaqueWall_Pass_TripleTexCombine(const entity_render_t *ent, const msurface_t *surf)
{
- int i;
- surfvertex_t *v;
- float *outv, *outc, *outst, *outuv, *outab, cl;
surfmesh_t *mesh;
rmeshbufferinfo_t m;
+ float cl;
memset(&m, 0, sizeof(m));
m.blendfunc1 = GL_ONE;
m.blendfunc2 = GL_ZERO;
m.texrgbscale[1] = 4.0f;
m.tex[2] = R_GetTexture(surf->currenttexture->detailtexture);
m.texrgbscale[2] = 2.0f;
+ m.matrix = ent->matrix;
for (mesh = surf->mesh;mesh;mesh = mesh->chain)
{
m.numtriangles = mesh->numtriangles;
m.numverts = mesh->numverts;
-
if (R_Mesh_Draw_GetBuffer(&m, false))
{
- cl = (float) (1 << lightscalebit) * m.colorscale;
memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
- for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0], outuv = m.texcoords[1], outab = m.texcoords[2];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2, outuv += 2, outab += 2)
- {
- softwaretransform(v->v, outv);
- outv[3] = 1;
- outc[0] = outc[1] = outc[2] = cl;
- outc[3] = 1;
- outst[0] = v->st[0];
- outst[1] = v->st[1];
- outuv[0] = v->uv[0];
- outuv[1] = v->uv[1];
- outab[0] = v->ab[0];
- outab[1] = v->ab[1];
- }
+ RSurf_CopyXYZ(mesh->vertex, m.vertex, m.numverts);
+ cl = (float) (1 << lightscalebit) * m.colorscale;
+ R_FillColors(m.color, m.numverts, cl, cl, cl, 1);
+ RSurf_CopyST(mesh->vertex, m.texcoords[0], m.numverts);
+ RSurf_CopyUV(mesh->vertex, m.texcoords[1], m.numverts);
+ RSurf_CopyAB(mesh->vertex, m.texcoords[2], m.numverts);
R_Mesh_Render();
}
}
}
-static void RSurfShader_OpaqueWall_Pass_BaseMTex(entity_render_t *ent, msurface_t *surf)
+static void RSurfShader_OpaqueWall_Pass_BaseMTex(const entity_render_t *ent, const msurface_t *surf)
{
- int i;
- surfvertex_t *v;
- float *outv, *outc, *outst, *outuv, cl;
surfmesh_t *mesh;
rmeshbufferinfo_t m;
+ float cl;
memset(&m, 0, sizeof(m));
m.blendfunc1 = GL_ONE;
m.blendfunc2 = GL_ZERO;
m.tex[0] = R_GetTexture(surf->currenttexture->texture);
m.tex[1] = R_GetTexture(surf->lightmaptexture);
+ m.matrix = ent->matrix;
for (mesh = surf->mesh;mesh;mesh = mesh->chain)
{
m.numtriangles = mesh->numtriangles;
m.numverts = mesh->numverts;
-
if (R_Mesh_Draw_GetBuffer(&m, true))
{
- cl = (float) (1 << lightscalebit) * m.colorscale;
memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
- for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0], outuv = m.texcoords[1];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2, outuv += 2)
- {
- softwaretransform(v->v, outv);
- outv[3] = 1;
- outc[0] = outc[1] = outc[2] = cl;
- outc[3] = 1;
- outst[0] = v->st[0];
- outst[1] = v->st[1];
- outuv[0] = v->uv[0];
- outuv[1] = v->uv[1];
- }
+ RSurf_CopyXYZ(mesh->vertex, m.vertex, m.numverts);
+ cl = (float) (1 << lightscalebit) * m.colorscale;
+ R_FillColors(m.color, m.numverts, cl, cl, cl, 1);
+ RSurf_CopyST(mesh->vertex, m.texcoords[0], m.numverts);
+ RSurf_CopyUV(mesh->vertex, m.texcoords[1], m.numverts);
R_Mesh_Render();
}
}
}
-static void RSurfShader_OpaqueWall_Pass_BaseTexture(entity_render_t *ent, msurface_t *surf)
+static void RSurfShader_OpaqueWall_Pass_BaseTexture(const entity_render_t *ent, const msurface_t *surf)
{
- int i;
- surfvertex_t *v;
- float *outv, *outc, *outst, cl;
surfmesh_t *mesh;
rmeshbufferinfo_t m;
+ float cl;
memset(&m, 0, sizeof(m));
m.blendfunc1 = GL_ONE;
m.blendfunc2 = GL_ZERO;
m.tex[0] = R_GetTexture(surf->currenttexture->texture);
+ m.matrix = ent->matrix;
for (mesh = surf->mesh;mesh;mesh = mesh->chain)
{
m.numtriangles = mesh->numtriangles;
m.numverts = mesh->numverts;
-
if (R_Mesh_Draw_GetBuffer(&m, false))
{
- cl = (float) (1 << lightscalebit) * m.colorscale;
memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
- for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2)
- {
- softwaretransform(v->v, outv);
- outv[3] = 1;
- outc[0] = outc[1] = outc[2] = cl;
- outc[3] = 1;
- outst[0] = v->st[0];
- outst[1] = v->st[1];
- }
+ RSurf_CopyXYZ(mesh->vertex, m.vertex, m.numverts);
+ cl = m.colorscale;
+ R_FillColors(m.color, m.numverts, cl, cl, cl, 1);
+ RSurf_CopyST(mesh->vertex, m.texcoords[0], m.numverts);
R_Mesh_Render();
}
}
}
-static void RSurfShader_OpaqueWall_Pass_BaseLightmap(entity_render_t *ent, msurface_t *surf)
+static void RSurfShader_OpaqueWall_Pass_BaseLightmap(const entity_render_t *ent, const msurface_t *surf)
{
- int i;
- surfvertex_t *v;
- float *outv, *outc, *outuv, cl;
surfmesh_t *mesh;
rmeshbufferinfo_t m;
+ float cl;
memset(&m, 0, sizeof(m));
m.blendfunc1 = GL_ZERO;
m.blendfunc2 = GL_SRC_COLOR;
m.tex[0] = R_GetTexture(surf->lightmaptexture);
+ m.matrix = ent->matrix;
for (mesh = surf->mesh;mesh;mesh = mesh->chain)
{
m.numtriangles = mesh->numtriangles;
m.numverts = mesh->numverts;
-
if (R_Mesh_Draw_GetBuffer(&m, true))
{
- cl = (float) (1 << lightscalebit) * m.colorscale;
memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
- for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outuv = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outuv += 2)
- {
- softwaretransform(v->v, outv);
- outv[3] = 1;
- outc[0] = outc[1] = outc[2] = cl;
- outc[3] = 1;
- outuv[0] = v->uv[0];
- outuv[1] = v->uv[1];
- }
+ RSurf_CopyXYZ(mesh->vertex, m.vertex, m.numverts);
+ cl = (float) (1 << lightscalebit) * m.colorscale;
+ R_FillColors(m.color, m.numverts, cl, cl, cl, 1);
+ RSurf_CopyUV(mesh->vertex, m.texcoords[0], m.numverts);
R_Mesh_Render();
}
}
}
-static void RSurfShader_OpaqueWall_Pass_Light(entity_render_t *ent, msurface_t *surf)
+static void RSurfShader_OpaqueWall_Pass_Light(const entity_render_t *ent, const msurface_t *surf)
{
- int i;
- surfvertex_t *v;
- float *outv, *outc, *outst, cl;
surfmesh_t *mesh;
rmeshbufferinfo_t m;
m.blendfunc1 = GL_SRC_ALPHA;
m.blendfunc2 = GL_ONE;
m.tex[0] = R_GetTexture(surf->currenttexture->texture);
+ m.matrix = ent->matrix;
for (mesh = surf->mesh;mesh;mesh = mesh->chain)
{
if (RSurf_LightCheck(surf->dlightbits, mesh))
{
m.numtriangles = mesh->numtriangles;
m.numverts = mesh->numverts;
-
if (R_Mesh_Draw_GetBuffer(&m, true))
{
- cl = m.colorscale;
memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
- for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2)
- {
- softwaretransform(v->v, outv);
- outv[3] = 1;
- VectorClear(outc);
- outc[3] = 1;
- outst[0] = v->st[0];
- outst[1] = v->st[1];
- }
- RSurf_LightSeparate(surf->dlightbits, m.numverts, m.vertex, m.color);
- if (cl != 1)
- for (i = 0, outc = m.color;i < m.numverts;i++, outc += 4)
- VectorScale(outc, cl, outc);
+ RSurf_CopyXYZ(mesh->vertex, m.vertex, m.numverts);
+ RSurf_CopyST(mesh->vertex, m.texcoords[0], m.numverts);
+ R_FillColors(m.color, m.numverts, 0, 0, 0, 1);
+ RSurf_LightSeparate(&ent->inversematrix, surf->dlightbits, m.numverts, m.vertex, m.color);
+ RSurf_ScaleColors(m.color, m.colorscale, m.numverts);
R_Mesh_Render();
}
}
}
}
-static void RSurfShader_OpaqueWall_Pass_Fog(entity_render_t *ent, msurface_t *surf)
+static void RSurfShader_OpaqueWall_Pass_Fog(const entity_render_t *ent, const msurface_t *surf)
{
- int i;
- surfvertex_t *v;
- float *outv, *outc, cl, diff[3], fcolor[3];
surfmesh_t *mesh;
rmeshbufferinfo_t m;
+ float modelorg[3];
+ Matrix4x4_Transform(&ent->inversematrix, r_origin, modelorg);
memset(&m, 0, sizeof(m));
m.blendfunc1 = GL_SRC_ALPHA;
m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
+ m.tex[0] = R_GetTexture(surf->currenttexture->fogtexture);
+ m.matrix = ent->matrix;
for (mesh = surf->mesh;mesh;mesh = mesh->chain)
{
m.numtriangles = mesh->numtriangles;
m.numverts = mesh->numverts;
-
if (R_Mesh_Draw_GetBuffer(&m, false))
{
- cl = m.colorscale;
- VectorScale(fogcolor, cl, fcolor);
memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
- for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color;i < m.numverts;i++, v++, outv += 4, outc += 4)
- {
- softwaretransform(v->v, outv);
- outv[3] = 1;
- VectorCopy(fcolor, outc);
- VectorSubtract(outv, r_origin, diff);
- outc[3] = exp(fogdensity/DotProduct(diff, diff));
- }
+ RSurf_CopyXYZ(mesh->vertex, m.vertex, m.numverts);
+ if (m.tex[0])
+ RSurf_CopyST(mesh->vertex, m.texcoords[0], m.numverts);
+ RSurf_FogPassColors(m.vertex, m.color, fogcolor[0], fogcolor[1], fogcolor[2], 1, m.colorscale, m.numverts, modelorg);
R_Mesh_Render();
}
}
}
-static void RSurfShader_OpaqueWall_Pass_BaseDetail(entity_render_t *ent, msurface_t *surf)
+static void RSurfShader_OpaqueWall_Pass_BaseDetail(const entity_render_t *ent, const msurface_t *surf)
{
- int i;
- surfvertex_t *v;
- float *outv, *outc, *outst;
surfmesh_t *mesh;
rmeshbufferinfo_t m;
memset(&m, 0, sizeof(m));
m.blendfunc1 = GL_DST_COLOR;
m.blendfunc2 = GL_SRC_COLOR;
m.tex[0] = R_GetTexture(surf->currenttexture->detailtexture);
+ m.matrix = ent->matrix;
for (mesh = surf->mesh;mesh;mesh = mesh->chain)
{
m.numtriangles = mesh->numtriangles;
m.numverts = mesh->numverts;
-
if (R_Mesh_Draw_GetBuffer(&m, false))
{
memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
- for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2)
- {
- softwaretransform(v->v, outv);
- outv[3] = 1;
- outc[0] = outc[1] = outc[2] = outc[3] = 1;
- outst[0] = v->ab[0];
- outst[1] = v->ab[1];
- }
+ RSurf_CopyXYZ(mesh->vertex, m.vertex, m.numverts);
+ R_FillColors(m.color, m.numverts, 1, 1, 1, 1);
+ RSurf_CopyAB(mesh->vertex, m.texcoords[0], m.numverts);
R_Mesh_Render();
}
}
}
-static void RSurfShader_OpaqueWall_Pass_Glow(entity_render_t *ent, msurface_t *surf)
+static void RSurfShader_OpaqueWall_Pass_Glow(const entity_render_t *ent, const msurface_t *surf)
{
- int i;
- surfvertex_t *v;
- float *outv, *outc, *outst, cl;
surfmesh_t *mesh;
rmeshbufferinfo_t m;
memset(&m, 0, sizeof(m));
m.blendfunc1 = GL_SRC_ALPHA;
m.blendfunc2 = GL_ONE;
m.tex[0] = R_GetTexture(surf->currenttexture->glowtexture);
+ m.matrix = ent->matrix;
for (mesh = surf->mesh;mesh;mesh = mesh->chain)
{
m.numtriangles = mesh->numtriangles;
m.numverts = mesh->numverts;
-
if (R_Mesh_Draw_GetBuffer(&m, false))
{
- cl = m.colorscale;
memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
- for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2)
- {
- softwaretransform(v->v, outv);
- outv[3] = 1;
- outc[0] = outc[1] = outc[2] = cl;
- outc[3] = 1;
- outst[0] = v->st[0];
- outst[1] = v->st[1];
- }
+ RSurf_CopyXYZ(mesh->vertex, m.vertex, m.numverts);
+ R_FillColors(m.color, m.numverts, m.colorscale, m.colorscale, m.colorscale, 1);
+ RSurf_CopyAB(mesh->vertex, m.texcoords[0], m.numverts);
R_Mesh_Render();
}
}
}
-static void RSurfShader_Wall_Fullbright(entity_render_t *ent, msurface_t *firstsurf)
+static void RSurfShader_Wall_Fullbright(const entity_render_t *ent, const msurface_t *firstsurf)
{
- msurface_t *surf;
+ const msurface_t *surf;
for (surf = firstsurf;surf;surf = surf->chain)
{
c_brush_polys++;
RSurfShader_Wall_Pass_Fog(ent, surf);
}
-static void RSurfShader_Wall_Vertex(entity_render_t *ent, msurface_t *firstsurf)
+static void RSurfShader_Wall_Vertex(const entity_render_t *ent, const msurface_t *firstsurf)
{
- msurface_t *surf;
+ const msurface_t *surf;
for (surf = firstsurf;surf;surf = surf->chain)
{
c_brush_polys++;
RSurfShader_Wall_Pass_Fog(ent, surf);
}
-static void RSurfShader_Wall_Lightmap(entity_render_t *ent, msurface_t *firstsurf)
+static void RSurfShader_Wall_Lightmap(const entity_render_t *ent, const msurface_t *firstsurf)
{
- msurface_t *surf;
+ const msurface_t *surf;
if (r_vertexsurfaces.integer || firstsurf->currenttexture->fogtexture != NULL || ent->alpha != 1 || ent->effects & EF_ADDITIVE)
{
for (surf = firstsurf;surf;surf = surf->chain)
m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
m.numverts = portal->numpoints;
m.numtriangles = portal->numpoints - 2;
+ Matrix4x4_CreateIdentity(&m.matrix);
if (R_Mesh_Draw_GetBuffer(&m, false))
{
for (i = 0;i < m.numtriangles;i++)
model = ent->model;
- softwaretransformforentity (ent);
- softwareuntransform(r_origin, modelorg);
-
+ Matrix4x4_Transform(&ent->inversematrix, r_origin, modelorg);
for (i = 0;i < model->nummodelsurfaces;i++)
{
surf = model->modelsortedsurfaces[i];
{
// there is only one instance of the world, but it can be rendered in
// multiple stages
- softwaretransformidentity();
}
static void R_SurfMarkLights (entity_render_t *ent)
#include "matrixlib.h"
#include <math.h>
-void Matrix4x4_Copy (matrix4x4_t *out, matrix4x4_t *in)
+void Matrix4x4_Copy (matrix4x4_t *out, const matrix4x4_t *in)
{
*out = *in;
}
-void Matrix4x4_CopyRotateOnly (matrix4x4_t *out, matrix4x4_t *in)
+void Matrix4x4_CopyRotateOnly (matrix4x4_t *out, const matrix4x4_t *in)
{
out->m[0][0] = in->m[0][0];
out->m[0][1] = in->m[0][1];
out->m[3][3] = 1.0f;
}
-void Matrix4x4_CopyTranslateOnly (matrix4x4_t *out, matrix4x4_t *in)
+void Matrix4x4_CopyTranslateOnly (matrix4x4_t *out, const matrix4x4_t *in)
{
out->m[0][0] = 0.0f;
out->m[0][1] = 0.0f;
out->m[3][3] = 1.0f;
}
-void Matrix4x4_FromMatrix3x4 (matrix4x4_t *out, matrix3x4_t *in)
+void Matrix4x4_FromMatrix3x4 (matrix4x4_t *out, const matrix3x4_t *in)
{
out->m[0][0] = in->m[0][0];
out->m[0][1] = in->m[0][1];
void Matrix4x4_Transpose (matrix4x4_t *out, const matrix4x4_t *in1)
{
- float scale;
- scale = 3.0 / (in1->m[0][0] * in1->m[0][0]
- + in1->m[0][1] * in1->m[0][1]
- + in1->m[0][2] * in1->m[0][2]
- + in1->m[1][0] * in1->m[1][0]
- + in1->m[1][1] * in1->m[1][1]
- + in1->m[1][2] * in1->m[1][2]
- + in1->m[2][0] * in1->m[2][0]
- + in1->m[2][1] * in1->m[2][1]
- + in1->m[2][2] * in1->m[2][2]);
+ out->m[0][0] = in1->m[0][0];
+ out->m[0][1] = in1->m[1][0];
+ out->m[0][2] = in1->m[2][0];
+ out->m[0][3] = in1->m[3][0];
+ out->m[1][0] = in1->m[0][1];
+ out->m[1][1] = in1->m[1][1];
+ out->m[1][2] = in1->m[2][1];
+ out->m[1][3] = in1->m[3][1];
+ out->m[2][0] = in1->m[0][2];
+ out->m[2][1] = in1->m[1][2];
+ out->m[2][2] = in1->m[2][2];
+ out->m[2][3] = in1->m[3][2];
+ out->m[3][0] = in1->m[0][3];
+ out->m[3][1] = in1->m[1][3];
+ out->m[3][2] = in1->m[2][3];
+ out->m[3][3] = in1->m[3][3];
+}
+
+void Matrix4x4_Transpose3x3 (matrix4x4_t *out, const matrix4x4_t *in1)
+{
+ out->m[0][0] = in1->m[0][0];
+ out->m[0][1] = in1->m[1][0];
+ out->m[0][2] = in1->m[2][0];
+ out->m[1][0] = in1->m[0][1];
+ out->m[1][1] = in1->m[1][1];
+ out->m[1][2] = in1->m[2][1];
+ out->m[2][0] = in1->m[0][2];
+ out->m[2][1] = in1->m[1][2];
+ out->m[2][2] = in1->m[2][2];
+
+ out->m[0][3] = in1->m[0][3];
+ out->m[1][3] = in1->m[1][3];
+ out->m[2][3] = in1->m[2][3];
+ out->m[3][0] = in1->m[0][3];
+ out->m[3][1] = in1->m[1][3];
+ out->m[3][2] = in1->m[2][3];
+ out->m[3][3] = in1->m[3][3];
+}
+
+void Matrix4x4_Invert_Simple (matrix4x4_t *out, const matrix4x4_t *in1)
+{
+ // we only support uniform scaling, so assume the first row is enough
+ // (note the lack of sqrt here, because we're trying to undo the scaling,
+ // this means multiplying by the inverse scale twice - squaring it, which
+ // makes the sqrt a waste of time)
+ double scale = 1.0 / (in1->m[0][0] * in1->m[0][0] + in1->m[0][1] * in1->m[0][1] + in1->m[0][2] * in1->m[0][2]);
+
+ // invert the rotation by transposing and multiplying by the squared
+ // recipricol of the input matrix scale as described above
out->m[0][0] = in1->m[0][0] * scale;
out->m[0][1] = in1->m[1][0] * scale;
out->m[0][2] = in1->m[2][0] * scale;
- out->m[0][3] = in1->m[3][0];
out->m[1][0] = in1->m[0][1] * scale;
out->m[1][1] = in1->m[1][1] * scale;
out->m[1][2] = in1->m[2][1] * scale;
- out->m[1][3] = in1->m[3][1];
out->m[2][0] = in1->m[0][2] * scale;
out->m[2][1] = in1->m[1][2] * scale;
out->m[2][2] = in1->m[2][2] * scale;
- out->m[2][3] = in1->m[3][2];
- out->m[3][0] = in1->m[0][3];
- out->m[3][1] = in1->m[1][3];
- out->m[3][2] = in1->m[2][3];
- out->m[3][3] = in1->m[3][3];
+
+ // invert the translate
+ out->m[0][3] = -(in1->m[0][3] * out->m[0][0] + in1->m[1][3] * out->m[0][1] + in1->m[2][3] * out->m[0][2]);
+ out->m[1][3] = -(in1->m[0][3] * out->m[1][0] + in1->m[1][3] * out->m[1][1] + in1->m[2][3] * out->m[1][2]);
+ out->m[2][3] = -(in1->m[0][3] * out->m[2][0] + in1->m[1][3] * out->m[2][1] + in1->m[2][3] * out->m[2][2]);
+
+ // don't know if there's anything worth doing here
+ out->m[3][0] = 0;
+ out->m[3][1] = 0;
+ out->m[3][2] = 0;
+ out->m[3][3] = 1;
}
void Matrix4x4_CreateIdentity (matrix4x4_t *out)
out->m[3][3]=1.0f;
}
+void Matrix4x4_CreateFromQuakeEntity(matrix4x4_t *out, float x, float y, float z, float pitch, float yaw, float roll, float scale)
+{
+ double angle, sr, sp, sy, cr, cp, cy;
+
+ angle = yaw * (M_PI*2 / 360);
+ sy = sin(angle);
+ cy = cos(angle);
+ angle = pitch * (M_PI*2 / 360);
+ sp = sin(angle);
+ cp = cos(angle);
+ angle = roll * (M_PI*2 / 360);
+ sr = sin(angle);
+ cr = cos(angle);
+ out->m[0][0] = cp*cy * scale;
+ out->m[0][1] = sr*sp*cy+cr*-sy * scale;
+ out->m[0][2] = cr*sp*cy+-sr*-sy * scale;
+ out->m[0][3] = x;
+ out->m[1][0] = cp*sy * scale;
+ out->m[1][1] = sr*sp*sy+cr*cy * scale;
+ out->m[1][2] = cr*sp*sy+-sr*cy * scale;
+ out->m[1][3] = y;
+ out->m[2][0] = -sp * scale;
+ out->m[2][1] = sr*cp * scale;
+ out->m[2][2] = cr*cp * scale;
+ out->m[2][3] = z;
+ out->m[3][0] = 0;
+ out->m[3][1] = 0;
+ out->m[3][2] = 0;
+ out->m[3][3] = 1;
+}
+
void Matrix4x4_ToVectors(const matrix4x4_t *in, float vx[3], float vy[3], float vz[3], float t[3])
{
vx[0] = in->m[0][0];
out[3] = v[0] * in->m[3][0] + v[1] * in->m[3][1] + v[2] * in->m[3][2] + v[3] * in->m[3][3];
}
+/*
void Matrix4x4_SimpleUntransform (const matrix4x4_t *in, const float v[3], float out[3])
{
float t[3];
out[1] = t[0] * in->m[0][1] + t[1] * in->m[1][1] + t[2] * in->m[2][1];
out[2] = t[0] * in->m[0][2] + t[1] * in->m[1][2] + t[2] * in->m[2][2];
}
+*/
// FIXME: optimize
void Matrix4x4_ConcatTranslate (matrix4x4_t *out, float x, float y, float z)
-void Matrix3x4_Copy (matrix3x4_t *out, matrix3x4_t *in)
+void Matrix3x4_Copy (matrix3x4_t *out, const matrix3x4_t *in)
{
*out = *in;
}
-void Matrix3x4_CopyRotateOnly (matrix3x4_t *out, matrix3x4_t *in)
+void Matrix3x4_CopyRotateOnly (matrix3x4_t *out, const matrix3x4_t *in)
{
out->m[0][0] = in->m[0][0];
out->m[0][1] = in->m[0][1];
out->m[2][3] = 0.0f;
}
-void Matrix3x4_CopyTranslateOnly (matrix3x4_t *out, matrix3x4_t *in)
+void Matrix3x4_CopyTranslateOnly (matrix3x4_t *out, const matrix3x4_t *in)
{
out->m[0][0] = 0.0f;
out->m[0][1] = 0.0f;
out->m[2][3] = in->m[0][3];
}
-void Matrix3x4_FromMatrix4x4 (matrix3x4_t *out, matrix4x4_t *in)
+void Matrix3x4_FromMatrix4x4 (matrix3x4_t *out, const matrix4x4_t *in)
{
out->m[0][0] = in->m[0][0];
out->m[0][1] = in->m[0][1];
void Matrix3x4_Transpose3x3 (matrix3x4_t *out, const matrix3x4_t *in1)
{
- float scale;
- scale = 3.0 / (in1->m[0][0] * in1->m[0][0]
- + in1->m[0][1] * in1->m[0][1]
- + in1->m[0][2] * in1->m[0][2]
- + in1->m[1][0] * in1->m[1][0]
- + in1->m[1][1] * in1->m[1][1]
- + in1->m[1][2] * in1->m[1][2]
- + in1->m[2][0] * in1->m[2][0]
- + in1->m[2][1] * in1->m[2][1]
- + in1->m[2][2] * in1->m[2][2]);
+ out->m[0][0] = in1->m[0][0];
+ out->m[0][1] = in1->m[1][0];
+ out->m[0][2] = in1->m[2][0];
+ out->m[0][3] = 0.0f;
+ out->m[1][0] = in1->m[0][1];
+ out->m[1][1] = in1->m[1][1];
+ out->m[1][2] = in1->m[2][1];
+ out->m[1][3] = 0.0f;
+ out->m[2][0] = in1->m[0][2];
+ out->m[2][1] = in1->m[1][2];
+ out->m[2][2] = in1->m[2][2];
+ out->m[2][3] = 0.0f;
+}
+
+void Matrix3x4_Invert_Simple (matrix3x4_t *out, const matrix3x4_t *in1)
+{
+ // we only support uniform scaling, so assume the first row is enough
+ // (note the lack of sqrt here, because we're trying to undo the scaling,
+ // this means multiplying by the inverse scale twice - squaring it, which
+ // makes the sqrt a waste of time)
+ double scale = 1.0 / (in1->m[0][0] * in1->m[0][0] + in1->m[0][1] * in1->m[0][1] + in1->m[0][2] * in1->m[0][2]);
+
+ // invert the rotation by transposing and multiplying by the squared
+ // recipricol of the input matrix scale as described above
out->m[0][0] = in1->m[0][0] * scale;
out->m[0][1] = in1->m[1][0] * scale;
out->m[0][2] = in1->m[2][0] * scale;
- out->m[0][3] = 0.0f;
out->m[1][0] = in1->m[0][1] * scale;
out->m[1][1] = in1->m[1][1] * scale;
out->m[1][2] = in1->m[2][1] * scale;
- out->m[1][3] = 0.0f;
out->m[2][0] = in1->m[0][2] * scale;
out->m[2][1] = in1->m[1][2] * scale;
out->m[2][2] = in1->m[2][2] * scale;
- out->m[2][3] = 0.0f;
+
+ // invert the translate
+ out->m[0][3] = -(in1->m[0][3] * out->m[0][0] + in1->m[1][3] * out->m[0][1] + in1->m[2][3] * out->m[0][2]);
+ out->m[1][3] = -(in1->m[0][3] * out->m[1][0] + in1->m[1][3] * out->m[1][1] + in1->m[2][3] * out->m[1][2]);
+ out->m[2][3] = -(in1->m[0][3] * out->m[2][0] + in1->m[1][3] * out->m[2][1] + in1->m[2][3] * out->m[2][2]);
}
+
void Matrix3x4_CreateIdentity (matrix3x4_t *out)
{
out->m[0][0]=1.0f;
out->m[2][3]=0.0f;
}
+void Matrix3x4_CreateFromQuakeEntity(matrix3x4_t *out, float x, float y, float z, float pitch, float yaw, float roll, float scale)
+{
+ double angle, sr, sp, sy, cr, cp, cy;
+
+ angle = yaw * (M_PI*2 / 360);
+ sy = sin(angle);
+ cy = cos(angle);
+ angle = pitch * (M_PI*2 / 360);
+ sp = sin(angle);
+ cp = cos(angle);
+ angle = roll * (M_PI*2 / 360);
+ sr = sin(angle);
+ cr = cos(angle);
+ out->m[0][0] = cp*cy * scale;
+ out->m[0][1] = sr*sp*cy+cr*-sy * scale;
+ out->m[0][2] = cr*sp*cy+-sr*-sy * scale;
+ out->m[0][3] = x;
+ out->m[1][0] = cp*sy * scale;
+ out->m[1][1] = sr*sp*sy+cr*cy * scale;
+ out->m[1][2] = cr*sp*sy+-sr*cy * scale;
+ out->m[1][3] = y;
+ out->m[2][0] = -sp * scale;
+ out->m[2][1] = sr*cp * scale;
+ out->m[2][2] = cr*cp * scale;
+ out->m[2][3] = z;
+}
+
void Matrix3x4_ToVectors(const matrix3x4_t *in, float vx[3], float vy[3], float vz[3], float t[3])
{
vx[0] = in->m[0][0];
// functions for manipulating 4x4 matrices
// copy a matrix4x4
-void Matrix4x4_Copy (matrix4x4_t *out, matrix4x4_t *in);
+void Matrix4x4_Copy (matrix4x4_t *out, const matrix4x4_t *in);
// copy only the rotation portion of a matrix4x4
-void Matrix4x4_CopyRotateOnly (matrix4x4_t *out, matrix4x4_t *in);
+void Matrix4x4_CopyRotateOnly (matrix4x4_t *out, const matrix4x4_t *in);
// copy only the translate portion of a matrix4x4
-void Matrix4x4_CopyTranslateOnly (matrix4x4_t *out, matrix4x4_t *in);
+void Matrix4x4_CopyTranslateOnly (matrix4x4_t *out, const matrix4x4_t *in);
// make a matrix4x4 from a matrix3x4
-void Matrix4x4_FromMatrix3x4 (matrix4x4_t *out, matrix3x4_t *in);
+void Matrix4x4_FromMatrix3x4 (matrix4x4_t *out, const matrix3x4_t *in);
// multiply two matrix4x4 together, combining their transformations
// (warning: order matters - Concat(a, b, c) != Concat(a, c, b))
void Matrix4x4_Concat (matrix4x4_t *out, const matrix4x4_t *in1, const matrix4x4_t *in2);
-// swaps the rows and columns of the matrix4x4 and attempts to undo uniform
-// scaling (Scale, not Scale3), resulting in a matrix that will do the opposite
-// (warning: this only inverts rotation, uniform scaling and translation,
-// do not use with shearing, Scale3, or other complex matrices)
+// swaps the rows and columns of the matrix
+// (is this useful for anything?)
void Matrix4x4_Transpose (matrix4x4_t *out, const matrix4x4_t *in1);
+// swaps the rows and columns of the rotation matrix
+// (inverting the rotation, but leaving everything else the same)
+void Matrix4x4_Transpose3x3 (matrix4x4_t *out, const matrix4x4_t *in1);
+// creates a matrix that does the opposite of the matrix provided
+// only supports translate, rotate, scale (not scale3) matrices
+void Matrix4x4_Invert_Simple (matrix4x4_t *out, const matrix4x4_t *in1);
// creates an identity matrix
// (a matrix which does nothing)
void Matrix4x4_CreateRotate (matrix4x4_t *out, float angle, float x, float y, float z);
// creates a scaling matrix
// (expands or contracts vectors)
-// (warning: this is not reversed by Transpose)
+// (warning: do not apply this kind of matrix to direction vectors)
void Matrix4x4_CreateScale (matrix4x4_t *out, float x);
// creates a squishing matrix
// (expands or contracts vectors differently in different axis)
-// (warning: this is not reversed by Transpose)
+// (warning: this is not reversed by Invert_Simple)
// (warning: do not apply this kind of matrix to direction vectors)
void Matrix4x4_CreateScale3 (matrix4x4_t *out, float x, float y, float z);
+// creates a matrix for a quake entity
+void Matrix4x4_CreateFromQuakeEntity(matrix4x4_t *out, float x, float y, float z, float pitch, float yaw, float roll, float scale);
// converts a matrix4x4 to a set of 3D vectors for the 3 axial directions, and the translate
void Matrix4x4_ToVectors(const matrix4x4_t *in, float vx[3], float vy[3], float vz[3], float t[3]);
// reverse transforms a 3D vector through a matrix4x4, at least for *simple*
// cases (rotation and translation *ONLY*), this attempts to undo the results
// of Transform
-void Matrix4x4_SimpleUntransform (const matrix4x4_t *in, const float v[3], float out[3]);
+//void Matrix4x4_SimpleUntransform (const matrix4x4_t *in, const float v[3], float out[3]);
// ease of use functions
// immediately applies a Translate to the matrix
// functions for manipulating 3x4 matrices
// copy a matrix3x4
-void Matrix3x4_Copy (matrix3x4_t *out, matrix3x4_t *in);
+void Matrix3x4_Copy (matrix3x4_t *out, const matrix3x4_t *in);
// copy only the rotation portion of a matrix3x4
-void Matrix3x4_CopyRotateOnly (matrix3x4_t *out, matrix3x4_t *in);
+void Matrix3x4_CopyRotateOnly (matrix3x4_t *out, const matrix3x4_t *in);
// copy only the translate portion of a matrix3x4
-void Matrix3x4_CopyTranslateOnly (matrix3x4_t *out, matrix3x4_t *in);
+void Matrix3x4_CopyTranslateOnly (matrix3x4_t *out, const matrix3x4_t *in);
// make a matrix3x4 from a matrix4x4
-void Matrix3x4_FromMatrix4x4 (matrix3x4_t *out, matrix4x4_t *in);
+void Matrix3x4_FromMatrix4x4 (matrix3x4_t *out, const matrix4x4_t *in);
// multiply two matrix3x4 together, combining their transformations
// (warning: order matters - Concat(a, b, c) != Concat(a, c, b))
void Matrix3x4_Concat (matrix3x4_t *out, const matrix3x4_t *in1, const matrix3x4_t *in2);
-// swaps the rows and columns of the rotation portion of the matrix, and
-// attempts to undo uniform scaling (Scale, not Scale3), resulting in a
-// matrix that will do the opposite
-// (warning: this only inverts rotation and uniform scaling, do not use with
-// translation, shearing, Scale3 or other complex matrices)
+// swaps the rows and columns of the rotation matrix
+// (inverting the rotation, but leaving everything else the same)
void Matrix3x4_Transpose3x3 (matrix3x4_t *out, const matrix3x4_t *in1);
+// creates a matrix that does the opposite of the matrix provided
+// only supports translate, rotate, scale (not scale3) matrices
+void Matrix3x4_Invert_Simple (matrix3x4_t *out, const matrix3x4_t *in1);
// creates an identity matrix
// (a matrix which does nothing)
void Matrix3x4_CreateRotate (matrix3x4_t *out, float angle, float x, float y, float z);
// creates a scaling matrix
// (expands or contracts vectors)
-// (warning: this is not reversed by Transpose)
+// (warning: do not apply this kind of matrix to direction vectors)
void Matrix3x4_CreateScale (matrix3x4_t *out, float x);
// creates a squishing matrix
// (expands or contracts vectors differently in different axis)
-// (warning: this is not reversed by Transpose)
+// (warning: this is not reversed by Invert_Simple)
// (warning: do not apply this kind of matrix to direction vectors)
void Matrix3x4_CreateScale3 (matrix3x4_t *out, float x, float y, float z);
+// creates a matrix for a quake entity
+void Matrix3x4_CreateFromQuakeEntity(matrix3x4_t *out, float x, float y, float z, float pitch, float yaw, float roll, float scale);
// converts a matrix3x4 to a set of 3D vectors for the 3 axial directions, and the translate
void Matrix3x4_ToVectors(const matrix3x4_t *in, float vx[3], float vy[3], float vz[3], float t[3]);
typedef struct meshqueue_s
{
struct meshqueue_s *next;
- void (*callback)(void *data1, int data2);
- void *data1;
+ void (*callback)(const void *data1, int data2);
+ const void *data1;
int data2;
float dist;
}
mqt_total = newtotal;
}
-void R_MeshQueue_Add(void (*callback)(void *data1, int data2), void *data1, int data2)
+void R_MeshQueue_Add(void (*callback)(const void *data1, int data2), const void *data1, int data2)
{
meshqueue_t *mq, **mqnext;
if (r_meshqueue_immediaterender.integer)
*mqnext = mq;
}
-void R_MeshQueue_AddTransparent(vec3_t center, void (*callback)(void *data1, int data2), void *data1, int data2)
+void R_MeshQueue_AddTransparent(const vec3_t center, void (*callback)(const void *data1, int data2), const void *data1, int data2)
{
meshqueue_t *mq;
if (mqt_count >= mqt_total)
#define MESHQUEUE_H
void R_MeshQueue_Init(void);
-void R_MeshQueue_Add(void (*callback)(void *data1, int data2), void *data1, int data2);
-void R_MeshQueue_AddTransparent(vec3_t center, void (*callback)(void *data1, int data2), void *data1, int data2);
+void R_MeshQueue_Add(void (*callback)(const void *data1, int data2), const void *data1, int data2);
+void R_MeshQueue_AddTransparent(const vec3_t center, void (*callback)(const void *data1, int data2), const void *data1, int data2);
void R_MeshQueue_BeginScene(void);
void R_MeshQueue_Render(void);
void R_MeshQueue_RenderTransparent(void);
Mod_PointInLeaf
===============
*/
-mleaf_t *Mod_PointInLeaf (vec3_t p, model_t *model)
+mleaf_t *Mod_PointInLeaf (const vec3_t p, model_t *model)
{
mnode_t *node;
// change this stuff when real shaders are added
typedef struct Cshader_s
{
- void (*shaderfunc[SHADERSTAGE_COUNT])(struct entity_render_s *ent, msurface_t *firstsurf);
+ void (*shaderfunc[SHADERSTAGE_COUNT])(const struct entity_render_s *ent, const msurface_t *firstsurf);
// list of surfaces using this shader (used during surface rendering)
msurface_t *chain;
}
void Mod_TouchModel (char *name);
void Mod_UnloadModel (model_t *mod);
-mleaf_t *Mod_PointInLeaf (float *p, model_t *model);
+mleaf_t *Mod_PointInLeaf (const float *p, model_t *model);
qbyte *Mod_LeafPVS (mleaf_t *leaf, model_t *model);
void Mod_ClearUsed(void);
m.numtriangles = 2;
m.numverts = 4;
m.tex[0] = R_GetTexture(texture);
+ Matrix4x4_CreateIdentity(&m.matrix);
if (R_Mesh_Draw_GetBuffer(&m, false))
{
m.index[0] = 0;
}
}
-void R_DrawExplosionCallback(void *calldata1, int calldata2)
+void R_DrawExplosionCallback(const void *calldata1, int calldata2)
{
int i;
float *c, *v, diff[3], centerdir[3], ifog, alpha, dist;
rmeshbufferinfo_t m;
- explosion_t *e;
+ const explosion_t *e;
e = calldata1;
memset(&m, 0, sizeof(m));
m.numtriangles = EXPLOSIONTRIS;
m.numverts = EXPLOSIONVERTS;
m.tex[0] = R_GetTexture(explosiontexture);
+ Matrix4x4_CreateIdentity(&m.matrix);
if (R_Mesh_Draw_GetBuffer(&m, false))
{
memcpy(m.index, explosiontris, m.numtriangles * sizeof(int[3]));
cvar_t r_modellights = {CVAR_SAVE, "r_modellights", "4"};
cvar_t r_vismarklights = {0, "r_vismarklights", "1"};
+cvar_t r_coronas = {CVAR_SAVE, "r_coronas", "1"};
+cvar_t gl_flashblend = {CVAR_SAVE, "gl_flashblend", "1"};
static rtexture_t *lightcorona;
static rtexturepool_t *lighttexturepool;
{
Cvar_RegisterVariable(&r_modellights);
Cvar_RegisterVariable(&r_vismarklights);
+ Cvar_RegisterVariable(&r_coronas);
+ Cvar_RegisterVariable(&gl_flashblend);
R_RegisterModule("R_Light", r_light_start, r_light_shutdown, r_light_newmap);
}
rd->cullradius = sqrt(rd->cullradius2);
rd->subtract = 1.0f / rd->cullradius2;
//rd->ent = cd->ent;
- r_numdlights++;
c_dlights++; // count every dlight in use
}
}
rmeshbufferinfo_t m;
float scale, viewdist, diff[3], dist;
rdlight_t *rd;
+ if (!r_coronas.integer)
+ return;
memset(&m, 0, sizeof(m));
m.blendfunc1 = GL_ONE;
m.blendfunc2 = GL_ONE;
dist = (DotProduct(rd->origin, vpn) - viewdist);
if (dist >= 24.0f)
{
- // trace to a point just barely closer to the eye
- VectorSubtract(rd->origin, vpn, diff);
- if (CL_TraceLine(r_origin, diff, NULL, NULL, 0, true) == 1 && R_Mesh_Draw_GetBuffer(&m, false))
+ if (CL_TraceLine(rd->origin, r_origin, NULL, NULL, 0, true) == 1)
{
- scale = m.colorscale * (1.0f / 131072.0f);
- if (fogenabled)
+ Matrix4x4_CreateIdentity(&m.matrix);
+ if (R_Mesh_Draw_GetBuffer(&m, false))
{
- VectorSubtract(rd->origin, r_origin, diff);
- scale *= 1 - exp(fogdensity/DotProduct(diff,diff));
+ scale = m.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));
+ }
+ m.index[0] = 0;
+ m.index[1] = 1;
+ m.index[2] = 2;
+ m.index[3] = 0;
+ m.index[4] = 2;
+ m.index[5] = 3;
+ m.color[0] = m.color[4] = m.color[8] = m.color[12] = rd->light[0] * scale;
+ m.color[1] = m.color[5] = m.color[9] = m.color[13] = rd->light[1] * scale;
+ m.color[2] = m.color[6] = m.color[10] = m.color[14] = rd->light[2] * scale;
+ m.color[3] = m.color[7] = m.color[11] = m.color[15] = 1;
+ m.texcoords[0][0] = 0;
+ m.texcoords[0][1] = 0;
+ m.texcoords[0][2] = 0;
+ m.texcoords[0][3] = 1;
+ m.texcoords[0][4] = 1;
+ m.texcoords[0][5] = 1;
+ m.texcoords[0][6] = 1;
+ m.texcoords[0][7] = 0;
+ scale = rd->cullradius * 0.25f;
+ if (gl_flashblend.integer)
+ scale *= 2.0f;
+ m.vertex[0] = rd->origin[0] - vright[0] * scale - vup[0] * scale;
+ m.vertex[1] = rd->origin[1] - vright[1] * scale - vup[1] * scale;
+ m.vertex[2] = rd->origin[2] - vright[2] * scale - vup[2] * scale;
+ m.vertex[4] = rd->origin[0] - vright[0] * scale + vup[0] * scale;
+ m.vertex[5] = rd->origin[1] - vright[1] * scale + vup[1] * scale;
+ m.vertex[6] = rd->origin[2] - vright[2] * scale + vup[2] * scale;
+ m.vertex[8] = rd->origin[0] + vright[0] * scale + vup[0] * scale;
+ m.vertex[9] = rd->origin[1] + vright[1] * scale + vup[1] * scale;
+ m.vertex[10] = rd->origin[2] + vright[2] * scale + vup[2] * scale;
+ m.vertex[12] = rd->origin[0] + vright[0] * scale - vup[0] * scale;
+ m.vertex[13] = rd->origin[1] + vright[1] * scale - vup[1] * scale;
+ m.vertex[14] = rd->origin[2] + vright[2] * scale - vup[2] * scale;
+ R_Mesh_Render();
}
- m.index[0] = 0;
- m.index[1] = 1;
- m.index[2] = 2;
- m.index[3] = 0;
- m.index[4] = 2;
- m.index[5] = 3;
- m.color[0] = m.color[4] = m.color[8] = m.color[12] = rd->light[0] * scale;
- m.color[1] = m.color[5] = m.color[9] = m.color[13] = rd->light[1] * scale;
- m.color[2] = m.color[6] = m.color[10] = m.color[14] = rd->light[2] * scale;
- m.color[3] = m.color[7] = m.color[11] = m.color[15] = 1;
- m.texcoords[0][0] = 0;
- m.texcoords[0][1] = 0;
- m.texcoords[0][2] = 0;
- m.texcoords[0][3] = 1;
- m.texcoords[0][4] = 1;
- m.texcoords[0][5] = 1;
- m.texcoords[0][6] = 1;
- m.texcoords[0][7] = 0;
- scale = rd->cullradius * 0.25f;
- m.vertex[0] = rd->origin[0] - vright[0] * scale - vup[0] * scale;
- m.vertex[1] = rd->origin[1] - vright[1] * scale - vup[1] * scale;
- m.vertex[2] = rd->origin[2] - vright[2] * scale - vup[2] * scale;
- m.vertex[4] = rd->origin[0] - vright[0] * scale + vup[0] * scale;
- m.vertex[5] = rd->origin[1] - vright[1] * scale + vup[1] * scale;
- m.vertex[6] = rd->origin[2] - vright[2] * scale + vup[2] * scale;
- m.vertex[8] = rd->origin[0] + vright[0] * scale + vup[0] * scale;
- m.vertex[9] = rd->origin[1] + vright[1] * scale + vup[1] * scale;
- m.vertex[10] = rd->origin[2] + vright[2] * scale + vup[2] * scale;
- m.vertex[12] = rd->origin[0] + vright[0] * scale - vup[0] * scale;
- m.vertex[13] = rd->origin[1] + vright[1] * scale - vup[1] * scale;
- m.vertex[14] = rd->origin[2] + vright[2] * scale - vup[2] * scale;
- R_Mesh_Render();
}
}
}
return;
model = ent->model;
- softwareuntransform(rd->origin, lightorigin);
+ //softwareuntransform(rd->origin, lightorigin);
+ Matrix4x4_Transform(&ent->inversematrix, rd->origin, lightorigin);
if (!r_vismarklights.integer)
{
void R_MarkLights(entity_render_t *ent)
{
int i;
- for (i = 0;i < r_numdlights;i++)
- R_VisMarkLights (ent, r_dlight + i, 1 << (i & 31), i >> 5);
+ if (!gl_flashblend.integer)
+ for (i = 0;i < r_numdlights;i++)
+ R_VisMarkLights (ent, r_dlight + i, 1 << (i & 31), i >> 5);
}
/*
=============================================================================
*/
-static int RecursiveLightPoint (vec3_t color, mnode_t *node, float x, float y, float startz, float endz)
+static int RecursiveLightPoint (vec3_t color, const mnode_t *node, float x, float y, float startz, float endz)
{
int side, distz = endz - startz;
float front, back;
}
}
-void R_CompleteLightPoint (vec3_t color, vec3_t p, int dynamic, mleaf_t *leaf)
+void R_CompleteLightPoint (vec3_t color, const vec3_t p, int dynamic, const mleaf_t *leaf)
{
- int i, *dlightbits;
+ int i;
+ const int *dlightbits;
vec3_t v;
float f;
rdlight_t *rd;
}
}
-void R_ModelLightPoint (entity_render_t *ent, vec3_t color, vec3_t p, int *dlightbits)
+void R_ModelLightPoint (const entity_render_t *ent, vec3_t color, const vec3_t p, int *dlightbits)
{
mleaf_t *leaf;
leaf = Mod_PointInLeaf(p, cl.worldmodel);
dlightbits[0] = dlightbits[1] = dlightbits[2] = dlightbits[3] = dlightbits[4] = dlightbits[5] = dlightbits[6] = dlightbits[7] = 0;
}
-void R_LightModel(entity_render_t *ent, int numverts, float colorr, float colorg, float colorb, int worldcoords)
+void R_LightModel(const entity_render_t *ent, int numverts, float colorr, float colorg, float colorb, int worldcoords)
{
int i, j, nearlights = 0, maxnearlights = r_modellights.integer;
float color[3], basecolor[3], v[3], t, *av, *avn, *avc, a, f, dist2, mscale, dot, stylescale, intensity, ambientcolor[3];
R_ModelLightPoint(ent, basecolor, ent->origin, modeldlightbits);
nl = &nearlight[0];
- VectorSubtract(ent->origin, ent->entlightsorigin, v);
- if ((realtime > ent->entlightstime && DotProduct(v,v) >= 1.0f))
- {
- ent->numentlights = 0;
- ent->entlightstime = realtime + 0.2;
- VectorCopy(ent->origin, ent->entlightsorigin);
- for (i = 0, sl = cl.worldmodel->lights;i < cl.worldmodel->numlights && ent->numentlights < MAXENTLIGHTS;i++, sl++)
- if (CL_TraceLine(ent->origin, sl->origin, NULL, NULL, 0, false) == 1)
- ent->entlights[ent->numentlights++] = i;
- }
for (i = 0;i < ent->numentlights;i++)
{
sl = cl.worldmodel->lights + ent->entlights[i];
if (worldcoords)
VectorCopy(sl->origin, nl->origin);
else
- softwareuntransform(sl->origin, nl->origin);
+ //softwareuntransform(sl->origin, nl->origin);
+ Matrix4x4_Transform(&ent->inversematrix, sl->origin, nl->origin);
// integrate mscale into falloff, for maximum speed
nl->falloff = sl->falloff * mscale;
VectorCopy(ambientcolor, nl->ambientlight);
if (worldcoords)
VectorCopy(rd->origin, nl->origin);
else
- softwareuntransform(rd->origin, nl->origin);
+ {
+ //softwareuntransform(rd->origin, nl->origin);
+ Matrix4x4_Transform(&ent->inversematrix, rd->origin, nl->origin);
+ /*
+ Con_Printf("%i %s : %f %f %f : %f %f %f\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n"
+ , rd - r_dlight, ent->model->name
+ , rd->origin[0], rd->origin[1], rd->origin[2]
+ , nl->origin[0], nl->origin[1], nl->origin[2]
+ , ent->inversematrix.m[0][0], ent->inversematrix.m[0][1], ent->inversematrix.m[0][2], ent->inversematrix.m[0][3]
+ , ent->inversematrix.m[1][0], ent->inversematrix.m[1][1], ent->inversematrix.m[1][2], ent->inversematrix.m[1][3]
+ , ent->inversematrix.m[2][0], ent->inversematrix.m[2][1], ent->inversematrix.m[2][2], ent->inversematrix.m[2][3]
+ , ent->inversematrix.m[3][0], ent->inversematrix.m[3][1], ent->inversematrix.m[3][2], ent->inversematrix.m[3][3]);
+ */
+ }
// integrate mscale into falloff, for maximum speed
nl->falloff = mscale;
VectorCopy(ambientcolor, nl->ambientlight);
}
}
+void R_UpdateEntLights(entity_render_t *ent)
+{
+ int i;
+ const mlight_t *sl;
+ vec3_t v;
+ VectorSubtract(ent->origin, ent->entlightsorigin, v);
+ if (ent->entlightsframe != (r_framecount - 1) || (realtime > ent->entlightstime && DotProduct(v,v) >= 1.0f))
+ {
+ ent->entlightstime = realtime + 0.1;
+ VectorCopy(ent->origin, ent->entlightsorigin);
+ ent->numentlights = 0;
+ for (i = 0, sl = cl.worldmodel->lights;i < cl.worldmodel->numlights && ent->numentlights < MAXENTLIGHTS;i++, sl++)
+ if (CL_TraceLine(ent->origin, sl->origin, NULL, NULL, 0, false) == 1)
+ ent->entlights[ent->numentlights++] = i;
+ }
+ ent->entlightsframe = r_framecount;
+}
void R_AnimateLight(void);
void R_MarkLights(entity_render_t *ent);
void R_DrawCoronas(void);
-void R_CompleteLightPoint(vec3_t color, vec3_t p, int dynamic, mleaf_t *leaf);
-void R_LightModel(entity_render_t *ent, int numverts, float colorr, float colorg, float colorb, int worldcoords);
+void R_CompleteLightPoint(vec3_t color, const vec3_t p, int dynamic, const mleaf_t *leaf);
+void R_LightModel(const entity_render_t *ent, int numverts, float colorr, float colorg, float colorb, int worldcoords);
+void R_UpdateEntLights(entity_render_t *ent);
#endif
rmeshbufferinfo_t m;
#define R_SkyBoxPolyVec(i,s,t,x,y,z) \
- m.vertex[i * 4 + 0] = (x) * 16.0f + r_origin[0];\
- m.vertex[i * 4 + 1] = (y) * 16.0f + r_origin[1];\
- m.vertex[i * 4 + 2] = (z) * 16.0f + r_origin[2];\
+ m.vertex[i * 4 + 0] = (x) * 16.0f;\
+ m.vertex[i * 4 + 1] = (y) * 16.0f;\
+ m.vertex[i * 4 + 2] = (z) * 16.0f;\
m.texcoords[0][i * 2 + 0] = (s) * (254.0f/256.0f) + (1.0f/256.0f);\
m.texcoords[0][i * 2 + 1] = (t) * (254.0f/256.0f) + (1.0f/256.0f);
m.numtriangles = 2;
m.numverts = 4;
m.tex[0] = R_GetTexture(skyboxside[3]); // front
+ Matrix4x4_CreateTranslate(&m.matrix, r_origin[0], r_origin[1], r_origin[2]);
if (R_Mesh_Draw_GetBuffer(&m, false))
{
memcpy(m.index, skyboxindex, sizeof(int[6]));
c[3] = 1;
t[0] = source[0] + s;
t[1] = source[1] + s;
- v[0] = source[2] + r_origin[0];
- v[1] = source[3] + r_origin[1];
- v[2] = source[4] + r_origin[2];
+ v[0] = source[2];
+ v[1] = source[3];
+ v[2] = source[4];
}
}
m.numtriangles = skygridx*skygridy*2;
m.numverts = skygridx1*skygridy1;
m.tex[0] = R_GetTexture(solidskytexture);
+ Matrix4x4_CreateTranslate(&m.matrix, r_origin[0], r_origin[1], r_origin[2]);
if (R_Mesh_Draw_GetBuffer(&m, false))
{
memcpy(m.index, skysphereindices, m.numtriangles * sizeof(int[3]));
#define LERPSPRITES
-static int R_SpriteSetup (entity_render_t *ent, int type, float org[3], float left[3], float up[3])
+static int R_SpriteSetup (const entity_render_t *ent, int type, float org[3], float left[3], float up[3])
{
float matrix1[3][3], matrix2[3][3], matrix3[3][3];
m.numtriangles = 2;
m.numverts = 4;
m.tex[0] = texture;
+ Matrix4x4_CreateIdentity(&m.matrix);
if (R_Mesh_Draw_GetBuffer(&m, wantoverbright))
{
m.index[0] = 0;
}
}
-void R_DrawSpriteModelCallback(void *calldata1, int calldata2)
+void R_DrawSpriteModelCallback(const void *calldata1, int calldata2)
{
- entity_render_t *ent;
+ const entity_render_t *ent = calldata1;
int i, wantoverbright;
vec3_t left, up, org, color;
mspriteframe_t *frame;
vec3_t diff;
float fog, ifog;
- ent = calldata1;
if (R_SpriteSetup(ent, ent->model->sprnum_type, org, left, up))
return;