|
|
/*==========================================================================;
* * Copyright (C) 1995 Microsoft Corporation. All Rights Reserved. * * File: material.c * Content: Direct3D material management *@@BEGIN_MSINTERNAL * * History: * Date By Reason * ==== == ====== * 11/12/95 stevela Initial rev with this header. *@@END_MSINTERNAL * ***************************************************************************/
#include "pch.cpp"
#pragma hdrstop
/*
* Create an api for the Direct3DMaterial object */
#undef DPF_MODNAME
#define DPF_MODNAME "Direct3DMaterial"
HRESULT hookMaterialToD3D(LPDIRECT3DI lpD3DI, LPDIRECT3DMATERIALI lpD3DMatI) {
LIST_INSERT_ROOT(&lpD3DI->materials, lpD3DMatI, list); lpD3DMatI->lpDirect3DI = lpD3DI;
lpD3DI->numMaterials++;
return (D3D_OK); }
HRESULT hookMaterialToDevice(LPDIRECT3DMATERIALI lpMatI, LPDIRECT3DDEVICEI lpDevI, D3DMATERIALHANDLE hMat, DWORD hMatDDI) { LPD3DI_MATERIALBLOCK mBlock;
if (D3DMalloc((void**)&mBlock, sizeof(D3DI_MATERIALBLOCK)) != D3D_OK) { D3D_ERR("failed to allocate space for material block"); return (DDERR_OUTOFMEMORY); } mBlock->lpDevI = lpDevI; mBlock->lpD3DMaterialI = lpMatI; mBlock->hMat = hMat; mBlock->hMatDDI = hMatDDI;
LIST_INSERT_ROOT(&lpMatI->blocks, mBlock, list); LIST_INSERT_ROOT(&lpDevI->matBlocks, mBlock, devList);
return (D3D_OK); }
void D3DI_RemoveMaterialBlock(LPD3DI_MATERIALBLOCK lpBlock) { // Remove from device
if ( lpBlock->lpDevI ) { D3DHAL_MaterialDestroy(lpBlock->lpDevI, lpBlock->hMat); }
LIST_DELETE(lpBlock, devList);
// Remove from material
LIST_DELETE(lpBlock, list);
D3DFree(lpBlock); }
D3DMATERIALHANDLE findMaterialHandle(LPDIRECT3DMATERIALI lpMat, LPDIRECT3DDEVICEI lpDev) { LPD3DI_MATERIALBLOCK mBlock; D3DMATERIALHANDLE hMat = 0;
mBlock = LIST_FIRST(&lpMat->blocks); while (mBlock) { if (!mBlock) { D3D_ERR("internal error - material list out of sync"); return 0; } if (mBlock->lpDevI == lpDev) { hMat = mBlock->hMat; break; } mBlock = LIST_NEXT(mBlock,list); } return hMat; }
HRESULT D3DAPI DIRECT3DMATERIALI::Initialize(LPDIRECT3D lpD3D) { return DDERR_ALREADYINITIALIZED; }
/*
* Create the Material */ #undef DPF_MODNAME
#define DPF_MODNAME "Direct3D::CreateMaterial"
HRESULT D3DAPI DIRECT3DI::CreateMaterial(LPDIRECT3DMATERIAL* lplpD3DMat, IUnknown* pUnkOuter) { LPDIRECT3DMATERIAL3 lpD3DMat3; HRESULT ret = CreateMaterial(&lpD3DMat3, pUnkOuter); if (ret == D3D_OK) *lplpD3DMat = static_cast<LPDIRECT3DMATERIAL>(static_cast<LPDIRECT3DMATERIALI>(lpD3DMat3)); return ret; }
HRESULT D3DAPI DIRECT3DI::CreateMaterial(LPDIRECT3DMATERIAL2* lplpD3DMat, IUnknown* pUnkOuter) { LPDIRECT3DMATERIAL3 lpD3DMat3; HRESULT ret = CreateMaterial(&lpD3DMat3, pUnkOuter); if (ret == D3D_OK) *lplpD3DMat = static_cast<LPDIRECT3DMATERIAL2>(static_cast<LPDIRECT3DMATERIALI>(lpD3DMat3)); return ret; }
HRESULT D3DAPI DIRECT3DI::CreateMaterial(LPDIRECT3DMATERIAL3* lplpD3DMat, IUnknown* pUnkOuter) { LPDIRECT3DMATERIALI lpMat; HRESULT ret;
if (pUnkOuter != NULL) { return CLASS_E_NOAGGREGATION; }
ret = D3D_OK;
CLockD3D lockObject(DPF_MODNAME, REMIND("")); // Takes D3D lock.
/*
* validate parms */ if (!VALID_DIRECT3D3_PTR(this)) { D3D_ERR( "Invalid Direct3D pointer" ); return DDERR_INVALIDOBJECT; } if (!VALID_OUTPTR(lplpD3DMat)) { D3D_ERR( "Invalid pointer to pointer" ); return DDERR_INVALIDPARAMS; } *lplpD3DMat = NULL;
lpMat = static_cast<LPDIRECT3DMATERIALI>(new DIRECT3DMATERIALI()); if (!lpMat) { D3D_ERR("failed to allocate space for object"); return (DDERR_OUTOFMEMORY); }
/*
* setup the object */ /*
* Put this device in the list of those owned by the * Direct3D object */ ret = hookMaterialToD3D(this, lpMat); if (ret != D3D_OK) { D3D_ERR("failed to associate material with object"); delete lpMat; return (ret); }
*lplpD3DMat = (LPDIRECT3DMATERIAL3)lpMat;
return (D3D_OK); }
DIRECT3DMATERIALI::DIRECT3DMATERIALI() { memset(&dmMaterial, 0, sizeof(D3DMATERIAL)); /* Data describing material */ dmMaterial.dwSize = sizeof(D3DMATERIAL); bRes= false; /* Is this material reserved in the driver */
refCnt = 1; LIST_INITIALIZE(&blocks);
}
#undef DPF_MODNAME
#define DPF_MODNAME "Direct3DMaterial::SetMaterial"
HRESULT D3DAPI DIRECT3DMATERIALI::SetMaterial(LPD3DMATERIAL lpData) { HRESULT ret; HRESULT err;
ret = D3D_OK;
CLockD3D lockObject(DPF_MODNAME, REMIND("")); // Takes D3D lock.
/*
* validate parms */ TRY { if (!VALID_DIRECT3DMATERIAL2_PTR(this)) { D3D_ERR( "Invalid Direct3DMaterial pointer" ); return DDERR_INVALIDOBJECT; } if (!VALID_D3DMATERIAL_PTR(lpData)) { D3D_ERR( "Invalid D3DMATERIAL pointer" ); return DDERR_INVALIDPARAMS; } } EXCEPT( EXCEPTION_EXECUTE_HANDLER ) { D3D_ERR( "Exception encountered validating parameters" ); return DDERR_INVALIDPARAMS; }
if (memcmp(&this->dmMaterial, lpData, sizeof(D3DMATERIAL))) { LPD3DI_MATERIALBLOCK mBlock = LIST_FIRST(&this->blocks); this->dmMaterial = *lpData;
/*
* Download material data */
while (mBlock) { err = D3DHAL_MaterialSetData(mBlock->lpDevI, mBlock->hMat, &this->dmMaterial); if ( err != DD_OK ) { D3D_ERR("error ocurred whilst informing device about material change"); return err; } mBlock = LIST_NEXT(mBlock,list); }
}
return (ret); }
#undef DPF_MODNAME
#define DPF_MODNAME "Direct3DMaterial::GetMaterial"
HRESULT D3DAPI DIRECT3DMATERIALI::GetMaterial(LPD3DMATERIAL lpData) { HRESULT ret;
ret = D3D_OK;
CLockD3D lockObject(DPF_MODNAME, REMIND("")); // Takes D3D lock.
/*
* validate parms */ TRY { if (!VALID_DIRECT3DMATERIAL2_PTR(this)) { D3D_ERR( "Invalid Direct3DMaterial pointer" ); return DDERR_INVALIDOBJECT; } if (!VALID_D3DMATERIAL_PTR(lpData)) { D3D_ERR( "Invalid D3DMATERIAL pointer" ); return DDERR_INVALIDPARAMS; } } EXCEPT( EXCEPTION_EXECUTE_HANDLER ) { D3D_ERR( "Exception encountered validating parameters" ); return DDERR_INVALIDPARAMS; }
*lpData = this->dmMaterial;
return (ret); }
#undef DPF_MODNAME
#define DPF_MODNAME "Direct3DMaterial::GetHandle"
HRESULT D3DAPI DIRECT3DMATERIALI::GetHandle(LPDIRECT3DDEVICE lpDev, LPD3DMATERIALHANDLE lphMat) { LPDIRECT3DDEVICE3 lpDev3 = static_cast<LPDIRECT3DDEVICE3>(static_cast<LPDIRECT3DDEVICEI>(lpDev)); return GetHandle(lpDev3, lphMat); }
HRESULT D3DAPI DIRECT3DMATERIALI::GetHandle(LPDIRECT3DDEVICE2 lpDev, LPD3DMATERIALHANDLE lphMat) { LPDIRECT3DDEVICE3 lpDev3 = static_cast<LPDIRECT3DDEVICE3>(static_cast<LPDIRECT3DDEVICEI>(lpDev)); return GetHandle(lpDev3, lphMat); }
HRESULT D3DAPI DIRECT3DMATERIALI::GetHandle(LPDIRECT3DDEVICE3 lpDev, LPD3DMATERIALHANDLE lphMat) { LPDIRECT3DDEVICEI lpD3DDevI; D3DMATERIALHANDLE hMat; HRESULT ret; HRESULT err;
ret = D3D_OK;
CLockD3D lockObject(DPF_MODNAME, REMIND("")); // Takes D3D lock.
/*
* validate parms */ TRY { lpD3DDevI = static_cast<LPDIRECT3DDEVICEI>(lpDev); if (!VALID_DIRECT3DMATERIAL2_PTR(this)) { D3D_ERR( "Invalid Direct3DMaterial pointer" ); return DDERR_INVALIDOBJECT; } if (!VALID_DIRECT3DDEVICE3_PTR(lpD3DDevI)) { D3D_ERR( "Invalid Direct3DDevice pointer" ); return DDERR_INVALIDOBJECT; } if (!VALID_D3DMATERIALHANDLE_PTR(lphMat)) { D3D_ERR( "Invalid D3DMATERIALHANDLE pointer" ); return DDERR_INVALIDPARAMS; } } EXCEPT( EXCEPTION_EXECUTE_HANDLER ) { D3D_ERR( "Exception encountered validating parameters" ); return DDERR_INVALIDPARAMS; }
/*
* If we're already on a device, return the right handle. */ hMat = findMaterialHandle(this, lpD3DDevI);
if (!hMat) { DWORD hMatDDI = 0x0; /*
* Create the material handle through RLDDI */ err = D3DHAL_MaterialCreate(lpD3DDevI, &hMat, &this->dmMaterial); if (err != DD_OK) { D3D_ERR("failed to allocate material through the device"); return err; }
err = hookMaterialToDevice(this, lpD3DDevI, hMat, hMatDDI); if (err != D3D_OK) { D3DHAL_MaterialDestroy(lpD3DDevI, hMat); D3D_ERR("failed to associated material to device"); return err; } }
*lphMat = hMat;
return (ret); }
#undef DPF_MODNAME
#define DPF_MODNAME "Direct3DMaterial::Reserve"
HRESULT D3DAPI DIRECT3DMATERIALI::Reserve() { #ifdef SUPPORT_RESERVE
LPD3DI_MATERIALBLOCK mBlock, nBlock; #endif
HRESULT ret;
ret = D3D_OK;
CLockD3D lockObject(DPF_MODNAME, REMIND("")); // Takes D3D lock.
/*
* validate parms */ TRY { if (!VALID_DIRECT3DMATERIAL2_PTR(this)) { D3D_ERR( "Invalid Direct3DMaterial pointer" ); return DDERR_INVALIDOBJECT; } } EXCEPT( EXCEPTION_EXECUTE_HANDLER ) { D3D_ERR( "Exception encountered validating parameters" ); return DDERR_INVALIDPARAMS; }
#ifdef SUPPORT_RESERVE
/*
* Reserve the material through RLDDI */
/*
* Iterate over all devices we're associated with. */
mBlock = LIST_FIRST(&this->blocks); while (mBlock) { if (RLDDIService(mBlock->lpDevI->stack, RLDDIMaterialReserve, mBlock->hMat, NULL) != DD_OK) { D3D_ERR("failed to reserve material"); goto free_and_exit; } mBlock = LIST_NEXT(mBlock,list); } this->bRes = 1;
return (ret);
free_and_exit: nBlock = LIST_FIRST(&this->blocks); while (nBlock != mBlock) { if (!nBlock) { D3D_ERR("internal error - material blocks out of sync"); return (DDERR_GENERIC); } ret = RLDDIService(nBlock->lpDevI->stack, RLDDIMaterialUnreserve, (LONG)nBlock->hMat, NULL); if (ret != D3D_OK) { D3D_ERR("error occured whilst unreserving material after error"); } nBlock = LIST_NEXT(nBlock,list); } #else
ret = DDERR_UNSUPPORTED; #endif
return (ret); }
#undef DPF_MODNAME
#define DPF_MODNAME "Direct3DMaterial::Unreserve"
HRESULT D3DAPI DIRECT3DMATERIALI::Unreserve() { #ifdef SUPPORT_RESERVE
LPD3DI_MATERIALBLOCK mBlock; #endif
HRESULT ret;
ret = D3D_OK;
CLockD3D lockObject(DPF_MODNAME, REMIND("")); // Takes D3D lock.
/*
* validate parms */ TRY { if (!VALID_DIRECT3DMATERIAL2_PTR(this)) { D3D_ERR( "Invalid Direct3DMaterial pointer" ); return DDERR_INVALIDOBJECT; } } EXCEPT( EXCEPTION_EXECUTE_HANDLER ) { D3D_ERR( "Exception encountered validating parameters" ); return DDERR_INVALIDPARAMS; }
#ifdef SUPPORT_RESERVE
/*
* Unreserve the material through RLDDI */ if (this->bRes) { mBlock = LIST_FIRST(&this->blocks); while (mBlock) { if (RLDDIService(mBlock->lpDevI->stack, RLDDIMaterialUnreserve, mBlock->hMat, NULL) != DD_OK) { D3D_ERR("failed to unreserve material"); } mBlock = LIST_NEXT(mBlock,list); } } #else
ret = DDERR_UNSUPPORTED; #endif
return (ret); }
|