From cf93d91077855abf71419763e56bc774bc3b244f Mon Sep 17 00:00:00 2001 From: havoc Date: Tue, 27 Aug 2002 09:42:59 +0000 Subject: [PATCH] engine mostly converted to use R_MeshQueue functions instead of true transparent meshs, this meant getting rid of currentrenderentity the rest of the conversion to R_MeshQueue will be in a future commit, just wanted to get this in now git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@2290 d7cf8633-e32d-0410-b094-e92efae38249 --- cl_particles.c | 254 +++++++++++++++++++++-------------------- gl_models.c | 299 +++++++++++++++++++++++++++---------------------- gl_rmain.c | 97 ++++++++-------- gl_rsurf.c | 200 ++++++++++++++++----------------- model_alias.c | 6 +- model_brush.h | 3 +- model_shared.h | 6 +- r_explosion.c | 8 +- r_light.c | 60 +++++----- r_light.h | 4 +- r_sprites.c | 97 +++++++++------- render.h | 25 +++-- 12 files changed, 562 insertions(+), 497 deletions(-) diff --git a/cl_particles.c b/cl_particles.c index 15f78ca5..2c9f2147 100644 --- a/cl_particles.c +++ b/cl_particles.c @@ -1183,30 +1183,147 @@ void R_Particles_Init (void) int partindexarray[6] = {0, 1, 2, 0, 2, 3}; -void R_DrawParticles (void) +void R_DrawParticleCallback(void *calldata1, int calldata2) { - int i, lighting, dynlight, additive, texnum, orientation; - float minparticledist, org[3], uprightangles[3], up2[3], right2[3], v[3], right[3], up[3], fog, ifog, fogvec[3], cr, cg, cb, ca; - mleaf_t *leaf; + 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; + + // LordHavoc: check if it's in a visible leaf + leaf = Mod_PointInLeaf(p->org, cl.worldmodel); + if (leaf->visframe != r_framecount) + return; + + lighting = r_dynamic.integer ? r_particles_lighting.integer : 0; + + VectorCopy(p->org, org); + orientation = (p->flags >> P_ORIENTATION_FIRSTBIT) & ((1 << P_ORIENTATION_BITS) - 1); + texnum = (p->flags >> P_TEXNUM_FIRSTBIT) & ((1 << P_TEXNUM_BITS) - 1); + dynlight = p->flags & P_DYNLIGHT; + additive = p->flags & P_ADDITIVE; + if (orientation == PARTICLE_BILLBOARD) + { + VectorScale(vright, p->scalex, right); + VectorScale(vup, p->scaley, up); + } + else if (orientation == PARTICLE_UPRIGHT_FACING) + { + v[0] = r_origin[0] - org[0]; + v[1] = r_origin[1] - org[1]; + v[2] = 0; + VectorNormalizeFast(v); + VectorVectors(v, right2, up2); + VectorScale(right2, p->scalex, right); + VectorScale(up2, p->scaley, up); + } + else if (orientation == PARTICLE_ORIENTED_DOUBLESIDED) + { + // double-sided + if (DotProduct(p->vel2, r_origin) > DotProduct(p->vel2, org)) + { + VectorNegate(p->vel2, v); + VectorVectors(v, right, up); + } + else + VectorVectors(p->vel2, right, up); + VectorScale(right, p->scalex, right); + VectorScale(up, p->scaley, up); + } + else + Host_Error("R_DrawParticles: unknown particle orientation %i\n", orientation); + + cr = p->color[0] * (1.0f / 255.0f); + cg = p->color[1] * (1.0f / 255.0f); + cb = p->color[2] * (1.0f / 255.0f); + ca = p->alpha * (1.0f / 255.0f); + if (lighting >= 1 && (dynlight || lighting >= 2)) + { + R_CompleteLightPoint(v, org, true, leaf); + cr *= v[0]; + cg *= v[1]; + cb *= v[2]; + } + + if (fogenabled) + { + VectorSubtract(org, r_origin, fogvec); + fog = exp(fogdensity/DotProduct(fogvec,fogvec)); + ifog = 1 - fog; + cr = cr * ifog; + cg = cg * ifog; + cb = cb * ifog; + if (!additive) + { + cr += fogcolor[0] * fog; + cg += fogcolor[1] * fog; + cb += fogcolor[2] * fog; + } + } + + memset(&m, 0, sizeof(m)); + m.transparent = false; + m.blendfunc1 = GL_SRC_ALPHA; + if (additive) + m.blendfunc2 = GL_ONE; + else + m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA; + m.numtriangles = 2; + m.numverts = 4; + m.tex[0] = R_GetTexture(particlefonttexture); + if (R_Mesh_Draw_GetBuffer(&m, false)) + { + 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.vertex[0] = org[0] - right[0] - up[0]; + m.vertex[1] = org[1] - right[1] - up[1]; + m.vertex[2] = org[2] - right[2] - up[2]; + m.vertex[4] = org[0] - right[0] + up[0]; + m.vertex[5] = org[1] - right[1] + up[1]; + m.vertex[6] = org[2] - right[2] + up[2]; + m.vertex[8] = org[0] + right[0] + up[0]; + m.vertex[9] = org[1] + right[1] + up[1]; + m.vertex[10] = org[2] + right[2] + up[2]; + m.vertex[12] = org[0] + right[0] - up[0]; + m.vertex[13] = org[1] + right[1] - up[1]; + m.vertex[14] = org[2] + right[2] - up[2]; + tex = &particletexture[texnum]; + m.texcoords[0][0] = tex->s1; + m.texcoords[0][1] = tex->t1; + m.texcoords[0][2] = tex->s1; + m.texcoords[0][3] = tex->t2; + m.texcoords[0][4] = tex->s2; + m.texcoords[0][5] = tex->t2; + m.texcoords[0][6] = tex->s2; + m.texcoords[0][7] = tex->t1; + m.color[0] = m.color[4] = m.color[8] = m.color[12] = cr * m.colorscale; + m.color[1] = m.color[5] = m.color[9] = m.color[13] = cg * m.colorscale; + m.color[2] = m.color[6] = m.color[10] = m.color[14] = cb * m.colorscale; + m.color[3] = m.color[7] = m.color[11] = m.color[15] = ca; + R_Mesh_Render(); + } +} + +void R_DrawParticles (void) +{ + int i; + float minparticledist; + particle_t *p; + // LordHavoc: early out conditions if ((!cl_numparticles) || (!r_drawparticles.integer)) return; - lighting = r_particles_lighting.integer; - if (!r_dynamic.integer) - lighting = 0; - c_particles += cl_numparticles; - uprightangles[0] = 0; - uprightangles[1] = r_refdef.viewangles[1]; - uprightangles[2] = 0; - AngleVectors (uprightangles, NULL, right2, up2); - minparticledist = DotProduct(r_origin, vpn) + 16.0f; for (i = 0, p = particles;i < cl_numparticles;i++, p++) @@ -1215,116 +1332,7 @@ void R_DrawParticles (void) if (DotProduct(p->org, vpn) < minparticledist) continue; - // LordHavoc: check if it's in a visible leaf - leaf = Mod_PointInLeaf(p->org, cl.worldmodel); - if (leaf->visframe != r_framecount) - continue; - - VectorCopy(p->org, org); - orientation = (p->flags >> P_ORIENTATION_FIRSTBIT) & ((1 << P_ORIENTATION_BITS) - 1); - texnum = (p->flags >> P_TEXNUM_FIRSTBIT) & ((1 << P_TEXNUM_BITS) - 1); - dynlight = p->flags & P_DYNLIGHT; - additive = p->flags & P_ADDITIVE; - if (orientation == PARTICLE_BILLBOARD) - { - VectorScale(vright, p->scalex, right); - VectorScale(vup, p->scaley, up); - } - else if (orientation == PARTICLE_UPRIGHT_FACING) - { - VectorScale(right2, p->scalex, right); - VectorScale(up2, p->scaley, up); - } - else if (orientation == PARTICLE_ORIENTED_DOUBLESIDED) - { - // double-sided - if (DotProduct(p->vel2, r_origin) > DotProduct(p->vel2, org)) - { - VectorNegate(p->vel2, v); - VectorVectors(v, right, up); - } - else - VectorVectors(p->vel2, right, up); - VectorScale(right, p->scalex, right); - VectorScale(up, p->scaley, up); - } - else - Host_Error("R_DrawParticles: unknown particle orientation %i\n", orientation); - - tex = &particletexture[texnum]; - - cr = p->color[0] * (1.0f / 255.0f); - cg = p->color[1] * (1.0f / 255.0f); - cb = p->color[2] * (1.0f / 255.0f); - ca = p->alpha * (1.0f / 255.0f); - if (lighting >= 1 && (dynlight || lighting >= 2)) - { - R_CompleteLightPoint(v, org, true, leaf); - cr *= v[0]; - cg *= v[1]; - cb *= v[2]; - } - - if (fogenabled) - { - VectorSubtract(org, r_origin, fogvec); - fog = exp(fogdensity/DotProduct(fogvec,fogvec)); - ifog = 1 - fog; - cr = cr * ifog; - cg = cg * ifog; - cb = cb * ifog; - if (!additive) - { - cr += fogcolor[0] * fog; - cg += fogcolor[1] * fog; - cb += fogcolor[2] * fog; - } - } - - memset(&m, 0, sizeof(m)); - m.transparent = true; - m.blendfunc1 = GL_SRC_ALPHA; - if (additive) - m.blendfunc2 = GL_ONE; - else - m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA; - m.numtriangles = 2; - m.numverts = 4; - m.tex[0] = R_GetTexture(particlefonttexture); - if (R_Mesh_Draw_GetBuffer(&m, false)) - { - 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.vertex[0] = org[0] - right[0] - up[0]; - m.vertex[1] = org[1] - right[1] - up[1]; - m.vertex[2] = org[2] - right[2] - up[2]; - m.vertex[4] = org[0] - right[0] + up[0]; - m.vertex[5] = org[1] - right[1] + up[1]; - m.vertex[6] = org[2] - right[2] + up[2]; - m.vertex[8] = org[0] + right[0] + up[0]; - m.vertex[9] = org[1] + right[1] + up[1]; - m.vertex[10] = org[2] + right[2] + up[2]; - m.vertex[12] = org[0] + right[0] - up[0]; - m.vertex[13] = org[1] + right[1] - up[1]; - m.vertex[14] = org[2] + right[2] - up[2]; - m.texcoords[0][0] = tex->s1; - m.texcoords[0][1] = tex->t1; - m.texcoords[0][2] = tex->s1; - m.texcoords[0][3] = tex->t2; - m.texcoords[0][4] = tex->s2; - m.texcoords[0][5] = tex->t2; - m.texcoords[0][6] = tex->s2; - m.texcoords[0][7] = tex->t1; - m.color[0] = m.color[4] = m.color[8] = m.color[12] = cr * m.colorscale; - m.color[1] = m.color[5] = m.color[9] = m.color[13] = cg * m.colorscale; - m.color[2] = m.color[6] = m.color[10] = m.color[14] = cb * m.colorscale; - m.color[3] = m.color[7] = m.color[11] = m.color[15] = ca; - R_Mesh_Render(); - } + R_MeshQueue_AddTransparent(p->org, R_DrawParticleCallback, p, 0); } } diff --git a/gl_models.c b/gl_models.c index 8b40edda..acfd701b 100644 --- a/gl_models.c +++ b/gl_models.c @@ -198,66 +198,89 @@ void R_AliasLerpVerts(int vertcount, } } -skinframe_t *R_FetchSkinFrame(void) +skinframe_t *R_FetchSkinFrame(entity_render_t *ent) { - model_t *model = currentrenderentity->model; - if (model->skinscenes[currentrenderentity->skinnum].framecount > 1) - return &model->skinframes[model->skinscenes[currentrenderentity->skinnum].firstframe + (int) (cl.time * 10) % model->skinscenes[currentrenderentity->skinnum].framecount]; + model_t *model = ent->model; + if (model->skinscenes[ent->skinnum].framecount > 1) + return &model->skinframes[model->skinscenes[ent->skinnum].firstframe + (int) (cl.time * 10) % model->skinscenes[ent->skinnum].framecount]; else - return &model->skinframes[model->skinscenes[currentrenderentity->skinnum].firstframe]; + return &model->skinframes[model->skinscenes[ent->skinnum].firstframe]; } -void R_SetupMDLMD2Frames(float colorr, float colorg, float colorb) +void R_SetupMDLMD2Frames(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 = currentrenderentity->model; - - frame1 = &model->mdlmd2data_frames[currentrenderentity->frameblend[0].frame]; - frame2 = &model->mdlmd2data_frames[currentrenderentity->frameblend[1].frame]; - frame3 = &model->mdlmd2data_frames[currentrenderentity->frameblend[2].frame]; - frame4 = &model->mdlmd2data_frames[currentrenderentity->frameblend[3].frame]; - frame1verts = &model->mdlmd2data_pose[currentrenderentity->frameblend[0].frame * model->numverts]; - frame2verts = &model->mdlmd2data_pose[currentrenderentity->frameblend[1].frame * model->numverts]; - frame3verts = &model->mdlmd2data_pose[currentrenderentity->frameblend[2].frame * model->numverts]; - frame4verts = &model->mdlmd2data_pose[currentrenderentity->frameblend[3].frame * model->numverts]; + model = ent->model; + + frame1 = &model->mdlmd2data_frames[ent->frameblend[0].frame]; + frame2 = &model->mdlmd2data_frames[ent->frameblend[1].frame]; + frame3 = &model->mdlmd2data_frames[ent->frameblend[2].frame]; + frame4 = &model->mdlmd2data_frames[ent->frameblend[3].frame]; + frame1verts = &model->mdlmd2data_pose[ent->frameblend[0].frame * model->numverts]; + frame2verts = &model->mdlmd2data_pose[ent->frameblend[1].frame * model->numverts]; + frame3verts = &model->mdlmd2data_pose[ent->frameblend[2].frame * model->numverts]; + frame4verts = &model->mdlmd2data_pose[ent->frameblend[3].frame * model->numverts]; R_AliasLerpVerts(model->numverts, - currentrenderentity->frameblend[0].lerp, frame1verts, frame1->scale, frame1->translate, - currentrenderentity->frameblend[1].lerp, frame2verts, frame2->scale, frame2->translate, - currentrenderentity->frameblend[2].lerp, frame3verts, frame3->scale, frame3->translate, - currentrenderentity->frameblend[3].lerp, frame4verts, frame4->scale, frame4->translate); + ent->frameblend[0].lerp, frame1verts, frame1->scale, frame1->translate, + ent->frameblend[1].lerp, frame2verts, frame2->scale, frame2->translate, + ent->frameblend[2].lerp, frame3verts, frame3->scale, frame3->translate, + ent->frameblend[3].lerp, frame4verts, frame4->scale, frame4->translate); - R_LightModel(model->numverts, colorr, colorg, colorb, false); + R_LightModel(ent, model->numverts, colorr, colorg, colorb, false); R_AliasTransformVerts(model->numverts); } -void R_DrawQ1Q2AliasModel (float fog) +void R_DrawQ1Q2AliasModelCallback (void *calldata1, int calldata2) { int c, pantsfullbright, shirtfullbright, colormapped; float pantscolor[3], shirtcolor[3]; + float fog; + vec3_t diff; qbyte *bcolor; rmeshbufferinfo_t m; model_t *model; skinframe_t *skinframe; + entity_render_t *ent; + + ent = calldata1; + softwaretransformforentity(ent); + + fog = 0; + if (fogenabled) + { + VectorSubtract(ent->origin, r_origin, diff); + fog = DotProduct(diff,diff); + if (fog < 0.01f) + fog = 0.01f; + fog = exp(fogdensity/fog); + if (fog > 1) + fog = 1; + if (fog < 0.01f) + fog = 0; + // fog method: darken, additive fog + // 1. render model as normal, scaled by inverse of fog alpha (darkens it) + // 2. render fog as additive + } - model = currentrenderentity->model; + model = ent->model; - skinframe = R_FetchSkinFrame(); + skinframe = R_FetchSkinFrame(ent); - colormapped = !skinframe->merged || (currentrenderentity->colormap >= 0 && skinframe->base && (skinframe->pants || skinframe->shirt)); + colormapped = !skinframe->merged || (ent->colormap >= 0 && skinframe->base && (skinframe->pants || skinframe->shirt)); if (!colormapped && !fog && !skinframe->glow && !skinframe->fog) { // fastpath for the normal situation (one texture) memset(&m, 0, sizeof(m)); - if (currentrenderentity->effects & EF_ADDITIVE) + if (ent->effects & EF_ADDITIVE) { m.transparent = true; m.blendfunc1 = GL_SRC_ALPHA; m.blendfunc2 = GL_ONE; } - else if (currentrenderentity->alpha != 1.0 || skinframe->fog != NULL) + else if (ent->alpha != 1.0 || skinframe->fog != NULL) { m.transparent = true; m.blendfunc1 = GL_SRC_ALPHA; @@ -281,7 +304,7 @@ void R_DrawQ1Q2AliasModel (float fog) aliasvert = m.vertex; aliasvertcolor = m.color; - R_SetupMDLMD2Frames(m.colorscale * (1 - fog), m.colorscale * (1 - fog), m.colorscale * (1 - fog)); + R_SetupMDLMD2Frames(ent, m.colorscale * (1 - fog), m.colorscale * (1 - fog), m.colorscale * (1 - fog)); aliasvert = aliasvertbuf; aliasvertcolor = aliasvertcolorbuf; @@ -290,16 +313,16 @@ void R_DrawQ1Q2AliasModel (float fog) return; } - R_SetupMDLMD2Frames(1 - fog, 1 - fog, 1 - fog); + R_SetupMDLMD2Frames(ent, 1 - fog, 1 - fog, 1 - fog); if (colormapped) { // 128-224 are backwards ranges - c = (currentrenderentity->colormap & 0xF) << 4;c += (c >= 128 && c < 224) ? 4 : 12; + c = (ent->colormap & 0xF) << 4;c += (c >= 128 && c < 224) ? 4 : 12; bcolor = (qbyte *) (&d_8to24table[c]); pantsfullbright = c >= 224; VectorScale(bcolor, (1.0f / 255.0f), pantscolor); - c = (currentrenderentity->colormap & 0xF0);c += (c >= 128 && c < 224) ? 4 : 12; + c = (ent->colormap & 0xF0);c += (c >= 128 && c < 224) ? 4 : 12; bcolor = (qbyte *) (&d_8to24table[c]); shirtfullbright = c >= 224; VectorScale(bcolor, (1.0f / 255.0f), shirtcolor); @@ -311,13 +334,13 @@ void R_DrawQ1Q2AliasModel (float fog) } memset(&m, 0, sizeof(m)); - if (currentrenderentity->effects & EF_ADDITIVE) + if (ent->effects & EF_ADDITIVE) { m.transparent = true; m.blendfunc1 = GL_SRC_ALPHA; m.blendfunc2 = GL_ONE; } - else if (currentrenderentity->alpha != 1.0 || skinframe->fog != NULL) + else if (ent->alpha != 1.0 || skinframe->fog != NULL) { m.transparent = true; m.blendfunc1 = GL_SRC_ALPHA; @@ -347,7 +370,7 @@ void R_DrawQ1Q2AliasModel (float fog) if (skinframe->pants) { memset(&m, 0, sizeof(m)); - m.transparent = currentrenderentity->effects & EF_ADDITIVE || currentrenderentity->alpha != 1.0 || skinframe->fog != NULL; + m.transparent = ent->effects & EF_ADDITIVE || ent->alpha != 1.0 || skinframe->fog != NULL; m.blendfunc1 = GL_SRC_ALPHA; m.blendfunc2 = GL_ONE; m.numtriangles = model->numtris; @@ -357,7 +380,7 @@ void R_DrawQ1Q2AliasModel (float fog) { c_alias_polys += m.numtriangles; if (pantsfullbright) - R_FillColors(m.color, m.numverts, pantscolor[0] * m.colorscale, pantscolor[1] * m.colorscale, pantscolor[2] * m.colorscale, currentrenderentity->alpha); + R_FillColors(m.color, m.numverts, pantscolor[0] * m.colorscale, pantscolor[1] * m.colorscale, pantscolor[2] * m.colorscale, ent->alpha); else R_ModulateColors(aliasvertcolor, m.color, m.numverts, pantscolor[0] * m.colorscale, pantscolor[1] * m.colorscale, pantscolor[2] * m.colorscale); memcpy(m.index, model->mdlmd2data_indices, m.numtriangles * sizeof(int[3])); @@ -369,7 +392,7 @@ void R_DrawQ1Q2AliasModel (float fog) if (skinframe->shirt) { memset(&m, 0, sizeof(m)); - m.transparent = currentrenderentity->effects & EF_ADDITIVE || currentrenderentity->alpha != 1.0 || skinframe->fog != NULL; + m.transparent = ent->effects & EF_ADDITIVE || ent->alpha != 1.0 || skinframe->fog != NULL; m.blendfunc1 = GL_SRC_ALPHA; m.blendfunc2 = GL_ONE; m.numtriangles = model->numtris; @@ -379,7 +402,7 @@ void R_DrawQ1Q2AliasModel (float fog) { c_alias_polys += m.numtriangles; if (shirtfullbright) - R_FillColors(m.color, m.numverts, shirtcolor[0] * m.colorscale, shirtcolor[1] * m.colorscale, shirtcolor[2] * m.colorscale, currentrenderentity->alpha); + R_FillColors(m.color, m.numverts, shirtcolor[0] * m.colorscale, shirtcolor[1] * m.colorscale, shirtcolor[2] * m.colorscale, ent->alpha); else R_ModulateColors(aliasvertcolor, m.color, m.numverts, shirtcolor[0] * m.colorscale, shirtcolor[1] * m.colorscale, shirtcolor[2] * m.colorscale); memcpy(m.index, model->mdlmd2data_indices, m.numtriangles * sizeof(int[3])); @@ -392,7 +415,7 @@ void R_DrawQ1Q2AliasModel (float fog) if (skinframe->glow) { memset(&m, 0, sizeof(m)); - m.transparent = currentrenderentity->effects & EF_ADDITIVE || currentrenderentity->alpha != 1.0 || skinframe->fog != NULL; + m.transparent = ent->effects & EF_ADDITIVE || ent->alpha != 1.0 || skinframe->fog != NULL; m.blendfunc1 = GL_SRC_ALPHA; m.blendfunc2 = GL_ONE; m.numtriangles = model->numtris; @@ -401,7 +424,7 @@ void R_DrawQ1Q2AliasModel (float fog) if (R_Mesh_Draw_GetBuffer(&m, true)) { c_alias_polys += m.numtriangles; - R_FillColors(m.color, m.numverts, (1 - fog) * m.colorscale, (1 - fog) * m.colorscale, (1 - fog) * m.colorscale, currentrenderentity->alpha); + R_FillColors(m.color, m.numverts, (1 - fog) * m.colorscale, (1 - fog) * m.colorscale, (1 - fog) * m.colorscale, ent->alpha); memcpy(m.index, model->mdlmd2data_indices, m.numtriangles * sizeof(int[3])); memcpy(m.vertex, aliasvert, m.numverts * sizeof(float[4])); memcpy(m.texcoords[0], model->mdlmd2data_texcoords, m.numverts * sizeof(float[2])); @@ -411,7 +434,7 @@ void R_DrawQ1Q2AliasModel (float fog) if (fog) { memset(&m, 0, sizeof(m)); - m.transparent = currentrenderentity->effects & EF_ADDITIVE || currentrenderentity->alpha != 1.0 || skinframe->fog != NULL; + m.transparent = ent->effects & EF_ADDITIVE || ent->alpha != 1.0 || skinframe->fog != NULL; m.blendfunc1 = GL_SRC_ALPHA; m.blendfunc2 = GL_ONE; m.numtriangles = model->numtris; @@ -420,7 +443,7 @@ void R_DrawQ1Q2AliasModel (float fog) if (R_Mesh_Draw_GetBuffer(&m, false)) { c_alias_polys += m.numtriangles; - R_FillColors(m.color, m.numverts, fog * m.colorscale, fog * m.colorscale, fog * m.colorscale, currentrenderentity->alpha); + R_FillColors(m.color, m.numverts, fog * m.colorscale, fog * m.colorscale, fog * m.colorscale, ent->alpha); memcpy(m.index, model->mdlmd2data_indices, m.numtriangles * sizeof(int[3])); memcpy(m.vertex, aliasvert, m.numverts * sizeof(float[4])); memcpy(m.texcoords[0], model->mdlmd2data_texcoords, m.numverts * sizeof(float[2])); @@ -689,126 +712,136 @@ void ZymoticCalcNormals(int vertcount, int shadercount, int *renderlist) } } -void R_DrawZymoticModelMesh(zymtype1header_t *m, float fog) +void R_DrawZymoticModelMeshCallback (void *calldata1, int calldata2) { - rmeshbufferinfo_t mbuf; + float fog; + vec3_t diff; int i, *renderlist; - rtexture_t **texture; + zymtype1header_t *m; + rtexture_t *texture; + rmeshbufferinfo_t mbuf; + entity_render_t *ent; + int shadernum; - texture = (rtexture_t **)(m->lump_shaders.start + (int) m); + ent = calldata1; + shadernum = calldata2; + // find the vertex index list and texture + m = ent->model->zymdata_header; renderlist = (int *)(m->lump_render.start + (int) m); - for (i = 0;i < m->numshaders;i++) + for (i = 0;i < shadernum;i++) + renderlist += renderlist[0] * 3 + 1; + texture = ((rtexture_t **)(m->lump_shaders.start + (int) m))[shadernum]; + + fog = 0; + if (fogenabled) + { + VectorSubtract(ent->origin, r_origin, diff); + fog = DotProduct(diff,diff); + if (fog < 0.01f) + fog = 0.01f; + fog = exp(fogdensity/fog); + if (fog > 1) + fog = 1; + if (fog < 0.01f) + fog = 0; + // fog method: darken, additive fog + // 1. render model as normal, scaled by inverse of fog alpha (darkens it) + // 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); + + memset(&mbuf, 0, sizeof(mbuf)); + mbuf.numverts = m->numverts; + mbuf.numtriangles = renderlist[0]; + mbuf.transparent = false; + if (ent->effects & EF_ADDITIVE) + { + mbuf.blendfunc1 = GL_SRC_ALPHA; + mbuf.blendfunc2 = GL_ONE; + } + else if (ent->alpha != 1.0 || R_TextureHasAlpha(texture)) + { + mbuf.blendfunc1 = GL_SRC_ALPHA; + mbuf.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA; + } + else + { + mbuf.blendfunc1 = GL_ONE; + mbuf.blendfunc2 = GL_ZERO; + } + mbuf.tex[0] = R_GetTexture(texture); + if (R_Mesh_Draw_GetBuffer(&mbuf, true)) + { + c_alias_polys += mbuf.numtriangles; + memcpy(mbuf.index, renderlist + 1, mbuf.numtriangles * sizeof(int[3])); + memcpy(mbuf.vertex, aliasvert, mbuf.numverts * sizeof(float[4])); + R_ModulateColors(aliasvertcolor, mbuf.color, mbuf.numverts, mbuf.colorscale, mbuf.colorscale, mbuf.colorscale); + //memcpy(mbuf.color, aliasvertcolor, mbuf.numverts * sizeof(float[4])); + memcpy(mbuf.texcoords[0], (float *)(m->lump_texcoords.start + (int) m), mbuf.numverts * sizeof(float[2])); + R_Mesh_Render(); + } + + if (fog) { memset(&mbuf, 0, sizeof(mbuf)); mbuf.numverts = m->numverts; - mbuf.numtriangles = *renderlist++; - if (currentrenderentity->effects & EF_ADDITIVE) - { - mbuf.transparent = true; - mbuf.blendfunc1 = GL_SRC_ALPHA; - mbuf.blendfunc2 = GL_ONE; - } - else if (currentrenderentity->alpha != 1.0 || R_TextureHasAlpha(texture[i])) - { - mbuf.transparent = true; - mbuf.blendfunc1 = GL_SRC_ALPHA; - mbuf.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA; - } - else - { - mbuf.transparent = false; - mbuf.blendfunc1 = GL_ONE; - mbuf.blendfunc2 = GL_ZERO; - } - mbuf.tex[0] = R_GetTexture(texture[i]); - if (R_Mesh_Draw_GetBuffer(&mbuf, true)) + mbuf.numtriangles = renderlist[0]; + mbuf.transparent = false; + mbuf.blendfunc1 = GL_SRC_ALPHA; + mbuf.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA; + // FIXME: need alpha mask for fogging... + //mbuf.tex[0] = R_GetTexture(texture); + if (R_Mesh_Draw_GetBuffer(&mbuf, false)) { c_alias_polys += mbuf.numtriangles; - memcpy(mbuf.index, renderlist, mbuf.numtriangles * sizeof(int[3])); + memcpy(mbuf.index, renderlist + 1, mbuf.numtriangles * sizeof(int[3])); memcpy(mbuf.vertex, aliasvert, mbuf.numverts * sizeof(float[4])); - R_ModulateColors(aliasvertcolor, mbuf.color, mbuf.numverts, mbuf.colorscale, mbuf.colorscale, mbuf.colorscale); - //memcpy(mbuf.color, aliasvertcolor, mbuf.numverts * sizeof(float[4])); - memcpy(mbuf.texcoords[0], (float *)(m->lump_texcoords.start + (int) m), mbuf.numverts * sizeof(float[2])); + R_FillColors(mbuf.color, mbuf.numverts, fogcolor[0] * mbuf.colorscale, fogcolor[1] * mbuf.colorscale, fogcolor[2] * mbuf.colorscale, ent->alpha * fog); + //memcpy(mbuf.texcoords[0], (float *)(m->lump_texcoords.start + (int) m), mbuf.numverts * sizeof(float[2])); R_Mesh_Render(); } - renderlist += mbuf.numtriangles * 3; - } - - if (fog) - { - renderlist = (int *)(m->lump_render.start + (int) m); - for (i = 0;i < m->numshaders;i++) - { - memset(&mbuf, 0, sizeof(mbuf)); - mbuf.numverts = m->numverts; - mbuf.numtriangles = *renderlist++; - mbuf.transparent = currentrenderentity->effects & EF_ADDITIVE || currentrenderentity->alpha != 1.0 || R_TextureHasAlpha(texture[i]); - mbuf.blendfunc1 = GL_SRC_ALPHA; - mbuf.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA; - // FIXME: need alpha mask for fogging... - //mbuf.tex[0] = R_GetTexture(texture[i]); - if (R_Mesh_Draw_GetBuffer(&mbuf, false)) - { - c_alias_polys += mbuf.numtriangles; - memcpy(mbuf.index, renderlist, mbuf.numtriangles * sizeof(int[3])); - memcpy(mbuf.vertex, aliasvert, mbuf.numverts * sizeof(float[4])); - R_FillColors(mbuf.color, mbuf.numverts, fogcolor[0] * mbuf.colorscale, fogcolor[1] * mbuf.colorscale, fogcolor[2] * mbuf.colorscale, currentrenderentity->alpha * fog); - //memcpy(mbuf.texcoords[0], (float *)(m->lump_texcoords.start + (int) m), mbuf.numverts * sizeof(float[2])); - R_Mesh_Render(); - } - renderlist += mbuf.numtriangles * 3; - } } } -void R_DrawZymoticModel (float fog) +void R_DrawZymoticModel (entity_render_t *ent) { + int i; zymtype1header_t *m; + rtexture_t *texture; - // FIXME: do better fog - m = currentrenderentity->model->zymdata_header; - ZymoticLerpBones(m->numbones, (zymbonematrix *)(m->lump_poses.start + (int) m), currentrenderentity->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)); + if (ent->alpha < (1.0f / 64.0f)) + return; // basically completely transparent - R_LightModel(m->numverts, 1 - fog, 1 - fog, 1 - fog, true); + c_models++; - R_DrawZymoticModelMesh(m, fog); + m = ent->model->zymdata_header; + for (i = 0;i < m->numshaders;i++) + { + texture = ((rtexture_t **)(m->lump_shaders.start + (int) m))[i]; + if (ent->effects & EF_ADDITIVE || ent->alpha != 1.0 || R_TextureHasAlpha(texture)) + R_MeshQueue_AddTransparent(ent->origin, R_DrawZymoticModelMeshCallback, ent, i); + else + R_MeshQueue_Add(R_DrawZymoticModelMeshCallback, ent, i); + } } -void R_DrawAliasModel (void) +void R_DrawQ1Q2AliasModel(entity_render_t *ent) { - float fog; - vec3_t diff; - - if (currentrenderentity->alpha < (1.0f / 64.0f)) + if (ent->alpha < (1.0f / 64.0f)) return; // basically completely transparent c_models++; - softwaretransformforentity(currentrenderentity); - - fog = 0; - if (fogenabled) - { - VectorSubtract(currentrenderentity->origin, r_origin, diff); - fog = DotProduct(diff,diff); - if (fog < 0.01f) - fog = 0.01f; - fog = exp(fogdensity/fog); - if (fog > 1) - fog = 1; - if (fog < 0.01f) - fog = 0; - // fog method: darken, additive fog - // 1. render model as normal, scaled by inverse of fog alpha (darkens it) - // 2. render fog as additive - } - - if (currentrenderentity->model->aliastype == ALIASTYPE_ZYM) - R_DrawZymoticModel(fog); + if (ent->effects & EF_ADDITIVE || ent->alpha != 1.0 || R_FetchSkinFrame(ent)->fog != NULL) + R_MeshQueue_AddTransparent(ent->origin, R_DrawQ1Q2AliasModelCallback, ent, 0); else - R_DrawQ1Q2AliasModel(fog); + R_MeshQueue_Add(R_DrawQ1Q2AliasModelCallback, ent, 0); } diff --git a/gl_rmain.c b/gl_rmain.c index 7640985b..6be6b3d8 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -21,8 +21,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "quakedef.h" -entity_render_t *currentrenderentity; - // used for dlight push checking and other things int r_framecount; @@ -351,6 +349,7 @@ void Render_Init(void) R_Textures_Init(); Mod_RenderInit(); gl_backend_init(); + R_MeshQueue_Init(); GL_Draw_Init(); GL_Main_Init(); GL_Models_Init(); @@ -388,6 +387,7 @@ static void R_MarkEntities (void) { int i; vec3_t v; + entity_render_t *ent; R_FarClip_Box(cl.worldmodel->normalmins, cl.worldmodel->normalmaxs); @@ -396,45 +396,45 @@ static void R_MarkEntities (void) for (i = 0;i < r_refdef.numentities;i++) { - currentrenderentity = r_refdef.entities[i]; - Mod_CheckLoaded(currentrenderentity->model); + ent = r_refdef.entities[i]; + Mod_CheckLoaded(ent->model); // move view-relative models to where they should be - if (currentrenderentity->flags & RENDER_VIEWMODEL) + if (ent->flags & RENDER_VIEWMODEL) { // remove flag so it will not be repeated incase RelinkEntities is not called again for a while - currentrenderentity->flags -= RENDER_VIEWMODEL; + ent->flags -= RENDER_VIEWMODEL; // transform origin - VectorCopy(currentrenderentity->origin, v); - currentrenderentity->origin[0] = v[0] * vpn[0] + v[1] * vright[0] + v[2] * vup[0] + r_origin[0]; - currentrenderentity->origin[1] = v[0] * vpn[1] + v[1] * vright[1] + v[2] * vup[1] + r_origin[1]; - currentrenderentity->origin[2] = v[0] * vpn[2] + v[1] * vright[2] + v[2] * vup[2] + r_origin[2]; + VectorCopy(ent->origin, v); + ent->origin[0] = v[0] * vpn[0] + v[1] * vright[0] + v[2] * vup[0] + r_origin[0]; + ent->origin[1] = v[0] * vpn[1] + v[1] * vright[1] + v[2] * vup[1] + r_origin[1]; + ent->origin[2] = v[0] * vpn[2] + v[1] * vright[2] + v[2] * vup[2] + r_origin[2]; // adjust angles - VectorAdd(currentrenderentity->angles, r_refdef.viewangles, currentrenderentity->angles); + VectorAdd(ent->angles, r_refdef.viewangles, ent->angles); } - if (currentrenderentity->angles[0] || currentrenderentity->angles[2]) + if (ent->angles[0] || ent->angles[2]) { - VectorMA(currentrenderentity->origin, currentrenderentity->scale, currentrenderentity->model->rotatedmins, currentrenderentity->mins); - VectorMA(currentrenderentity->origin, currentrenderentity->scale, currentrenderentity->model->rotatedmaxs, currentrenderentity->maxs); + VectorMA(ent->origin, ent->scale, ent->model->rotatedmins, ent->mins); + VectorMA(ent->origin, ent->scale, ent->model->rotatedmaxs, ent->maxs); } - else if (currentrenderentity->angles[1]) + else if (ent->angles[1]) { - VectorMA(currentrenderentity->origin, currentrenderentity->scale, currentrenderentity->model->yawmins, currentrenderentity->mins); - VectorMA(currentrenderentity->origin, currentrenderentity->scale, currentrenderentity->model->yawmaxs, currentrenderentity->maxs); + VectorMA(ent->origin, ent->scale, ent->model->yawmins, ent->mins); + VectorMA(ent->origin, ent->scale, ent->model->yawmaxs, ent->maxs); } else { - VectorMA(currentrenderentity->origin, currentrenderentity->scale, currentrenderentity->model->normalmins, currentrenderentity->mins); - VectorMA(currentrenderentity->origin, currentrenderentity->scale, currentrenderentity->model->normalmaxs, currentrenderentity->maxs); + VectorMA(ent->origin, ent->scale, ent->model->normalmins, ent->mins); + VectorMA(ent->origin, ent->scale, ent->model->normalmaxs, ent->maxs); } - if (R_VisibleCullBox(currentrenderentity->mins, currentrenderentity->maxs)) + if (R_VisibleCullBox(ent->mins, ent->maxs)) continue; - R_LerpAnimation(currentrenderentity); - currentrenderentity->visframe = r_framecount; + R_LerpAnimation(ent); + ent->visframe = r_framecount; - R_FarClip_Box(currentrenderentity->mins, currentrenderentity->maxs); + R_FarClip_Box(ent->mins, ent->maxs); } } @@ -442,6 +442,7 @@ static void R_MarkEntities (void) int R_DrawBModelSky (void) { int i, sky; + entity_render_t *ent; if (!r_drawentities.integer) return false; @@ -449,10 +450,10 @@ int R_DrawBModelSky (void) sky = false; for (i = 0;i < r_refdef.numentities;i++) { - currentrenderentity = r_refdef.entities[i]; - if (currentrenderentity->visframe == r_framecount && currentrenderentity->model->DrawSky) + ent = r_refdef.entities[i]; + if (ent->visframe == r_framecount && ent->model->DrawSky) { - currentrenderentity->model->DrawSky(); + ent->model->DrawSky(ent); sky = true; } } @@ -462,15 +463,16 @@ int R_DrawBModelSky (void) void R_DrawModels (void) { int i; + entity_render_t *ent; if (!r_drawentities.integer) return; for (i = 0;i < r_refdef.numentities;i++) { - currentrenderentity = r_refdef.entities[i]; - if (currentrenderentity->visframe == r_framecount && currentrenderentity->model->Draw) - currentrenderentity->model->Draw(); + ent = r_refdef.entities[i]; + if (ent->visframe == r_framecount && ent->model->Draw) + ent->model->Draw(ent); } } @@ -481,16 +483,18 @@ R_DrawViewModel */ void R_DrawViewModel (void) { + entity_render_t *ent; + // FIXME: move these checks to client if (!r_drawviewmodel.integer || chase_active.integer || envmap || !r_drawentities.integer || cl.items & IT_INVISIBILITY || cl.stats[STAT_HEALTH] <= 0 || !cl.viewent.render.model) return; - currentrenderentity = &cl.viewent.render; - Mod_CheckLoaded(currentrenderentity->model); + ent = &cl.viewent.render; + Mod_CheckLoaded(ent->model); - R_LerpAnimation(currentrenderentity); + R_LerpAnimation(ent); - currentrenderentity->model->Draw(); + ent->model->Draw(ent); } static void R_SetFrustum (void) @@ -596,6 +600,7 @@ r_refdef must be set before the first call */ void R_RenderView (void) { + entity_render_t *world = &cl_entities[0].render; if (!cl.worldmodel) return; //Host_Error ("R_RenderView: NULL worldmodel"); @@ -609,23 +614,26 @@ void R_RenderView (void) R_SkyStartFrame(); R_BuildLightList(); + R_MeshQueue_BeginScene(); + R_FarClip_Start(r_origin, vpn, 768.0f); R_TimeReport("setup"); - R_DrawWorld(); + R_DrawWorld(world); R_TimeReport("worldnode"); R_MarkEntities(); R_TimeReport("markentity"); - R_MarkWorldLights(); + R_MarkWorldLights(world); R_TimeReport("marklights"); r_farclip = R_FarClip_Finish() + 256.0f; R_Mesh_Start(r_farclip); + if (skyrendermasked) { if (R_DrawBModelSky()) @@ -637,17 +645,17 @@ void R_RenderView (void) R_TimeReport("viewmodel"); } - R_SetupForWorldRendering(); - R_PrepareSurfaces(); + R_SetupForWorldRendering(world); + R_PrepareSurfaces(world); R_TimeReport("surfprep"); - R_DrawSurfaces(SHADERSTAGE_SKY); - R_DrawSurfaces(SHADERSTAGE_NORMAL); + R_DrawSurfaces(world, SHADERSTAGE_SKY); + R_DrawSurfaces(world, SHADERSTAGE_NORMAL); R_TimeReport("surfdraw"); if (r_drawportals.integer) { - R_DrawPortals(); + R_DrawPortals(world); R_TimeReport("portals"); } @@ -670,6 +678,8 @@ void R_RenderView (void) R_DrawExplosions(); R_TimeReport("explosions"); + R_MeshQueue_EndScene(); + // draw transparent meshs R_Mesh_AddTransparent(); R_TimeReport("addtrans"); @@ -677,13 +687,12 @@ void R_RenderView (void) R_DrawCoronas(); R_TimeReport("coronas"); - R_BlendView(); - R_TimeReport("blendview"); - R_DrawCrosshair(); R_TimeReport("crosshair"); - // render any queued meshs + R_BlendView(); + R_TimeReport("blendview"); + R_Mesh_Finish(); R_TimeReport("meshfinish"); } diff --git a/gl_rsurf.c b/gl_rsurf.c index c9ce94ca..c0dbab46 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 (msurface_t *surf, int dlightchanged) +static void R_BuildLightMap (entity_render_t *ent, msurface_t *surf, int dlightchanged) { if (!r_floatbuildlightmap.integer) { @@ -261,7 +261,7 @@ static void R_BuildLightMap (msurface_t *surf, int dlightchanged) // set to full bright if no light data bl = intblocklights; - if ((currentrenderentity->effects & EF_FULLBRIGHT) || !currentrenderentity->model->lightdata) + if ((ent->effects & EF_FULLBRIGHT) || !ent->model->lightdata) { for (i = 0;i < size3;i++) bl[i] = 255*256; @@ -302,7 +302,7 @@ static void R_BuildLightMap (msurface_t *surf, int dlightchanged) out = templight; // deal with lightmap brightness scale shift = 7 + lightscalebit + 8; - if (currentrenderentity->model->lightmaprgba) + if (ent->model->lightmaprgba) { stride = (surf->lightmaptexturestride - smax) * 4; for (i = 0;i < tmax;i++, out += stride) @@ -355,7 +355,7 @@ static void R_BuildLightMap (msurface_t *surf, int dlightchanged) // set to full bright if no light data bl = floatblocklights; - if ((currentrenderentity->effects & EF_FULLBRIGHT) || !currentrenderentity->model->lightdata) + if ((ent->effects & EF_FULLBRIGHT) || !ent->model->lightdata) j = 255*256; else j = r_ambient.value * 512.0f; // would be 128.0f logically, but using 512.0f to match winquake style @@ -392,7 +392,7 @@ static void R_BuildLightMap (msurface_t *surf, int dlightchanged) out = templight; // deal with lightmap brightness scale scale = 1.0f / (1 << (7 + lightscalebit + 8)); - if (currentrenderentity->model->lightmaprgba) + if (ent->model->lightmaprgba) { stride = (surf->lightmaptexturestride - smax) * 4; for (i = 0;i < tmax;i++, out += stride) @@ -617,7 +617,7 @@ void R_Stain (vec3_t origin, float radius, int cr1, int cg1, int cb1, int ca1, i ============================================================= */ -static void RSurfShader_Sky(msurface_t *firstsurf) +static void RSurfShader_Sky(entity_render_t *ent, msurface_t *firstsurf) { msurface_t *surf; int i; @@ -628,7 +628,7 @@ static void RSurfShader_Sky(msurface_t *firstsurf) float *outv, *outc; // LordHavoc: HalfLife maps have freaky skypolys... - if (currentrenderentity->model->ishlbsp) + if (ent->model->ishlbsp) return; if (skyrendernow) @@ -732,7 +732,7 @@ static int RSurf_LightCheck(int *dlightbits, surfmesh_t *mesh) return false; } -static void RSurfShader_Water_Pass_Base(msurface_t *surf) +static void RSurfShader_Water_Pass_Base(entity_render_t *ent, msurface_t *surf) { int i, size3; surfvertex_t *v; @@ -741,9 +741,9 @@ static void RSurfShader_Water_Pass_Base(msurface_t *surf) qbyte *lm; surfmesh_t *mesh; rmeshbufferinfo_t m; - float alpha = currentrenderentity->alpha * (surf->flags & SURF_DRAWNOALPHA ? 1 : r_wateralpha.value); + float alpha = ent->alpha * (surf->flags & SURF_DRAWNOALPHA ? 1 : r_wateralpha.value); memset(&m, 0, sizeof(m)); - if (currentrenderentity->effects & EF_ADDITIVE) + if (ent->effects & EF_ADDITIVE) { m.transparent = true; m.blendfunc1 = GL_SRC_ALPHA; @@ -764,7 +764,7 @@ static void RSurfShader_Water_Pass_Base(msurface_t *surf) m.depthwrite = false; m.depthdisable = false; m.tex[0] = R_GetTexture(surf->currenttexture->texture); - if (surf->flags & SURF_DRAWFULLBRIGHT || currentrenderentity->effects & EF_FULLBRIGHT) + if (surf->flags & SURF_DRAWFULLBRIGHT || ent->effects & EF_FULLBRIGHT) { for (mesh = surf->mesh;mesh;mesh = mesh->chain) { @@ -858,7 +858,7 @@ static void RSurfShader_Water_Pass_Base(msurface_t *surf) } } -static void RSurfShader_Water_Pass_Fog(msurface_t *surf) +static void RSurfShader_Water_Pass_Fog(entity_render_t *ent, msurface_t *surf) { int i; surfvertex_t *v; @@ -866,9 +866,9 @@ static void RSurfShader_Water_Pass_Fog(msurface_t *surf) float base[3], f; surfmesh_t *mesh; rmeshbufferinfo_t m; - float alpha = currentrenderentity->alpha * (surf->flags & SURF_DRAWNOALPHA ? 1 : r_wateralpha.value); + float alpha = ent->alpha * (surf->flags & SURF_DRAWNOALPHA ? 1 : r_wateralpha.value); memset(&m, 0, sizeof(m)); - m.transparent = currentrenderentity->effects & EF_ADDITIVE || surf->currenttexture->fogtexture != NULL || alpha < 1; + m.transparent = ent->effects & EF_ADDITIVE || surf->currenttexture->fogtexture != NULL || alpha < 1; m.blendfunc1 = GL_SRC_ALPHA; m.blendfunc2 = GL_ONE; m.depthwrite = false; @@ -904,17 +904,17 @@ static void RSurfShader_Water_Pass_Fog(msurface_t *surf) } } -static void RSurfShader_Water(msurface_t *firstsurf) +static void RSurfShader_Water(entity_render_t *ent, msurface_t *firstsurf) { msurface_t *surf; for (surf = firstsurf;surf;surf = surf->chain) - RSurfShader_Water_Pass_Base(surf); + RSurfShader_Water_Pass_Base(ent, surf); if (fogenabled) for (surf = firstsurf;surf;surf = surf->chain) - RSurfShader_Water_Pass_Fog(surf); + RSurfShader_Water_Pass_Fog(ent, surf); } -static void RSurfShader_Wall_Pass_BaseVertex(msurface_t *surf) +static void RSurfShader_Wall_Pass_BaseVertex(entity_render_t *ent, msurface_t *surf) { int i, size3; surfvertex_t *v; @@ -924,13 +924,13 @@ static void RSurfShader_Wall_Pass_BaseVertex(msurface_t *surf) surfmesh_t *mesh; rmeshbufferinfo_t m; memset(&m, 0, sizeof(m)); - if (currentrenderentity->effects & EF_ADDITIVE) + if (ent->effects & EF_ADDITIVE) { m.transparent = true; m.blendfunc1 = GL_SRC_ALPHA; m.blendfunc2 = GL_ONE; } - else if (surf->currenttexture->fogtexture != NULL || currentrenderentity->alpha != 1) + else if (surf->currenttexture->fogtexture != NULL || ent->alpha != 1) { m.transparent = true; m.blendfunc1 = GL_SRC_ALPHA; @@ -948,9 +948,9 @@ static void RSurfShader_Wall_Pass_BaseVertex(msurface_t *surf) size3 = ((surf->extents[0]>>4)+1)*((surf->extents[1]>>4)+1)*3; - base[0] = base[1] = base[2] = currentrenderentity->effects & EF_FULLBRIGHT ? 2.0f : r_ambient.value * (1.0f / 64.0f); + base[0] = base[1] = base[2] = ent->effects & EF_FULLBRIGHT ? 2.0f : r_ambient.value * (1.0f / 64.0f); - ca = currentrenderentity->alpha; + ca = ent->alpha; for (mesh = surf->mesh;mesh;mesh = mesh->chain) { m.numtriangles = mesh->numtriangles; @@ -961,7 +961,7 @@ static void RSurfShader_Wall_Pass_BaseVertex(msurface_t *surf) cl = m.colorscale; memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3])); - if (currentrenderentity->effects & EF_FULLBRIGHT) + 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) { @@ -1030,7 +1030,7 @@ static void RSurfShader_Wall_Pass_BaseVertex(msurface_t *surf) } } -static void RSurfShader_Wall_Pass_BaseFullbright(msurface_t *surf) +static void RSurfShader_Wall_Pass_BaseFullbright(entity_render_t *ent, msurface_t *surf) { int i; surfvertex_t *v; @@ -1038,13 +1038,13 @@ static void RSurfShader_Wall_Pass_BaseFullbright(msurface_t *surf) surfmesh_t *mesh; rmeshbufferinfo_t m; memset(&m, 0, sizeof(m)); - if (currentrenderentity->effects & EF_ADDITIVE) + if (ent->effects & EF_ADDITIVE) { m.transparent = true; m.blendfunc1 = GL_SRC_ALPHA; m.blendfunc2 = GL_ONE; } - else if (surf->currenttexture->fogtexture != NULL || currentrenderentity->alpha != 1) + else if (surf->currenttexture->fogtexture != NULL || ent->alpha != 1) { m.transparent = true; m.blendfunc1 = GL_SRC_ALPHA; @@ -1059,7 +1059,7 @@ static void RSurfShader_Wall_Pass_BaseFullbright(msurface_t *surf) m.depthwrite = false; m.depthdisable = false; m.tex[0] = R_GetTexture(surf->currenttexture->texture); - ca = currentrenderentity->alpha; + ca = ent->alpha; for (mesh = surf->mesh;mesh;mesh = mesh->chain) { m.numtriangles = mesh->numtriangles; @@ -1089,7 +1089,7 @@ static void RSurfShader_Wall_Pass_BaseFullbright(msurface_t *surf) } } -static void RSurfShader_Wall_Pass_Glow(msurface_t *surf) +static void RSurfShader_Wall_Pass_Glow(entity_render_t *ent, msurface_t *surf) { int i; surfvertex_t *v; @@ -1097,11 +1097,11 @@ static void RSurfShader_Wall_Pass_Glow(msurface_t *surf) surfmesh_t *mesh; rmeshbufferinfo_t m; memset(&m, 0, sizeof(m)); - m.transparent = currentrenderentity->effects & EF_ADDITIVE || surf->currenttexture->fogtexture != NULL || currentrenderentity->alpha != 1; + 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 = currentrenderentity->alpha; + ca = ent->alpha; for (mesh = surf->mesh;mesh;mesh = mesh->chain) { m.numtriangles = mesh->numtriangles; @@ -1131,7 +1131,7 @@ static void RSurfShader_Wall_Pass_Glow(msurface_t *surf) } } -static void RSurfShader_Wall_Pass_Fog(msurface_t *surf) +static void RSurfShader_Wall_Pass_Fog(entity_render_t *ent, msurface_t *surf) { int i; surfvertex_t *v; @@ -1139,10 +1139,10 @@ static void RSurfShader_Wall_Pass_Fog(msurface_t *surf) surfmesh_t *mesh; rmeshbufferinfo_t m; memset(&m, 0, sizeof(m)); - m.transparent = currentrenderentity->effects & EF_ADDITIVE || surf->currenttexture->fogtexture != NULL || currentrenderentity->alpha != 1; + m.transparent = ent->effects & EF_ADDITIVE || surf->currenttexture->fogtexture != NULL || ent->alpha != 1; m.blendfunc1 = GL_SRC_ALPHA; m.blendfunc2 = GL_ONE; - ca = currentrenderentity->alpha; + ca = ent->alpha; for (mesh = surf->mesh;mesh;mesh = mesh->chain) { m.numtriangles = mesh->numtriangles; @@ -1168,7 +1168,7 @@ static void RSurfShader_Wall_Pass_Fog(msurface_t *surf) } } -static void RSurfShader_OpaqueWall_Pass_TripleTexCombine(msurface_t *surf) +static void RSurfShader_OpaqueWall_Pass_TripleTexCombine(entity_render_t *ent, msurface_t *surf) { int i; surfvertex_t *v; @@ -1214,7 +1214,7 @@ static void RSurfShader_OpaqueWall_Pass_TripleTexCombine(msurface_t *surf) } } -static void RSurfShader_OpaqueWall_Pass_BaseMTex(msurface_t *surf) +static void RSurfShader_OpaqueWall_Pass_BaseMTex(entity_render_t *ent, msurface_t *surf) { int i; surfvertex_t *v; @@ -1254,7 +1254,7 @@ static void RSurfShader_OpaqueWall_Pass_BaseMTex(msurface_t *surf) } } -static void RSurfShader_OpaqueWall_Pass_BaseTexture(msurface_t *surf) +static void RSurfShader_OpaqueWall_Pass_BaseTexture(entity_render_t *ent, msurface_t *surf) { int i; surfvertex_t *v; @@ -1291,7 +1291,7 @@ static void RSurfShader_OpaqueWall_Pass_BaseTexture(msurface_t *surf) } } -static void RSurfShader_OpaqueWall_Pass_BaseLightmap(msurface_t *surf) +static void RSurfShader_OpaqueWall_Pass_BaseLightmap(entity_render_t *ent, msurface_t *surf) { int i; surfvertex_t *v; @@ -1328,7 +1328,7 @@ static void RSurfShader_OpaqueWall_Pass_BaseLightmap(msurface_t *surf) } } -static void RSurfShader_OpaqueWall_Pass_Light(msurface_t *surf) +static void RSurfShader_OpaqueWall_Pass_Light(entity_render_t *ent, msurface_t *surf) { int i; surfvertex_t *v; @@ -1338,7 +1338,7 @@ static void RSurfShader_OpaqueWall_Pass_Light(msurface_t *surf) if (surf->dlightframe != r_framecount) return; - if (currentrenderentity->effects & EF_FULLBRIGHT) + if (ent->effects & EF_FULLBRIGHT) return; memset(&m, 0, sizeof(m)); @@ -1378,7 +1378,7 @@ static void RSurfShader_OpaqueWall_Pass_Light(msurface_t *surf) } } -static void RSurfShader_OpaqueWall_Pass_Fog(msurface_t *surf) +static void RSurfShader_OpaqueWall_Pass_Fog(entity_render_t *ent, msurface_t *surf) { int i; surfvertex_t *v; @@ -1412,7 +1412,7 @@ static void RSurfShader_OpaqueWall_Pass_Fog(msurface_t *surf) } } -static void RSurfShader_OpaqueWall_Pass_BaseDetail(msurface_t *surf) +static void RSurfShader_OpaqueWall_Pass_BaseDetail(entity_render_t *ent, msurface_t *surf) { int i; surfvertex_t *v; @@ -1447,7 +1447,7 @@ static void RSurfShader_OpaqueWall_Pass_BaseDetail(msurface_t *surf) } } -static void RSurfShader_OpaqueWall_Pass_Glow(msurface_t *surf) +static void RSurfShader_OpaqueWall_Pass_Glow(entity_render_t *ent, msurface_t *surf) { int i; surfvertex_t *v; @@ -1482,54 +1482,54 @@ static void RSurfShader_OpaqueWall_Pass_Glow(msurface_t *surf) } } -static void RSurfShader_Wall_Fullbright(msurface_t *firstsurf) +static void RSurfShader_Wall_Fullbright(entity_render_t *ent, msurface_t *firstsurf) { msurface_t *surf; for (surf = firstsurf;surf;surf = surf->chain) { c_brush_polys++; - RSurfShader_Wall_Pass_BaseFullbright(surf); + RSurfShader_Wall_Pass_BaseFullbright(ent, surf); } for (surf = firstsurf;surf;surf = surf->chain) if (surf->currenttexture->glowtexture) - RSurfShader_Wall_Pass_Glow(surf); + RSurfShader_Wall_Pass_Glow(ent, surf); if (fogenabled) for (surf = firstsurf;surf;surf = surf->chain) - RSurfShader_Wall_Pass_Fog(surf); + RSurfShader_Wall_Pass_Fog(ent, surf); } -static void RSurfShader_Wall_Vertex(msurface_t *firstsurf) +static void RSurfShader_Wall_Vertex(entity_render_t *ent, msurface_t *firstsurf) { msurface_t *surf; for (surf = firstsurf;surf;surf = surf->chain) { c_brush_polys++; - RSurfShader_Wall_Pass_BaseVertex(surf); + RSurfShader_Wall_Pass_BaseVertex(ent, surf); } for (surf = firstsurf;surf;surf = surf->chain) if (surf->currenttexture->glowtexture) - RSurfShader_Wall_Pass_Glow(surf); + RSurfShader_Wall_Pass_Glow(ent, surf); if (fogenabled) for (surf = firstsurf;surf;surf = surf->chain) - RSurfShader_Wall_Pass_Fog(surf); + RSurfShader_Wall_Pass_Fog(ent, surf); } -static void RSurfShader_Wall_Lightmap(msurface_t *firstsurf) +static void RSurfShader_Wall_Lightmap(entity_render_t *ent, msurface_t *firstsurf) { msurface_t *surf; - if (r_vertexsurfaces.integer || firstsurf->currenttexture->fogtexture != NULL || currentrenderentity->alpha != 1 || currentrenderentity->effects & EF_ADDITIVE) + if (r_vertexsurfaces.integer || firstsurf->currenttexture->fogtexture != NULL || ent->alpha != 1 || ent->effects & EF_ADDITIVE) { for (surf = firstsurf;surf;surf = surf->chain) { c_brush_polys++; - RSurfShader_Wall_Pass_BaseVertex(surf); + RSurfShader_Wall_Pass_BaseVertex(ent, surf); } for (surf = firstsurf;surf;surf = surf->chain) if (surf->currenttexture->glowtexture) - RSurfShader_Wall_Pass_Glow(surf); + RSurfShader_Wall_Pass_Glow(ent, surf); if (fogenabled) for (surf = firstsurf;surf;surf = surf->chain) - RSurfShader_Wall_Pass_Fog(surf); + RSurfShader_Wall_Pass_Fog(ent, surf); } else { @@ -1540,7 +1540,7 @@ static void RSurfShader_Wall_Lightmap(msurface_t *firstsurf) for (surf = firstsurf;surf;surf = surf->chain) { c_brush_polys++; - RSurfShader_OpaqueWall_Pass_TripleTexCombine(surf); + RSurfShader_OpaqueWall_Pass_TripleTexCombine(ent, surf); } } else @@ -1548,11 +1548,11 @@ static void RSurfShader_Wall_Lightmap(msurface_t *firstsurf) for (surf = firstsurf;surf;surf = surf->chain) { c_brush_polys++; - RSurfShader_OpaqueWall_Pass_BaseMTex(surf); + RSurfShader_OpaqueWall_Pass_BaseMTex(ent, surf); } if (r_detailtextures.integer) for (surf = firstsurf;surf;surf = surf->chain) - RSurfShader_OpaqueWall_Pass_BaseDetail(surf); + RSurfShader_OpaqueWall_Pass_BaseDetail(ent, surf); } } else @@ -1560,24 +1560,24 @@ static void RSurfShader_Wall_Lightmap(msurface_t *firstsurf) for (surf = firstsurf;surf;surf = surf->chain) { c_brush_polys++; - RSurfShader_OpaqueWall_Pass_BaseTexture(surf); + RSurfShader_OpaqueWall_Pass_BaseTexture(ent, surf); } for (surf = firstsurf;surf;surf = surf->chain) - RSurfShader_OpaqueWall_Pass_BaseLightmap(surf); + RSurfShader_OpaqueWall_Pass_BaseLightmap(ent, surf); if (r_detailtextures.integer) for (surf = firstsurf;surf;surf = surf->chain) - RSurfShader_OpaqueWall_Pass_BaseDetail(surf); + RSurfShader_OpaqueWall_Pass_BaseDetail(ent, surf); } if (!r_dlightmap.integer) for (surf = firstsurf;surf;surf = surf->chain) if (surf->dlightframe == r_framecount) - RSurfShader_OpaqueWall_Pass_Light(surf); + RSurfShader_OpaqueWall_Pass_Light(ent, surf); for (surf = firstsurf;surf;surf = surf->chain) if (surf->currenttexture->glowtexture) - RSurfShader_OpaqueWall_Pass_Glow(surf); + RSurfShader_OpaqueWall_Pass_Glow(ent, surf); if (fogenabled) for (surf = firstsurf;surf;surf = surf->chain) - RSurfShader_OpaqueWall_Pass_Fog(surf); + RSurfShader_OpaqueWall_Pass_Fog(ent, surf); } } @@ -1589,7 +1589,7 @@ static void RSurfShader_Wall_Lightmap(msurface_t *firstsurf) ============================================================= */ -static void R_SolidWorldNode (void) +static void R_SolidWorldNode (entity_render_t *ent) { if (r_viewleaf->contents != CONTENTS_SOLID) { @@ -1829,7 +1829,7 @@ Cshader_t *Cshaders[5] = &Cshader_sky }; -void R_PrepareSurfaces(void) +void R_PrepareSurfaces(entity_render_t *ent) { int i, alttextures, texframe, framecount; texture_t *t; @@ -1839,8 +1839,8 @@ void R_PrepareSurfaces(void) for (i = 0;i < Cshader_count;i++) Cshaders[i]->chain = NULL; - model = currentrenderentity->model; - alttextures = currentrenderentity->frame != 0; + model = ent->model; + alttextures = ent->frame != 0; texframe = (int)(cl.time * 5.0f); for (i = 0;i < model->nummodelsurfaces;i++) @@ -1871,7 +1871,7 @@ void R_PrepareSurfaces(void) } } -void R_DrawSurfaces (int type) +void R_DrawSurfaces (entity_render_t *ent, int type) { int i; Cshader_t *shader; @@ -1880,11 +1880,11 @@ void R_DrawSurfaces (int type) { shader = Cshaders[i]; if (shader->chain && shader->shaderfunc[type]) - shader->shaderfunc[type](shader->chain); + shader->shaderfunc[type](ent, shader->chain); } } -void R_DrawPortals(void) +void R_DrawPortals(entity_render_t *ent) { int drawportals, i; float *v; @@ -1933,7 +1933,7 @@ void R_DrawPortals(void) } } -void R_SetupForBModelRendering(void) +void R_SetupForBModelRendering(entity_render_t *ent) { int i; msurface_t *surf; @@ -1943,9 +1943,9 @@ void R_SetupForBModelRendering(void) // because bmodels can be reused, we have to decide which things to render // from scratch every time - model = currentrenderentity->model; + model = ent->model; - softwaretransformforentity (currentrenderentity); + softwaretransformforentity (ent); softwareuntransform(r_origin, modelorg); for (i = 0;i < model->nummodelsurfaces;i++) @@ -1962,53 +1962,51 @@ void R_SetupForBModelRendering(void) } } -void R_SetupForWorldRendering(void) +void R_SetupForWorldRendering(entity_render_t *ent) { // there is only one instance of the world, but it can be rendered in // multiple stages - - currentrenderentity = &cl_entities[0].render; softwaretransformidentity(); } -static void R_SurfMarkLights (void) +static void R_SurfMarkLights (entity_render_t *ent) { int i; msurface_t *surf; if (r_dynamic.integer) - R_MarkLights(); + R_MarkLights(ent); if (!r_vertexsurfaces.integer) { - for (i = 0;i < currentrenderentity->model->nummodelsurfaces;i++) + for (i = 0;i < ent->model->nummodelsurfaces;i++) { - surf = currentrenderentity->model->modelsortedsurfaces[i]; + surf = ent->model->modelsortedsurfaces[i]; if (surf->visframe == r_framecount && surf->lightmaptexture != NULL) { if (surf->cached_dlight || surf->cached_ambient != r_ambient.value || surf->cached_lightscalebit != lightscalebit) - R_BuildLightMap(surf, false); // base lighting changed + R_BuildLightMap(ent, surf, false); // base lighting changed else if (r_dynamic.integer) { if (surf->styles[0] != 255 && (d_lightstylevalue[surf->styles[0]] != surf->cached_light[0] || (surf->styles[1] != 255 && (d_lightstylevalue[surf->styles[1]] != surf->cached_light[1] || (surf->styles[2] != 255 && (d_lightstylevalue[surf->styles[2]] != surf->cached_light[2] || (surf->styles[3] != 255 && (d_lightstylevalue[surf->styles[3]] != surf->cached_light[3])))))))) - R_BuildLightMap(surf, false); // base lighting changed + R_BuildLightMap(ent, surf, false); // base lighting changed else if (surf->dlightframe == r_framecount && r_dlightmap.integer) - R_BuildLightMap(surf, true); // only dlights + R_BuildLightMap(ent, surf, true); // only dlights } } } } } -void R_MarkWorldLights(void) +void R_MarkWorldLights(entity_render_t *ent) { - R_SetupForWorldRendering(); - R_SurfMarkLights(); + R_SetupForWorldRendering(ent); + R_SurfMarkLights(ent); } /* @@ -2016,14 +2014,14 @@ void R_MarkWorldLights(void) R_DrawWorld ============= */ -void R_DrawWorld (void) +void R_DrawWorld (entity_render_t *ent) { - R_SetupForWorldRendering(); + R_SetupForWorldRendering(ent); if (r_viewleaf->contents == CONTENTS_SOLID || r_novis.integer || r_viewleaf->compressed_vis == NULL) - R_SolidWorldNode (); + R_SolidWorldNode (ent); else - R_PVSWorldNode (); + R_PVSWorldNode (ent); } /* @@ -2031,30 +2029,30 @@ void R_DrawWorld (void) R_DrawBrushModel ================= */ -void R_DrawBrushModelSky (void) +void R_DrawBrushModelSky (entity_render_t *ent) { - R_SetupForBModelRendering(); + R_SetupForBModelRendering(ent); - R_PrepareSurfaces(); - R_DrawSurfaces(SHADERSTAGE_SKY); + R_PrepareSurfaces(ent); + R_DrawSurfaces(ent, SHADERSTAGE_SKY); } -void R_DrawBrushModelNormal (void) +void R_DrawBrushModelNormal (entity_render_t *ent) { c_bmodels++; // have to flush queue because of possible lightmap reuse R_Mesh_Render(); - R_SetupForBModelRendering(); + R_SetupForBModelRendering(ent); - R_SurfMarkLights(); + R_SurfMarkLights(ent); - R_PrepareSurfaces(); + R_PrepareSurfaces(ent); if (!skyrendermasked) - R_DrawSurfaces(SHADERSTAGE_SKY); - R_DrawSurfaces(SHADERSTAGE_NORMAL); + R_DrawSurfaces(ent, SHADERSTAGE_SKY); + R_DrawSurfaces(ent, SHADERSTAGE_NORMAL); } static void gl_surf_start(void) diff --git a/model_alias.c b/model_alias.c index 6247e5b6..baf58a1a 100644 --- a/model_alias.c +++ b/model_alias.c @@ -492,7 +492,7 @@ void Mod_LoadAliasModel (model_t *mod, void *buffer) loadmodel->yawmins[2] = loadmodel->normalmins[2]; loadmodel->yawmaxs[2] = loadmodel->normalmaxs[2]; - loadmodel->Draw = R_DrawAliasModel; + loadmodel->Draw = R_DrawQ1Q2AliasModel; loadmodel->DrawSky = NULL; loadmodel->DrawShadow = NULL; } @@ -566,7 +566,7 @@ void Mod_LoadQ2AliasModel (model_t *mod, void *buffer) loadmodel->type = mod_alias; loadmodel->aliastype = ALIASTYPE_MDLMD2; - loadmodel->Draw = R_DrawAliasModel; + loadmodel->Draw = R_DrawQ1Q2AliasModel; loadmodel->DrawSky = NULL; loadmodel->DrawShadow = NULL; @@ -952,7 +952,7 @@ void Mod_LoadZymoticModel(model_t *mod, void *buffer) loadmodel->yawmins[2] = loadmodel->normalmins[2]; loadmodel->yawmaxs[2] = loadmodel->normalmaxs[2]; - loadmodel->Draw = R_DrawAliasModel; + loadmodel->Draw = R_DrawZymoticModel; loadmodel->DrawSky = NULL; loadmodel->DrawShadow = NULL; } diff --git a/model_brush.h b/model_brush.h index 05d81058..9d6ffc68 100644 --- a/model_brush.h +++ b/model_brush.h @@ -204,10 +204,11 @@ msurface_t; #define SHADERSTAGE_NORMAL 1 #define SHADERSTAGE_COUNT 2 +struct entity_render_s; // change this stuff when real shaders are added typedef struct Cshader_s { - void (*shaderfunc[SHADERSTAGE_COUNT])(msurface_t *firstsurf); + void (*shaderfunc[SHADERSTAGE_COUNT])(struct entity_render_s *ent, 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 90657ed2..6fc568cf 100644 --- a/model_shared.h +++ b/model_shared.h @@ -193,11 +193,11 @@ typedef struct model_s mspriteframe_t *sprdata_frames; // draw the model - void(*Draw)(void); + void(*Draw)(struct entity_render_s *ent); // draw the model's sky polygons (only used by brush models) - void(*DrawSky)(void); + void(*DrawSky)(struct entity_render_s *ent); // draw the model's shadows - void(*DrawShadow)(void); + void(*DrawShadow)(struct entity_render_s *ent); // memory pool for allocations mempool_t *mempool; diff --git a/r_explosion.c b/r_explosion.c index 507f1f74..da305b98 100644 --- a/r_explosion.c +++ b/r_explosion.c @@ -173,14 +173,16 @@ void R_NewExplosion(vec3_t org) } } -void R_DrawExplosion(explosion_t *e) +void R_DrawExplosionCallback(void *calldata1, int calldata2) { int i; float *c, *v, diff[3], centerdir[3], ifog, alpha, dist; rmeshbufferinfo_t m; + explosion_t *e; + e = calldata1; memset(&m, 0, sizeof(m)); - m.transparent = true; + m.transparent = false; m.blendfunc1 = GL_SRC_ALPHA; m.blendfunc2 = GL_ONE; m.numtriangles = EXPLOSIONTRIS; @@ -303,6 +305,6 @@ void R_DrawExplosions(void) return; for (i = 0;i < MAX_EXPLOSIONS;i++) if (explosion[i].alpha > 0.01f) - R_DrawExplosion(&explosion[i]); + R_MeshQueue_AddTransparent(explosion[i].origin, R_DrawExplosionCallback, &explosion[i], 0); } diff --git a/r_light.c b/r_light.c index e1207de8..f801562f 100644 --- a/r_light.c +++ b/r_light.c @@ -212,7 +212,7 @@ DYNAMIC LIGHTS R_MarkLights ============= */ -static void R_OldMarkLights (vec3_t lightorigin, rdlight_t *rd, int bit, int bitindex, mnode_t *node) +static void R_OldMarkLights (entity_render_t *ent, vec3_t lightorigin, rdlight_t *rd, int bit, int bitindex, mnode_t *node) { float ndist, maxdist; msurface_t *surf; @@ -255,7 +255,7 @@ loc0: } // mark the polygons - surf = currentrenderentity->model->surfaces + node->firstsurface; + surf = ent->model->surfaces + node->firstsurface; for (i=0 ; inumsurfaces ; i++, surf++) { int d, impacts, impactt; @@ -311,7 +311,7 @@ loc0: { if (node->children[1]->contents >= 0) { - R_OldMarkLights (lightorigin, rd, bit, bitindex, node->children[0]); + R_OldMarkLights (ent, lightorigin, rd, bit, bitindex, node->children[0]); node = node->children[1]; goto loc0; } @@ -329,7 +329,7 @@ loc0: } -static void R_VisMarkLights (rdlight_t *rd, int bit, int bitindex) +static void R_VisMarkLights (entity_render_t *ent, rdlight_t *rd, int bit, int bitindex) { static int lightframe = 0; mleaf_t *pvsleaf; @@ -345,12 +345,12 @@ static void R_VisMarkLights (rdlight_t *rd, int bit, int bitindex) if (!r_dynamic.integer) return; - model = currentrenderentity->model; + model = ent->model; softwareuntransform(rd->origin, lightorigin); if (!r_vismarklights.integer) { - R_OldMarkLights(lightorigin, rd, bit, bitindex, model->nodes + model->hulls[0].firstclipnode); + R_OldMarkLights(ent, lightorigin, rd, bit, bitindex, model->nodes + model->hulls[0].firstclipnode); return; } @@ -358,7 +358,7 @@ static void R_VisMarkLights (rdlight_t *rd, int bit, int bitindex) if (pvsleaf == NULL) { Con_Printf("R_VisMarkLights: NULL leaf??\n"); - R_OldMarkLights(lightorigin, rd, bit, bitindex, model->nodes + model->hulls[0].firstclipnode); + R_OldMarkLights(ent, lightorigin, rd, bit, bitindex, model->nodes + model->hulls[0].firstclipnode); return; } @@ -366,7 +366,7 @@ static void R_VisMarkLights (rdlight_t *rd, int bit, int bitindex) if (!in) { // no vis info, so make all visible - R_OldMarkLights(lightorigin, rd, bit, bitindex, model->nodes + model->hulls[0].firstclipnode); + R_OldMarkLights(ent, lightorigin, rd, bit, bitindex, model->nodes + model->hulls[0].firstclipnode); return; } @@ -476,11 +476,11 @@ static void R_VisMarkLights (rdlight_t *rd, int bit, int bitindex) } } -void R_MarkLights(void) +void R_MarkLights(entity_render_t *ent) { int i; for (i = 0;i < r_numdlights;i++) - R_VisMarkLights (r_dlight + i, 1 << (i & 31), i >> 5); + R_VisMarkLights (ent, r_dlight + i, 1 << (i & 31), i >> 5); } /* @@ -693,7 +693,7 @@ void R_CompleteLightPoint (vec3_t color, vec3_t p, int dynamic, mleaf_t *leaf) } } -void R_ModelLightPoint (vec3_t color, vec3_t p, int *dlightbits) +void R_ModelLightPoint (entity_render_t *ent, vec3_t color, vec3_t p, int *dlightbits) { mleaf_t *leaf; leaf = Mod_PointInLeaf(p, cl.worldmodel); @@ -704,7 +704,7 @@ void R_ModelLightPoint (vec3_t color, vec3_t p, int *dlightbits) return; } - if (r_fullbright.integer || !cl.worldmodel->lightdata || currentrenderentity->effects & EF_FULLBRIGHT) + if (r_fullbright.integer || !cl.worldmodel->lightdata || ent->effects & EF_FULLBRIGHT) { color[0] = color[1] = color[2] = 2; dlightbits[0] = dlightbits[1] = dlightbits[2] = dlightbits[3] = dlightbits[4] = dlightbits[5] = dlightbits[6] = dlightbits[7] = 0; @@ -730,7 +730,7 @@ void R_ModelLightPoint (vec3_t color, vec3_t p, int *dlightbits) dlightbits[0] = dlightbits[1] = dlightbits[2] = dlightbits[3] = dlightbits[4] = dlightbits[5] = dlightbits[6] = dlightbits[7] = 0; } -void R_LightModel(int numverts, float colorr, float colorg, float colorb, int worldcoords) +void R_LightModel(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]; @@ -751,30 +751,30 @@ void R_LightModel(int numverts, float colorr, float colorg, float colorb, int wo int modeldlightbits[8]; mlight_t *sl; rdlight_t *rd; - a = currentrenderentity->alpha; + a = ent->alpha; // scale of the model's coordinate space, to alter light attenuation to match // make the mscale squared so it can scale the squared distance results - mscale = currentrenderentity->scale * currentrenderentity->scale; - if ((maxnearlights != 0) && !r_fullbright.integer && !(currentrenderentity->effects & EF_FULLBRIGHT)) + mscale = ent->scale * ent->scale; + if ((maxnearlights != 0) && !r_fullbright.integer && !(ent->effects & EF_FULLBRIGHT)) { - R_ModelLightPoint(basecolor, currentrenderentity->origin, modeldlightbits); + R_ModelLightPoint(ent, basecolor, ent->origin, modeldlightbits); nl = &nearlight[0]; - VectorSubtract(currentrenderentity->origin, currentrenderentity->entlightsorigin, v); - if ((realtime > currentrenderentity->entlightstime && DotProduct(v,v) >= 1.0f)) + VectorSubtract(ent->origin, ent->entlightsorigin, v); + if ((realtime > ent->entlightstime && DotProduct(v,v) >= 1.0f)) { - currentrenderentity->numentlights = 0; - currentrenderentity->entlightstime = realtime + 0.2; - VectorCopy(currentrenderentity->origin, currentrenderentity->entlightsorigin); - for (i = 0, sl = cl.worldmodel->lights;i < cl.worldmodel->numlights && currentrenderentity->numentlights < MAXENTLIGHTS;i++, sl++) - if (CL_TraceLine(currentrenderentity->origin, sl->origin, NULL, NULL, 0, false) == 1) - currentrenderentity->entlights[currentrenderentity->numentlights++] = i; + 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 < currentrenderentity->numentlights;i++) + for (i = 0;i < ent->numentlights;i++) { - sl = cl.worldmodel->lights + currentrenderentity->entlights[i]; + sl = cl.worldmodel->lights + ent->entlights[i]; stylescale = d_lightstylevalue[sl->style] * (1.0f / 65536.0f); - VectorSubtract (currentrenderentity->origin, sl->origin, v); + VectorSubtract (ent->origin, sl->origin, v); f = ((1.0f / (DotProduct(v, v) * sl->falloff + sl->distbias)) - sl->subtract) * stylescale; VectorScale(sl->light, f, ambientcolor); intensity = DotProduct(ambientcolor, ambientcolor); @@ -825,7 +825,7 @@ void R_LightModel(int numverts, float colorr, float colorg, float colorb, int wo if (!(modeldlightbits[i >> 5] & (1 << (i & 31)))) continue; rd = r_dlight + i; - VectorSubtract (currentrenderentity->origin, rd->origin, v); + VectorSubtract (ent->origin, rd->origin, v); f = ((1.0f / (DotProduct(v, v) + LIGHTOFFSET)) - rd->subtract); VectorScale(rd->light, f, ambientcolor); intensity = DotProduct(ambientcolor, ambientcolor); @@ -874,7 +874,7 @@ void R_LightModel(int numverts, float colorr, float colorg, float colorb, int wo } else { - R_CompleteLightPoint (basecolor, currentrenderentity->origin, true, NULL); + R_CompleteLightPoint (basecolor, ent->origin, true, NULL); } basecolor[0] *= colorr; basecolor[1] *= colorg; diff --git a/r_light.h b/r_light.h index cc63e8bb..026a4ec0 100644 --- a/r_light.h +++ b/r_light.h @@ -18,10 +18,10 @@ extern rdlight_t r_dlight[MAX_DLIGHTS]; void R_BuildLightList(void); void R_AnimateLight(void); -void R_MarkLights(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(int numverts, float colorr, float colorg, float colorb, int worldcoords); +void R_LightModel(entity_render_t *ent, int numverts, float colorr, float colorg, float colorb, int worldcoords); #endif diff --git a/r_sprites.c b/r_sprites.c index f6ca3a4a..40abceff 100644 --- a/r_sprites.c +++ b/r_sprites.c @@ -3,11 +3,11 @@ #define LERPSPRITES -static int R_SpriteSetup (int type, float org[3], float left[3], float up[3]) +static int R_SpriteSetup (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]; - VectorCopy(currentrenderentity->origin, org); + VectorCopy(ent->origin, org); switch(type) { case SPR_VP_PARALLEL_UPRIGHT: @@ -26,7 +26,7 @@ static int R_SpriteSetup (int type, float org[3], float left[3], float up[3]) case SPR_FACING_UPRIGHT: // flames and such // vertical beam sprite, faces viewer's origin (not the view plane) - VectorSubtract(currentrenderentity->origin, r_origin, matrix3[0]); + VectorSubtract(ent->origin, r_origin, matrix3[0]); matrix3[0][2] = 0; VectorNormalizeFast(matrix3[0]); matrix3[1][0] = matrix3[0][1]; @@ -49,7 +49,7 @@ static int R_SpriteSetup (int type, float org[3], float left[3], float up[3]) case SPR_ORIENTED: // bullet marks on walls // ignores viewer entirely - AngleVectorsFLU (currentrenderentity->angles, matrix3[0], matrix3[1], matrix3[2]); + AngleVectorsFLU (ent->angles, matrix3[0], matrix3[1], matrix3[2]); // nudge it toward the view, so it will be infront of the wall VectorSubtract(org, vpn, org); break; @@ -57,7 +57,7 @@ static int R_SpriteSetup (int type, float org[3], float left[3], float up[3]) // I have no idea what people would use this for // oriented relative to view space // FIXME: test this and make sure it mimicks software - AngleVectorsFLU (currentrenderentity->angles, matrix1[0], matrix1[1], matrix1[2]); + AngleVectorsFLU (ent->angles, matrix1[0], matrix1[1], matrix1[2]); VectorCopy(vpn, matrix2[0]); VectorNegate(vright, matrix2[1]); VectorCopy(vup, matrix2[2]); @@ -65,10 +65,10 @@ static int R_SpriteSetup (int type, float org[3], float left[3], float up[3]) break; } - if (currentrenderentity->scale != 1) + if (ent->scale != 1) { - VectorScale(matrix3[1], currentrenderentity->scale, left); - VectorScale(matrix3[2], currentrenderentity->scale, up); + VectorScale(matrix3[1], ent->scale, left); + VectorScale(matrix3[2], ent->scale, up); } else { @@ -78,21 +78,20 @@ static int R_SpriteSetup (int type, float org[3], float left[3], float up[3]) return false; } -static void GL_DrawSpriteImage (int fog, mspriteframe_t *frame, int texture, vec3_t origin, vec3_t up, vec3_t left, float red, float green, float blue, float alpha) +static void R_DrawSpriteImage (int wantoverbright, int additive, mspriteframe_t *frame, int texture, vec3_t origin, vec3_t up, vec3_t left, float red, float green, float blue, float alpha) { rmeshbufferinfo_t m; memset(&m, 0, sizeof(m)); - m.transparent = true; + // the mesh was sorted already, so don't transparent sort + m.transparent = false; m.blendfunc1 = GL_SRC_ALPHA; m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA; - if ((currentrenderentity->effects & EF_ADDITIVE) - || (currentrenderentity->model->flags & EF_ADDITIVE) - || fog) + if (additive) m.blendfunc2 = GL_ONE; m.numtriangles = 2; m.numverts = 4; m.tex[0] = texture; - if (R_Mesh_Draw_GetBuffer(&m, !(currentrenderentity->model->flags & EF_FULLBRIGHT || currentrenderentity->effects & EF_FULLBRIGHT))) + if (R_Mesh_Draw_GetBuffer(&m, wantoverbright)) { m.index[0] = 0; m.index[1] = 1; @@ -125,38 +124,37 @@ static void GL_DrawSpriteImage (int fog, mspriteframe_t *frame, int texture, vec m.vertex[12] = origin[0] + frame->down * up[0] - frame->right * left[0]; m.vertex[13] = origin[1] + frame->down * up[1] - frame->right * left[1]; m.vertex[14] = origin[2] + frame->down * up[2] - frame->right * left[2]; + R_Mesh_Render(); } } -/* -================= -R_DrawSpriteModel -================= -*/ -void R_DrawSpriteModel () +void R_DrawSpriteModelCallback(void *calldata1, int calldata2) { - int i; - vec3_t left, up, org, color; + entity_render_t *ent; + int i, wantoverbright; + vec3_t left, up, org, color; mspriteframe_t *frame; vec3_t diff; - float fog, ifog; - - if (currentrenderentity->frameblend[0].frame < 0) - return; + float fog, ifog; - if (R_SpriteSetup(currentrenderentity->model->sprnum_type, org, left, up)) + ent = calldata1; + if (R_SpriteSetup(ent, ent->model->sprnum_type, org, left, up)) return; - c_sprites++; - - if ((currentrenderentity->model->flags & EF_FULLBRIGHT) || (currentrenderentity->effects & EF_FULLBRIGHT)) + if ((ent->model->flags & EF_FULLBRIGHT) || (ent->effects & EF_FULLBRIGHT)) + { color[0] = color[1] = color[2] = 1; + wantoverbright = false; + } else - R_CompleteLightPoint(color, currentrenderentity->origin, true, NULL); + { + R_CompleteLightPoint(color, ent->origin, true, NULL); + wantoverbright = color[0] > 1 || color[1] > 1 || color[2] > 1; + } if (fogenabled) { - VectorSubtract(currentrenderentity->origin, r_origin, diff); + VectorSubtract(ent->origin, r_origin, diff); fog = exp(fogdensity/DotProduct(diff,diff)); if (fog > 1) fog = 1; @@ -169,23 +167,38 @@ void R_DrawSpriteModel () // LordHavoc: interpolated sprite rendering for (i = 0;i < 4;i++) { - if (currentrenderentity->frameblend[i].lerp >= 0.01f) + if (ent->frameblend[i].lerp >= 0.01f) { - frame = currentrenderentity->model->sprdata_frames + currentrenderentity->frameblend[i].frame; - GL_DrawSpriteImage(false, frame, R_GetTexture(frame->texture), org, up, left, color[0] * ifog, color[1] * ifog, color[2] * ifog, currentrenderentity->alpha * currentrenderentity->frameblend[i].lerp); - if (fog * currentrenderentity->frameblend[i].lerp >= 0.01f) - GL_DrawSpriteImage(true, frame, R_GetTexture(frame->fogtexture), org, up, left, fogcolor[0],fogcolor[1],fogcolor[2], fog * currentrenderentity->alpha * currentrenderentity->frameblend[i].lerp); + frame = ent->model->sprdata_frames + ent->frameblend[i].frame; + R_DrawSpriteImage(wantoverbright, (ent->effects & EF_ADDITIVE) || (ent->model->flags & EF_ADDITIVE), frame, R_GetTexture(frame->texture), org, up, left, color[0] * ifog, color[1] * ifog, color[2] * ifog, ent->alpha * ent->frameblend[i].lerp); + if (fog * ent->frameblend[i].lerp >= 0.01f) + R_DrawSpriteImage(false, true, frame, R_GetTexture(frame->fogtexture), org, up, left, fogcolor[0],fogcolor[1],fogcolor[2], fog * ent->alpha * ent->frameblend[i].lerp); } } #else // LordHavoc: no interpolation frame = NULL; - for (i = 0;i < 4 && currentrenderentity->frameblend[i].lerp;i++) - frame = currentrenderentity->model->sprdata_frames + currentrenderentity->frameblend[i].frame; + for (i = 0;i < 4 && ent->frameblend[i].lerp;i++) + frame = ent->model->sprdata_frames + ent->frameblend[i].frame; - GL_DrawSpriteImage(false, frame, R_GetTexture(frame->texture), org, up, left, color[0] * ifog, color[1] * ifog, color[2] * ifog, currentrenderentity->alpha); - if (fog * currentrenderentity->frameblend[i].lerp >= 0.01f) - GL_DrawSpriteImage(true, frame, R_GetTexture(frame->fogtexture), org, up, left, fogcolor[0],fogcolor[1],fogcolor[2], fog * currentrenderentity->alpha); + R_DrawSpriteImage(wantoverbright, (ent->effects & EF_ADDITIVE) || (ent->model->flags & EF_ADDITIVE), frame, R_GetTexture(frame->texture), org, up, left, color[0] * ifog, color[1] * ifog, color[2] * ifog, ent->alpha); + if (fog * ent->frameblend[i].lerp >= 0.01f) + R_DrawSpriteImage(false, true, frame, R_GetTexture(frame->fogtexture), org, up, left, fogcolor[0],fogcolor[1],fogcolor[2], fog * ent->alpha); #endif } +/* +================= +R_DrawSpriteModel +================= +*/ +void R_DrawSpriteModel (entity_render_t *ent) +{ + if (ent->frameblend[0].frame < 0) + return; + + c_sprites++; + + R_MeshQueue_AddTransparent(ent->origin, R_DrawSpriteModelCallback, ent, 0); +} + diff --git a/render.h b/render.h index 394cc410..c3a5e09a 100644 --- a/render.h +++ b/render.h @@ -77,7 +77,6 @@ void R_FillColors(float *out, int verts, float r, float g, float b, float a); //============================================================================= -extern entity_render_t *currentrenderentity; extern int r_framecount; extern mplane_t frustum[4]; extern int c_brush_polys, c_alias_polys, c_light_polys, c_faces, c_nodes, c_leafs, c_models, c_bmodels, c_sprites, c_particles, c_dlights; @@ -111,14 +110,19 @@ void R_InitSky (qbyte *src, int bytesperpixel); // called at level load void R_NewMap (void); -void R_DrawWorld(void); -void R_SetupForWorldRendering(void); -void R_MarkWorldLights(void); -void R_PrepareSurfaces(void); -void R_DrawSurfaces(int type); -void R_DrawPortals(void); +void R_DrawWorld(entity_render_t *ent); +void R_SetupForWorldRendering(entity_render_t *ent); +void R_MarkWorldLights(entity_render_t *ent); +void R_PrepareSurfaces(entity_render_t *ent); +void R_DrawSurfaces(entity_render_t *ent, int type); +void R_DrawPortals(entity_render_t *ent); void R_DrawParticles(void); void R_DrawExplosions(void); +void R_DrawBrushModelSky (entity_render_t *ent); +void R_DrawBrushModelNormal (entity_render_t *ent); +void R_DrawZymoticModel (entity_render_t *ent); +void R_DrawQ1Q2AliasModel(entity_render_t *ent); +void R_DrawSpriteModel (entity_render_t *ent); // LordHavoc: vertex transform #include "transform.h" @@ -151,15 +155,12 @@ void R_Mesh_EnlargeFarClipBBox(vec3_t mins, vec3_t maxs); #include "r_modules.h" +#include "meshqueue.h" + extern float overbrightscale; #include "r_lerpanim.h" -void R_DrawBrushModelSky (void); -void R_DrawBrushModelNormal (void); -void R_DrawAliasModel (void); -void R_DrawSpriteModel (void); - extern cvar_t r_render; #include "image.h" -- 2.39.2