예제 #1
0
FTextureID FTextureManager::PalCheck(FTextureID tex)
{
	//if (vid_nopalsubstitutions) return tex;
	int *newtex = PalettedVersions.CheckKey(tex.GetIndex());
	if (newtex == NULL || *newtex == 0) return tex;
	return *newtex;
}
예제 #2
0
static void ParseFloor (FScanner &sc)
{
	FTextureID picnum;
	int terrain;

	bool opt = sc.CheckString("optional");
	sc.MustGetString ();

	picnum = TexMan.CheckForTexture (sc.String, FTexture::TEX_Flat,
		FTextureManager::TEXMAN_Overridable|FTextureManager::TEXMAN_TryAny);

	if (!picnum.Exists())
	{
		if (!opt)
		{
			Printf("Unknown flat %s\n", sc.String);
		}
		sc.MustGetString();
		return;
	}
	sc.MustGetString ();
	terrain = P_FindTerrain (sc.String);
	if (terrain == -1)
	{
		Printf ("Unknown terrain %s\n", sc.String);
		terrain = 0;
	}
	TerrainTypes.Set(picnum.GetIndex(), terrain);
}
예제 #3
0
bool FTextureManager::AreTexturesCompatible (FTextureID picnum1, FTextureID picnum2)
{
	int index1 = picnum1.GetIndex();
	int index2 = picnum2.GetIndex();
	if (unsigned(index1) >= Textures.Size() || unsigned(index2) >= Textures.Size())
		return false;

	FTexture *texture1 = Textures[index1].Texture;
	FTexture *texture2 = Textures[index2].Texture;

	// both textures must be the same type.
	if (texture1 == NULL || texture2 == NULL || texture1->UseType != texture2->UseType)
		return false;

	// both textures must be from the same file
	for(unsigned i = 0; i < FirstTextureForFile.Size() - 1; i++)
	{
		if (index1 >= FirstTextureForFile[i] && index1 < FirstTextureForFile[i+1])
		{
			return (index2 >= FirstTextureForFile[i] && index2 < FirstTextureForFile[i+1]);
		}
	}
	return false;
}
예제 #4
0
void FTextureManager::ReplaceTexture (FTextureID picnum, FTexture *newtexture, bool free)
{
	int index = picnum.GetIndex();
	if (unsigned(index) >= Textures.Size())
		return;

	FTexture *oldtexture = Textures[index].Texture;

	strcpy (newtexture->Name, oldtexture->Name);
	newtexture->UseType = oldtexture->UseType;
	Textures[index].Texture = newtexture;

	newtexture->id = oldtexture->id;
	if (free)
	{
		delete oldtexture;
	}
	else
	{
		oldtexture->id.SetInvalid();
	}
}
예제 #5
0
FTexture *FTextureManager::FindTexture(const char *texname, int usetype, BITFIELD flags)
{
	FTextureID texnum = CheckForTexture (texname, usetype, flags);
	return !texnum.isValid()? NULL : Textures[texnum.GetIndex()].Texture;
}
예제 #6
0
void SetHUDIcon(PClass *cls, FTextureID tex)
{
	cls->Meta.SetMetaInt(HUMETA_AltIcon, tex.GetIndex());
}
예제 #7
0
//==========================================================================
//
// Creates all 3D floors defined by one linedef
//
//==========================================================================
static int P_Set3DFloor(line_t * line, int param, int param2, int alpha)
{
	int s;
	int flags;
	int tag = line->args[0];
	sector_t * sec = line->frontsector, *ss;

	FSectorTagIterator itr(tag);
	while ((s = itr.Next()) >= 0)
	{
		ss = &level.sectors[s];

		if (param == 0)
		{
			flags = FF_EXISTS | FF_RENDERALL | FF_SOLID | FF_INVERTSECTOR;
			alpha = 255;
			for (auto l: sec->Lines)
			{
				if (l->special == Sector_SetContents && l->frontsector == sec)
				{
					alpha = clamp<int>(l->args[1], 0, 100);
					if (l->args[2] & 1) flags &= ~FF_SOLID;
					if (l->args[2] & 2) flags |= FF_SEETHROUGH;
					if (l->args[2] & 4) flags |= FF_SHOOTTHROUGH;
					if (l->args[2] & 8) flags |= FF_ADDITIVETRANS;
					if (alpha != 100) flags |= FF_TRANSLUCENT;//|FF_BOTHPLANES|FF_ALLSIDES;
					if (l->args[0])
					{
						// Yes, Vavoom's 3D-floor definitions suck!
						// The content list changed in r1783 of Vavoom to be unified
						// among all its supported games, so it has now ten different
						// values instead of just five.
						static DWORD vavoomcolors[] = { VC_EMPTY,
							VC_WATER, VC_LAVA, VC_NUKAGE, VC_SLIME, VC_HELLSLIME,
							VC_BLOOD, VC_SLUDGE, VC_HAZARD, VC_BOOMWATER };
						flags |= FF_SWIMMABLE | FF_BOTHPLANES | FF_ALLSIDES | FF_FLOOD;

						l->frontsector->ColorMap =
							GetSpecialLights(l->frontsector->ColorMap->Color,
							vavoomcolors[l->args[0]],
							l->frontsector->ColorMap->Desaturate);
					}
					alpha = (alpha * 255) / 100;
					break;
				}
			}
		}
		else if (param == 4)
		{
			flags = FF_EXISTS | FF_RENDERPLANES | FF_INVERTPLANES | FF_NOSHADE | FF_FIX;
			if (param2 & 1) flags |= FF_SEETHROUGH;	// marker for allowing missing texture checks
			alpha = 255;
		}
		else
		{
			static const int defflags[] = { 0,
				FF_SOLID,
				FF_SWIMMABLE | FF_BOTHPLANES | FF_ALLSIDES | FF_SHOOTTHROUGH | FF_SEETHROUGH,
				FF_SHOOTTHROUGH | FF_SEETHROUGH,
			};

			flags = defflags[param & 3] | FF_EXISTS | FF_RENDERALL;

			if (param & 4) flags |= FF_ALLSIDES | FF_BOTHPLANES;
			if (param & 16) flags ^= FF_SEETHROUGH;
			if (param & 32) flags ^= FF_SHOOTTHROUGH;

			if (param2 & 1) flags |= FF_NOSHADE;
			if (param2 & 2) flags |= FF_DOUBLESHADOW;
			if (param2 & 4) flags |= FF_FOG;
			if (param2 & 8) flags |= FF_THINFLOOR;
			if (param2 & 16) flags |= FF_UPPERTEXTURE;
			if (param2 & 32) flags |= FF_LOWERTEXTURE;
			if (param2 & 64) flags |= FF_ADDITIVETRANS | FF_TRANSLUCENT;
			// if flooding is used the floor must be non-solid and is automatically made shootthrough and seethrough
			if ((param2 & 128) && !(flags & FF_SOLID)) flags |= FF_FLOOD | FF_SEETHROUGH | FF_SHOOTTHROUGH;
			if (param2 & 512) flags |= FF_FADEWALLS;
			if (param2&1024) flags |= FF_RESET;
			FTextureID tex = line->sidedef[0]->GetTexture(side_t::top);
			if (!tex.Exists() && alpha < 255)
			{
				alpha = -tex.GetIndex();
			}
			alpha = clamp(alpha, 0, 255);
			if (alpha == 0) flags &= ~(FF_RENDERALL | FF_BOTHPLANES | FF_ALLSIDES);
			else if (alpha != 255) flags |= FF_TRANSLUCENT;

		}
		P_Add3DFloor(ss, sec, line, flags, alpha);
	}
	// To be 100% safe this should be done even if the alpha by texture value isn't used.
	if (!line->sidedef[0]->GetTexture(side_t::top).isValid())
		line->sidedef[0]->SetTexture(side_t::top, FNullTextureID());
	return 1;
}
예제 #8
0
void FGLInterface::Precache(BYTE *texhitlist, TMap<PClassActor*, bool> &actorhitlist)
{
	SpriteHits *spritelist = new SpriteHits[sprites.Size()];
	SpriteHits **spritehitlist = new SpriteHits*[TexMan.NumTextures()];
	TMap<PClassActor*, bool>::Iterator it(actorhitlist);
	TMap<PClassActor*, bool>::Pair *pair;
	BYTE *modellist = new BYTE[Models.Size()];
	memset(modellist, 0, Models.Size());
	memset(spritehitlist, 0, sizeof(SpriteHits**) * TexMan.NumTextures());

	// this isn't done by the main code so it needs to be done here first:
	// check skybox textures and mark the separate faces as used
	for (int i = 0; i<TexMan.NumTextures(); i++)
	{
		// HIT_Wall must be checked for MBF-style sky transfers. 
		if (texhitlist[i] & (FTextureManager::HIT_Sky | FTextureManager::HIT_Wall))
		{
			FTexture *tex = TexMan.ByIndex(i);
			if (tex->gl_info.bSkybox)
			{
				FSkyBox *sb = static_cast<FSkyBox*>(tex);
				for (int i = 0; i<6; i++)
				{
					if (sb->faces[i])
					{
						int index = sb->faces[i]->id.GetIndex();
						texhitlist[index] |= FTextureManager::HIT_Flat;
					}
				}
			}
		}
	}

	// Check all used actors.
	// 1. mark all sprites associated with its states
	// 2. mark all model data and skins associated with its states
	while (it.NextPair(pair))
	{
		PClassActor *cls = pair->Key;
		int gltrans = GLTranslationPalette::GetInternalTranslation(GetDefaultByType(cls)->Translation);

		for (int i = 0; i < cls->NumOwnedStates; i++)
		{
			spritelist[cls->OwnedStates[i].sprite].Insert(gltrans, true);
			FSpriteModelFrame * smf = gl_FindModelFrame(cls, cls->OwnedStates[i].sprite, cls->OwnedStates[i].Frame, false);
			if (smf != NULL)
			{
				for (int i = 0; i < MAX_MODELS_PER_FRAME; i++)
				{
					if (smf->skinIDs[i].isValid())
					{
						texhitlist[smf->skinIDs[i].GetIndex()] |= FTexture::TEX_Flat;
					}
					else if (smf->modelIDs[i] != -1)
					{
						Models[smf->modelIDs[i]]->PushSpriteMDLFrame(smf, i);
						Models[smf->modelIDs[i]]->AddSkins(texhitlist);
					}
					if (smf->modelIDs[i] != -1)
					{
						modellist[smf->modelIDs[i]] = 1;
					}
				}
			}
		}
	}

	// mark all sprite textures belonging to the marked sprites.
	for (int i = (int)(sprites.Size() - 1); i >= 0; i--)
	{
		if (spritelist[i].CountUsed())
		{
			int j, k;
			for (j = 0; j < sprites[i].numframes; j++)
			{
				const spriteframe_t *frame = &SpriteFrames[sprites[i].spriteframes + j];

				for (k = 0; k < 16; k++)
				{
					FTextureID pic = frame->Texture[k];
					if (pic.isValid())
					{
						spritehitlist[pic.GetIndex()] = &spritelist[i];
					}
				}
			}
		}
	}

	// delete everything unused before creating any new resources to avoid memory usage peaks.

	// delete unused models
	for (unsigned i = 0; i < Models.Size(); i++)
	{
		if (!modellist[i]) Models[i]->DestroyVertexBuffer();
	}

	// delete unused textures
	int cnt = TexMan.NumTextures();
	for (int i = cnt - 1; i >= 0; i--)
	{
		FTexture *tex = TexMan.ByIndex(i);
		if (tex != nullptr)
		{
			if (!texhitlist[i])
			{
				if (tex->gl_info.Material[0]) tex->gl_info.Material[0]->Clean(true);
			}
			if (spritehitlist[i] == nullptr || (*spritehitlist[i]).CountUsed() == 0)
			{
				if (tex->gl_info.Material[1]) tex->gl_info.Material[1]->Clean(true);
			}
		}
	}

	if (gl_precache)
	{
		// cache all used textures
		for (int i = cnt - 1; i >= 0; i--)
		{
			FTexture *tex = TexMan.ByIndex(i);
			if (tex != nullptr)
			{
				PrecacheTexture(tex, texhitlist[i]);
				if (spritehitlist[i] != nullptr && (*spritehitlist[i]).CountUsed() > 0)
				{
					PrecacheSprite(tex, *spritehitlist[i]);
				}
			}
		}

		// cache all used models
		for (unsigned i = 0; i < Models.Size(); i++)
		{
			if (modellist[i]) 
				Models[i]->BuildVertexBuffer();
		}
	}

	delete[] spritehitlist;
	delete[] spritelist;
	delete[] modellist;
}