Пример #1
0
void d3d_texture_blit(unsigned pixel_size,
      LPDIRECT3DTEXTURE tex, D3DLOCKED_RECT *lr, const void *frame,
      unsigned width, unsigned height, unsigned pitch)
{
#ifdef _XBOX
   D3DTexture_LockRect(tex, 0, lr, NULL, D3DLOCK_NOSYSLOCK);
#if defined(_XBOX360)
   D3DSURFACE_DESC desc;
   tex->GetLevelDesc(0, &desc);
   XGCopySurface(lr->pBits, lr->Pitch, width, height, desc.Format, NULL,
      frame, pitch, desc.Format, NULL, 0, 0);
#elif defined(_XBOX1)
   unsigned y;
   for (y = 0; y < height; y++)
   {
      const uint8_t *in = (const uint8_t*)frame + y * pitch;
      uint8_t *out = (uint8_t*)lr->pBits + y * lr->Pitch;
      memcpy(out, in, width * pixel_size);
   }
#endif
   D3DTexture_UnlockRect(tex, 0);
#else
   if (SUCCEEDED(tex->LockRect(0, lr, NULL, D3DLOCK_NOSYSLOCK)))
   {
      unsigned y;
      for (y = 0; y < height; y++)
      { 
         const uint8_t *in = (const uint8_t*)frame + y * pitch;
         uint8_t *out = (uint8_t*)lr->pBits + y * lr->Pitch;
         memcpy(out, in, width * pixel_size);
      }
      tex->UnlockRect(0);
   }
#endif
}
Пример #2
0
void d3d_lockrectangle_clear(void *data, 
      LPDIRECT3DTEXTURE tex,
      unsigned level, D3DLOCKED_RECT *lock_rect, RECT *rect,
      unsigned rectangle_height, unsigned flags)
{
#if defined(_XBOX)
   d3d_video_t *d3d = (d3d_video_t*)data;
   D3DTexture_LockRect(tex, level, lock_rect, rect, flags);
   memset(lock_rect->pBits, 0, d3d->tex_h * lock_rect->Pitch);
#else
   if (SUCCEEDED(tex->LockRect(level, lock_rect, rect, flags)))
   {
      memset(lock_rect->pBits, level, rectangle_height * lock_rect->Pitch);
      tex->UnlockRect(0);
   }
#endif
}
Пример #3
0
void d3d_texture_blit(void *data, unsigned pixel_size,
      LPDIRECT3DTEXTURE tex, D3DLOCKED_RECT *lr, const void *frame,
      unsigned width, unsigned height, unsigned pitch)
{
   unsigned y;
	d3d_video_t *d3d = (d3d_video_t*)data;

   (void)y;

   if (!d3d)
	   return;

#ifdef _XBOX
   /* Set the texture to NULL so D3D doesn't complain about it being in use... */
   d3d_set_texture(d3d->dev, 0, NULL); 
   D3DTexture_LockRect(tex, 0, lr, NULL, D3DLOCK_NOSYSLOCK);
#if defined(_XBOX360)
   D3DSURFACE_DESC desc;
   tex->GetLevelDesc(0, &desc);
   XGCopySurface(lr->pBits, lr->Pitch, width, height, desc.Format, NULL,
      frame, pitch, desc.Format, NULL, 0, 0);
#elif defined(_XBOX1)
   for (y = 0; y < height; y++)
   {
      const uint8_t *in = (const uint8_t*)frame + y * pitch;
      uint8_t *out = (uint8_t*)lr->pBits + y * lr->Pitch;
      memcpy(out, in, width * d3d->pixel_size);
   }
#endif
   D3DTexture_UnlockRect(tex, 0);
#else
   if (SUCCEEDED(tex->LockRect(0, lr, NULL, D3DLOCK_NOSYSLOCK)))
   {
      for (y = 0; y < height; y++)
      { 
         const uint8_t *in = (const uint8_t*)frame + y * pitch;
         uint8_t *out = (uint8_t*)lr->pBits + y * lr->Pitch;
         memcpy(out, in, width * pixel_size);
      }
      tex->UnlockRect(0);
   }
#endif
}
Пример #4
0
void d3d_texture_free(LPDIRECT3DTEXTURE tex)
{
   if (tex)
   {
#if defined(HAVE_D3D9) && !defined(__cplusplus)
      IDirect3DTexture9_Release(tex);
#else
      tex->Release();
#endif
   }
}
Пример #5
0
void d3d_unlock_rectangle(LPDIRECT3DTEXTURE tex)
{
#ifdef _XBOX
   D3DTexture_UnlockRect(tex, 0);
#else
#if defined(HAVE_D3D9) && !defined(__cplusplus)
   IDirect3DSurface9_UnlockRect(tex);
#else
   tex->UnlockRect(0);
#endif
#endif
}
Пример #6
0
bool d3d_lock_rectangle(LPDIRECT3DTEXTURE tex,
      unsigned level, D3DLOCKED_RECT *lock_rect, RECT *rect,
      unsigned rectangle_height, unsigned flags)
{
#if defined(_XBOX)
   D3DTexture_LockRect(tex, level, lock_rect, rect, flags);
   return true;
#else
   if (SUCCEEDED(tex->LockRect(level, lock_rect, rect, flags)))
      return true;
   return false;
#endif
}
Пример #7
0
bool d3d_lock_rectangle(LPDIRECT3DTEXTURE tex,
      unsigned level, D3DLOCKED_RECT *lock_rect, RECT *rect,
      unsigned rectangle_height, unsigned flags)
{
#if defined(_XBOX)
   D3DTexture_LockRect(tex, level, lock_rect, rect, flags);
#elif defined(HAVE_D3D9) && !defined(__cplusplus)
   if (IDirect3DSurface9_LockRect(tex, lock_rect, rect, flags) != D3D_OK)
      return false;
#else
   if (FAILED(tex->LockRect(level, lock_rect, rect, flags)))
      return false;
#endif
   return true;
}
Пример #8
0
void d3d_texture_blit(unsigned pixel_size,
      LPDIRECT3DTEXTURE tex, D3DLOCKED_RECT *lr, const void *frame,
      unsigned width, unsigned height, unsigned pitch)
{
   if (d3d_lock_rectangle(tex, 0, lr, NULL, 0, 0))
   {
#if defined(_XBOX360) && defined(_XBOX360)
      D3DSURFACE_DESC desc;
      tex->GetLevelDesc(0, &desc);
      XGCopySurface(lr->pBits, lr->Pitch, width, height, desc.Format, NULL,
            frame, pitch, desc.Format, NULL, 0, 0);
#else
      unsigned y;
      for (y = 0; y < height; y++)
      {
         const uint8_t *in = (const uint8_t*)frame + y * pitch;
         uint8_t *out = (uint8_t*)lr->pBits + y * lr->Pitch;
         memcpy(out, in, width * pixel_size);
      }
#endif
      d3d_unlock_rectangle(tex);
   }
}
Пример #9
0
void d3d_texture_free(LPDIRECT3DTEXTURE tex)
{
   if (tex)
      tex->Release();
   tex = NULL;
}
Пример #10
0
void d3d_unlock_rectangle(LPDIRECT3DTEXTURE tex)
{
#ifndef _XBOX
   tex->UnlockRect(0);
#endif
}
Пример #11
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;
}