/* ================= R_SetShellBlend ================= */ void R_SetShellBlend (qboolean toggle) { // shells only if ( !(currententity->flags & RF_MASK_SHELL) ) return; if (toggle) //turn on { // Psychospaz's envmapping if (EnvMapShell()) { glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); GL_Bind(glMedia.spheremappic->texnum); glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); } else if (FlowingShell()) GL_Bind(glMedia.shelltexture->texnum); else GL_DisableTexture(0); GL_ClearStencil(0); glClear(GL_STENCIL_BUFFER_BIT); GL_StencilFunc(GL_EQUAL, 1, 2); glStencilOp(GL_KEEP,GL_KEEP,GL_INCR); GL_Enable(GL_STENCIL_TEST); shellFlowH = 0.25 * sin(r_newrefdef.time * 0.5 * M_PI); shellFlowV = -(r_newrefdef.time / 2.0); } else // turn off { // Psychospaz's envmapping if (EnvMapShell()) { glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); } else if (FlowingShell()) { /*nothing*/ } else GL_EnableTexture(0); GL_Disable(GL_STENCIL_TEST); } }
/* ================= R_DrawAliasFrameLerp ================= */ void R_DrawAliasFrameLerp (maliasmodel_t *paliashdr, entity_t *e) { int i, j, k, meshnum; maliasframe_t *frame, *oldframe; maliasmesh_t mesh; maliasvertex_t *v, *ov; vec3_t move, delta, vectors[3]; vec3_t curScale, oldScale, curNormal, oldNormal; vec3_t tempNormalsArray[MD3_MAX_VERTS]; vec2_t tempSkinCoord; vec3_t meshlight, lightcolor; float alpha, meshalpha, thisalpha, shellscale, frontlerp, backlerp = e->backlerp; image_t *skin; renderparms_t skinParms; qboolean shellModel = e->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM); frontlerp = 1.0 - backlerp; if (e->flags & RF_TRANSLUCENT) alpha = e->alpha; else alpha = 1.0; frame = paliashdr->frames + e->frame; oldframe = paliashdr->frames + e->oldframe; VectorScale(frame->scale, frontlerp, curScale); VectorScale(oldframe->scale, backlerp, oldScale); // move should be the delta back to the previous frame * backlerp VectorSubtract (e->oldorigin, e->origin, delta); AngleVectors (e->angles, vectors[0], vectors[1], vectors[2]); move[0] = DotProduct (delta, vectors[0]); // forward move[1] = -DotProduct (delta, vectors[1]); // left move[2] = DotProduct (delta, vectors[2]); // up VectorAdd (move, oldframe->translate, move); for (i=0 ; i<3 ; i++) move[i] = backlerp*move[i] + frontlerp*frame->translate[i]; R_SetVertexOverbrights(true); R_SetShellBlend (true); // new outer loop for whole model for (k=0, meshnum=0; k < paliashdr->num_meshes; k++, meshnum++) { mesh = paliashdr->meshes[k]; skinParms = mesh.skins[e->skinnum].renderparms; // select skin if (e->skin) skin = e->skin; // custom player skin else skin = currentmodel->skins[k][e->skinnum]; if (!skin) skin = r_notexture; if ( !shellModel ) GL_Bind(skin->texnum); else if (FlowingShell()) alpha = 0.7; // md3 skin scripting if (skinParms.nodraw) continue; // skip this mesh for this skin if (skinParms.twosided) GL_Disable(GL_CULL_FACE); if (skinParms.alphatest && !shellModel) GL_Enable(GL_ALPHA_TEST); if (skinParms.fullbright) VectorSet(meshlight, 1.0f, 1.0f, 1.0f); else VectorCopy(shadelight, meshlight); meshalpha = alpha * skinParms.basealpha; if (meshalpha < 1.0f || skinParms.blend) GL_Enable (GL_BLEND); else GL_Disable (GL_BLEND); if (skinParms.blend && !shellModel) GL_BlendFunc (skinParms.blendfunc_src, skinParms.blendfunc_dst); else GL_BlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // md3 skin scripting v = mesh.vertexes + e->frame*mesh.num_verts; ov = mesh.vertexes + e->oldframe*mesh.num_verts; rb_vertex = 0; for (i=0; i<mesh.num_verts; i++, v++, ov++) { // lerp verts curNormal[0] = r_sinTable[v->normal[0]] * r_cosTable[v->normal[1]]; curNormal[1] = r_sinTable[v->normal[0]] * r_sinTable[v->normal[1]]; curNormal[2] = r_cosTable[v->normal[0]]; oldNormal[0] = r_sinTable[ov->normal[0]] * r_cosTable[ov->normal[1]]; oldNormal[1] = r_sinTable[ov->normal[0]] * r_sinTable[ov->normal[1]]; oldNormal[2] = r_cosTable[ov->normal[0]]; VectorSet ( tempNormalsArray[i], curNormal[0] + (oldNormal[0] - curNormal[0])*backlerp, curNormal[1] + (oldNormal[1] - curNormal[1])*backlerp, curNormal[2] + (oldNormal[2] - curNormal[2])*backlerp ); if (shellModel) shellscale = (e->flags & RF_WEAPONMODEL) ? WEAPON_SHELL_SCALE: POWERSUIT_SCALE; else shellscale = 0.0; VectorSet ( tempVertexArray[meshnum][i], move[0] + ov->point[0]*oldScale[0] + v->point[0]*curScale[0] + tempNormalsArray[i][0]*shellscale, move[1] + ov->point[1]*oldScale[1] + v->point[1]*curScale[1] + tempNormalsArray[i][1]*shellscale, move[2] + ov->point[2]*oldScale[2] + v->point[2]*curScale[2] + tempNormalsArray[i][2]*shellscale ); // calc lighting and alpha if (shellModel) VectorCopy(meshlight, lightcolor); else R_LightAliasModel(meshlight, tempNormalsArray[i], lightcolor, v->lightnormalindex, !skinParms.nodiffuse); //thisalpha = R_CalcEntAlpha(meshalpha, tempVertexArray[meshnum][i]); thisalpha = meshalpha; // get tex coords if (shellModel && FlowingShell()) { tempSkinCoord[0] = (tempVertexArray[meshnum][i][0] + tempVertexArray[meshnum][i][1]) / 40.0 + shellFlowH; tempSkinCoord[1] = tempVertexArray[meshnum][i][2] / 40.0 + shellFlowV; } else { tempSkinCoord[0] = mesh.stcoords[i].st[0]; tempSkinCoord[1] = mesh.stcoords[i].st[1]; } // add to arrays VA_SetElem2(texCoordArray[0][rb_vertex], tempSkinCoord[0], tempSkinCoord[1]); VA_SetElem3(vertexArray[rb_vertex], tempVertexArray[meshnum][i][0], tempVertexArray[meshnum][i][1], tempVertexArray[meshnum][i][2]); VA_SetElem4(colorArray[rb_vertex], lightcolor[0], lightcolor[1], lightcolor[2], thisalpha); rb_vertex++; } if (!shellModel) RB_ModifyTextureCoords (&texCoordArray[0][0][0], &vertexArray[0][0], rb_vertex, skinParms); // set indices for each triangle and draw rb_index = 0; for (j=0; j < mesh.num_tris; j++) { indexArray[rb_index++] = mesh.indexes[3*j+0]; indexArray[rb_index++] = mesh.indexes[3*j+1]; indexArray[rb_index++] = mesh.indexes[3*j+2]; } RB_DrawArrays (GL_TRIANGLES); // glow pass if (mesh.skins[e->skinnum].glowimage && !shellModel) { float glowcolor; if (skinParms.glow.type > -1) glowcolor = RB_CalcGlowColor (skinParms); else glowcolor = 1.0; qglDisableClientState (GL_COLOR_ARRAY); qglColor4f(glowcolor, glowcolor, glowcolor, 1.0); GL_Enable (GL_BLEND); GL_BlendFunc (GL_ONE, GL_ONE); GL_Bind(mesh.skins[e->skinnum].glowimage->texnum); RB_DrawArrays (GL_TRIANGLES); qglEnableClientState (GL_COLOR_ARRAY); qglColor4f(1.0, 1.0, 1.0, 1.0); } // envmap pass if (skinParms.envmap > 0.0f && !shellModel) { GL_Enable (GL_BLEND); GL_BlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); qglTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); qglTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); // apply alpha to array for (i=0; i<mesh.num_verts; i++) //colorArray[i][3] = R_CalcEntAlpha(meshalpha*skinParms.envmap, tempVertexArray[meshnum][i]); colorArray[i][3] = meshalpha*skinParms.envmap; GL_Bind(r_envmappic->texnum); qglEnable(GL_TEXTURE_GEN_S); qglEnable(GL_TEXTURE_GEN_T); RB_DrawArrays (GL_TRIANGLES); qglDisable(GL_TEXTURE_GEN_S); qglDisable(GL_TEXTURE_GEN_T); } RB_DrawMeshTris (GL_TRIANGLES, 1); // md3 skin scripting if (skinParms.twosided) GL_Enable(GL_CULL_FACE); if (skinParms.alphatest && !shellModel) GL_Disable(GL_ALPHA_TEST); GL_Disable (GL_BLEND); // md3 skin scripting } // end new outer loop R_SetShellBlend (false); R_SetVertexOverbrights(false); }