/////////////////////////////////////
// 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;
}
Exemple #2
0
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;
}