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++)
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);
}
}
}
}
-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;
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;
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);
}
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;
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;
{
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]));
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;
{
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]));
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;
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]));
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;
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]));
}
}
-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);
}
#include "quakedef.h"
-entity_render_t *currentrenderentity;
-
// used for dlight push checking and other things
int r_framecount;
R_Textures_Init();
Mod_RenderInit();
gl_backend_init();
+ R_MeshQueue_Init();
GL_Draw_Init();
GL_Main_Init();
GL_Models_Init();
{
int i;
vec3_t v;
+ entity_render_t *ent;
R_FarClip_Box(cl.worldmodel->normalmins, cl.worldmodel->normalmaxs);
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);
}
}
int R_DrawBModelSky (void)
{
int i, sky;
+ entity_render_t *ent;
if (!r_drawentities.integer)
return false;
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;
}
}
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);
}
}
*/
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)
*/
void R_RenderView (void)
{
+ entity_render_t *world = &cl_entities[0].render;
if (!cl.worldmodel)
return; //Host_Error ("R_RenderView: NULL worldmodel");
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())
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");
}
R_DrawExplosions();
R_TimeReport("explosions");
+ R_MeshQueue_EndScene();
+
// draw transparent meshs
R_Mesh_AddTransparent();
R_TimeReport("addtrans");
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");
}
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)
{
// 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;
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)
// 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
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)
=============================================================
*/
-static void RSurfShader_Sky(msurface_t *firstsurf)
+static void RSurfShader_Sky(entity_render_t *ent, msurface_t *firstsurf)
{
msurface_t *surf;
int i;
float *outv, *outc;
// LordHavoc: HalfLife maps have freaky skypolys...
- if (currentrenderentity->model->ishlbsp)
+ if (ent->model->ishlbsp)
return;
if (skyrendernow)
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;
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;
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)
{
}
}
-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;
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;
}
}
-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;
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;
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;
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)
{
}
}
-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;
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;
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;
}
}
-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;
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;
}
}
-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;
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;
}
}
-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;
}
}
-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;
}
}
-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;
}
}
-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;
}
}
-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;
if (surf->dlightframe != r_framecount)
return;
- if (currentrenderentity->effects & EF_FULLBRIGHT)
+ if (ent->effects & EF_FULLBRIGHT)
return;
memset(&m, 0, sizeof(m));
}
}
-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;
}
}
-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;
}
}
-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;
}
}
-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
{
for (surf = firstsurf;surf;surf = surf->chain)
{
c_brush_polys++;
- RSurfShader_OpaqueWall_Pass_TripleTexCombine(surf);
+ RSurfShader_OpaqueWall_Pass_TripleTexCombine(ent, surf);
}
}
else
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
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);
}
}
=============================================================
*/
-static void R_SolidWorldNode (void)
+static void R_SolidWorldNode (entity_render_t *ent)
{
if (r_viewleaf->contents != CONTENTS_SOLID)
{
&Cshader_sky
};
-void R_PrepareSurfaces(void)
+void R_PrepareSurfaces(entity_render_t *ent)
{
int i, alttextures, texframe, framecount;
texture_t *t;
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++)
}
}
-void R_DrawSurfaces (int type)
+void R_DrawSurfaces (entity_render_t *ent, int type)
{
int i;
Cshader_t *shader;
{
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;
}
}
-void R_SetupForBModelRendering(void)
+void R_SetupForBModelRendering(entity_render_t *ent)
{
int i;
msurface_t *surf;
// 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++)
}
}
-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);
}
/*
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);
}
/*
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)
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;
}
loadmodel->type = mod_alias;
loadmodel->aliastype = ALIASTYPE_MDLMD2;
- loadmodel->Draw = R_DrawAliasModel;
+ loadmodel->Draw = R_DrawQ1Q2AliasModel;
loadmodel->DrawSky = NULL;
loadmodel->DrawShadow = NULL;
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;
}
#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;
}
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;
}
}
-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;
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);
}
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;
}
// mark the polygons
- surf = currentrenderentity->model->surfaces + node->firstsurface;
+ surf = ent->model->surfaces + node->firstsurface;
for (i=0 ; i<node->numsurfaces ; i++, surf++)
{
int d, impacts, impactt;
{
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;
}
}
-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;
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;
}
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;
}
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;
}
}
}
-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);
}
/*
}
}
-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);
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;
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];
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);
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);
}
else
{
- R_CompleteLightPoint (basecolor, currentrenderentity->origin, true, NULL);
+ R_CompleteLightPoint (basecolor, ent->origin, true, NULL);
}
basecolor[0] *= colorr;
basecolor[1] *= colorg;
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
#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:
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];
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;
// 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]);
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
{
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;
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;
// 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);
+}
+
//=============================================================================
-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;
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"
#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"