///////////////////////////////////// // Name: // Purpose: // Output: // Return: ///////////////////////////////////// PUBLIC hTXT TextureCreateAlphaCircle(const char *name, BYTE r, BYTE g, BYTE b, DWORD usage, DWORD radius) { hTXT newTxt = TextureCreateCustom(0, name, radius, radius, 0, usage, BPP_32); if(!newTxt) { ASSERT_MSG(0, "Unable to allocate new texture", "Error in TextureCreateAlphaCircle"); return 0; } //now calculate circle stuff BYTE *gooks, *gooksWalk; int xOff, yOff, Value, x, y, pitch; double TempValue; if(TextureLock(newTxt, 0, 0, 0, &pitch, (void**)&gooks) == RETCODE_SUCCESS) { for (y = 0; y < newTxt->height; y++) { gooksWalk = gooks + y*pitch; //BYTE *gooksWalker = &BOARDPOS(gooks, y, 0, Width); for (x = 0; x < newTxt->width; x++) { xOff = x - newTxt->width / 2; yOff = y - newTxt->height / 2; TempValue = sqrtf(xOff * xOff + yOff * yOff) / (newTxt->width / 2); // You can run TempValue through whatever transforms you want here. // Here I've chosen to make the solid center a bit larger by having // TempValue stay zero over a larger range while still hitting 1.0 // at the same point. TempValue = (TempValue - 0.1) * (1.0 / 0.9); Value = 255 - (int)(TempValue * 255 + 0.5); if (Value < 0) Value = 0; if (Value > 255) Value = 255; gooksWalk[3] = Value; gooksWalk[2] = r; gooksWalk[1] = g; gooksWalk[0] = b; gooksWalk+=4; } } TextureUnlock(newTxt, 0); } return newTxt; }
static bool TextureCompressQDM(LPDIRECT3DTEXTURE *base, LPDIRECT3DTEXTURE *norm, int minlevel) { LPDIRECT3DTEXTURE baset; LPDIRECT3DTEXTURE normt; RESOURCEINFO based, baseo; RESOURCEINFO normd, normo; TextureInfoLevel(*base, baseo, 0); TextureInfoLevel(*norm, normo, 0); #if 0 /* Converts a height map into a normal map. The (x,y,z) * components of each normal are mapped to the (r,g,b) * channels of the output texture. */ HRESULT D3DXComputeNormalMap( __out LPDIRECT3DTEXTURE pTexture, __in LPDIRECT3DTEXTURE pSrcTexture, __in const PALETTEENTRY *pSrcPalette, __in DWORD Flags, __in DWORD Channel, __in FLOAT Amplitude ); #endif /* they have to have the same dimension */ if ((baseo.Width != normo.Width ) || (baseo.Height != normo.Height)) return false; /* convert to ARGB8 (TODO: support at least the 16bit formats as well) */ if ((baseo.Format != TEXFMT_A8B8G8R8) && baseo.Format = TEXFMT_A8R8G8B8, !TextureConvert(baseo, base, false)) return false; if ((normo.Format != TEXFMT_A8B8G8R8) && normo.Format = TEXFMT_A8R8G8B8, !TextureConvert(normo, norm, true)) return false; /* create the textures */ int levels = TextureCalcMip(baseo.Width, baseo.Height, minlevel); int flags = squish::kColourIterativeClusterFit | squish::kBtc3; #ifdef DX11 ULONG *bases; ULONG *norms; DWORD basel = 1; DWORD norml = 1; DWORD level = max(basel, norml); #else /* create the textures */ pD3DDevice->CreateTexture(baseo.Width, baseo.Height, levels, 0, D3DFMT_DXT5, D3DPOOL_SYSTEMMEM, &baset, NULL); pD3DDevice->CreateTexture(normo.Width, normo.Height, levels, 0, D3DFMT_DXT5, D3DPOOL_SYSTEMMEM, &normt, NULL); /* damit */ if (!baset || !normt) { if (baset) baset->Release(); if (normt) normt->Release(); return false; } ULONG bPch, *bases = TextureLock(*base, &bPch, 0); ULONG nPch, *norms = TextureLock(*norm, &nPch, 0); DWORD basel = baset->GetLevelCount(); DWORD norml = normt->GetLevelCount(); DWORD level = max(basel, norml); #endif for (unsigned int l = 0; l < level; l++) { /* square dimension of this surface-level */ /* square area of this surface-level */ int lv = (1 << l); int av = lv * lv; TextureInfoLevel(baset, based, l); TextureInfoLevel(normt, normd, l); ULONG sPch, *baser = TextureLock(baset, l, &sPch, true); ULONG nPch, *normr = TextureLock(normt, l, &nPch, true); ULONG *sBase = (ULONG *)bases; ULONG *sNorm = (ULONG *)norms; ULONG *dBase = (ULONG *)baser; ULONG *dNorm = (ULONG *)normr; /* loop over 4x4-blocks of this level (DXT5) */ for (unsigned int y = 0; y < based.Height; y += TY) { if (!(y & 0x3F)) { // logrf("line processed %d/%d of level %d/%d\r", y, based.Height, l, level); // PollProgress(); } for (unsigned int x = 0; x < based.Width; x += TX) { UTYPE bBase[2][TY][TX]; ULONG bNorm[2][TY][TX]; type fBase[2][TY][TX][DIM]; float fNorm[2][TY][TX][DIM]; /* generate this level's 4x4-block from the original surface */ for (int ly = 0; ly < TY; ly += 1) for (int lx = 0; lx < TX; lx += 1) { type bs[DIM] = {0}; int yl = ((y + ly) << l); /*ng ns[DIM] = {0*/ int xl = ((x + lx) << l); float nn[DIM] = {0.0f}; /* access all pixels this level's 4x4-block represents in * the full dimension original surface (high quality mip-mapping) */ for (int oy = 0; oy < lv; oy += 1) for (int ox = 0; ox < lv; ox += 1) { /* assume seamless tiling: wrap pixels around */ int posx = (xl + ox) % baseo.Width; int posy = (yl + oy) % baseo.Height; ULONG &b = sBase[(posy * sPch) + posx]; ULONG &n = sNorm[(posy * nPch) + posx]; /* transfer heightmap into the normal-map (overwrite) */ if (LODed) n = (n & 0x00FFFFFF) + (b & 0xFF000000); { static const f<TCOMPRESS_RGBH> fmt; Accu(bs, b); } { static const f<TCOMPRESS_XYZD> fmt; Accu(nn, n); } // AccuRGBM<ACCUMODE_LINEAR>(bs, b, level, l, colorgamma); // += and max #if defined(NORMALS_INTEGER) // AccuXYZD<ACCUMODE_SCALE >(ns, n, level, l, NORMALS_SCALEBYLEVEL); // += #else // AccuXYZD<ACCUMODE_SCALE >(nn, n, level, l, NORMALS_SCALEBYLEVEL); // += #endif } /* build average of each channel */ { const int format = TCOMPRESS_RGBH; Norm(fBase[0][ly][lx], bs, av, levels, l); } { const int format = TCOMPRESS_XYZD; Norm(fNorm[0][ly][lx], nn, av, levels, l); } // NormRGBM<TRGTMODE_CODING_RGB >(fBase[0][ly][lx], bs, av, colorgammainv); #if defined(NORMALS_INTEGER) // NormXYZD<TRGTMODE_CODING_DXDYdZt | TRGTNORM_CUBESPACE>(fNorm[0][ly][lx], ns, av); #else // NormXYZD<TRGTMODE_CODING_DXDYdZt | TRGTNORM_CUBESPACE>(fNorm[0][ly][lx], nn, av); #endif } type br[DIM] = {0}; /*ng nr[DIM] = {0*/ float rn[DIM] = {0.0f}; /* analyze this level's 4x4-block */ for (int ly = 0; ly < TY; ly += 1) for (int lx = 0; lx < TX; lx += 1) { { const int format = TCOMPRESS_RGBH; Look(fBase[0][ly][lx], br); } { const int format = TCOMPRESS_XYZD; Look(fNorm[0][ly][lx], rn); } // LookRGBH<TRGTMODE_CODING_RGB >(fBase[0][ly][lx], br); #if defined(NORMALS_INTEGER) // LookXYZD<TRGTMODE_CODING_DXDYdZt | TRGTNORM_CUBESPACE>(fNorm[0][ly][lx], nr); #else // LookXYZD<TRGTMODE_CODING_DXDYdZt | TRGTNORM_CUBESPACE>(fNorm[0][ly][lx], rn); #endif } /* generate this level's 4x4-block from the original surface */ for (int ly = 0; ly < TY; ly += 1) for (int lx = 0; lx < TX; lx += 1) { /* build average of each channel an join */ UTYPE b; ULONG n; { const int format = TCOMPRESS_RGBH; Code(fBase[0][ly][lx], br, (TCOMPRESS_CHANNELS(format) + (TCOMPRESS_GREYS (format) ? 2 : 0)) == 2 ? 8 : (TCOMPRESS_SWIZZL (format) ? 6 : 5)); } { const int format = TCOMPRESS_XYZD; Code(fNorm[0][ly][lx], rn, (TCOMPRESS_CHANNELS(format) + (TCOMPRESS_GREYS (format) ? 2 : 0)) == 2 ? 8 : (TCOMPRESS_SWIZZL (format) ? 6 : 5)); } { const int format = TCOMPRESS_RGBH; b = Join(fBase[0][ly][lx], br); } { const int format = TCOMPRESS_XYZD; n = Join(fNorm[0][ly][lx], rn); } // CodeRGBH<TRGTMODE_CODING_RGB >(fBase[0][ly][lx], br); #if defined(NORMALS_INTEGER) // CodeXYZD<TRGTMODE_CODING_DXDYdZt | TRGTNORM_CUBESPACE, TCOMPRESS_SWIZZL(format) ? 6 : 5>(fNorm[0][ly][lx], nr); #else // CodeXYZD<TRGTMODE_CODING_DXDYdZt | TRGTNORM_CUBESPACE, TCOMPRESS_SWIZZL(format) ? 6 : 5>(fNorm[0][ly][lx], rn); #endif // b = JoinRGBH<TRGTMODE_CODING_RGB >(fBase[0][ly][lx], br); #if defined(NORMALS_INTEGER) // n = JoinXYZD<TRGTMODE_CODING_DXDYdZt | TRGTNORM_CUBESPACE>(fNorm[0][ly][lx], nr); #else // n = JoinXYZD<TRGTMODE_CODING_DXDYdZt | TRGTNORM_CUBESPACE>(fNorm[0][ly][lx], rn); #endif /* write the result ABGR */ bBase[0][ly][lx] = b; bNorm[0][ly][lx] = n; } /* compress to DXT5 */ #if 0 stb_compress_dxt_block((unsigned char *)dBase, (unsigned char *)bBase[0], true, STB_DXT_DITHER | STB_DXT_HIGHQUAL); stb_compress_dxt_block((unsigned char *)dNorm, (unsigned char *)bNorm[0], true, STB_DXT_NORMAL | STB_DXT_HIGHQUAL); #else squish::Compress((unsigned char *)bBase[0], dBase, flags + squish::kColourMetricPerceptual); squish::Compress((unsigned char *)bNorm[0], dNorm, flags + squish::kColourMetricUniform); #endif /* advance pointer of compressed blocks */ dBase += (128 / 32); dNorm += (128 / 32); #if 0 for (int ly = 0; ly < TY; ly += 1) for (int lx = 0; lx < TX; lx += 1) { dBase[((y + ly) * bPch) + (x + lx)] = bBase[0][ly][lx]; dNorm[((y + ly) * nPch) + (x + lx)] = bNorm[0][ly][lx]; } #endif } } TextureUnlock(baset, l); TextureUnlock(normt, l); } TextureUnlock((*base), 0); TextureUnlock((*norm), 0); (*base)->Release(); (*norm)->Release(); (*base) = baset; (*norm) = normt; return true; }