/* This is a small part of the implementation of C4Landscape for what is
 * required by mape. We cannot link the full implementation since it would
 * introduce a dependency on C4Game, and therefore the rest of the engine. */
int32_t PixCol2Mat(BYTE pixc)
{
        // Get texture 
        int32_t iTex = PixCol2Tex(pixc);
        if (!iTex) return MNone;
        // Get material-texture mapping
        const C4TexMapEntry *pTex = ::TextureMap.GetEntry(iTex);
        // Return material
        return pTex ? pTex->GetMaterialIndex() : MNone;
}
void C4LandscapeRenderClassic::Update(C4Rect To, C4Landscape *pSource)
{
	// clip to landscape size
	To.Intersect(C4Rect(0,0,iWidth,iHeight));
	// everything clipped?
	if (To.Wdt<=0 || To.Hgt<=0) return;
	if (!Surface32->Lock()) return;

	// We clear the affected region here because ClearBoxDw allocates the
	// main memory buffer for the box, so that only that box needs to be
	// sent to the gpu, and not the whole texture, or every pixel
	// separately. It's an important optimization.
	Surface32->ClearBoxDw(To.x, To.y, To.Wdt, To.Hgt);

	// do lightning
	for (int32_t iX=To.x; iX<To.x+To.Wdt; ++iX)
	{
		int AboveDensity = 0, BelowDensity = 0;
		for (int i = 1; i <= 8; ++i)
		{
			AboveDensity += pSource->GetPlacement(iX, To.y - i - 1);
			BelowDensity += pSource->GetPlacement(iX, To.y + i - 1);
		}
		for (int32_t iY=To.y; iY<To.y+To.Hgt; ++iY)
		{
			AboveDensity -= pSource->GetPlacement(iX, iY - 9);
			AboveDensity += pSource->GetPlacement(iX, iY - 1);
			BelowDensity -= pSource->GetPlacement(iX, iY);
			BelowDensity += pSource->GetPlacement(iX, iY + 8);
			BYTE pix = pSource->_GetPix(iX, iY);
			// Sky
			if (!pix)
			{
				Surface32->SetPixDw(iX, iY, 0x00ffffff);
				continue;
			}
			// get density
			int iOwnDens = pSource->_GetPlacement(iX, iY);
			if (!iOwnDens) continue;
			iOwnDens *= 2;
			iOwnDens += pSource->GetPlacement(iX + 1, iY) + pSource->GetPlacement(iX - 1, iY);
			iOwnDens /= 4;
			// get texture map entry for pixel
			const C4TexMapEntry *pTex = pTexs->GetEntry(PixCol2Tex(pix));
			assert(pTex);
			// get texture contents
			DWORD dwBackClr = 0u;
			if (pTex) dwBackClr = pTex->GetPattern().PatternClr(iX, iY);
			// get density of surrounding materials
			int iCompareDens = AboveDensity / 8;
			if (iOwnDens > iCompareDens)
			{
				// apply light
				LightenClrBy(dwBackClr, std::min(30, 2 * (iOwnDens - iCompareDens)));
			}
			else if (iOwnDens < iCompareDens && iOwnDens < 30)
			{
				DarkenClrBy(dwBackClr, std::min(30, 2 * (iCompareDens - iOwnDens)));
			}
			iCompareDens = BelowDensity / 8;
			if (iOwnDens > iCompareDens)
			{
				DarkenClrBy(dwBackClr, std::min(30, 2 * (iOwnDens - iCompareDens)));
			}
			Surface32->SetPixDw(iX, iY, dwBackClr);
		}
	}
	Surface32->Unlock();
}
Example #3
0
void C4LandscapeRenderGL::BuildMatMap(uint32_t *pTex)
{
	// TODO: Still merely an inefficient placeholder for things to come...

	// Build material-texture map (depth parameter where to find appropriate texture)
	for(int pix = 0; pix < 256; pix++)
	{
		// Look up indexed entry
		const C4TexMapEntry *pEntry = pTexs->GetEntry(PixCol2Tex(BYTE(pix)));
		if(!pEntry->GetTextureName())
		{
			// Undefined textures transparent
			pTex[2*pix] = 0;
			pTex[2*pix+1] = RGBA(0,0,0,255);
			continue;
		}

		// Got animation?
		int iPhases = 1; const char *p = pEntry->GetTextureName();
		while((p = strchr(p, '-'))) { p++; iPhases++; }
		// Hard-coded hack. Fix me!
		C4Material *pMaterial = pEntry->GetMaterial();
		const int iPhaseLength = pMaterial->AnimationSpeed;
		float phase = 0;
		if (iPhases > 1) {
			phase = C4TimeMilliseconds::Now().AsInt() % (iPhases * iPhaseLength);
			phase /= iPhaseLength;
		}

		// Find our transition
		const char *pFrom = pEntry->GetTextureName();
		float gTexCoo = 0;
		for(int iP = 0;; iP++)
		{
			// Get next phase
			const char *pTo = strchr(pFrom, '-');
			if(!pTo) pTo = pEntry->GetTextureName(); else pTo++;
			// Add transition
			if(iP == int(phase))
			{
				StdStrBuf From, To;
				From.CopyUntil(pFrom, '-');
				To.CopyUntil(pTo, '-');
				// Find transition
				int iTrans;
				if ((iTrans = LookupTextureTransition(From.getData(), To.getData())) >= 0)
					gTexCoo = float(iTrans) + fmod(phase, 1.0f);
				else if ((iTrans = LookupTextureTransition(To.getData(), From.getData())) >= 0)
					gTexCoo = float(iTrans) + 1.0 - fmod(phase, 1.0f);
				break;
			}
			// Advance
			pFrom = pTo;
		}

		// Assign texture
		int iTexCoo = int((gTexCoo * 256.0 / iMaterialTextureDepth) + 0.5);
		pTex[2*pix] = RGBA(
			Clamp(pMaterial->LightEmit[0], 0, 255),
			Clamp(pMaterial->LightEmit[1], 0, 255),
			Clamp(pMaterial->LightEmit[2], 0, 255),
			iTexCoo);
		pTex[2*pix+1] = RGBA(
			Clamp(pMaterial->LightSpot[0], 0, 255),
			Clamp(pMaterial->LightSpot[1], 0, 255),
			Clamp(pMaterial->LightSpot[2], 0, 255),
			Clamp(pMaterial->LightAngle, 0, 255));
	}
}