X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;ds=sidebyside;f=model_shared.c;h=eac0865badb3468fbce1e2de18665989cedbde85;hb=49b02ed536f0537ee36b6f21a2f130aad56d428d;hp=f54b6da0de902b7d33c755b50d0601501e8cd9b8;hpb=3e8cbd0ede462753431e4480eb786e5b3051cd4f;p=xonotic%2Fdarkplaces.git diff --git a/model_shared.c b/model_shared.c index f54b6da0..eac0865b 100644 --- a/model_shared.c +++ b/model_shared.c @@ -58,7 +58,7 @@ static void mod_start(void) Mod_LoadQ3Shaders(); for (i = 0;i < nummodels;i++) - if ((mod = Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->name[0] && mod->name[0] != '*') + if ((mod = (dp_model_t*) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->name[0] && mod->name[0] != '*') if (mod->used) Mod_LoadModel(mod, true, false, mod->isworldmodel); } @@ -70,7 +70,7 @@ static void mod_shutdown(void) dp_model_t *mod; for (i = 0;i < nummodels;i++) - if ((mod = Mem_ExpandableArray_RecordAtIndex(&models, i)) && (mod->loaded || mod->mempool)) + if ((mod = (dp_model_t*) Mem_ExpandableArray_RecordAtIndex(&models, i)) && (mod->loaded || mod->mempool)) Mod_UnloadModel(mod); Mem_FreePool (&q3shaders_mem); @@ -86,7 +86,7 @@ static void mod_newmap(void) R_SkinFrame_PrepareForPurge(); for (i = 0;i < nummodels;i++) { - if ((mod = Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->mempool && mod->data_textures) + if ((mod = (dp_model_t*) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->mempool && mod->data_textures) { for (j = 0;j < mod->num_textures;j++) { @@ -104,7 +104,7 @@ static void mod_newmap(void) for (i = 0;i < nummodels;i++) { - if ((mod = Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->mempool && mod->data_surfaces) + if ((mod = (dp_model_t*) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->mempool && mod->data_surfaces) { for (surfacenum = 0, surface = mod->data_surfaces;surfacenum < mod->num_surfaces;surfacenum++, surface++) { @@ -113,7 +113,7 @@ static void mod_newmap(void) ssize = (surface->lightmapinfo->extents[0] >> 4) + 1; tsize = (surface->lightmapinfo->extents[1] >> 4) + 1; memset(surface->lightmapinfo->stainsamples, 255, ssize * tsize * 3); - surface->cached_dlight = true; + mod->brushq1.lightmapupdateflags[surfacenum] = true; } } } @@ -177,6 +177,11 @@ void Mod_UnloadModel (dp_model_t *mod) mod->loaded = false; } +void R_Model_Null_Draw(entity_render_t *ent) +{ + return; +} + /* ================== Mod_LoadModel @@ -195,6 +200,44 @@ dp_model_t *Mod_LoadModel(dp_model_t *mod, qboolean crash, qboolean checkdisk, q if (mod->name[0] == '*') // submodel return mod; + + if (!strcmp(mod->name, "null")) + { + if (mod->isworldmodel != isworldmodel) + mod->loaded = false; + + if(mod->loaded) + return mod; + + if (mod->loaded || mod->mempool) + Mod_UnloadModel(mod); + + if (developer_loading.integer) + Con_Printf("loading model %s\n", mod->name); + + mod->isworldmodel = isworldmodel; + mod->used = true; + mod->crc = -1; + mod->loaded = false; + + VectorClear(mod->normalmins); + VectorClear(mod->normalmaxs); + VectorClear(mod->yawmins); + VectorClear(mod->yawmaxs); + VectorClear(mod->rotatedmins); + VectorClear(mod->rotatedmaxs); + + mod->modeldatatypestring = "null"; + mod->type = mod_null; + mod->Draw = R_Model_Null_Draw; + mod->numframes = 2; + mod->numskins = 1; + + // no fatal errors occurred, so this model is ready to use. + mod->loaded = true; + + return mod; + } crc = 0; buf = NULL; @@ -308,7 +351,7 @@ void Mod_ClearUsed(void) int nummodels = Mem_ExpandableArray_IndexRange(&models); dp_model_t *mod; for (i = 0;i < nummodels;i++) - if ((mod = Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->name[0]) + if ((mod = (dp_model_t*) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->name[0]) mod->used = false; } @@ -319,7 +362,7 @@ void Mod_PurgeUnused(void) dp_model_t *mod; for (i = 0;i < nummodels;i++) { - if ((mod = Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->name[0] && !mod->used) + if ((mod = (dp_model_t*) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->name[0] && !mod->used) { Mod_UnloadModel(mod); Mem_ExpandableArray_FreeRecord(&models, mod); @@ -335,7 +378,7 @@ void Mod_RemoveStaleWorldModels(dp_model_t *skip) dp_model_t *mod; for (i = 0;i < nummodels;i++) { - if ((mod = Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->isworldmodel && mod->loaded && skip != mod) + if ((mod = (dp_model_t*) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->isworldmodel && mod->loaded && skip != mod) { Mod_UnloadModel(mod); mod->isworldmodel = false; @@ -362,7 +405,7 @@ dp_model_t *Mod_FindName(const char *name) // search the currently loaded models for (i = 0;i < nummodels;i++) { - if ((mod = Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->name[0] && !strcmp(mod->name, name)) + if ((mod = (dp_model_t*) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->name[0] && !strcmp(mod->name, name)) { mod->used = true; return mod; @@ -370,7 +413,7 @@ dp_model_t *Mod_FindName(const char *name) } // no match found, create a new one - mod = Mem_ExpandableArray_AllocRecord(&models); + mod = (dp_model_t *) Mem_ExpandableArray_AllocRecord(&models); strlcpy(mod->name, name, sizeof(mod->name)); mod->loaded = false; mod->used = true; @@ -406,7 +449,7 @@ void Mod_Reload(void) int nummodels = Mem_ExpandableArray_IndexRange(&models); dp_model_t *mod; for (i = 0;i < nummodels;i++) - if ((mod = Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->name[0] && mod->name[0] != '*' && mod->used) + if ((mod = (dp_model_t *) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->name[0] && mod->name[0] != '*' && mod->used) Mod_LoadModel(mod, true, true, mod->isworldmodel); } @@ -428,7 +471,7 @@ static void Mod_Print(void) Con_Print("Loaded models:\n"); for (i = 0;i < nummodels;i++) - if ((mod = Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->name[0]) + if ((mod = (dp_model_t *) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->name[0]) Con_Printf("%4iK %s\n", mod->mempool ? (int)((mod->mempool->totalsize + 1023) / 1024) : 0, mod->name); } @@ -1360,7 +1403,7 @@ void Mod_LoadQ3Shaders(void) int i; layer->numframes = min(numparameters - 2, TEXTURE_MAXFRAMES); layer->framerate = atof(parameter[1]); - layer->texturename = Mem_Alloc (q3shaders_mem, sizeof (char*) * layer->numframes); + layer->texturename = (char **) Mem_Alloc (q3shaders_mem, sizeof (char*) * layer->numframes); for (i = 0;i < layer->numframes;i++) layer->texturename[i] = Mem_strdup (q3shaders_mem, parameter[i + 2]); } @@ -1402,7 +1445,7 @@ void Mod_LoadQ3Shaders(void) else if (!strcasecmp(parameter[1], "vertex")) layer->alphagen.alphagen = Q3ALPHAGEN_VERTEX; else if (!strcasecmp(parameter[1], "wave")) { - layer->alphagen.alphagen = Q3RGBGEN_WAVE; + layer->alphagen.alphagen = Q3ALPHAGEN_WAVE; layer->alphagen.wavefunc = Mod_LoadQ3Shaders_EnumerateWaveFunc(parameter[2]); for (i = 0;i < numparameters - 3 && i < Q3WAVEPARMS;i++) layer->alphagen.waveparms[i] = atof(parameter[i+3]); @@ -1447,6 +1490,7 @@ void Mod_LoadQ3Shaders(void) else if (!strcasecmp(parameter[1], "rotate")) layer->tcmods[tcmodindex].tcmod = Q3TCMOD_ROTATE; else if (!strcasecmp(parameter[1], "scale")) layer->tcmods[tcmodindex].tcmod = Q3TCMOD_SCALE; else if (!strcasecmp(parameter[1], "scroll")) layer->tcmods[tcmodindex].tcmod = Q3TCMOD_SCROLL; + else if (!strcasecmp(parameter[1], "page")) layer->tcmods[tcmodindex].tcmod = Q3TCMOD_PAGE; else if (!strcasecmp(parameter[1], "stretch")) { layer->tcmods[tcmodindex].tcmod = Q3TCMOD_STRETCH; @@ -1483,7 +1527,7 @@ void Mod_LoadQ3Shaders(void) layer->texflags = TEXF_ALPHA | TEXF_PRECACHE; if (!(shader.surfaceparms & Q3SURFACEPARM_NOMIPMAPS)) layer->texflags |= TEXF_MIPMAP; - if (!(shader.textureflags & Q3TEXTUREFLAG_NOPICMIP) && (r_picmipworld.integer || (layer->texturename && layer->texturename[0] && strncmp(layer->texturename[0], "textures/", 9)))) + if (!(shader.textureflags & Q3TEXTUREFLAG_NOPICMIP)) layer->texflags |= TEXF_PICMIP | TEXF_COMPRESS; if (layer->clampmap) layer->texflags |= TEXF_CLAMP; @@ -1582,6 +1626,10 @@ void Mod_LoadQ3Shaders(void) else Con_DPrintf("%s parsing warning: unknown surfaceparm \"%s\"\n", search->filenames[fileindex], parameter[1]); } + else if (!strcasecmp(parameter[0], "dpshadow")) + shader.dpshadow = true; + else if (!strcasecmp(parameter[0], "dpnoshadow")) + shader.dpnoshadow = true; else if (!strcasecmp(parameter[0], "sky") && numparameters >= 2) { // some q3 skies don't have the sky parm set @@ -1731,6 +1779,13 @@ qboolean Mod_LoadTextureFromQ3Shader(texture_t *texture, const char *name, qbool Con_Printf("%s: loaded shader for %s\n", loadmodel->name, name); texture->surfaceparms = shader->surfaceparms; texture->textureflags = shader->textureflags; + + // allow disabling of picmip or compression by defaulttexflags + if(!(defaulttexflags & TEXF_PICMIP)) + texture->textureflags &= ~TEXF_PICMIP; + if(!(defaulttexflags & TEXF_COMPRESS)) + texture->textureflags &= ~TEXF_COMPRESS; + texture->basematerialflags = 0; if (shader->surfaceparms & Q3SURFACEPARM_SKY) { @@ -1811,7 +1866,11 @@ nothing GL_ZERO GL_ONE texture->skinframerate = primarylayer->framerate; for (j = 0;j < primarylayer->numframes;j++) { - if (!(texture->skinframes[j] = R_SkinFrame_LoadExternal(primarylayer->texturename[j], primarylayer->texflags, false))) + if(cls.state == ca_dedicated) + { + texture->skinframes[j] = NULL; + } + else if (!(texture->skinframes[j] = R_SkinFrame_LoadExternal(primarylayer->texturename[j], primarylayer->texflags, false))) { Con_Printf("^1%s:^7 could not load texture ^3\"%s\"^7 (frame %i) for shader ^2\"%s\"\n", loadmodel->name, primarylayer->texturename[j], j, texture->name); texture->skinframes[j] = R_SkinFrame_LoadMissing(); @@ -1825,13 +1884,21 @@ nothing GL_ZERO GL_ONE texture->backgroundskinframerate = backgroundlayer->framerate; for (j = 0;j < backgroundlayer->numframes;j++) { - if (!(texture->backgroundskinframes[j] = R_SkinFrame_LoadExternal(backgroundlayer->texturename[j], backgroundlayer->texflags, false))) + if(cls.state == ca_dedicated) + { + texture->skinframes[j] = NULL; + } + else if (!(texture->backgroundskinframes[j] = R_SkinFrame_LoadExternal(backgroundlayer->texturename[j], backgroundlayer->texflags, false))) { Con_Printf("^1%s:^7 could not load texture ^3\"%s\"^7 (background frame %i) for shader ^2\"%s\"\n", loadmodel->name, backgroundlayer->texturename[j], j, texture->name); texture->backgroundskinframes[j] = R_SkinFrame_LoadMissing(); } } } + if (shader->dpshadow) + texture->basematerialflags &= ~MATERIALFLAG_NOSHADOW; + if (shader->dpnoshadow) + texture->basematerialflags |= MATERIALFLAG_NOSHADOW; memcpy(texture->deforms, shader->deforms, sizeof(texture->deforms)); texture->reflectmin = shader->reflectmin; texture->reflectmax = shader->reflectmax; @@ -1866,15 +1933,28 @@ nothing GL_ZERO GL_ONE else texture->basematerialflags |= MATERIALFLAG_WALL; texture->numskinframes = 1; - if (fallback) + if(cls.state == ca_dedicated) { - if (!(texture->skinframes[0] = R_SkinFrame_LoadExternal(texture->name, defaulttexflags, false))) - success = false; + texture->skinframes[0] = NULL; } else - success = false; - if (!success && warnmissing) - Con_Printf("^1%s:^7 could not load texture ^3\"%s\"\n", loadmodel->name, texture->name); + { + if (fallback) + { + qboolean has_alpha; + if ((texture->skinframes[0] = R_SkinFrame_LoadExternal_CheckAlpha(texture->name, defaulttexflags, false, &has_alpha))) + { + if(has_alpha && (defaulttexflags & TEXF_ALPHA)) + texture->basematerialflags |= MATERIALFLAG_ALPHA | MATERIALFLAG_BLENDED | MATERIALFLAG_NOSHADOW; + } + else + success = false; + } + else + success = false; + if (!success && warnmissing) + Con_Printf("^1%s:^7 could not load texture ^3\"%s\"\n", loadmodel->name, texture->name); + } } // init the animation variables texture->currentframe = texture; @@ -2025,23 +2105,20 @@ void Mod_SnapVertices(int numcomponents, int numvertices, float *vertices, float int Mod_RemoveDegenerateTriangles(int numtriangles, const int *inelement3i, int *outelement3i, const float *vertex3f) { int i, outtriangles; - float d, edgedir[3], temp[3]; + float edgedir1[3], edgedir2[3], temp[3]; // a degenerate triangle is one with no width (thickness, surface area) // these are characterized by having all 3 points colinear (along a line) // or having two points identical + // the simplest check is to calculate the triangle's area for (i = 0, outtriangles = 0;i < numtriangles;i++, inelement3i += 3) { // calculate first edge - VectorSubtract(vertex3f + inelement3i[1] * 3, vertex3f + inelement3i[0] * 3, edgedir); - if (VectorLength2(edgedir) < 0.0001f) - continue; // degenerate first edge (no length) - VectorNormalize(edgedir); - // check if third point is on the edge (colinear) - d = -DotProduct(vertex3f + inelement3i[2] * 3, edgedir); - VectorMA(vertex3f + inelement3i[2] * 3, d, edgedir, temp); - if (VectorLength2(temp) < 0.0001f) - continue; // third point colinear with first edge - // valid triangle (no colinear points, no duplicate points) + VectorSubtract(vertex3f + inelement3i[1] * 3, vertex3f + inelement3i[0] * 3, edgedir1); + VectorSubtract(vertex3f + inelement3i[2] * 3, vertex3f + inelement3i[0] * 3, edgedir2); + CrossProduct(edgedir1, edgedir2, temp); + if (VectorLength2(temp) < 0.001f) + continue; // degenerate triangle (no area) + // valid triangle (has area) VectorCopy(inelement3i, outelement3i); outelement3i += 3; outtriangles++;