Commit 99cd0de7 authored by Jason Edmeades's avatar Jason Edmeades Committed by Alexandre Julliard

Add the basic support for volume textures / volumes (3d textures).

parent b3854da2
......@@ -518,6 +518,10 @@ struct IDirect3DVolume8Impl
D3DRESOURCETYPE ResourceType;
void *Container;
D3DVOLUME_DESC myDesc;
BYTE *allocatedMemory;
UINT textureName;
UINT bytesPerPixel;
};
......@@ -797,6 +801,17 @@ struct IDirect3DVolumeTexture8Impl
/* IDirect3DVolumeTexture8 fields */
IDirect3DDevice8Impl *Device;
D3DRESOURCETYPE ResourceType;
UINT width;
UINT height;
UINT depth;
UINT levels;
DWORD usage;
D3DFORMAT format;
IDirect3DDevice8Impl *device;
IDirect3DVolume8Impl *volumes[MAX_LEVELS];
BOOL Dirty;
};
/* IUnknown: */
......
......@@ -30,7 +30,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
/* CreateVertexShader can return > 0xFFFF */
#define VS_HIGHESTFIXEDFXF 0xFFFF
#define VS_HIGHESTFIXEDFXF 0xF0000000
/* Used for CreateStateBlock */
#define NUM_SAVEDPIXELSTATES_R 38
......@@ -293,6 +293,18 @@ void DrawPrimitiveI(LPDIRECT3DDEVICE8 iface,
TRACE("tex:%d, s,t=%f,%f\n", textureNo, s,t);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB + textureNo, s, t);
break;
case D3DRTYPE_VOLUMETEXTURE:
s = *(float *)curPos;
curPos = curPos + sizeof(float);
t = *(float *)curPos;
curPos = curPos + sizeof(float);
r = *(float *)curPos;
curPos = curPos + sizeof(float);
TRACE("tex:%d, s,t,r=%f,%f,%f\n", textureNo, s,t,r);
glMultiTexCoord3fARB(GL_TEXTURE0_ARB + textureNo, s, t, r);
break;
default:
r=0;q=0; /* Avoid compiler warnings, need these vars later for other textures */
FIXME("Unhandled texture type\n");
......@@ -676,15 +688,83 @@ HRESULT WINAPI IDirect3DDevice8Impl_CreateTexture(LPDIRECT3DDEVICE8 iface, UIN
HRESULT WINAPI IDirect3DDevice8Impl_CreateVolumeTexture(LPDIRECT3DDEVICE8 iface, UINT Width,UINT Height,UINT Depth,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DVolumeTexture8** ppVolumeTexture) {
IDirect3DVolumeTexture8Impl *object;
int i;
UINT tmpW;
UINT tmpH;
UINT tmpD;
ICOM_THIS(IDirect3DDevice8Impl,iface);
/* Allocate the storage for it */
TRACE("(%p) : W(%d) H(%d) D(%d), Lvl(%d) Usage(%ld), Fmt(%d), Pool(%d)\n", This, Width, Height, Depth, Levels, Usage, Format, Pool);
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVolumeTexture8Impl));
object->lpVtbl = &Direct3DVolumeTexture8_Vtbl;
object->ref = 1;
object->Device = This;
object->ResourceType = D3DRTYPE_VOLUMETEXTURE;
TRACE("(%p) : Iface@%p\n", This, object);
object->ref = 1;
object->width = Width;
object->height = Height;
object->depth = Depth;
object->levels = Levels;
object->usage = Usage;
object->format = Format;
object->device = This;
/* Calculate levels for mip mapping */
if (Levels == 0) {
object->levels++;
tmpW = Width;
tmpH = Height;
tmpD = Depth;
while (tmpW > 1 && tmpH > 1 && tmpD > 1) {
tmpW = max(1,tmpW / 2);
tmpH = max(1, tmpH / 2);
tmpD = max(1, tmpD / 2);
object->levels++;
}
TRACE("Calculated levels = %d\n", object->levels);
}
/* Generate all the surfaces */
tmpW = Width;
tmpH = Height;
tmpD = Depth;
/*for (i=0; i<object->levels; i++) { */
i=0;
{
IDirect3DVolume8Impl *volume;
/* Create the volume - No entry point for this seperately?? */
volume = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVolume8Impl));
object->volumes[i] = (IDirect3DVolume8Impl *) volume;
volume->lpVtbl = &Direct3DVolume8_Vtbl;
volume->Device = This;
volume->ResourceType = D3DRTYPE_VOLUME;
volume->Container = object;
volume->ref = 1;
volume->myDesc.Width = Width;
volume->myDesc.Height= Height;
volume->myDesc.Depth = Depth;
volume->myDesc.Format= Format;
volume->myDesc.Type = D3DRTYPE_VOLUME;
volume->myDesc.Pool = Pool;
volume->myDesc.Usage = Usage;
volume->bytesPerPixel = bytesPerPixel(Format);
volume->myDesc.Size = (Width * volume->bytesPerPixel) * Height * Depth;
volume->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, volume->myDesc.Size);
TRACE("(%p) : Volume at w(%d) h(%d) d(%d) fmt(%d) surf@%p, surfmem@%p, %d bytes\n", This, Width, Height, Depth, Format,
volume, volume->allocatedMemory, volume->myDesc.Size);
tmpW = max(1,tmpW / 2);
tmpH = max(1, tmpH / 2);
tmpD = max(1, tmpD / 2);
}
*ppVolumeTexture = (LPDIRECT3DVOLUMETEXTURE8)object;
return D3D_OK;
}
......@@ -2292,8 +2372,80 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetTexture(LPDIRECT3DDEVICE8 iface, DWORD
checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
}
} else if (textureType == D3DRTYPE_VOLUMETEXTURE) {
IDirect3DVolumeTexture8Impl *pTexture2 = (IDirect3DVolumeTexture8Impl *) pTexture;
int i;
float col[4];
/* Standard 3D (volume) texture */
TRACE("Standard 3d texture\n");
/* for (i=0; i<pTexture2->levels; i++) { */
i=0;
{
if (pTexture2->volumes[i]->textureName != 0 && pTexture2->Dirty == FALSE) {
glBindTexture(GL_TEXTURE_3D, pTexture2->volumes[i]->textureName);
checkGLcall("glBindTexture");
TRACE("Texture %p given name %d\n", pTexture2->volumes[i], pTexture2->volumes[i]->textureName);
} else {
if (pTexture2->volumes[i]->textureName == 0) {
glGenTextures(1, &pTexture2->volumes[i]->textureName);
checkGLcall("glGenTextures");
TRACE("Texture %p given name %d\n", pTexture2->volumes[i], pTexture2->volumes[i]->textureName);
}
glBindTexture(GL_TEXTURE_3D, pTexture2->volumes[i]->textureName);
checkGLcall("glBindTexture");
TRACE("Calling glTexImage3D %x i=%d, intfmt=%x, w=%d, h=%d,d=%d, 0=%d, glFmt=%x, glType=%lx, Mem=%p\n",
GL_TEXTURE_3D, i, fmt2glintFmt(pTexture2->format), pTexture2->volumes[i]->myDesc.Width,
pTexture2->volumes[i]->myDesc.Height, pTexture2->volumes[i]->myDesc.Depth,
0, fmt2glFmt(pTexture2->format),fmt2glType(pTexture2->format),
pTexture2->volumes[i]->allocatedMemory);
glTexImage3D(GL_TEXTURE_3D, i,
fmt2glintFmt(pTexture2->format),
pTexture2->volumes[i]->myDesc.Width,
pTexture2->volumes[i]->myDesc.Height,
pTexture2->volumes[i]->myDesc.Depth,
0,
fmt2glFmt(pTexture2->format),
fmt2glType(pTexture2->format),
pTexture2->volumes[i]->allocatedMemory
);
checkGLcall("glTexImage3D");
/*
* The following enable things to work but I dont think
* they all go here - FIXME! @@@
*/
glTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT );
glTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT );
glTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT );
glTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glEnable(GL_TEXTURE_3D);
checkGLcall("glEnable");
pTexture2->Dirty = FALSE;
}
/* Note the D3DRS value applies to all textures, but GL has one
per texture, so apply it now ready to be used! */
col[0] = ((This->StateBlock.renderstate[D3DRS_TEXTUREFACTOR]>> 16) & 0xFF) / 255.0;
col[1] = ((This->StateBlock.renderstate[D3DRS_TEXTUREFACTOR] >> 8 ) & 0xFF) / 255.0;
col[2] = ((This->StateBlock.renderstate[D3DRS_TEXTUREFACTOR] >> 0 ) & 0xFF) / 255.0;
col[3] = ((This->StateBlock.renderstate[D3DRS_TEXTUREFACTOR] >> 24 ) & 0xFF) / 255.0;
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
}
} else {
FIXME("(%p) : stub\n", This);
FIXME("(%p) : Incorrect type for a texture : %d\n", This, textureType);
}
}
return D3D_OK;
......@@ -2309,6 +2461,8 @@ HRESULT WINAPI IDirect3DDevice8Impl_GetTextureStageState(LPDIRECT3DDEVICE8 ifa
HRESULT WINAPI IDirect3DDevice8Impl_SetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD Value) {
ICOM_THIS(IDirect3DDevice8Impl,iface);
/* FIXME: Handle 3d textures? What if TSS value set before set texture? Need to reapply all values? */
TRACE("(%p) : stub, Stage=%ld, Type=%d, Value =%ld\n", This, Stage, Type, Value);
This->UpdateStateBlock->Changed.texture_state[Stage][Type] = TRUE;
......@@ -2329,7 +2483,7 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetTextureStageState(LPDIRECT3DDEVICE8 ifa
switch (Type) {
case D3DTSS_MINFILTER :
if (Value == D3DTEXF_POINT) {
if (Value == D3DTEXF_POINT) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
checkGLcall("glTexParameter GL_TEXTURE_MINFILTER, GL_NEAREST");
} else if (Value == D3DTEXF_LINEAR) {
......
......@@ -319,7 +319,7 @@ HRESULT WINAPI IDirect3D8Impl_GetDeviceCaps (LPDIRECT3D8 iface,
pCaps->DestBlendCaps = 0;
pCaps->AlphaCmpCaps = 0;
pCaps->ShadeCaps = D3DPSHADECAPS_SPECULARGOURAUDRGB | D3DPSHADECAPS_COLORGOURAUDRGB ;
pCaps->TextureCaps = D3DPTEXTURECAPS_ALPHA | D3DPTEXTURECAPS_ALPHAPALETTE | D3DPTEXTURECAPS_CUBEMAP | D3DPTEXTURECAPS_POW2;
pCaps->TextureCaps = D3DPTEXTURECAPS_ALPHA | D3DPTEXTURECAPS_ALPHAPALETTE | D3DPTEXTURECAPS_CUBEMAP | D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_VOLUMEMAP;
pCaps->TextureFilterCaps = 0;
pCaps->CubeTextureFilterCaps = 0;
pCaps->VolumeTextureFilterCaps = 0;
......
......@@ -54,8 +54,10 @@ ULONG WINAPI IDirect3DVolume8Impl_Release(LPDIRECT3DVOLUME8 iface) {
ICOM_THIS(IDirect3DVolume8Impl,iface);
ULONG ref = --This->ref;
TRACE("(%p) : ReleaseRef to %ld\n", This, This->ref);
if (ref == 0)
if (ref == 0) {
HeapFree(GetProcessHeap(), 0, This->allocatedMemory);
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
}
......@@ -64,6 +66,11 @@ HRESULT WINAPI IDirect3DVolume8Impl_GetDevice(LPDIRECT3DVOLUME8 iface, IDirect3D
ICOM_THIS(IDirect3DVolume8Impl,iface);
TRACE("(%p) : returning %p\n", This, This->Device);
*ppDevice = (LPDIRECT3DDEVICE8) This->Device;
/* Note Calling this method will increase the internal reference count
on the IDirect3DDevice8 interface. */
IDirect3DDevice8Impl_AddRef(*ppDevice);
return D3D_OK;
}
HRESULT WINAPI IDirect3DVolume8Impl_SetPrivateData(LPDIRECT3DVOLUME8 iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) {
......@@ -78,6 +85,7 @@ HRESULT WINAPI IDirect3DVolume8Impl_FreePrivateData(LPDIRECT3DVOLUME8 iface, REF
ICOM_THIS(IDirect3DVolume8Impl,iface);
FIXME("(%p) : stub\n", This); return D3D_OK;
}
HRESULT WINAPI IDirect3DVolume8Impl_GetContainer(LPDIRECT3DVOLUME8 iface, REFIID riid, void** ppContainer) {
ICOM_THIS(IDirect3DVolume8Impl,iface);
TRACE("(%p) : returning %p\n", This, This->Container);
......@@ -86,15 +94,52 @@ HRESULT WINAPI IDirect3DVolume8Impl_GetContainer(LPDIRECT3DVOLUME8 iface, REFIID
}
HRESULT WINAPI IDirect3DVolume8Impl_GetDesc(LPDIRECT3DVOLUME8 iface, D3DVOLUME_DESC* pDesc) {
ICOM_THIS(IDirect3DVolume8Impl,iface);
FIXME("(%p) : stub\n", This); return D3D_OK;
TRACE("(%p) : copying into %p\n", This, pDesc);
memcpy(pDesc, &This->myDesc, sizeof(D3DVOLUME_DESC));
return D3D_OK;
}
HRESULT WINAPI IDirect3DVolume8Impl_LockBox(LPDIRECT3DVOLUME8 iface, D3DLOCKED_BOX* pLockedVolume,CONST D3DBOX* pBox, DWORD Flags) {
ICOM_THIS(IDirect3DVolume8Impl,iface);
FIXME("(%p) : stub\n", This); return D3D_OK;
FIXME("(%p) : pBox=%p stub\n", This, pBox);
/* fixme: should we really lock as such? */
TRACE("(%p) : box=%p, output pbox=%p, allMem=%p\n", This, pBox, pLockedVolume, This->allocatedMemory);
pLockedVolume->RowPitch = This->bytesPerPixel * This->myDesc.Width; /* Bytes / row */
pLockedVolume->SlicePitch = This->bytesPerPixel * This->myDesc.Width * This->myDesc.Height; /* Bytes / slice */
if (!pBox) {
TRACE("No box supplied - all is ok\n");
pLockedVolume->pBits = This->allocatedMemory;
} else {
TRACE("Lock Box (%p) = l %d, t %d, r %d, b %d, fr %d, ba %d\n", pBox, pBox->Left, pBox->Top,
pBox->Right, pBox->Bottom, pBox->Front, pBox->Back);
pLockedVolume->pBits = This->allocatedMemory +
(pLockedVolume->SlicePitch * pBox->Front) + /* FIXME: is front < back or vica versa? */
(pLockedVolume->RowPitch * pBox->Top) +
(pBox->Left * This->bytesPerPixel);
}
TRACE("returning pBits=%p, rpitch=%d, spitch=%d\n", pLockedVolume->pBits, pLockedVolume->RowPitch, pLockedVolume->SlicePitch);
return D3D_OK;
return D3D_OK;
}
HRESULT WINAPI IDirect3DVolume8Impl_UnlockBox(LPDIRECT3DVOLUME8 iface) {
ICOM_THIS(IDirect3DVolume8Impl,iface);
FIXME("(%p) : stub\n", This); return D3D_OK;
TRACE("(%p) : stub\n", This);
if (This->Container) {
IDirect3DVolumeTexture8 *cont = This->Container;
int containerType = IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) cont);
if (containerType == D3DRTYPE_VOLUMETEXTURE) {
IDirect3DTexture8Impl *pTexture = (IDirect3DTexture8Impl *)cont;
pTexture->Dirty = TRUE;
} else {
FIXME("Set dirty on container type %d\n", containerType);
}
}
return D3D_OK;
}
......
......@@ -55,9 +55,18 @@ ULONG WINAPI IDirect3DVolumeTexture8Impl_AddRef(LPDIRECT3DVOLUMETEXTURE8 iface)
ULONG WINAPI IDirect3DVolumeTexture8Impl_Release(LPDIRECT3DVOLUMETEXTURE8 iface) {
ICOM_THIS(IDirect3DVolumeTexture8Impl,iface);
ULONG ref = --This->ref;
int i;
TRACE("(%p) : ReleaseRef to %ld\n", This, This->ref);
if (ref == 0)
if (ref == 0) {
for (i=0; i<This->levels; i++) {
if (This->volumes[i] != NULL) {
TRACE("(%p) : Releasing volume %p\n", This, This->volumes[i]);
IDirect3DVolume8Impl_Release((LPDIRECT3DVOLUME8) This->volumes[i]);
}
}
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
}
......@@ -109,28 +118,47 @@ DWORD WINAPI IDirect3DVolumeTexture8Impl_GetLOD(LPDIRECT3DVOLUMETEXTUR
}
DWORD WINAPI IDirect3DVolumeTexture8Impl_GetLevelCount(LPDIRECT3DVOLUMETEXTURE8 iface) {
ICOM_THIS(IDirect3DVolumeTexture8Impl,iface);
FIXME("(%p) : stub\n", This); return D3D_OK;
TRACE("(%p) : returning %d\n", This, This->levels);
return This->levels;
}
/* IDirect3DVolumeTexture8 */
HRESULT WINAPI IDirect3DVolumeTexture8Impl_GetLevelDesc(LPDIRECT3DVOLUMETEXTURE8 iface, UINT Level,D3DVOLUME_DESC *pDesc) {
ICOM_THIS(IDirect3DVolumeTexture8Impl,iface);
FIXME("(%p) : stub\n", This); return D3D_OK;
if (Level < This->levels) {
TRACE("(%p) Level (%d)\n", This, Level);
return IDirect3DVolume8Impl_GetDesc((LPDIRECT3DVOLUME8)This->volumes[Level], pDesc);
} else {
FIXME("(%p) Level (%d)\n", This, Level);
}
return D3D_OK;
}
HRESULT WINAPI IDirect3DVolumeTexture8Impl_GetVolumeLevel(LPDIRECT3DVOLUMETEXTURE8 iface, UINT Level,IDirect3DVolume8** ppVolumeLevel) {
ICOM_THIS(IDirect3DVolumeTexture8Impl,iface);
FIXME("(%p) : stub\n", This); return D3D_OK;
IDirect3DVolume8Impl_AddRef((LPDIRECT3DVOLUME8)This->volumes[Level]);
*ppVolumeLevel = (LPDIRECT3DVOLUME8)This->volumes[Level];
TRACE("(%p) : returning %p for level %d\n", This, *ppVolumeLevel, Level);
return D3D_OK;
}
HRESULT WINAPI IDirect3DVolumeTexture8Impl_LockBox(LPDIRECT3DVOLUMETEXTURE8 iface, UINT Level,D3DLOCKED_BOX* pLockedVolume,CONST D3DBOX* pBox,DWORD Flags) {
ICOM_THIS(IDirect3DVolumeTexture8Impl,iface);
FIXME("(%p) : stub\n", This); return D3D_OK;
TRACE("(%p) Level (%d)\n", This, Level);
if (Level < This->levels) {
return IDirect3DVolume8Impl_LockBox((LPDIRECT3DVOLUME8)This->volumes[Level], pLockedVolume, pBox, Flags);
} else {
FIXME("Volume Levels seems too high?!!\n");
}
return D3D_OK;
}
HRESULT WINAPI IDirect3DVolumeTexture8Impl_UnlockBox(LPDIRECT3DVOLUMETEXTURE8 iface, UINT Level) {
ICOM_THIS(IDirect3DVolumeTexture8Impl,iface);
FIXME("(%p) : stub\n", This); return D3D_OK;
This->Dirty = TRUE;
TRACE("(%p) : stub\n", This);
return D3D_OK;
}
HRESULT WINAPI IDirect3DVolumeTexture8Impl_AddDirtyBox(LPDIRECT3DVOLUMETEXTURE8 iface, CONST D3DBOX* pDirtyBox) {
ICOM_THIS(IDirect3DVolumeTexture8Impl,iface);
This->Dirty = TRUE;
FIXME("(%p) : stub\n", This); return D3D_OK;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment