From 5715fdeb47caa02252ab9b6c0895310e43bea716 Mon Sep 17 00:00:00 2001 From: havoc Date: Wed, 28 Aug 2002 11:56:00 +0000 Subject: [PATCH] most of the framework for hardware accelerated transforms is back, just the actual gl calls need to be put in, but that will be a later commit gl_backend internal mesh structure now has a matrix stored in it entity_render_t now has a matrix and a inverse matrix many additions of const to various functions, this required restructuring some code transparent mesh sorting is gone, this also means subsorting of triangles by depth is gone (meshqueue should be used for transparent mesh sorting, I have not yet written a new triangle sorter) rewrote RSurf_ shader functions *yet again*, they are now more compact and share code (by way of using lots of function calls) lots of changes/bugfixes/additions to matrixlib.c and .h, including an actual working Matrix4x4_Invert_Simple function added gl_flashblend (brightens and enlarges coronas, turns off all actual lighting) added r_coronas (can turn off coronas) git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@2295 d7cf8633-e32d-0410-b094-e92efae38249 --- cl_collision.c | 2 +- cl_collision.h | 2 +- cl_light.c | 1 + cl_particles.c | 7 +- cl_screen.c | 4 +- client.h | 7 + gl_backend.c | 260 +++--------------- gl_backend.h | 24 +- gl_models.c | 71 +++-- gl_rmain.c | 14 +- gl_rsurf.c | 719 +++++++++++++++++++++---------------------------- matrixlib.c | 196 +++++++++++--- matrixlib.h | 52 ++-- meshqueue.c | 8 +- meshqueue.h | 4 +- model_brush.c | 2 +- model_brush.h | 2 +- model_shared.h | 2 +- r_crosshairs.c | 1 + r_explosion.c | 5 +- r_light.c | 155 ++++++----- r_light.h | 5 +- r_sky.c | 14 +- r_sprites.c | 8 +- 24 files changed, 722 insertions(+), 843 deletions(-) diff --git a/cl_collision.c b/cl_collision.c index 6457fbf2..1bc60f72 100644 --- a/cl_collision.c +++ b/cl_collision.c @@ -30,7 +30,7 @@ physentity_t; 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; diff --git a/cl_collision.h b/cl_collision.h index 370349c2..15c1e06a 100644 --- a/cl_collision.h +++ b/cl_collision.h @@ -6,6 +6,6 @@ // (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 diff --git a/cl_light.c b/cl_light.c index 5d0bcec6..9c5d291d 100644 --- a/cl_light.c +++ b/cl_light.c @@ -33,6 +33,7 @@ void CL_AllocDlight (entity_render_t *ent, vec3_t org, float radius, float red, 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); diff --git a/cl_particles.c b/cl_particles.c index be86db56..a2d00944 100644 --- a/cl_particles.c +++ b/cl_particles.c @@ -1183,16 +1183,14 @@ void R_Particles_Init (void) 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); @@ -1274,6 +1272,7 @@ void R_DrawParticleCallback(void *calldata1, int calldata2) 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; diff --git a/cl_screen.c b/cl_screen.c index bbe08834..c29c7ca7 100644 --- a/cl_screen.c +++ b/cl_screen.c @@ -357,11 +357,11 @@ void R_TimeReport_Start(void) "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; diff --git a/client.h b/client.h index c7e61e49..02a6c558 100644 --- a/client.h +++ b/client.h @@ -22,6 +22,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #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 @@ -92,6 +94,10 @@ typedef struct entity_render_s 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 @@ -135,6 +141,7 @@ typedef struct entity_render_s // caching results of static light traces (this is semi-persistent) double entlightstime; vec3_t entlightsorigin; + int entlightsframe; int numentlights; unsigned short entlights[MAXENTLIGHTS]; } diff --git a/gl_backend.c b/gl_backend.c index 0dd8752f..19b70cd1 100644 --- a/gl_backend.c +++ b/gl_backend.c @@ -2,7 +2,6 @@ #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"}; @@ -13,8 +12,6 @@ cvar_t gl_lockarrays = {0, "gl_lockarrays", "1"}; // 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; @@ -74,7 +71,7 @@ static float viewdist; // 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; @@ -83,10 +80,7 @@ float overbrightscale; 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 { @@ -99,20 +93,11 @@ 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]; @@ -143,7 +128,7 @@ typedef struct } 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; @@ -151,15 +136,6 @@ static buf_fcolor_t *buf_fcolor; 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; @@ -170,7 +146,7 @@ static void gl_backend_start(void) 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")) @@ -181,7 +157,6 @@ static void gl_backend_start(void) Con_Printf("\n"); max_verts = max_meshs * 3; - max_transverts = max_transmeshs * 3; if (!gl_backend_mempool) gl_backend_mempool = Mem_AllocPool("GL_Backend"); @@ -200,25 +175,16 @@ static void gl_backend_start(void) 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); @@ -244,10 +210,6 @@ static void gl_backend_bufferchanges(int init) 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) @@ -265,15 +227,9 @@ static void gl_backend_bufferchanges(int init) 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) { @@ -299,7 +255,6 @@ void gl_backend_init(void) #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); @@ -492,10 +447,6 @@ void R_Mesh_Start(float farclip) 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; @@ -504,8 +455,6 @@ void R_Mesh_Start(float farclip) c_meshs = 0; c_meshtris = 0; - c_transmeshs = 0; - c_transtris = 0; GL_SetupFrame(); @@ -761,7 +710,8 @@ void GL_DrawRangeElements(int firstvert, int endvert, int indexcount, GLuint *in // 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) @@ -791,6 +741,14 @@ void R_Mesh_Render(void) } 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 @@ -868,8 +826,6 @@ void R_Mesh_Finish(void) void R_Mesh_ClearDepth(void) { - if (currenttransmesh) - R_Mesh_AddTransparent(); if (currentmesh) R_Mesh_Render(); R_Mesh_Finish(); @@ -877,123 +833,6 @@ void R_Mesh_ClearDepth(void) 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) @@ -1030,65 +869,36 @@ 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; diff --git a/gl_backend.h b/gl_backend.h index 2efbd9a0..51c6a12f 100644 --- a/gl_backend.h +++ b/gl_backend.h @@ -6,28 +6,6 @@ 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 @@ -40,6 +18,8 @@ typedef struct 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; diff --git a/gl_models.c b/gl_models.c index bf87df5a..893d9a0b 100644 --- a/gl_models.c +++ b/gl_models.c @@ -50,6 +50,7 @@ void GL_Models_Init(void) R_RegisterModule("GL_Models", gl_models_start, gl_models_shutdown, gl_models_newmap); } +/* void R_AliasTransformVerts(int vertcount) { vec3_t point; @@ -69,16 +70,17 @@ void R_AliasTransformVerts(int vertcount) 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; @@ -198,7 +200,7 @@ void R_AliasLerpVerts(int vertcount, } } -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) @@ -207,12 +209,11 @@ skinframe_t *R_FetchSkinFrame(entity_render_t *ent) 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]; @@ -230,10 +231,10 @@ void R_SetupMDLMD2Frames(entity_render_t *ent, float colorr, float colorg, float 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]; @@ -243,10 +244,9 @@ void R_DrawQ1Q2AliasModelCallback (void *calldata1, int calldata2) 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) @@ -292,6 +292,7 @@ void R_DrawQ1Q2AliasModelCallback (void *calldata1, int calldata2) 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)) @@ -349,6 +350,7 @@ void R_DrawQ1Q2AliasModelCallback (void *calldata1, int calldata2) 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; @@ -369,6 +371,7 @@ void R_DrawQ1Q2AliasModelCallback (void *calldata1, int calldata2) 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; @@ -390,6 +393,7 @@ void R_DrawQ1Q2AliasModelCallback (void *calldata1, int calldata2) 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; @@ -412,6 +416,7 @@ void R_DrawQ1Q2AliasModelCallback (void *calldata1, int calldata2) 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; @@ -430,6 +435,7 @@ void R_DrawQ1Q2AliasModelCallback (void *calldata1, int calldata2) 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; @@ -442,12 +448,14 @@ void R_DrawQ1Q2AliasModelCallback (void *calldata1, int calldata2) } } -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]; @@ -461,6 +469,19 @@ int ZymoticLerpBones(int count, zymbonematrix *bonebase, frameblend_t *blend, zy 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; @@ -702,7 +723,7 @@ void ZymoticCalcNormals(int vertcount, int shadercount, int *renderlist) } } -void R_DrawZymoticModelMeshCallback (void *calldata1, int calldata2) +void R_DrawZymoticModelMeshCallback (const void *calldata1, int calldata2) { float fog; vec3_t diff; @@ -710,11 +731,8 @@ void R_DrawZymoticModelMeshCallback (void *calldata1, int calldata2) 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; @@ -740,12 +758,11 @@ void R_DrawZymoticModelMeshCallback (void *calldata1, int calldata2) // 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; @@ -766,6 +783,7 @@ void R_DrawZymoticModelMeshCallback (void *calldata1, int calldata2) 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; @@ -786,6 +804,7 @@ void R_DrawZymoticModelMeshCallback (void *calldata1, int calldata2) 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; diff --git a/gl_rmain.c b/gl_rmain.c index fbb0c1dc..09c48a7c 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -389,6 +389,10 @@ static void R_MarkEntities (void) 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) @@ -431,10 +435,17 @@ static void R_MarkEntities (void) 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); } } @@ -566,6 +577,7 @@ static void R_BlendView(void) 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; @@ -678,8 +690,6 @@ void R_RenderView (void) R_TimeReport("explosions"); R_MeshQueue_RenderTransparent(); - - R_Mesh_AddTransparent(); R_TimeReport("addtrans"); R_DrawCoronas(); diff --git a/gl_rsurf.c b/gl_rsurf.c index 3ce3800e..aa83cc9e 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -236,7 +236,7 @@ R_BuildLightMap 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) { @@ -587,7 +587,6 @@ void R_Stain (vec3_t origin, float radius, int cr1, int cg1, int cb1, int ca1, i icolor[7] = ca2; model = cl.worldmodel; - softwaretransformidentity(); R_StainNode(model->nodes + model->hulls[0].firstclipnode, model, origin, radius, icolor); // look for embedded bmodels @@ -600,8 +599,7 @@ void R_Stain (vec3_t origin, float radius, int cr1, int cg1, int cb1, int ca1, i 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); } } @@ -617,72 +615,160 @@ void R_Stain (vec3_t origin, float radius, int cr1, int cg1, int cb1, int ca1, i ============================================================= */ -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; @@ -691,8 +777,7 @@ static int RSurf_LightSeparate(int *dlightbits, int numverts, float *vert, float 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; @@ -710,7 +795,7 @@ static int RSurf_LightSeparate(int *dlightbits, int numverts, float *vert, float // 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; @@ -730,20 +815,56 @@ static int RSurf_LightCheck(int *dlightbits, surfmesh_t *mesh) 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) { @@ -761,75 +882,26 @@ static void RSurfShader_Water_Callback(void *calldata1, int calldata2) 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(); } } @@ -840,40 +912,27 @@ static void RSurfShader_Water_Callback(void *calldata1, int calldata2) 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) @@ -883,15 +942,13 @@ static void RSurfShader_Water(entity_render_t *ent, msurface_t *firstsurf) } } -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) { @@ -911,98 +968,37 @@ static void RSurfShader_Wall_Pass_BaseVertex(entity_render_t *ent, msurface_t *s 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) { @@ -1022,122 +1018,82 @@ static void RSurfShader_Wall_Pass_BaseFullbright(entity_render_t *ent, msurface_ 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; @@ -1147,143 +1103,107 @@ static void RSurfShader_OpaqueWall_Pass_TripleTexCombine(entity_render_t *ent, m 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; @@ -1296,138 +1216,105 @@ static void RSurfShader_OpaqueWall_Pass_Light(entity_render_t *ent, msurface_t * 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++; @@ -1441,9 +1328,9 @@ static void RSurfShader_Wall_Fullbright(entity_render_t *ent, msurface_t *firsts 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++; @@ -1457,9 +1344,9 @@ static void RSurfShader_Wall_Vertex(entity_render_t *ent, msurface_t *firstsurf) 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) @@ -1848,6 +1735,7 @@ void R_DrawPortals(entity_render_t *ent) 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++) @@ -1888,9 +1776,7 @@ void R_SetupForBModelRendering(entity_render_t *ent) 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]; @@ -1909,7 +1795,6 @@ void R_SetupForWorldRendering(entity_render_t *ent) { // 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) diff --git a/matrixlib.c b/matrixlib.c index c6c4161a..ff447d7a 100644 --- a/matrixlib.c +++ b/matrixlib.c @@ -3,12 +3,12 @@ #include "matrixlib.h" #include -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]; @@ -28,7 +28,7 @@ void Matrix4x4_CopyRotateOnly (matrix4x4_t *out, matrix4x4_t *in) 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; @@ -48,7 +48,7 @@ void Matrix4x4_CopyTranslateOnly (matrix4x4_t *out, matrix4x4_t *in) 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]; @@ -90,32 +90,75 @@ void Matrix4x4_Concat (matrix4x4_t *out, const matrix4x4_t *in1, const matrix4x4 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) @@ -231,6 +274,37 @@ void Matrix4x4_CreateScale3 (matrix4x4_t *out, float x, float y, float z) 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]; @@ -282,6 +356,7 @@ void Matrix4x4_Transform4 (const matrix4x4_t *in, const float v[4], float out[4] 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]; @@ -292,6 +367,7 @@ void Matrix4x4_SimpleUntransform (const matrix4x4_t *in, const float v[3], float 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) @@ -336,12 +412,12 @@ void Matrix4x4_ConcatScale3 (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]; @@ -357,7 +433,7 @@ void Matrix3x4_CopyRotateOnly (matrix3x4_t *out, matrix3x4_t *in) 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; @@ -373,7 +449,7 @@ void Matrix3x4_CopyTranslateOnly (matrix3x4_t *out, matrix3x4_t *in) 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]; @@ -407,30 +483,47 @@ void Matrix3x4_Concat (matrix3x4_t *out, const matrix3x4_t *in1, const matrix3x4 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; @@ -524,6 +617,33 @@ void Matrix3x4_CreateScale3 (matrix3x4_t *out, float x, float y, float z) 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]; diff --git a/matrixlib.h b/matrixlib.h index 77c20b0c..62b8a3e1 100644 --- a/matrixlib.h +++ b/matrixlib.h @@ -17,21 +17,25 @@ matrix3x4_t; // 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) @@ -44,13 +48,15 @@ void Matrix4x4_CreateTranslate (matrix4x4_t *out, float x, float y, float z); 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]); @@ -66,7 +72,7 @@ void Matrix4x4_Transform4 (const matrix4x4_t *in, const float v[4], float out[4] // 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 @@ -83,22 +89,22 @@ void Matrix4x4_ConcatScale3 (matrix4x4_t *out, float x, float y, float z); // 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) @@ -111,13 +117,15 @@ void Matrix3x4_CreateTranslate (matrix3x4_t *out, float x, float y, float z); 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]); diff --git a/meshqueue.c b/meshqueue.c index 467b4c55..fdbb60e9 100644 --- a/meshqueue.c +++ b/meshqueue.c @@ -9,8 +9,8 @@ cvar_t r_meshqueue_sort = {0, "r_meshqueue_sort", "0"}; 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; } @@ -60,7 +60,7 @@ static void R_MeshQueue_EnlargeTransparentArray(int newtotal) 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) @@ -103,7 +103,7 @@ void R_MeshQueue_Add(void (*callback)(void *data1, int data2), void *data1, int *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) diff --git a/meshqueue.h b/meshqueue.h index f3f9e3fc..ed587e14 100644 --- a/meshqueue.h +++ b/meshqueue.h @@ -3,8 +3,8 @@ #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); diff --git a/model_brush.c b/model_brush.c index 79be4373..92244c45 100644 --- a/model_brush.c +++ b/model_brush.c @@ -109,7 +109,7 @@ void Mod_BrushShutdown (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; diff --git a/model_brush.h b/model_brush.h index eebdc525..fdc69165 100644 --- a/model_brush.h +++ b/model_brush.h @@ -210,7 +210,7 @@ struct entity_render_s; // 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; } diff --git a/model_shared.h b/model_shared.h index 6fc568cf..f6a6bdc9 100644 --- a/model_shared.h +++ b/model_shared.h @@ -226,7 +226,7 @@ model_t *Mod_ForName (char *name, qboolean crash, qboolean checkdisk, qboolean i 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); diff --git a/r_crosshairs.c b/r_crosshairs.c index 4a765927..49b68a3b 100644 --- a/r_crosshairs.c +++ b/r_crosshairs.c @@ -172,6 +172,7 @@ void R_DrawCrosshairSprite(rtexture_t *texture, vec3_t origin, vec_t scale, floa 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; diff --git a/r_explosion.c b/r_explosion.c index 5cd7fb9a..0f027e5f 100644 --- a/r_explosion.c +++ b/r_explosion.c @@ -173,12 +173,12 @@ void R_NewExplosion(vec3_t org) } } -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)); @@ -187,6 +187,7 @@ void R_DrawExplosionCallback(void *calldata1, int calldata2) 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])); diff --git a/r_light.c b/r_light.c index 13895c3e..965b8191 100644 --- a/r_light.c +++ b/r_light.c @@ -27,6 +27,8 @@ int r_numdlights = 0; 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; @@ -68,6 +70,8 @@ void R_Light_Init(void) { 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); } @@ -126,7 +130,6 @@ void R_BuildLightList(void) rd->cullradius = sqrt(rd->cullradius2); rd->subtract = 1.0f / rd->cullradius2; //rd->ent = cd->ent; - r_numdlights++; c_dlights++; // count every dlight in use } } @@ -137,6 +140,8 @@ void R_DrawCoronas(void) 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; @@ -151,48 +156,54 @@ void R_DrawCoronas(void) 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(); } } } @@ -345,7 +356,8 @@ static void R_VisMarkLights (entity_render_t *ent, rdlight_t *rd, int bit, int b return; model = ent->model; - softwareuntransform(rd->origin, lightorigin); + //softwareuntransform(rd->origin, lightorigin); + Matrix4x4_Transform(&ent->inversematrix, rd->origin, lightorigin); if (!r_vismarklights.integer) { @@ -478,8 +490,9 @@ static void R_VisMarkLights (entity_render_t *ent, rdlight_t *rd, int bit, int b 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); } /* @@ -490,7 +503,7 @@ LIGHT SAMPLING ============================================================================= */ -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; @@ -630,9 +643,10 @@ middle sample (the one which was requested) } } -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; @@ -692,7 +706,7 @@ void R_CompleteLightPoint (vec3_t color, vec3_t p, int dynamic, mleaf_t *leaf) } } -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); @@ -729,7 +743,7 @@ void R_ModelLightPoint (entity_render_t *ent, vec3_t color, vec3_t p, int *dligh 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]; @@ -759,16 +773,6 @@ void R_LightModel(entity_render_t *ent, int numverts, float colorr, float colorg 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]; @@ -808,7 +812,8 @@ void R_LightModel(entity_render_t *ent, int numverts, float colorr, float colorg 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); @@ -859,7 +864,20 @@ void R_LightModel(entity_render_t *ent, int numverts, float colorr, float colorg 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); @@ -938,3 +956,20 @@ void R_LightModel(entity_render_t *ent, int numverts, float colorr, float colorg } } +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; +} diff --git a/r_light.h b/r_light.h index 026a4ec0..6fafe722 100644 --- a/r_light.h +++ b/r_light.h @@ -20,8 +20,9 @@ void R_BuildLightList(void); 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 diff --git a/r_sky.c b/r_sky.c index d7f95cff..364818a8 100644 --- a/r_sky.c +++ b/r_sky.c @@ -157,9 +157,9 @@ static void R_SkyBox(void) 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); @@ -170,6 +170,7 @@ static void R_SkyBox(void) 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])); @@ -316,9 +317,9 @@ static void skyspherearrays(float *v, float *t, float *c, float *source, float s 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]; } } @@ -345,6 +346,7 @@ static void R_SkySphere(void) 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])); diff --git a/r_sprites.c b/r_sprites.c index 8277f211..58dd2d21 100644 --- a/r_sprites.c +++ b/r_sprites.c @@ -3,7 +3,7 @@ #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]; @@ -89,6 +89,7 @@ static void R_DrawSpriteImage (int wantoverbright, int additive, mspriteframe_t 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; @@ -126,16 +127,15 @@ static void R_DrawSpriteImage (int wantoverbright, int additive, mspriteframe_t } } -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; -- 2.39.2