From 5dcb4e75bb0749c22bff68ea97e363a9142b20fb Mon Sep 17 00:00:00 2001 From: havoc Date: Fri, 18 Apr 2003 12:11:30 +0000 Subject: [PATCH] reorganized aliaslayer_t handling to fix a few bugs fixed md2 models fixed skinless models git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@2963 d7cf8633-e32d-0410-b094-e92efae38249 --- gl_models.c | 141 +++++++++++++++++++++++++++----------------------- model_alias.c | 125 ++++++++++++++++++-------------------------- model_alias.h | 10 ++-- 3 files changed, 131 insertions(+), 145 deletions(-) diff --git a/gl_models.c b/gl_models.c index bb63bf3d..f19fa26d 100644 --- a/gl_models.c +++ b/gl_models.c @@ -208,24 +208,34 @@ void R_Model_Alias_GetMesh_Vertex3f(const entity_render_t *ent, aliasmesh_t *mes } } +aliaslayer_t r_aliasnoskinlayers[2] = {{ALIASLAYER_DIFFUSE, NULL, NULL}, {ALIASLAYER_FOG | ALIASLAYER_FORCEDRAW_IF_FIRSTPASS, NULL, NULL}}; +aliasskin_t r_aliasnoskin = {0, 2, r_aliasnoskinlayers}; aliasskin_t *R_FetchAliasSkin(const entity_render_t *ent, const aliasmesh_t *mesh) { model_t *model = ent->model; - int s = ent->skinnum; - if ((unsigned int)s >= (unsigned int)model->numskins) - s = 0; - if (model->skinscenes[s].framecount > 1) - s = model->skinscenes[s].firstframe + (int) (cl.time * model->skinscenes[s].framerate) % model->skinscenes[s].framecount; + if (model->numskins) + { + int s = ent->skinnum; + if ((unsigned int)s >= (unsigned int)model->numskins) + s = 0; + if (model->skinscenes[s].framecount > 1) + s = model->skinscenes[s].firstframe + (int) (cl.time * model->skinscenes[s].framerate) % model->skinscenes[s].framecount; + else + s = model->skinscenes[s].firstframe; + if (s >= mesh->num_skins) + s = 0; + return mesh->data_skins + s; + } else - s = model->skinscenes[s].firstframe; - if (s >= mesh->num_skins) - s = 0; - return mesh->data_skins + s; + { + r_aliasnoskinlayers[0].texture = r_notexture; + return &r_aliasnoskin; + } } void R_DrawAliasModelCallback (const void *calldata1, int calldata2) { - int c, fullbright, layernum; + int c, fullbright, layernum, firstpass; float tint[3], fog, ifog, colorscale; vec3_t diff; qbyte *bcolor; @@ -255,38 +265,26 @@ void R_DrawAliasModelCallback (const void *calldata1, int calldata2) } ifog = 1 - fog; + firstpass = true; memset(&m, 0, sizeof(m)); skin = R_FetchAliasSkin(ent, mesh); for (layernum = 0, layer = skin->data_layers;layernum < skin->num_layers;layernum++, layer++) { - if (((layer->flags & ALIASLAYER_NODRAW_IF_NOTCOLORMAPPED) && ent->colormap < 0) - || ((layer->flags & ALIASLAYER_NODRAW_IF_COLORMAPPED) && ent->colormap >= 0) - || (layer->flags & ALIASLAYER_DRAW_PER_LIGHT)) - continue; - expandaliasvert(mesh->num_vertices); - if (layer->flags & ALIASLAYER_FOG) + if (!(layer->flags & ALIASLAYER_FORCEDRAW_IF_FIRSTPASS) || !firstpass) { - m.blendfunc1 = GL_SRC_ALPHA; - m.blendfunc2 = GL_ONE; - colorscale = r_colorscale; - m.texrgbscale[0] = 1; - m.tex[0] = R_GetTexture(layer->texture); - R_Mesh_State(&m); - GL_Color(fogcolor[0] * fog * colorscale, fogcolor[1] * fog * colorscale, fogcolor[2] * fog * colorscale, ent->alpha); - c_alias_polys += mesh->num_triangles; - R_Mesh_GetSpace(mesh->num_vertices); - R_Model_Alias_GetMesh_Vertex3f(ent, mesh, varray_vertex3f, aliasvert_normal3f, NULL, NULL); - if (layer->texture != NULL) - R_Mesh_CopyTexCoord2f(0, mesh->data_texcoord2f, mesh->num_vertices); - R_Mesh_Draw(mesh->num_vertices, mesh->num_triangles, mesh->data_element3i); - continue; + if (((layer->flags & ALIASLAYER_NODRAW_IF_NOTCOLORMAPPED) && ent->colormap < 0) + || ((layer->flags & ALIASLAYER_NODRAW_IF_COLORMAPPED) && ent->colormap >= 0) + || ((layer->flags & ALIASLAYER_FOG) && !fogenabled) + || (layer->flags & ALIASLAYER_SPECULAR) + || ((layer->flags & ALIASLAYER_DIFFUSE) && (r_shadow_realtime_world.integer && r_ambient.integer <= 0 && r_fullbright.integer == 0 && !(ent->effects & EF_FULLBRIGHT)))) + continue; } - if ((layer->flags & ALIASLAYER_ADD) || ((layer->flags & ALIASLAYER_ALPHA) && (ent->effects & EF_ADDITIVE))) + if (!firstpass || (ent->effects & EF_ADDITIVE)) { m.blendfunc1 = GL_SRC_ALPHA; m.blendfunc2 = GL_ONE; } - else if ((layer->flags & ALIASLAYER_ALPHA) || ent->alpha != 1.0) + else if ((skin->flags & ALIASSKIN_TRANSPARENT) || ent->alpha != 1.0) { m.blendfunc1 = GL_SRC_ALPHA; m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA; @@ -296,49 +294,64 @@ void R_DrawAliasModelCallback (const void *calldata1, int calldata2) m.blendfunc1 = GL_ONE; m.blendfunc2 = GL_ZERO; } + firstpass = false; + expandaliasvert(mesh->num_vertices); colorscale = r_colorscale; m.texrgbscale[0] = 1; - if (gl_combine.integer) + m.tex[0] = R_GetTexture(layer->texture); + if (gl_combine.integer && layer->flags & (ALIASLAYER_DIFFUSE | ALIASLAYER_SPECULAR)) { colorscale *= 0.25f; m.texrgbscale[0] = 4; } - m.tex[0] = R_GetTexture(layer->texture); R_Mesh_State(&m); - if (layer->flags & ALIASLAYER_COLORMAP_PANTS) - { - // 128-224 are backwards ranges - c = (ent->colormap & 0xF) << 4;c += (c >= 128 && c < 224) ? 4 : 12; - bcolor = (qbyte *) (&palette_complete[c]); - fullbright = c >= 224; - VectorScale(bcolor, (1.0f / 255.0f), tint); - } - else if (layer->flags & ALIASLAYER_COLORMAP_SHIRT) + c_alias_polys += mesh->num_triangles; + R_Mesh_GetSpace(mesh->num_vertices); + if (layer->texture != NULL) + R_Mesh_CopyTexCoord2f(0, mesh->data_texcoord2f, mesh->num_vertices); + if (layer->flags & ALIASLAYER_FOG) { - // 128-224 are backwards ranges - c = (ent->colormap & 0xF0);c += (c >= 128 && c < 224) ? 4 : 12; - bcolor = (qbyte *) (&palette_complete[c]); - fullbright = c >= 224; - VectorScale(bcolor, (1.0f / 255.0f), tint); + colorscale *= fog; + R_Model_Alias_GetMesh_Vertex3f(ent, mesh, varray_vertex3f, NULL, NULL, NULL); + GL_Color(fogcolor[0] * colorscale, fogcolor[1] * colorscale, fogcolor[2] * colorscale, ent->alpha); } else { - tint[0] = tint[1] = tint[2] = 1; - fullbright = false; + if (layer->flags & (ALIASLAYER_COLORMAP_PANTS | ALIASLAYER_COLORMAP_SHIRT)) + { + // 128-224 are backwards ranges + if (layer->flags & ALIASLAYER_COLORMAP_PANTS) + c = (ent->colormap & 0xF) << 4; + else //if (layer->flags & ALIASLAYER_COLORMAP_SHIRT) + c = (ent->colormap & 0xF0); + c += (c >= 128 && c < 224) ? 4 : 12; + bcolor = (qbyte *) (&palette_complete[c]); + fullbright = c >= 224; + VectorScale(bcolor, (1.0f / 255.0f), tint); + } + else + { + tint[0] = tint[1] = tint[2] = 1; + fullbright = false; + } + colorscale *= ifog; + if (fullbright || !(layer->flags & ALIASLAYER_DIFFUSE) || r_fullbright.integer || (ent->effects & EF_FULLBRIGHT)) + { + R_Model_Alias_GetMesh_Vertex3f(ent, mesh, varray_vertex3f, NULL, NULL, NULL); + GL_Color(tint[0] * colorscale, tint[1] * colorscale, tint[2] * colorscale, ent->alpha); + } + else if (r_shadow_realtime_world.integer) + { + R_Model_Alias_GetMesh_Vertex3f(ent, mesh, varray_vertex3f, NULL, NULL, NULL); + colorscale *= r_ambient.value * (2.0f / 128.0f); + GL_Color(tint[0] * colorscale, tint[1] * colorscale, tint[2] * colorscale, ent->alpha); + } + else + { + R_Model_Alias_GetMesh_Vertex3f(ent, mesh, varray_vertex3f, aliasvert_normal3f, NULL, NULL); + R_LightModel(ent, mesh->num_vertices, varray_vertex3f, aliasvert_normal3f, varray_color4f, tint[0] * colorscale, tint[1] * colorscale, tint[2] * colorscale, false); + } } - VectorScale(tint, ifog * colorscale, tint); - if (!(layer->flags & ALIASLAYER_DIFFUSE)) - fullbright = true; - if (ent->effects & EF_FULLBRIGHT) - fullbright = true; - c_alias_polys += mesh->num_triangles; - R_Mesh_GetSpace(mesh->num_vertices); - R_Model_Alias_GetMesh_Vertex3f(ent, mesh, varray_vertex3f, aliasvert_normal3f, NULL, NULL); - R_Mesh_CopyTexCoord2f(0, mesh->data_texcoord2f, mesh->num_vertices); - if (fullbright) - GL_Color(tint[0], tint[1], tint[2], ent->alpha); - else - R_LightModel(ent, mesh->num_vertices, varray_vertex3f, aliasvert_normal3f, varray_color4f, tint[0], tint[1], tint[2], false); R_Mesh_Draw(mesh->num_vertices, mesh->num_triangles, mesh->data_element3i); } } @@ -488,7 +501,7 @@ void R_Model_Alias_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, v R_Model_Alias_GetMesh_Vertex3f(ent, mesh, vertices, aliasvert_normal3f, aliasvert_svector3f, aliasvert_tvector3f); for (layernum = 0, layer = skin->data_layers;layernum < skin->num_layers;layernum++, layer++) { - if (!(layer->flags & ALIASLAYER_DRAW_PER_LIGHT) + if (!(layer->flags & (ALIASLAYER_DIFFUSE | ALIASLAYER_SPECULAR)) || ((layer->flags & ALIASLAYER_NODRAW_IF_NOTCOLORMAPPED) && ent->colormap < 0) || ((layer->flags & ALIASLAYER_NODRAW_IF_COLORMAPPED) && ent->colormap >= 0)) continue; diff --git a/model_alias.c b/model_alias.c index b095d9bf..417c7832 100644 --- a/model_alias.c +++ b/model_alias.c @@ -171,103 +171,72 @@ static void Mod_MDL_LoadFrames (qbyte* datapointer, int inverts, int outverts, v Mem_Free(vertexbuffer); } +aliaslayer_t mod_alias_layersbuffer[16]; // 7 currently used void Mod_BuildAliasSkinFromSkinFrame(aliasskin_t *skin, skinframe_t *skinframe) { aliaslayer_t *layer; - skin->flags = 0; - // fog texture only exists if some pixels are transparent... - if (skinframe->fog != NULL) - skin->flags |= ALIASSKIN_TRANSPARENT; - // fog and gloss layers always exist - skin->num_layers = 2; - if (skinframe->glow != NULL) - skin->num_layers++; - if (skinframe->merged != NULL) - skin->num_layers += 2; - if (skinframe->base != NULL) - skin->num_layers += 2; - if (skinframe->pants != NULL) - skin->num_layers += 2; - if (skinframe->shirt != NULL) - skin->num_layers += 2; - layer = skin->data_layers = Mem_Alloc(loadmodel->mempool, skin->num_layers * sizeof(aliaslayer_t)); - if (skinframe->glow != NULL) - { - layer->flags = 0; - layer->texture = skinframe->glow; - layer++; - } + + memset(&mod_alias_layersbuffer, 0, sizeof(mod_alias_layersbuffer)); + layer = mod_alias_layersbuffer; + layer->flags = ALIASLAYER_SPECULAR; + layer->texture = skinframe->gloss; + layer->nmap = skinframe->nmap; + layer++; if (skinframe->merged != NULL) { - layer->flags = ALIASLAYER_NODRAW_IF_COLORMAPPED | ALIASLAYER_DIFFUSE; - if (skinframe->glow != NULL) - layer->flags |= ALIASLAYER_ADD; + layer->flags = ALIASLAYER_DIFFUSE | ALIASLAYER_NODRAW_IF_COLORMAPPED; layer->texture = skinframe->merged; layer->nmap = skinframe->nmap; layer++; } if (skinframe->base != NULL) { - layer->flags = (skinframe->merged != NULL ? ALIASLAYER_NODRAW_IF_NOTCOLORMAPPED : 0) | ALIASLAYER_DIFFUSE; - if (skinframe->glow != NULL) - layer->flags |= ALIASLAYER_ADD; + layer->flags = ALIASLAYER_DIFFUSE; + if (skinframe->merged != NULL) + layer->flags |= ALIASLAYER_NODRAW_IF_NOTCOLORMAPPED; layer->texture = skinframe->base; layer->nmap = skinframe->nmap; layer++; } if (skinframe->pants != NULL) { - layer->flags = ALIASLAYER_NODRAW_IF_NOTCOLORMAPPED | ALIASLAYER_DIFFUSE | ALIASLAYER_COLORMAP_SHIRT; - if (skinframe->glow != NULL || skinframe->base != NULL) - layer->flags |= ALIASLAYER_ADD; + layer->flags = ALIASLAYER_DIFFUSE | ALIASLAYER_NODRAW_IF_NOTCOLORMAPPED | ALIASLAYER_COLORMAP_PANTS; layer->texture = skinframe->pants; layer->nmap = skinframe->nmap; layer++; } if (skinframe->shirt != NULL) { - layer->flags = ALIASLAYER_NODRAW_IF_NOTCOLORMAPPED | ALIASLAYER_DIFFUSE | ALIASLAYER_COLORMAP_SHIRT; - if (skinframe->glow != NULL || skinframe->base != NULL || skinframe->pants != NULL) - layer->flags |= ALIASLAYER_ADD; + layer->flags = ALIASLAYER_DIFFUSE | ALIASLAYER_NODRAW_IF_NOTCOLORMAPPED | ALIASLAYER_COLORMAP_SHIRT; layer->texture = skinframe->shirt; layer->nmap = skinframe->nmap; layer++; } - layer->flags = ALIASLAYER_FOG; - layer->texture = skinframe->fog; - layer++; - layer->flags = ALIASLAYER_DRAW_PER_LIGHT | ALIASLAYER_SPECULAR; - layer->texture = skinframe->gloss; - layer->nmap = skinframe->nmap; - layer++; - if (skinframe->merged != NULL) - { - layer->flags = ALIASLAYER_DRAW_PER_LIGHT | ALIASLAYER_NODRAW_IF_COLORMAPPED | ALIASLAYER_DIFFUSE; - layer->texture = skinframe->merged; - layer->nmap = skinframe->nmap; - layer++; - } - if (skinframe->base != NULL) + + if (skinframe->glow != NULL) { - layer->flags = ALIASLAYER_DRAW_PER_LIGHT | (skinframe->merged != NULL ? ALIASLAYER_NODRAW_IF_NOTCOLORMAPPED : 0) | ALIASLAYER_DIFFUSE; - layer->texture = skinframe->base; - layer->nmap = skinframe->nmap; + layer->flags = 0; + layer->texture = skinframe->glow; layer++; - } - if (skinframe->pants != NULL) - { - layer->flags = ALIASLAYER_DRAW_PER_LIGHT | ALIASLAYER_NODRAW_IF_NOTCOLORMAPPED | ALIASLAYER_DIFFUSE | ALIASLAYER_COLORMAP_PANTS; - layer->texture = skinframe->pants; - layer->nmap = skinframe->nmap; + layer->flags = ALIASLAYER_FOG; + layer->texture = skinframe->fog; layer++; } - if (skinframe->shirt != NULL) + else { - layer->flags = ALIASLAYER_DRAW_PER_LIGHT | ALIASLAYER_NODRAW_IF_NOTCOLORMAPPED | ALIASLAYER_DIFFUSE | ALIASLAYER_COLORMAP_SHIRT; - layer->texture = skinframe->shirt; - layer->nmap = skinframe->nmap; + layer->flags = ALIASLAYER_FOG | ALIASLAYER_FORCEDRAW_IF_FIRSTPASS; + layer->texture = skinframe->fog; layer++; } + + skin->flags = 0; + // fog texture only exists if some pixels are transparent... + if (skinframe->fog != NULL) + skin->flags |= ALIASSKIN_TRANSPARENT; + + skin->num_layers = layer - mod_alias_layersbuffer; + skin->data_layers = Mem_Alloc(loadmodel->mempool, skin->num_layers * sizeof(aliaslayer_t)); + memcpy(skin->data_layers, mod_alias_layersbuffer, skin->num_layers * sizeof(aliaslayer_t)); } void Mod_BuildMDLMD2MeshInfo(int numverts, int numtris, int *elements, float *texcoord2f, aliasvertex_t *posedata) @@ -655,17 +624,25 @@ void Mod_LoadQ2AliasModel (model_t *mod, void *buffer) inskin = (void*)(base + LittleLong(pinmodel->ofs_skins)); if (loadmodel->numskins) { - loadmodel->skinscenes = Mem_Alloc(loadmodel->mempool, sizeof(animscene_t) * loadmodel->numskins + sizeof(skinframe_t) * loadmodel->numskins); - loadmodel->skinframes = (void *)(loadmodel->skinscenes + loadmodel->numskins); - for (i = 0;i < loadmodel->numskins;i++) - { - loadmodel->skinscenes[i].firstframe = i; - loadmodel->skinscenes[i].framecount = 1; - loadmodel->skinscenes[i].loop = true; - loadmodel->skinscenes[i].framerate = 10; + // skins found (most likely not a player model) + loadmodel->skinframes = Mem_Alloc(loadmodel->mempool, sizeof(skinframe_t) * loadmodel->numskins); + for (i = 0;i < loadmodel->numskins;i++, inskin += MD2_SKINNAME) Mod_LoadSkinFrame (loadmodel->skinframes + i, inskin, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_PRECACHE, true, false, true); - inskin += MD2_SKINNAME; - } + } + else + { + // no skins (most likely a player model) + loadmodel->numskins = 1; + loadmodel->skinframes = Mem_Alloc(loadmodel->mempool, sizeof(skinframe_t) * loadmodel->numskins); + } + + loadmodel->skinscenes = Mem_Alloc(loadmodel->mempool, sizeof(animscene_t) * loadmodel->numskins); + for (i = 0;i < loadmodel->numskins;i++) + { + loadmodel->skinscenes[i].firstframe = i; + loadmodel->skinscenes[i].framecount = 1; + loadmodel->skinscenes[i].loop = true; + loadmodel->skinscenes[i].framerate = 10; } // load the triangles and stvert data @@ -749,7 +726,7 @@ void Mod_LoadQ2AliasModel (model_t *mod, void *buffer) // load the frames datapointer = (base + LittleLong(pinmodel->ofs_frames)); loadmodel->animscenes = Mem_Alloc(loadmodel->mempool, loadmodel->numframes * sizeof(animscene_t)); - posedata = Mem_Alloc(loadmodel->mempool, numverts * loadmodel->numframes * sizeof(trivertx_t)); + posedata = Mem_Alloc(loadmodel->mempool, numverts * loadmodel->numframes * sizeof(aliasvertex_t)); vertexbuffer = Mem_Alloc(tempmempool, numverts * sizeof(float[3+3+3+3])); svectorsbuffer = vertexbuffer + numverts * 3; diff --git a/model_alias.h b/model_alias.h index 36d4e50e..879f4cee 100644 --- a/model_alias.h +++ b/model_alias.h @@ -229,12 +229,8 @@ typedef struct aliasvertex_s } aliasvertex_t; -// this layer is fog (completely specialized behavior) +// this layer is fog (completely specialized behavior, automatic NODRAW_IF_NOTFOGGED behavior) #define ALIASLAYER_FOG 1 -// alpha blending -#define ALIASLAYER_ALPHA 2 -// additive blending -#define ALIASLAYER_ADD 4 // apply diffuse lighting #define ALIASLAYER_DIFFUSE 8 // apply specular lighting @@ -247,8 +243,8 @@ aliasvertex_t; #define ALIASLAYER_NODRAW_IF_NOTCOLORMAPPED 128 // don't draw this layer if colormap is used #define ALIASLAYER_NODRAW_IF_COLORMAPPED 256 -// draw this layer for realtime lighting passes, otherwise don't -#define ALIASLAYER_DRAW_PER_LIGHT 512 +// ignore NODRAW flags on this layer only if all previous layers were skipped +#define ALIASLAYER_FORCEDRAW_IF_FIRSTPASS 512 typedef struct aliaslayer_s { -- 2.39.2