2009-11-04 21:44:48 +00:00
|
|
|
#include "quakedef.h"
|
2012-07-05 19:42:36 +00:00
|
|
|
#include "winquake.h"
|
2012-09-30 05:52:03 +00:00
|
|
|
#ifdef D3D9QUAKE
|
2011-01-04 02:56:16 +00:00
|
|
|
#if !defined(HMONITOR_DECLARED) && (WINVER < 0x0500)
|
|
|
|
#define HMONITOR_DECLARED
|
|
|
|
DECLARE_HANDLE(HMONITOR);
|
|
|
|
#endif
|
2009-11-04 21:44:48 +00:00
|
|
|
#include <d3d9.h>
|
2011-03-31 02:32:32 +00:00
|
|
|
extern LPDIRECT3DDEVICE9 pD3DDev9;
|
2009-11-04 21:44:48 +00:00
|
|
|
|
2014-10-05 20:04:11 +00:00
|
|
|
void D3D9_DestroyTexture (texid_t tex)
|
2009-11-04 21:44:48 +00:00
|
|
|
{
|
2014-10-05 20:04:11 +00:00
|
|
|
if (!tex)
|
|
|
|
return;
|
2009-11-04 21:44:48 +00:00
|
|
|
|
2014-10-05 20:04:11 +00:00
|
|
|
if (tex->ptr)
|
2017-08-29 02:29:06 +00:00
|
|
|
IDirect3DBaseTexture9_Release((IDirect3DBaseTexture9*)tex->ptr);
|
2014-10-05 20:04:11 +00:00
|
|
|
tex->ptr = NULL;
|
2009-11-04 21:44:48 +00:00
|
|
|
}
|
|
|
|
|
2017-08-14 16:38:44 +00:00
|
|
|
qboolean D3D9_LoadTextureMips(image_t *tex, const struct pendingtextureinfo *mips)
|
2013-11-21 23:02:28 +00:00
|
|
|
{
|
2014-10-05 20:04:11 +00:00
|
|
|
qbyte *fte_restrict out, *fte_restrict in;
|
|
|
|
int x, y, i;
|
|
|
|
D3DLOCKED_RECT lock;
|
2018-03-04 14:41:16 +00:00
|
|
|
D3DFORMAT fmt = D3DFMT_UNKNOWN;
|
2014-10-05 20:04:11 +00:00
|
|
|
D3DSURFACE_DESC desc;
|
2017-08-29 02:29:06 +00:00
|
|
|
IDirect3DBaseTexture9 *dbt;
|
2014-10-05 20:04:11 +00:00
|
|
|
qboolean swap = false;
|
2017-12-28 16:24:50 +00:00
|
|
|
unsigned int blockwidth, blockheight, blockbytes;
|
2013-11-21 23:02:28 +00:00
|
|
|
|
2014-10-05 20:04:11 +00:00
|
|
|
switch(mips->encoding)
|
2013-11-21 23:02:28 +00:00
|
|
|
{
|
2014-10-11 19:39:45 +00:00
|
|
|
case PTI_RGB565:
|
|
|
|
fmt = D3DFMT_R5G6B5;
|
|
|
|
break;
|
|
|
|
case PTI_RGBA4444://not supported on d3d9
|
|
|
|
return false;
|
|
|
|
case PTI_ARGB4444:
|
|
|
|
fmt = D3DFMT_A4R4G4B4;
|
|
|
|
break;
|
|
|
|
case PTI_RGBA5551://not supported on d3d9
|
|
|
|
return false;
|
|
|
|
case PTI_ARGB1555:
|
|
|
|
fmt = D3DFMT_A1R5G5B5;
|
|
|
|
break;
|
2017-07-12 08:15:27 +00:00
|
|
|
case PTI_RGBA8_SRGB:
|
2014-10-05 20:04:11 +00:00
|
|
|
case PTI_RGBA8:
|
2014-10-11 19:39:45 +00:00
|
|
|
// fmt = D3DFMT_A8B8G8R8; /*how do we check
|
2014-10-05 20:04:11 +00:00
|
|
|
fmt = D3DFMT_A8R8G8B8;
|
|
|
|
swap = true;
|
|
|
|
break;
|
2017-07-12 08:15:27 +00:00
|
|
|
case PTI_RGBX8_SRGB:
|
2014-10-05 20:04:11 +00:00
|
|
|
case PTI_RGBX8:
|
2014-10-11 19:39:45 +00:00
|
|
|
// fmt = D3DFMT_X8B8G8R8;
|
2014-10-05 20:04:11 +00:00
|
|
|
fmt = D3DFMT_X8R8G8B8;
|
|
|
|
swap = true;
|
|
|
|
break;
|
2017-07-12 08:15:27 +00:00
|
|
|
case PTI_BGRA8_SRGB:
|
2014-10-05 20:04:11 +00:00
|
|
|
case PTI_BGRA8:
|
|
|
|
fmt = D3DFMT_A8R8G8B8;
|
|
|
|
break;
|
2017-07-12 08:15:27 +00:00
|
|
|
case PTI_BGRX8_SRGB:
|
2014-10-05 20:04:11 +00:00
|
|
|
case PTI_BGRX8:
|
|
|
|
fmt = D3DFMT_X8R8G8B8;
|
|
|
|
break;
|
2013-11-21 23:02:28 +00:00
|
|
|
|
2018-03-04 14:41:16 +00:00
|
|
|
case PTI_A2BGR10:
|
|
|
|
fmt = D3DFMT_A2B10G10R10;
|
|
|
|
break;
|
|
|
|
|
2014-10-05 20:04:11 +00:00
|
|
|
//too lazy to support these for now
|
2017-12-28 16:24:50 +00:00
|
|
|
case PTI_BC1_RGB_SRGB:
|
|
|
|
case PTI_BC1_RGBA_SRGB: //d3d doesn't distinguish between these
|
|
|
|
case PTI_BC1_RGB:
|
|
|
|
case PTI_BC1_RGBA: //d3d doesn't distinguish between these
|
2015-05-03 19:57:46 +00:00
|
|
|
fmt = D3DFMT_DXT1;
|
|
|
|
break;
|
2017-12-28 16:24:50 +00:00
|
|
|
case PTI_BC2_RGBA_SRGB:
|
|
|
|
case PTI_BC2_RGBA:
|
2015-05-03 19:57:46 +00:00
|
|
|
fmt = D3DFMT_DXT3;
|
|
|
|
break;
|
2017-12-28 16:24:50 +00:00
|
|
|
case PTI_BC3_RGBA_SRGB:
|
|
|
|
case PTI_BC3_RGBA:
|
2015-05-03 19:57:46 +00:00
|
|
|
fmt = D3DFMT_DXT5;
|
|
|
|
break;
|
2013-11-21 23:02:28 +00:00
|
|
|
|
2017-12-28 16:24:50 +00:00
|
|
|
//bc4-7 not supported on d3d9.
|
|
|
|
//etc2 have no chance.
|
|
|
|
|
2018-03-04 14:41:16 +00:00
|
|
|
case PTI_EMULATED: //no idea
|
|
|
|
default:
|
|
|
|
break;
|
2013-11-21 23:02:28 +00:00
|
|
|
}
|
2018-03-04 14:41:16 +00:00
|
|
|
if (fmt == D3DFMT_UNKNOWN)
|
|
|
|
return false;
|
2013-11-21 23:02:28 +00:00
|
|
|
|
2017-12-28 16:24:50 +00:00
|
|
|
Image_BlockSizeForEncoding(mips->encoding, &blockbytes, &blockwidth, &blockheight);
|
|
|
|
|
2015-07-01 23:15:25 +00:00
|
|
|
if (!pD3DDev9)
|
|
|
|
return false; //can happen on errors
|
2017-08-29 02:29:06 +00:00
|
|
|
if (mips->type == PTI_CUBEMAP)
|
2009-11-04 21:44:48 +00:00
|
|
|
{
|
2017-08-29 02:29:06 +00:00
|
|
|
IDirect3DCubeTexture9 *dt;
|
|
|
|
if (FAILED(IDirect3DDevice9_CreateCubeTexture(pD3DDev9, mips->mip[0].width, mips->mipcount/6, 0, fmt, D3DPOOL_MANAGED, &dt, NULL)))
|
2014-10-05 20:04:11 +00:00
|
|
|
return false;
|
2017-08-29 02:29:06 +00:00
|
|
|
dbt = (IDirect3DBaseTexture9*)dt;
|
2009-11-04 21:44:48 +00:00
|
|
|
|
2017-08-29 02:29:06 +00:00
|
|
|
for (i = 0; i < mips->mipcount; i++)
|
2010-11-06 23:05:29 +00:00
|
|
|
{
|
2017-08-29 02:29:06 +00:00
|
|
|
IDirect3DCubeTexture9_GetLevelDesc(dt, i/6, &desc);
|
|
|
|
|
|
|
|
if (mips->mip[i].height != desc.Height || mips->mip[i].width != desc.Width)
|
2010-11-06 23:05:29 +00:00
|
|
|
{
|
2017-08-29 02:29:06 +00:00
|
|
|
IDirect3DCubeTexture9_Release(dt);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
IDirect3DCubeTexture9_LockRect(dt, i%6, i/6, &lock, NULL, D3DLOCK_NOSYSLOCK|D3DLOCK_DISCARD);
|
|
|
|
//can't do it in one go. pitch might contain padding or be upside down.
|
|
|
|
if (!mips->mip[i].data)
|
|
|
|
;
|
|
|
|
else if (swap)
|
2017-12-28 16:24:50 +00:00
|
|
|
{ //only works for blockbytes=4
|
|
|
|
size_t rowbytes = ((mips->mip[i].width+blockwidth-1)/blockwidth)*blockbytes;
|
|
|
|
for (y = 0, out = lock.pBits, in = mips->mip[i].data; y < mips->mip[i].height; y+=blockheight, out += lock.Pitch, in += rowbytes)
|
2014-10-05 20:04:11 +00:00
|
|
|
{
|
2017-12-28 16:24:50 +00:00
|
|
|
for (x = 0; x < rowbytes; x+=4)
|
2017-08-29 02:29:06 +00:00
|
|
|
{
|
|
|
|
out[x+0] = in[x+2];
|
|
|
|
out[x+1] = in[x+1];
|
|
|
|
out[x+2] = in[x+0];
|
|
|
|
out[x+3] = in[x+3];
|
|
|
|
}
|
2014-10-05 20:04:11 +00:00
|
|
|
}
|
2010-11-06 23:05:29 +00:00
|
|
|
}
|
2017-08-29 02:29:06 +00:00
|
|
|
else
|
|
|
|
{
|
2017-12-28 16:24:50 +00:00
|
|
|
size_t rowbytes = ((mips->mip[i].width+blockwidth-1)/blockwidth)*blockbytes;
|
|
|
|
for (y = 0, out = lock.pBits, in = mips->mip[i].data; y < mips->mip[i].height; y+=blockheight, out += lock.Pitch, in += rowbytes)
|
|
|
|
memcpy(out, in, rowbytes);
|
2017-08-29 02:29:06 +00:00
|
|
|
}
|
|
|
|
IDirect3DCubeTexture9_UnlockRect(dt, i%6, i/6);
|
2010-11-06 23:05:29 +00:00
|
|
|
}
|
2017-08-29 02:29:06 +00:00
|
|
|
}
|
2018-03-04 14:41:16 +00:00
|
|
|
else if (mips->type == PTI_2D)
|
2017-08-29 02:29:06 +00:00
|
|
|
{
|
|
|
|
IDirect3DTexture9 *dt;
|
2018-04-15 02:48:23 +00:00
|
|
|
int mipcount = mips->mipcount;
|
|
|
|
for (i = 1; i < mipcount; i++)
|
|
|
|
{ //OpenGL and Direct3D have different interpretations of mipmap sizes.
|
|
|
|
//OpenGL rounds up, direct3D rounds down. (d3d:3->1, gl:3->2)
|
|
|
|
//so if the mips are incompatible, just drop the smaller ones.
|
|
|
|
if (mips->mip[i].width != max(1,(mips->mip[i-1].width)>>1) ||
|
|
|
|
mips->mip[i].height != max(1,(mips->mip[i-1].height)>>1))
|
|
|
|
{
|
|
|
|
mipcount = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (FAILED(IDirect3DDevice9_CreateTexture(pD3DDev9, mips->mip[0].width, mips->mip[0].height, mipcount, 0, fmt, D3DPOOL_MANAGED, &dt, NULL)))
|
2017-08-29 02:29:06 +00:00
|
|
|
return false;
|
|
|
|
dbt = (IDirect3DBaseTexture9*)dt;
|
|
|
|
|
2018-04-15 02:48:23 +00:00
|
|
|
for (i = 0; i < mipcount; i++)
|
2013-11-21 23:02:28 +00:00
|
|
|
{
|
2017-08-29 02:29:06 +00:00
|
|
|
IDirect3DTexture9_GetLevelDesc(dt, i, &desc);
|
|
|
|
|
|
|
|
if (mips->mip[i].height != desc.Height || mips->mip[i].width != desc.Width)
|
2018-04-15 02:48:23 +00:00
|
|
|
{ //we got the above mipcount clamping wrong!
|
2017-08-29 02:29:06 +00:00
|
|
|
IDirect3DTexture9_Release(dt);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
IDirect3DTexture9_LockRect(dt, i, &lock, NULL, D3DLOCK_NOSYSLOCK|D3DLOCK_DISCARD);
|
|
|
|
//can't do it in one go. pitch might contain padding or be upside down.
|
|
|
|
if (!mips->mip[i].data)
|
|
|
|
;
|
|
|
|
else if (swap)
|
|
|
|
{
|
2017-12-28 16:24:50 +00:00
|
|
|
size_t rowbytes = ((mips->mip[i].width+blockwidth-1)/blockwidth)*blockbytes;
|
|
|
|
for (y = 0, out = lock.pBits, in = mips->mip[i].data; y < mips->mip[i].height; y+=blockheight, out += lock.Pitch, in += rowbytes)
|
2017-08-29 02:29:06 +00:00
|
|
|
{
|
2017-12-28 16:24:50 +00:00
|
|
|
for (x = 0; x < rowbytes; x+=4)
|
2017-08-29 02:29:06 +00:00
|
|
|
{
|
|
|
|
out[x+0] = in[x+2];
|
|
|
|
out[x+1] = in[x+1];
|
|
|
|
out[x+2] = in[x+0];
|
|
|
|
out[x+3] = in[x+3];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-12-28 16:24:50 +00:00
|
|
|
size_t rowbytes = ((mips->mip[i].width+blockwidth-1)/blockwidth)*blockbytes;
|
|
|
|
for (y = 0, out = lock.pBits, in = mips->mip[i].data; y < mips->mip[i].height; y+=blockheight, out += lock.Pitch, in += rowbytes)
|
|
|
|
memcpy(out, in, rowbytes);
|
2017-08-29 02:29:06 +00:00
|
|
|
}
|
|
|
|
IDirect3DTexture9_UnlockRect(dt, i);
|
2013-11-21 23:02:28 +00:00
|
|
|
}
|
2009-11-04 21:44:48 +00:00
|
|
|
}
|
2018-03-04 14:41:16 +00:00
|
|
|
else
|
|
|
|
dbt = NULL;
|
2014-10-05 20:04:11 +00:00
|
|
|
D3D9_DestroyTexture(tex);
|
2017-08-29 02:29:06 +00:00
|
|
|
tex->ptr = dbt;
|
2010-05-01 22:47:47 +00:00
|
|
|
|
2014-10-05 20:04:11 +00:00
|
|
|
return true;
|
2010-05-01 22:47:47 +00:00
|
|
|
}
|
2014-10-05 20:04:11 +00:00
|
|
|
void D3D9_UploadLightmap(lightmapinfo_t *lm)
|
2009-11-04 21:44:48 +00:00
|
|
|
{
|
|
|
|
}
|
2010-11-02 23:17:25 +00:00
|
|
|
|
2009-11-04 23:20:50 +00:00
|
|
|
#endif
|