mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-04-27 07:15:37 +00:00
Engine directory for ticket #1
This commit is contained in:
parent
352279af7a
commit
7dbfe6994d
3795 changed files with 1363358 additions and 0 deletions
148
Engine/source/gfx/D3D9/d3dx9Functions.h
Normal file
148
Engine/source/gfx/D3D9/d3dx9Functions.h
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
D3DX_FUNCTION( D3DXCreateBuffer, HRESULT,
|
||||
(DWORD NumBytes,
|
||||
LPD3DXBUFFER * ppBuffer) )
|
||||
|
||||
D3DX_FUNCTION( D3DXSaveSurfaceToFileA, HRESULT,
|
||||
(LPCSTR pDestFile,
|
||||
D3DXIMAGE_FILEFORMAT DestFormat,
|
||||
LPDIRECT3DSURFACE9 pSrcSurface,
|
||||
CONST PALETTEENTRY* pSrcPalette,
|
||||
CONST RECT* pSrcRect) )
|
||||
|
||||
D3DX_FUNCTION( D3DXSaveSurfaceToFileW, HRESULT,
|
||||
(LPCWSTR pDestFile,
|
||||
D3DXIMAGE_FILEFORMAT DestFormat,
|
||||
LPDIRECT3DSURFACE9 pSrcSurface,
|
||||
CONST PALETTEENTRY* pSrcPalette,
|
||||
CONST RECT* pSrcRect) )
|
||||
|
||||
D3DX_FUNCTION( D3DXCompileShader, HRESULT,
|
||||
(LPCSTR pSrcData,
|
||||
UINT srcDataLen,
|
||||
CONST D3DXMACRO* pDefines,
|
||||
LPD3DXINCLUDE pInclude,
|
||||
LPCSTR pFunctionName,
|
||||
LPCSTR pProfile,
|
||||
DWORD Flags,
|
||||
LPD3DXBUFFER* ppShader,
|
||||
LPD3DXBUFFER* ppErrorMsgs,
|
||||
LPD3DXCONSTANTTABLE * ppConstantTable) )
|
||||
|
||||
D3DX_FUNCTION( D3DXGetShaderConstantTable, HRESULT,
|
||||
(CONST DWORD* pFunction,
|
||||
LPD3DXCONSTANTTABLE* ppConstantTable) )
|
||||
|
||||
|
||||
D3DX_FUNCTION( D3DXLoadSurfaceFromSurface, HRESULT,
|
||||
(LPDIRECT3DSURFACE9 pDestSurface,
|
||||
CONST PALETTEENTRY* pDestPalette,
|
||||
CONST RECT* pDestRect,
|
||||
LPDIRECT3DSURFACE9 pSrcSurface,
|
||||
CONST PALETTEENTRY* pSrcPalette,
|
||||
CONST RECT* pSrcRect,
|
||||
DWORD Filter,
|
||||
D3DCOLOR ColorKey) )
|
||||
|
||||
D3DX_FUNCTION( D3DXCreateVolumeTexture, HRESULT,
|
||||
(LPDIRECT3DDEVICE9 pDevice,
|
||||
UINT Width,
|
||||
UINT Height,
|
||||
UINT Depth,
|
||||
UINT MipLevels,
|
||||
DWORD Usage,
|
||||
D3DFORMAT Format,
|
||||
D3DPOOL Pool,
|
||||
LPDIRECT3DVOLUMETEXTURE9* ppVolumeTexture) )
|
||||
|
||||
D3DX_FUNCTION( D3DXCreateTexture, HRESULT,
|
||||
(LPDIRECT3DDEVICE9 pDevice,
|
||||
UINT Width,
|
||||
UINT Height,
|
||||
UINT MipLevels,
|
||||
DWORD Usage,
|
||||
D3DFORMAT Format,
|
||||
D3DPOOL Pool,
|
||||
LPDIRECT3DTEXTURE9* ppTexture) )
|
||||
|
||||
#ifdef TORQUE_OS_XENON
|
||||
D3DX_FUNCTION( D3DXLoadVolumeFromMemory, HRESULT,
|
||||
(LPDIRECT3DVOLUME9 pDestVolume,
|
||||
CONST PALETTEENTRY* pDestPalette,
|
||||
CONST D3DBOX* pDestBox,
|
||||
LPCVOID pSrcMemory,
|
||||
D3DFORMAT SrcFormat,
|
||||
UINT SrcRowPitch,
|
||||
UINT SrcSlicePitch,
|
||||
CONST PALETTEENTRY* pSrcPalette,
|
||||
CONST D3DBOX* pSrcBox,
|
||||
BOOL SrcParentPacked,
|
||||
UINT SrcParentWidth,
|
||||
UINT SrcParentHeight,
|
||||
UINT SrcParentDepth,
|
||||
DWORD Filter,
|
||||
D3DCOLOR ColorKey) )
|
||||
#else
|
||||
D3DX_FUNCTION( D3DXLoadVolumeFromMemory, HRESULT,
|
||||
(LPDIRECT3DVOLUME9 pDestVolume,
|
||||
CONST PALETTEENTRY* pDestPalette,
|
||||
CONST D3DBOX* pDestBox,
|
||||
LPCVOID pSrcMemory,
|
||||
D3DFORMAT SrcFormat,
|
||||
UINT SrcRowPitch,
|
||||
UINT SrcSlicePitch,
|
||||
CONST PALETTEENTRY* pSrcPalette,
|
||||
CONST D3DBOX* pSrcBox,
|
||||
DWORD Filter,
|
||||
D3DCOLOR ColorKey) )
|
||||
#endif
|
||||
|
||||
D3DX_FUNCTION( D3DXSaveTextureToFileInMemory, HRESULT,
|
||||
(LPD3DXBUFFER *ppDestBuf,
|
||||
D3DXIMAGE_FILEFORMAT DestFormat,
|
||||
LPDIRECT3DBASETEXTURE9 pSrcTexture,
|
||||
const PALETTEENTRY *pSrcPalette) )
|
||||
|
||||
D3DX_FUNCTION( D3DXGetImageInfoFromFileInMemory, HRESULT,
|
||||
(LPCVOID pSrcData,
|
||||
UINT SrcDataSize,
|
||||
D3DXIMAGE_INFO* pSrcInfo) )
|
||||
|
||||
D3DX_FUNCTION( D3DXLoadSurfaceFromFileInMemory, HRESULT,
|
||||
(LPDIRECT3DSURFACE9 pDestSurface,
|
||||
CONST PALETTEENTRY * pDestPalette,
|
||||
CONST RECT * pDestRect,
|
||||
LPCVOID pSrcData,
|
||||
UINT SrcData,
|
||||
CONST RECT * pSrcRect,
|
||||
DWORD Filter,
|
||||
D3DCOLOR ColorKey,
|
||||
D3DXIMAGE_INFO * pSrcInfo) )
|
||||
|
||||
D3DX_FUNCTION( D3DXSaveSurfaceToFileInMemory, HRESULT,
|
||||
(LPD3DXBUFFER* ppDestBuf,
|
||||
D3DXIMAGE_FILEFORMAT DestFormat,
|
||||
LPDIRECT3DSURFACE9 pSrcSurface,
|
||||
CONST PALETTEENTRY* pSrcPalette,
|
||||
CONST RECT* pSrcRect) )
|
||||
161
Engine/source/gfx/D3D9/gfxD3D9CardProfiler.cpp
Normal file
161
Engine/source/gfx/D3D9/gfxD3D9CardProfiler.cpp
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "gfx/D3D9/gfxD3D9Device.h"
|
||||
#include "console/console.h"
|
||||
#include "gfx/primBuilder.h"
|
||||
#include "gfx/D3D9/gfxD3D9CardProfiler.h"
|
||||
#include "gfx/D3D9/gfxD3D9EnumTranslate.h"
|
||||
#ifdef TORQUE_OS_WIN32
|
||||
#include "platformWin32/videoInfo/wmiVideoInfo.h"
|
||||
#endif
|
||||
|
||||
|
||||
GFXD3D9CardProfiler::GFXD3D9CardProfiler() : GFXCardProfiler()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
GFXD3D9CardProfiler::~GFXD3D9CardProfiler()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void GFXD3D9CardProfiler::init()
|
||||
{
|
||||
mD3DDevice = dynamic_cast<GFXD3D9Device *>(GFX)->getDevice();
|
||||
AssertISV( mD3DDevice, "GFXD3D9CardProfiler::init() - No D3D9 Device found!");
|
||||
|
||||
// Grab the caps so we can get our adapter ordinal and look up our name.
|
||||
D3DCAPS9 caps;
|
||||
D3D9Assert(mD3DDevice->GetDeviceCaps(&caps), "GFXD3D9CardProfiler::init - failed to get device caps!");
|
||||
|
||||
#ifdef TORQUE_OS_XENON
|
||||
mCardDescription = "Xbox360 GPU";
|
||||
mChipSet = "ATI";
|
||||
mVersionString = String::ToString(_XDK_VER);
|
||||
mVideoMemory = 512 * 1024 * 1024;
|
||||
#else
|
||||
WMIVideoInfo wmiVidInfo;
|
||||
if( wmiVidInfo.profileAdapters() )
|
||||
{
|
||||
const PlatformVideoInfo::PVIAdapter &adapter = wmiVidInfo.getAdapterInformation( caps.AdapterOrdinal );
|
||||
|
||||
mCardDescription = adapter.description;
|
||||
mChipSet = adapter.chipSet;
|
||||
mVersionString = adapter.driverVersion;
|
||||
mVideoMemory = adapter.vram;
|
||||
}
|
||||
#endif
|
||||
|
||||
Parent::init();
|
||||
}
|
||||
|
||||
void GFXD3D9CardProfiler::setupCardCapabilities()
|
||||
{
|
||||
// Get the D3D device caps
|
||||
D3DCAPS9 caps;
|
||||
mD3DDevice->GetDeviceCaps(&caps);
|
||||
|
||||
setCapability( "autoMipMapLevel", ( caps.Caps2 & D3DCAPS2_CANAUTOGENMIPMAP ? 1 : 0 ) );
|
||||
|
||||
setCapability( "maxTextureWidth", caps.MaxTextureWidth );
|
||||
setCapability( "maxTextureHeight", caps.MaxTextureHeight );
|
||||
setCapability( "maxTextureSize", getMin( (U32)caps.MaxTextureWidth, (U32)caps.MaxTextureHeight) );
|
||||
|
||||
bool canDoLERPDetailBlend = ( caps.TextureOpCaps & D3DTEXOPCAPS_LERP ) && ( caps.MaxTextureBlendStages > 1 );
|
||||
|
||||
bool canDoFourStageDetailBlend = ( caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT ) &&
|
||||
( caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP ) &&
|
||||
( caps.MaxTextureBlendStages > 3 );
|
||||
|
||||
setCapability( "lerpDetailBlend", canDoLERPDetailBlend );
|
||||
setCapability( "fourStageDetailBlend", canDoFourStageDetailBlend );
|
||||
}
|
||||
|
||||
bool GFXD3D9CardProfiler::_queryCardCap(const String &query, U32 &foundResult)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool GFXD3D9CardProfiler::_queryFormat( const GFXFormat fmt, const GFXTextureProfile *profile, bool &inOutAutogenMips )
|
||||
{
|
||||
LPDIRECT3D9 pD3D = static_cast<GFXD3D9Device *>(GFX)->getD3D();
|
||||
D3DDISPLAYMODE displayMode = static_cast<GFXD3D9Device *>(GFX)->getDisplayMode();
|
||||
|
||||
DWORD usage = 0;
|
||||
D3DRESOURCETYPE rType = D3DRTYPE_TEXTURE;
|
||||
D3DFORMAT adapterFormat = displayMode.Format;
|
||||
|
||||
D3DFORMAT texFormat = GFXD3D9TextureFormat[fmt];
|
||||
|
||||
#if defined(TORQUE_OS_XENON)
|
||||
inOutAutogenMips = false;
|
||||
adapterFormat = D3DFMT_A8B8G8R8;
|
||||
|
||||
if(profile->isRenderTarget())
|
||||
{
|
||||
texFormat = (D3DFORMAT)MAKELEFMT(texFormat);
|
||||
}
|
||||
#else
|
||||
if( profile->isRenderTarget() )
|
||||
usage |= D3DUSAGE_RENDERTARGET;
|
||||
else if( profile->isZTarget() )
|
||||
{
|
||||
usage |= D3DUSAGE_DEPTHSTENCIL;
|
||||
rType = D3DRTYPE_SURFACE;
|
||||
}
|
||||
|
||||
if( inOutAutogenMips )
|
||||
usage |= D3DUSAGE_AUTOGENMIPMAP;
|
||||
#endif
|
||||
|
||||
// Early-check to see if the enum translation table has an unsupported value
|
||||
if(texFormat == (_D3DFORMAT)GFX_UNSUPPORTED_VAL)
|
||||
return false;
|
||||
|
||||
HRESULT hr = pD3D->CheckDeviceFormat( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
|
||||
adapterFormat, usage, rType, texFormat );
|
||||
|
||||
bool retVal = SUCCEEDED( hr );
|
||||
|
||||
#if !defined(TORQUE_OS_XENON)
|
||||
// If check device format failed, and auto gen mips were requested, try again
|
||||
// without autogen mips.
|
||||
if( !retVal && inOutAutogenMips )
|
||||
{
|
||||
usage ^= D3DUSAGE_AUTOGENMIPMAP;
|
||||
|
||||
hr = pD3D->CheckDeviceFormat( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
|
||||
adapterFormat, usage, D3DRTYPE_TEXTURE, GFXD3D9TextureFormat[fmt] );
|
||||
|
||||
retVal = SUCCEEDED( hr );
|
||||
|
||||
// If this one passed, auto gen mips are not supported with this format,
|
||||
// so set the variable properly
|
||||
if( retVal )
|
||||
inOutAutogenMips = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return retVal;
|
||||
}
|
||||
51
Engine/source/gfx/D3D9/gfxD3D9CardProfiler.h
Normal file
51
Engine/source/gfx/D3D9/gfxD3D9CardProfiler.h
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GFXD3D9CARDPROFILER_H_
|
||||
#define _GFXD3D9CARDPROFILER_H_
|
||||
|
||||
|
||||
#include "gfx/gfxCardProfile.h"
|
||||
|
||||
struct IDirect3DDevice9;
|
||||
class GFXD3D9CardProfiler : public GFXCardProfiler
|
||||
{
|
||||
private:
|
||||
typedef GFXCardProfiler Parent;
|
||||
|
||||
IDirect3DDevice9 *mD3DDevice;
|
||||
UINT mAdapterOrdinal;
|
||||
|
||||
public:
|
||||
GFXD3D9CardProfiler();
|
||||
~GFXD3D9CardProfiler();
|
||||
void init();
|
||||
|
||||
protected:
|
||||
const String &getRendererString() const { static String sRS("D3D9"); return sRS; }
|
||||
|
||||
void setupCardCapabilities();
|
||||
bool _queryCardCap(const String &query, U32 &foundResult);
|
||||
bool _queryFormat(const GFXFormat fmt, const GFXTextureProfile *profile, bool &inOutAutogenMips);
|
||||
};
|
||||
|
||||
#endif
|
||||
239
Engine/source/gfx/D3D9/gfxD3D9Cubemap.cpp
Normal file
239
Engine/source/gfx/D3D9/gfxD3D9Cubemap.cpp
Normal file
|
|
@ -0,0 +1,239 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "gfx/D3D9/gfxD3D9Cubemap.h"
|
||||
#include "gfx/gfxTextureManager.h"
|
||||
#include "gfx/D3D9/gfxD3D9EnumTranslate.h"
|
||||
|
||||
_D3DCUBEMAP_FACES GFXD3D9Cubemap::faceList[6] =
|
||||
{
|
||||
D3DCUBEMAP_FACE_POSITIVE_X, D3DCUBEMAP_FACE_NEGATIVE_X,
|
||||
D3DCUBEMAP_FACE_POSITIVE_Y, D3DCUBEMAP_FACE_NEGATIVE_Y,
|
||||
D3DCUBEMAP_FACE_POSITIVE_Z, D3DCUBEMAP_FACE_NEGATIVE_Z
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
GFXD3D9Cubemap::GFXD3D9Cubemap()
|
||||
{
|
||||
mCubeTex = NULL;
|
||||
mDynamic = false;
|
||||
mFaceFormat = GFXFormatR8G8B8A8;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
GFXD3D9Cubemap::~GFXD3D9Cubemap()
|
||||
{
|
||||
releaseSurfaces();
|
||||
|
||||
if ( mDynamic )
|
||||
GFXTextureManager::removeEventDelegate( this, &GFXD3D9Cubemap::_onTextureEvent );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Release D3D surfaces
|
||||
//-----------------------------------------------------------------------------
|
||||
void GFXD3D9Cubemap::releaseSurfaces()
|
||||
{
|
||||
if ( !mCubeTex )
|
||||
return;
|
||||
|
||||
mCubeTex->Release();
|
||||
mCubeTex = NULL;
|
||||
}
|
||||
|
||||
void GFXD3D9Cubemap::_onTextureEvent( GFXTexCallbackCode code )
|
||||
{
|
||||
// Can this happen?
|
||||
if ( !mDynamic )
|
||||
return;
|
||||
|
||||
if ( code == GFXZombify )
|
||||
releaseSurfaces();
|
||||
else if ( code == GFXResurrect )
|
||||
initDynamic( mTexSize );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Init Static
|
||||
//-----------------------------------------------------------------------------
|
||||
void GFXD3D9Cubemap::initStatic( GFXTexHandle *faces )
|
||||
{
|
||||
//if( mCubeTex )
|
||||
// return;
|
||||
|
||||
if( faces )
|
||||
{
|
||||
AssertFatal( faces[0], "empty texture passed to CubeMap::create" );
|
||||
|
||||
GFXD3D9Device *dev = static_cast<GFXD3D9Device *>(GFX);
|
||||
|
||||
D3DPOOL pool = D3DPOOL_MANAGED;
|
||||
|
||||
if (dev->isD3D9Ex())
|
||||
pool = D3DPOOL_DEFAULT;
|
||||
|
||||
LPDIRECT3DDEVICE9 D3D9Device = dev->getDevice();
|
||||
|
||||
// NOTE - check tex sizes on all faces - they MUST be all same size
|
||||
mTexSize = faces[0].getWidth();
|
||||
mFaceFormat = faces[0].getFormat();
|
||||
|
||||
D3D9Assert( D3D9Device->CreateCubeTexture( mTexSize, 1, 0, GFXD3D9TextureFormat[mFaceFormat],
|
||||
pool, &mCubeTex, NULL ), NULL );
|
||||
|
||||
fillCubeTextures( faces, D3D9Device );
|
||||
// mCubeTex->GenerateMipSubLevels();
|
||||
}
|
||||
}
|
||||
|
||||
void GFXD3D9Cubemap::initStatic( DDSFile *dds )
|
||||
{
|
||||
AssertFatal( dds, "GFXD3D9Cubemap::initStatic - Got null DDS file!" );
|
||||
AssertFatal( dds->isCubemap(), "GFXD3D9Cubemap::initStatic - Got non-cubemap DDS file!" );
|
||||
AssertFatal( dds->mSurfaces.size() == 6, "GFXD3D9Cubemap::initStatic - DDS has less than 6 surfaces!" );
|
||||
|
||||
GFXD3D9Device *dev = static_cast<GFXD3D9Device *>(GFX);
|
||||
|
||||
D3DPOOL pool = D3DPOOL_MANAGED;
|
||||
|
||||
if (dev->isD3D9Ex())
|
||||
pool = D3DPOOL_DEFAULT;
|
||||
|
||||
LPDIRECT3DDEVICE9 D3D9Device = dev->getDevice();
|
||||
|
||||
// NOTE - check tex sizes on all faces - they MUST be all same size
|
||||
mTexSize = dds->getWidth();
|
||||
mFaceFormat = dds->getFormat();
|
||||
U32 levels = dds->getMipLevels();
|
||||
|
||||
D3D9Assert( D3D9Device->CreateCubeTexture( mTexSize, levels, 0, GFXD3D9TextureFormat[mFaceFormat],
|
||||
pool, &mCubeTex, NULL ), NULL );
|
||||
|
||||
for( U32 i=0; i < 6; i++ )
|
||||
{
|
||||
if ( !dds->mSurfaces[i] )
|
||||
{
|
||||
// TODO: The DDS can skip surfaces, but i'm unsure what i should
|
||||
// do here when creating the cubemap. Ignore it for now.
|
||||
continue;
|
||||
}
|
||||
|
||||
// Now loop thru the mip levels!
|
||||
for( U32 l = 0; l < levels; l++ )
|
||||
{
|
||||
IDirect3DSurface9 *cubeSurf = NULL;
|
||||
D3D9Assert( mCubeTex->GetCubeMapSurface( faceList[i], l, &cubeSurf ),
|
||||
"GFXD3D9Cubemap::initStatic - Get cubemap surface failed!" );
|
||||
|
||||
// Lock the dest surface.
|
||||
D3DLOCKED_RECT lockedRect;
|
||||
D3D9Assert( cubeSurf->LockRect( &lockedRect, NULL, 0 ),
|
||||
"GFXD3D9Cubemap::initStatic - Failed to lock surface level for load!" );
|
||||
|
||||
dMemcpy( lockedRect.pBits, dds->mSurfaces[i]->mMips[l], dds->getSurfaceSize(l) );
|
||||
|
||||
cubeSurf->UnlockRect();
|
||||
cubeSurf->Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Init Dynamic
|
||||
//-----------------------------------------------------------------------------
|
||||
void GFXD3D9Cubemap::initDynamic( U32 texSize, GFXFormat faceFormat )
|
||||
{
|
||||
if ( mCubeTex )
|
||||
return;
|
||||
|
||||
if ( !mDynamic )
|
||||
GFXTextureManager::addEventDelegate( this, &GFXD3D9Cubemap::_onTextureEvent );
|
||||
|
||||
mDynamic = true;
|
||||
mTexSize = texSize;
|
||||
mFaceFormat = faceFormat;
|
||||
|
||||
LPDIRECT3DDEVICE9 D3D9Device = reinterpret_cast<GFXD3D9Device *>(GFX)->getDevice();
|
||||
|
||||
// might want to try this as a 16 bit texture...
|
||||
D3D9Assert( D3D9Device->CreateCubeTexture( texSize,
|
||||
1,
|
||||
#ifdef TORQUE_OS_XENON
|
||||
0,
|
||||
#else
|
||||
D3DUSAGE_RENDERTARGET,
|
||||
#endif
|
||||
GFXD3D9TextureFormat[faceFormat],
|
||||
D3DPOOL_DEFAULT,
|
||||
&mCubeTex,
|
||||
NULL ), NULL );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Fills in face textures of cube map from existing textures
|
||||
//-----------------------------------------------------------------------------
|
||||
void GFXD3D9Cubemap::fillCubeTextures( GFXTexHandle *faces, LPDIRECT3DDEVICE9 D3DDevice )
|
||||
{
|
||||
for( U32 i=0; i<6; i++ )
|
||||
{
|
||||
// get cube face surface
|
||||
IDirect3DSurface9 *cubeSurf = NULL;
|
||||
D3D9Assert( mCubeTex->GetCubeMapSurface( faceList[i], 0, &cubeSurf ), NULL );
|
||||
|
||||
// get incoming texture surface
|
||||
GFXD3D9TextureObject *texObj = dynamic_cast<GFXD3D9TextureObject*>( (GFXTextureObject*)faces[i] );
|
||||
IDirect3DSurface9 *inSurf;
|
||||
D3D9Assert( texObj->get2DTex()->GetSurfaceLevel( 0, &inSurf ), NULL );
|
||||
|
||||
// copy incoming texture into cube face
|
||||
D3D9Assert( GFXD3DX.D3DXLoadSurfaceFromSurface( cubeSurf, NULL, NULL, inSurf, NULL,
|
||||
NULL, D3DX_FILTER_NONE, 0 ), NULL );
|
||||
cubeSurf->Release();
|
||||
inSurf->Release();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Set the cubemap to the specified texture unit num
|
||||
//-----------------------------------------------------------------------------
|
||||
void GFXD3D9Cubemap::setToTexUnit( U32 tuNum )
|
||||
{
|
||||
static_cast<GFXD3D9Device *>(GFX)->getDevice()->SetTexture( tuNum, mCubeTex );
|
||||
}
|
||||
|
||||
void GFXD3D9Cubemap::zombify()
|
||||
{
|
||||
// Static cubemaps are handled by D3D
|
||||
if( mDynamic )
|
||||
releaseSurfaces();
|
||||
}
|
||||
|
||||
void GFXD3D9Cubemap::resurrect()
|
||||
{
|
||||
// Static cubemaps are handled by D3D
|
||||
if( mDynamic )
|
||||
initDynamic( mTexSize, mFaceFormat );
|
||||
}
|
||||
72
Engine/source/gfx/D3D9/gfxD3D9Cubemap.h
Normal file
72
Engine/source/gfx/D3D9/gfxD3D9Cubemap.h
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GFXD3D9CUBEMAP_H_
|
||||
#define _GFXD3D9CUBEMAP_H_
|
||||
|
||||
#include "gfx/D3D9/gfxD3D9Device.h"
|
||||
#include "gfx/gfxCubemap.h"
|
||||
#include "gfx/gfxResource.h"
|
||||
#include "gfx/gfxTarget.h"
|
||||
|
||||
//**************************************************************************
|
||||
// Cube map
|
||||
//**************************************************************************
|
||||
class GFXD3D9Cubemap : public GFXCubemap
|
||||
{
|
||||
public:
|
||||
virtual void initStatic( GFXTexHandle *faces );
|
||||
virtual void initStatic( DDSFile *dds );
|
||||
virtual void initDynamic( U32 texSize, GFXFormat faceFormat = GFXFormatR8G8B8A8 );
|
||||
virtual void setToTexUnit( U32 tuNum );
|
||||
virtual U32 getSize() const { return mTexSize; }
|
||||
virtual GFXFormat getFormat() const { return mFaceFormat; }
|
||||
|
||||
GFXD3D9Cubemap();
|
||||
virtual ~GFXD3D9Cubemap();
|
||||
|
||||
// GFXResource interface
|
||||
virtual void zombify();
|
||||
virtual void resurrect();
|
||||
|
||||
protected:
|
||||
|
||||
friend class GFXPCD3D9TextureTarget;
|
||||
friend class GFX360TextureTarget;
|
||||
friend class GFXD3D9Device;
|
||||
|
||||
LPDIRECT3DCUBETEXTURE9 mCubeTex;
|
||||
|
||||
static _D3DCUBEMAP_FACES faceList[6];
|
||||
bool mDynamic;
|
||||
U32 mTexSize;
|
||||
GFXFormat mFaceFormat;
|
||||
|
||||
void fillCubeTextures( GFXTexHandle *faces, LPDIRECT3DDEVICE9 D3DDevice );
|
||||
void releaseSurfaces();
|
||||
|
||||
/// The callback used to get texture events.
|
||||
/// @see GFXTextureManager::addEventDelegate
|
||||
void _onTextureEvent( GFXTexCallbackCode code );
|
||||
};
|
||||
|
||||
#endif // GFXD3D9CUBEMAP
|
||||
1145
Engine/source/gfx/D3D9/gfxD3D9Device.cpp
Normal file
1145
Engine/source/gfx/D3D9/gfxD3D9Device.cpp
Normal file
File diff suppressed because it is too large
Load diff
357
Engine/source/gfx/D3D9/gfxD3D9Device.h
Normal file
357
Engine/source/gfx/D3D9/gfxD3D9Device.h
Normal file
|
|
@ -0,0 +1,357 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GFXD3D9DEVICE_H_
|
||||
#define _GFXD3D9DEVICE_H_
|
||||
|
||||
#include "platform/tmm_off.h"
|
||||
|
||||
#ifdef TORQUE_OS_XENON
|
||||
# include "platformXbox/platformXbox.h"
|
||||
#else
|
||||
# include <d3dx9.h>
|
||||
# include "platformWin32/platformWin32.h"
|
||||
#endif
|
||||
#ifndef _GFXD3D9STATEBLOCK_H_
|
||||
#include "gfx/D3D9/gfxD3D9StateBlock.h"
|
||||
#endif
|
||||
#ifndef _GFXD3DTEXTUREMANAGER_H_
|
||||
#include "gfx/D3D9/gfxD3D9TextureManager.h"
|
||||
#endif
|
||||
#ifndef _GFXD3D9CUBEMAP_H_
|
||||
#include "gfx/D3D9/gfxD3D9Cubemap.h"
|
||||
#endif
|
||||
#ifndef _GFXD3D9PRIMITIVEBUFFER_H_
|
||||
#include "gfx/D3D9/gfxD3D9PrimitiveBuffer.h"
|
||||
#endif
|
||||
#ifndef _GFXINIT_H_
|
||||
#include "gfx/gfxInit.h"
|
||||
#endif
|
||||
#ifndef _PLATFORMDLIBRARY_H
|
||||
#include "platform/platformDlibrary.h"
|
||||
#endif
|
||||
|
||||
#ifndef TORQUE_OS_XENON
|
||||
#include <DxErr.h>
|
||||
#else
|
||||
#include <dxerr9.h>
|
||||
#define DXGetErrorStringA DXGetErrorString9A
|
||||
#define DXGetErrorDescriptionA DXGetErrorDescription9A
|
||||
#endif
|
||||
|
||||
#include "platform/tmm_on.h"
|
||||
|
||||
inline void D3D9Assert( HRESULT hr, const char *info )
|
||||
{
|
||||
#if defined( TORQUE_DEBUG )
|
||||
if( FAILED( hr ) )
|
||||
{
|
||||
char buf[256];
|
||||
dSprintf( buf, 256, "%s\n%s\n%s", DXGetErrorStringA( hr ), DXGetErrorDescriptionA( hr ), info );
|
||||
AssertFatal( false, buf );
|
||||
// DXTrace( __FILE__, __LINE__, hr, info, true );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// Typedefs
|
||||
#define D3DX_FUNCTION(fn_name, fn_return, fn_args) \
|
||||
typedef fn_return (WINAPI *D3DXFNPTR##fn_name##)##fn_args##;
|
||||
#include "gfx/D3D9/d3dx9Functions.h"
|
||||
#undef D3DX_FUNCTION
|
||||
|
||||
// Function table
|
||||
struct D3DXFNTable
|
||||
{
|
||||
D3DXFNTable() : isLoaded( false ){};
|
||||
bool isLoaded;
|
||||
DLibraryRef dllRef;
|
||||
DLibraryRef compilerDllRef;
|
||||
#define D3DX_FUNCTION(fn_name, fn_return, fn_args) \
|
||||
D3DXFNPTR##fn_name fn_name;
|
||||
#include "gfx/D3D9/d3dx9Functions.h"
|
||||
#undef D3DX_FUNCTION
|
||||
};
|
||||
|
||||
#define GFXD3DX static_cast<GFXD3D9Device *>(GFX)->smD3DX
|
||||
|
||||
class GFXResource;
|
||||
class GFXD3D9ShaderConstBuffer;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class GFXD3D9Device : public GFXDevice
|
||||
{
|
||||
friend class GFXResource;
|
||||
friend class GFXD3D9PrimitiveBuffer;
|
||||
friend class GFXD3D9VertexBuffer;
|
||||
friend class GFXD3D9TextureObject;
|
||||
friend class GFXPCD3D9TextureTarget;
|
||||
friend class GFXPCD3D9WindowTarget;
|
||||
|
||||
typedef GFXDevice Parent;
|
||||
|
||||
protected:
|
||||
|
||||
MatrixF mTempMatrix; ///< Temporary matrix, no assurances on value at all
|
||||
RectI mClipRect;
|
||||
|
||||
typedef StrongRefPtr<GFXD3D9VertexBuffer> RPGDVB;
|
||||
Vector<RPGDVB> mVolatileVBList;
|
||||
|
||||
class D3D9VertexDecl : public GFXVertexDecl
|
||||
{
|
||||
public:
|
||||
virtual ~D3D9VertexDecl()
|
||||
{
|
||||
SAFE_RELEASE( decl );
|
||||
}
|
||||
|
||||
IDirect3DVertexDeclaration9 *decl;
|
||||
};
|
||||
|
||||
/// Used to lookup a vertex declaration for the vertex format.
|
||||
/// @see allocVertexDecl
|
||||
typedef Map<String,D3D9VertexDecl*> VertexDeclMap;
|
||||
VertexDeclMap mVertexDecls;
|
||||
|
||||
IDirect3DSurface9 *mDeviceBackbuffer;
|
||||
IDirect3DSurface9 *mDeviceDepthStencil;
|
||||
IDirect3DSurface9 *mDeviceColor;
|
||||
|
||||
/// The stream 0 vertex buffer used for volatile VB offseting.
|
||||
GFXD3D9VertexBuffer *mVolatileVB;
|
||||
|
||||
static void initD3DXFnTable();
|
||||
//-----------------------------------------------------------------------
|
||||
StrongRefPtr<GFXD3D9PrimitiveBuffer> mDynamicPB; ///< Dynamic index buffer
|
||||
GFXD3D9PrimitiveBuffer *mCurrentPB;
|
||||
|
||||
IDirect3DVertexShader9 *mLastVertShader;
|
||||
IDirect3DPixelShader9 *mLastPixShader;
|
||||
|
||||
S32 mCreateFenceType;
|
||||
|
||||
LPDIRECT3D9 mD3D; ///< D3D Handle
|
||||
LPDIRECT3DDEVICE9 mD3DDevice; ///< Handle for D3DDevice
|
||||
|
||||
#if !defined(TORQUE_OS_XENON)
|
||||
LPDIRECT3D9EX mD3DEx; ///< D3D9Ex Handle
|
||||
LPDIRECT3DDEVICE9EX mD3DDeviceEx; ///< Handle for D3DDevice9Ex
|
||||
#endif
|
||||
|
||||
U32 mAdapterIndex; ///< Adapter index because D3D supports multiple adapters
|
||||
|
||||
F32 mPixVersion;
|
||||
U32 mNumSamplers; ///< Profiled (via caps)
|
||||
U32 mNumRenderTargets; ///< Profiled (via caps)
|
||||
|
||||
D3DMULTISAMPLE_TYPE mMultisampleType;
|
||||
DWORD mMultisampleLevel;
|
||||
|
||||
bool mOcclusionQuerySupported;
|
||||
|
||||
/// The current adapter display mode.
|
||||
D3DDISPLAYMODE mDisplayMode;
|
||||
|
||||
/// To manage creating and re-creating of these when device is aquired
|
||||
void reacquireDefaultPoolResources();
|
||||
|
||||
/// To release all resources we control from D3DPOOL_DEFAULT
|
||||
void releaseDefaultPoolResources();
|
||||
|
||||
/// This you will probably never, ever use, but it is used to generate the code for
|
||||
/// the initStates() function
|
||||
void regenStates();
|
||||
|
||||
virtual GFXD3D9VertexBuffer* findVBPool( const GFXVertexFormat *vertexFormat, U32 numVertsNeeded );
|
||||
virtual GFXD3D9VertexBuffer* createVBPool( const GFXVertexFormat *vertexFormat, U32 vertSize );
|
||||
|
||||
#ifdef TORQUE_DEBUG
|
||||
/// @name Debug Vertex Buffer information/management
|
||||
/// @{
|
||||
|
||||
///
|
||||
U32 mNumAllocatedVertexBuffers; ///< To keep track of how many are allocated and freed
|
||||
GFXD3D9VertexBuffer *mVBListHead;
|
||||
void addVertexBuffer( GFXD3D9VertexBuffer *buffer );
|
||||
void removeVertexBuffer( GFXD3D9VertexBuffer *buffer );
|
||||
void logVertexBuffers();
|
||||
/// @}
|
||||
#endif
|
||||
|
||||
// State overrides
|
||||
// {
|
||||
|
||||
///
|
||||
virtual void setTextureInternal(U32 textureUnit, const GFXTextureObject* texture);
|
||||
|
||||
/// Called by GFXDevice to create a device specific stateblock
|
||||
virtual GFXStateBlockRef createStateBlockInternal(const GFXStateBlockDesc& desc);
|
||||
/// Called by GFXDevice to actually set a stateblock.
|
||||
virtual void setStateBlockInternal(GFXStateBlock* block, bool force);
|
||||
|
||||
/// Track the last const buffer we've used. Used to notify new constant buffers that
|
||||
/// they should send all of their constants up
|
||||
StrongRefPtr<GFXD3D9ShaderConstBuffer> mCurrentConstBuffer;
|
||||
/// Called by base GFXDevice to actually set a const buffer
|
||||
virtual void setShaderConstBufferInternal(GFXShaderConstBuffer* buffer);
|
||||
|
||||
// CodeReview - How exactly do we want to deal with this on the Xenon?
|
||||
// Right now it's just in an #ifndef in gfxD3D9Device.cpp - AlexS 4/11/07
|
||||
virtual void setLightInternal(U32 lightStage, const GFXLightInfo light, bool lightEnable);
|
||||
virtual void setLightMaterialInternal(const GFXLightMaterial mat);
|
||||
virtual void setGlobalAmbientInternal(ColorF color);
|
||||
|
||||
virtual void initStates()=0;
|
||||
// }
|
||||
|
||||
// Index buffer management
|
||||
// {
|
||||
virtual void _setPrimitiveBuffer( GFXPrimitiveBuffer *buffer );
|
||||
virtual void drawIndexedPrimitive( GFXPrimitiveType primType,
|
||||
U32 startVertex,
|
||||
U32 minIndex,
|
||||
U32 numVerts,
|
||||
U32 startIndex,
|
||||
U32 primitiveCount );
|
||||
// }
|
||||
|
||||
virtual GFXShader* createShader();
|
||||
|
||||
/// Device helper function
|
||||
virtual D3DPRESENT_PARAMETERS setupPresentParams( const GFXVideoMode &mode, const HWND &hwnd ) const = 0;
|
||||
|
||||
public:
|
||||
static D3DXFNTable smD3DX;
|
||||
|
||||
static GFXDevice *createInstance( U32 adapterIndex );
|
||||
|
||||
GFXTextureObject* createRenderSurface( U32 width, U32 height, GFXFormat format, U32 mipLevel );
|
||||
|
||||
const D3DDISPLAYMODE& getDisplayMode() const { return mDisplayMode; }
|
||||
|
||||
/// Constructor
|
||||
/// @param d3d Direct3D object to instantiate this device with
|
||||
/// @param index Adapter index since D3D can use multiple graphics adapters
|
||||
GFXD3D9Device( LPDIRECT3D9 d3d, U32 index );
|
||||
virtual ~GFXD3D9Device();
|
||||
|
||||
// Activate/deactivate
|
||||
// {
|
||||
virtual void init( const GFXVideoMode &mode, PlatformWindow *window = NULL ) = 0;
|
||||
|
||||
virtual void preDestroy() { Parent::preDestroy(); if(mTextureManager) mTextureManager->kill(); }
|
||||
|
||||
GFXAdapterType getAdapterType(){ return Direct3D9; }
|
||||
|
||||
virtual GFXCubemap *createCubemap();
|
||||
|
||||
virtual F32 getPixelShaderVersion() const { return mPixVersion; }
|
||||
virtual void setPixelShaderVersion( F32 version ){ mPixVersion = version; }
|
||||
virtual void disableShaders();
|
||||
virtual void setShader( GFXShader *shader );
|
||||
virtual U32 getNumSamplers() const { return mNumSamplers; }
|
||||
virtual U32 getNumRenderTargets() const { return mNumRenderTargets; }
|
||||
// }
|
||||
|
||||
// Misc rendering control
|
||||
// {
|
||||
virtual void clear( U32 flags, ColorI color, F32 z, U32 stencil );
|
||||
virtual bool beginSceneInternal();
|
||||
virtual void endSceneInternal();
|
||||
|
||||
virtual void setClipRect( const RectI &rect );
|
||||
virtual const RectI& getClipRect() const { return mClipRect; }
|
||||
|
||||
// }
|
||||
|
||||
/// @name Render Targets
|
||||
/// @{
|
||||
virtual void _updateRenderTargets();
|
||||
/// @}
|
||||
|
||||
// Vertex/Index buffer management
|
||||
// {
|
||||
virtual GFXVertexBuffer* allocVertexBuffer( U32 numVerts,
|
||||
const GFXVertexFormat *vertexFormat,
|
||||
U32 vertSize,
|
||||
GFXBufferType bufferType );
|
||||
virtual GFXPrimitiveBuffer *allocPrimitiveBuffer( U32 numIndices,
|
||||
U32 numPrimitives,
|
||||
GFXBufferType bufferType );
|
||||
virtual void deallocVertexBuffer( GFXD3D9VertexBuffer *vertBuff );
|
||||
virtual GFXVertexDecl* allocVertexDecl( const GFXVertexFormat *vertexFormat );
|
||||
virtual void setVertexDecl( const GFXVertexDecl *decl );
|
||||
|
||||
virtual void setVertexStream( U32 stream, GFXVertexBuffer *buffer );
|
||||
virtual void setVertexStreamFrequency( U32 stream, U32 frequency );
|
||||
// }
|
||||
|
||||
virtual U32 getMaxDynamicVerts() { return MAX_DYNAMIC_VERTS; }
|
||||
virtual U32 getMaxDynamicIndices() { return MAX_DYNAMIC_INDICES; }
|
||||
|
||||
// Rendering
|
||||
// {
|
||||
virtual void drawPrimitive( GFXPrimitiveType primType, U32 vertexStart, U32 primitiveCount );
|
||||
// }
|
||||
|
||||
virtual LPDIRECT3DDEVICE9 getDevice(){ return mD3DDevice; }
|
||||
virtual LPDIRECT3D9 getD3D() { return mD3D; }
|
||||
|
||||
/// Reset
|
||||
virtual void reset( D3DPRESENT_PARAMETERS &d3dpp ) = 0;
|
||||
|
||||
GFXShaderRef mGenericShader[GS_COUNT];
|
||||
|
||||
virtual void setupGenericShaders( GenericShaderType type = GSColor );
|
||||
|
||||
// Function only really used on the, however a centralized function for
|
||||
// destroying resources is probably a good thing -patw
|
||||
virtual void destroyD3DResource( IDirect3DResource9 *d3dResource ) { SAFE_RELEASE( d3dResource ); };
|
||||
|
||||
inline virtual F32 getFillConventionOffset() const { return 0.5f; }
|
||||
virtual void doParanoidStateCheck();
|
||||
|
||||
GFXFence *createFence();
|
||||
|
||||
GFXOcclusionQuery* createOcclusionQuery();
|
||||
|
||||
// Default multisample parameters
|
||||
D3DMULTISAMPLE_TYPE getMultisampleType() const { return mMultisampleType; }
|
||||
DWORD getMultisampleLevel() const { return mMultisampleLevel; }
|
||||
|
||||
// Whether or not the Direct3D device was created with Direct3D9Ex support
|
||||
#if !defined(TORQUE_OS_XENON)
|
||||
virtual bool isD3D9Ex() { return mD3DEx != NULL; }
|
||||
#else
|
||||
virtual bool isD3D9Ex() { return false; }
|
||||
#endif
|
||||
|
||||
// Get the backbuffer, currently only access for WPF support
|
||||
virtual IDirect3DSurface9* getBackBuffer() { return mDeviceBackbuffer; }
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // _GFXD3D9DEVICE_H_
|
||||
92
Engine/source/gfx/D3D9/gfxD3D9Device.regen-states.cpp
Normal file
92
Engine/source/gfx/D3D9/gfxD3D9Device.regen-states.cpp
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "gfx/D3D9/gfxD3D9Device.h"
|
||||
#include "console/console.h"
|
||||
#include "gfx/D3D9/gfxD3D9EnumTranslate.h"
|
||||
|
||||
// Cut and paste from console.log into GFXD3D9Device::initStates()
|
||||
void GFXD3D9Device::regenStates()
|
||||
{
|
||||
DWORD temp;
|
||||
Con::printf( " //-------------------------------------" );
|
||||
Con::printf( " // Auto-generated default states, see regenStates() for details" );
|
||||
Con::printf( " //" );
|
||||
Con::printf( "" );
|
||||
Con::printf( " // Render states" );
|
||||
|
||||
for( U32 state = GFXRenderState_FIRST; state < GFXRenderState_COUNT; state++ )
|
||||
{
|
||||
if( GFXD3D9RenderState[state] == GFX_UNSUPPORTED_VAL )
|
||||
continue;
|
||||
|
||||
temp = 0;
|
||||
mD3DDevice->GetRenderState( GFXD3D9RenderState[state], &temp );
|
||||
Con::printf( " mD3DDevice->SetRenderState( GFXD3D9RenderState[%d], %d );", state, temp );
|
||||
}
|
||||
|
||||
#ifndef TORQUE_OS_XENON
|
||||
Con::printf( "" );
|
||||
Con::printf( " // Texture Stage states" );
|
||||
|
||||
for( U32 stage = 0; stage < TEXTURE_STAGE_COUNT; stage++ )
|
||||
{
|
||||
if( stage >= GFX->getNumSamplers() )
|
||||
{
|
||||
Con::errorf( "Sampler %d out of range for this device, ignoring.", stage );
|
||||
break;
|
||||
}
|
||||
|
||||
for( U32 state = GFXTSS_FIRST; state < GFXTSS_COUNT; state++ )
|
||||
{
|
||||
if( GFXD3D9TextureStageState[state] == GFX_UNSUPPORTED_VAL )
|
||||
continue;
|
||||
|
||||
temp = 0;
|
||||
mD3DDevice->GetTextureStageState( stage, GFXD3D9TextureStageState[state], &temp );
|
||||
Con::printf( " mD3DDevice->SetTextureStageState( %d, GFXD3D9TextureStageState[%d], %d );", stage, state, temp );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Con::printf( "" );
|
||||
Con::printf( " // Sampler states" );
|
||||
for( U32 stage = 0; stage < TEXTURE_STAGE_COUNT; stage++ )
|
||||
{
|
||||
if( stage >= GFX->getNumSamplers() )
|
||||
{
|
||||
Con::errorf( "Sampler %d out of range for this device, ignoring.", stage );
|
||||
break;
|
||||
}
|
||||
|
||||
for( U32 state = GFXSAMP_FIRST; state < GFXSAMP_COUNT; state++ )
|
||||
{
|
||||
if( GFXD3D9SamplerState[state] == GFX_UNSUPPORTED_VAL )
|
||||
continue;
|
||||
|
||||
temp = 0;
|
||||
|
||||
mD3DDevice->GetSamplerState( stage, GFXD3D9SamplerState[state], &temp );
|
||||
Con::printf( " mD3DDevice->SetSamplerState( %d, GFXD3D9SamplerState[%d], %d );", stage, state, temp );
|
||||
}
|
||||
}
|
||||
}
|
||||
63
Engine/source/gfx/D3D9/gfxD3D9EnumTranslate.h
Normal file
63
Engine/source/gfx/D3D9/gfxD3D9EnumTranslate.h
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "gfx/D3D9/gfxD3D9Shader.h"
|
||||
|
||||
#include "gfx/gfxEnums.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace GFXD3D9EnumTranslate
|
||||
{
|
||||
void init();
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
extern _D3DFORMAT GFXD3D9IndexFormat[GFXIndexFormat_COUNT];
|
||||
extern _D3DSAMPLERSTATETYPE GFXD3D9SamplerState[GFXSAMP_COUNT];
|
||||
extern _D3DFORMAT GFXD3D9TextureFormat[GFXFormat_COUNT];
|
||||
#ifdef TORQUE_OS_XENON
|
||||
extern _D3DFORMAT GFXD3D9RenderTargetFormat[GFXFormat_COUNT];
|
||||
#endif
|
||||
extern _D3DRENDERSTATETYPE GFXD3D9RenderState[GFXRenderState_COUNT];
|
||||
extern _D3DTEXTUREFILTERTYPE GFXD3D9TextureFilter[GFXTextureFilter_COUNT];
|
||||
extern _D3DBLEND GFXD3D9Blend[GFXBlend_COUNT];
|
||||
extern _D3DBLENDOP GFXD3D9BlendOp[GFXBlendOp_COUNT];
|
||||
extern _D3DSTENCILOP GFXD3D9StencilOp[GFXStencilOp_COUNT];
|
||||
extern _D3DCMPFUNC GFXD3D9CmpFunc[GFXCmp_COUNT];
|
||||
extern _D3DCULL GFXD3D9CullMode[GFXCull_COUNT];
|
||||
extern _D3DFILLMODE GFXD3D9FillMode[GFXFill_COUNT];
|
||||
extern _D3DPRIMITIVETYPE GFXD3D9PrimType[GFXPT_COUNT];
|
||||
extern _D3DTEXTURESTAGESTATETYPE GFXD3D9TextureStageState[GFXTSS_COUNT];
|
||||
extern _D3DTEXTUREADDRESS GFXD3D9TextureAddress[GFXAddress_COUNT];
|
||||
extern _D3DTEXTUREOP GFXD3D9TextureOp[GFXTOP_COUNT];
|
||||
extern _D3DDECLTYPE GFXD3D9DeclType[GFXDeclType_COUNT];
|
||||
|
||||
#define GFXREVERSE_LOOKUP( tablearray, enumprefix, val ) \
|
||||
for( int i = enumprefix##_FIRST; i < enumprefix##_COUNT; i++ ) \
|
||||
if( (int)tablearray##[i] == val ) \
|
||||
{ \
|
||||
val = i; \
|
||||
break; \
|
||||
} \
|
||||
|
||||
163
Engine/source/gfx/D3D9/gfxD3D9OcclusionQuery.cpp
Normal file
163
Engine/source/gfx/D3D9/gfxD3D9OcclusionQuery.cpp
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "gfx/D3D9/gfxD3D9Device.h"
|
||||
#include "gfx/D3D9/gfxD3D9OcclusionQuery.h"
|
||||
|
||||
#include "gui/3d/guiTSControl.h"
|
||||
|
||||
#ifdef TORQUE_GATHER_METRICS
|
||||
// For TickMs define
|
||||
#include "T3D/gameBase/processList.h"
|
||||
#endif
|
||||
|
||||
GFXD3D9OcclusionQuery::GFXD3D9OcclusionQuery( GFXDevice *device )
|
||||
: GFXOcclusionQuery( device ),
|
||||
mQuery( NULL )
|
||||
{
|
||||
#ifdef TORQUE_GATHER_METRICS
|
||||
mTimer = PlatformTimer::create();
|
||||
mTimer->getElapsedMs();
|
||||
|
||||
mTimeSinceEnd = 0;
|
||||
mBeginFrame = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
GFXD3D9OcclusionQuery::~GFXD3D9OcclusionQuery()
|
||||
{
|
||||
SAFE_RELEASE( mQuery );
|
||||
|
||||
#ifdef TORQUE_GATHER_METRICS
|
||||
SAFE_DELETE( mTimer );
|
||||
#endif
|
||||
}
|
||||
|
||||
bool GFXD3D9OcclusionQuery::begin()
|
||||
{
|
||||
if ( GFXDevice::getDisableOcclusionQuery() )
|
||||
return true;
|
||||
|
||||
if ( mQuery == NULL )
|
||||
{
|
||||
#ifdef TORQUE_OS_XENON
|
||||
HRESULT hRes = static_cast<GFXD3D9Device*>( mDevice )->getDevice()->CreateQueryTiled( D3DQUERYTYPE_OCCLUSION, 2, &mQuery );
|
||||
#else
|
||||
HRESULT hRes = static_cast<GFXD3D9Device*>( mDevice )->getDevice()->CreateQuery( D3DQUERYTYPE_OCCLUSION, &mQuery );
|
||||
#endif
|
||||
|
||||
AssertFatal( hRes != D3DERR_NOTAVAILABLE, "GFXD3D9OcclusionQuery::begin - Hardware does not support D3D9 Occlusion-Queries, this should be caught before this type is created" );
|
||||
AssertISV( hRes != E_OUTOFMEMORY, "GFXD3D9OcclusionQuery::begin - Out of memory" );
|
||||
}
|
||||
|
||||
// Add a begin marker to the command buffer queue.
|
||||
mQuery->Issue( D3DISSUE_BEGIN );
|
||||
|
||||
#ifdef TORQUE_GATHER_METRICS
|
||||
mBeginFrame = GuiTSCtrl::getFrameCount();
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GFXD3D9OcclusionQuery::end()
|
||||
{
|
||||
if ( GFXDevice::getDisableOcclusionQuery() )
|
||||
return;
|
||||
|
||||
// Add an end marker to the command buffer queue.
|
||||
mQuery->Issue( D3DISSUE_END );
|
||||
|
||||
#ifdef TORQUE_GATHER_METRICS
|
||||
AssertFatal( mBeginFrame == GuiTSCtrl::getFrameCount(), "GFXD3D9OcclusionQuery::end - ended query on different frame than begin!" );
|
||||
mTimer->getElapsedMs();
|
||||
mTimer->reset();
|
||||
#endif
|
||||
}
|
||||
|
||||
GFXD3D9OcclusionQuery::OcclusionQueryStatus GFXD3D9OcclusionQuery::getStatus( bool block, U32 *data )
|
||||
{
|
||||
// If this ever shows up near the top of a profile then your system is
|
||||
// GPU bound or you are calling getStatus too soon after submitting it.
|
||||
//
|
||||
// To test if you are GPU bound resize your window very small and see if
|
||||
// this profile no longer appears at the top.
|
||||
//
|
||||
// To test if you are calling getStatus to soon after submitting it,
|
||||
// check the value of mTimeSinceEnd in a debug build. If it is < half the length
|
||||
// of time to render an individual frame you could have problems.
|
||||
PROFILE_SCOPE(GFXD3D9OcclusionQuery_getStatus);
|
||||
|
||||
if ( GFXDevice::getDisableOcclusionQuery() )
|
||||
return NotOccluded;
|
||||
|
||||
if ( mQuery == NULL )
|
||||
return Unset;
|
||||
|
||||
#ifdef TORQUE_GATHER_METRICS
|
||||
AssertFatal( mBeginFrame < GuiTSCtrl::getFrameCount(), "GFXD3D9OcclusionQuery::getStatus - called on the same frame as begin!" );
|
||||
|
||||
//U32 mTimeSinceEnd = mTimer->getElapsedMs();
|
||||
//AssertFatal( mTimeSinceEnd >= 5, "GFXD3DOcculsionQuery::getStatus - less than TickMs since called ::end!" );
|
||||
#endif
|
||||
|
||||
HRESULT hRes;
|
||||
DWORD dwOccluded = 0;
|
||||
|
||||
if ( block )
|
||||
{
|
||||
while( ( hRes = mQuery->GetData( &dwOccluded, sizeof(DWORD), D3DGETDATA_FLUSH ) ) == S_FALSE )
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
hRes = mQuery->GetData( &dwOccluded, sizeof(DWORD), 0 );
|
||||
}
|
||||
|
||||
if ( hRes == S_OK )
|
||||
{
|
||||
if ( data != NULL )
|
||||
*data = dwOccluded;
|
||||
|
||||
return dwOccluded > 0 ? NotOccluded : Occluded;
|
||||
}
|
||||
|
||||
if ( hRes == S_FALSE )
|
||||
return Waiting;
|
||||
|
||||
return Error;
|
||||
}
|
||||
|
||||
void GFXD3D9OcclusionQuery::zombify()
|
||||
{
|
||||
SAFE_RELEASE( mQuery );
|
||||
}
|
||||
|
||||
void GFXD3D9OcclusionQuery::resurrect()
|
||||
{
|
||||
}
|
||||
|
||||
const String GFXD3D9OcclusionQuery::describeSelf() const
|
||||
{
|
||||
// We've got nothing
|
||||
return String();
|
||||
}
|
||||
64
Engine/source/gfx/D3D9/gfxD3D9OcclusionQuery.h
Normal file
64
Engine/source/gfx/D3D9/gfxD3D9OcclusionQuery.h
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GFX_D3D9_OCCLUSIONQUERY_H_
|
||||
#define _GFX_D3D9_OCCLUSIONQUERY_H_
|
||||
|
||||
#ifndef _GFXOCCLUSIONQUERY_H_
|
||||
#include "gfx/gfxOcclusionQuery.h"
|
||||
#endif
|
||||
|
||||
#ifdef TORQUE_GATHER_METRICS
|
||||
#ifndef _PLATFORM_PLATFORMTIMER_H_
|
||||
#include "platform/platformTimer.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
struct IDirect3DQuery9;
|
||||
|
||||
|
||||
class GFXD3D9OcclusionQuery : public GFXOcclusionQuery
|
||||
{
|
||||
private:
|
||||
mutable IDirect3DQuery9 *mQuery;
|
||||
|
||||
#ifdef TORQUE_GATHER_METRICS
|
||||
U32 mBeginFrame;
|
||||
U32 mTimeSinceEnd;
|
||||
PlatformTimer *mTimer;
|
||||
#endif
|
||||
|
||||
public:
|
||||
GFXD3D9OcclusionQuery( GFXDevice *device );
|
||||
virtual ~GFXD3D9OcclusionQuery();
|
||||
|
||||
virtual bool begin();
|
||||
virtual void end();
|
||||
virtual OcclusionQueryStatus getStatus( bool block, U32 *data = NULL );
|
||||
|
||||
// GFXResource
|
||||
virtual void zombify();
|
||||
virtual void resurrect();
|
||||
virtual const String describeSelf() const;
|
||||
};
|
||||
|
||||
#endif // _GFX_D3D9_OCCLUSIONQUERY_H_
|
||||
114
Engine/source/gfx/D3D9/gfxD3D9PrimitiveBuffer.cpp
Normal file
114
Engine/source/gfx/D3D9/gfxD3D9PrimitiveBuffer.cpp
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "gfx/D3D9/gfxD3D9Device.h"
|
||||
#include "gfx/D3D9/gfxD3D9EnumTranslate.h"
|
||||
#include "gfx/D3D9/gfxD3D9PrimitiveBuffer.h"
|
||||
#include "core/util/safeRelease.h"
|
||||
|
||||
void GFXD3D9PrimitiveBuffer::prepare()
|
||||
{
|
||||
static_cast<GFXD3D9Device *>( mDevice )->_setPrimitiveBuffer(this);
|
||||
}
|
||||
|
||||
void GFXD3D9PrimitiveBuffer::unlock()
|
||||
{
|
||||
#ifdef TORQUE_DEBUG
|
||||
|
||||
if ( mDebugGuardBuffer )
|
||||
{
|
||||
const U32 guardSize = sizeof( _PBGuardString );
|
||||
|
||||
// First check the guard areas for overwrites.
|
||||
AssertFatal( dMemcmp( mDebugGuardBuffer, _PBGuardString, guardSize ) == 0,
|
||||
"GFXD3D9PrimitiveBuffer::unlock - Caught lock memory underrun!" );
|
||||
AssertFatal( dMemcmp( mDebugGuardBuffer + mLockedSize + guardSize, _PBGuardString, guardSize ) == 0,
|
||||
"GFXD3D9PrimitiveBuffer::unlock - Caught lock memory overrun!" );
|
||||
|
||||
// Copy the debug content down to the real PB.
|
||||
dMemcpy( mLockedBuffer, mDebugGuardBuffer + guardSize, mLockedSize );
|
||||
|
||||
// Cleanup.
|
||||
delete [] mDebugGuardBuffer;
|
||||
mDebugGuardBuffer = NULL;
|
||||
mLockedBuffer = NULL;
|
||||
mLockedSize = 0;
|
||||
}
|
||||
|
||||
#endif // TORQUE_DEBUG
|
||||
|
||||
ib->Unlock();
|
||||
mLocked = false;
|
||||
mIsFirstLock = false;
|
||||
mVolatileBuffer = NULL;
|
||||
}
|
||||
|
||||
GFXD3D9PrimitiveBuffer::~GFXD3D9PrimitiveBuffer()
|
||||
{
|
||||
if( mBufferType != GFXBufferTypeVolatile )
|
||||
{
|
||||
#if defined(TORQUE_OS_XENON)
|
||||
if(ib->IsSet(reinterpret_cast<GFXD3D9Device *>(mDevice)->mD3DDevice))
|
||||
{
|
||||
reinterpret_cast<GFXD3D9Device *>(mDevice)->mD3DDevice->SetIndices(NULL);
|
||||
}
|
||||
#endif
|
||||
SAFE_RELEASE( ib );
|
||||
}
|
||||
}
|
||||
|
||||
void GFXD3D9PrimitiveBuffer::zombify()
|
||||
{
|
||||
if(mBufferType == GFXBufferTypeStatic)
|
||||
return;
|
||||
|
||||
AssertFatal(!mLocked, "GFXD3D9PrimitiveBuffer::zombify - Cannot zombify a locked buffer!");
|
||||
|
||||
if (mBufferType == GFXBufferTypeVolatile)
|
||||
{
|
||||
// We must null the volatile buffer else we're holding
|
||||
// a dead pointer which can be set on the device.
|
||||
ib = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
// Dynamic buffers get released.
|
||||
SAFE_RELEASE(ib);
|
||||
}
|
||||
|
||||
void GFXD3D9PrimitiveBuffer::resurrect()
|
||||
{
|
||||
if ( mBufferType != GFXBufferTypeDynamic )
|
||||
return;
|
||||
|
||||
U32 usage = D3DUSAGE_WRITEONLY;
|
||||
|
||||
#ifndef TORQUE_OS_XENON
|
||||
usage |= D3DUSAGE_DYNAMIC;
|
||||
#endif
|
||||
|
||||
D3DPOOL pool = D3DPOOL_DEFAULT;
|
||||
|
||||
D3D9Assert(static_cast<GFXD3D9Device*>(mDevice)->mD3DDevice->CreateIndexBuffer( sizeof(U16) * mIndexCount ,
|
||||
usage , GFXD3D9IndexFormat[GFXIndexFormat16], pool, &ib, 0),
|
||||
"GFXD3D9PrimitiveBuffer::resurrect - Failed to allocate an index buffer.");
|
||||
}
|
||||
88
Engine/source/gfx/D3D9/gfxD3D9PrimitiveBuffer.h
Normal file
88
Engine/source/gfx/D3D9/gfxD3D9PrimitiveBuffer.h
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GFXD3D9PRIMITIVEBUFFER_H_
|
||||
#define _GFXD3D9PRIMITIVEBUFFER_H_
|
||||
|
||||
#ifndef _GFXPRIMITIVEBUFFER_H_
|
||||
#include "gfx/gfxPrimitiveBuffer.h"
|
||||
#endif
|
||||
|
||||
|
||||
struct IDirect3DIndexBuffer9;
|
||||
|
||||
class GFXD3D9PrimitiveBuffer : public GFXPrimitiveBuffer
|
||||
{
|
||||
public:
|
||||
IDirect3DIndexBuffer9 *ib;
|
||||
StrongRefPtr<GFXD3D9PrimitiveBuffer> mVolatileBuffer;
|
||||
U32 mVolatileStart;
|
||||
|
||||
#ifdef TORQUE_DEBUG
|
||||
#define _PBGuardString "GFX_PRIMTIVE_BUFFER_GUARD_STRING"
|
||||
U8 *mDebugGuardBuffer;
|
||||
void *mLockedBuffer;
|
||||
U32 mLockedSize;
|
||||
#endif TORQUE_DEBUG
|
||||
|
||||
bool mLocked;
|
||||
bool mIsFirstLock;
|
||||
|
||||
GFXD3D9PrimitiveBuffer( GFXDevice *device,
|
||||
U32 indexCount,
|
||||
U32 primitiveCount,
|
||||
GFXBufferType bufferType );
|
||||
|
||||
virtual ~GFXD3D9PrimitiveBuffer();
|
||||
|
||||
virtual void lock(U32 indexStart, U32 indexEnd, void **indexPtr);
|
||||
virtual void unlock();
|
||||
|
||||
virtual void prepare();
|
||||
|
||||
#ifdef TORQUE_DEBUG
|
||||
//GFXD3D9PrimitiveBuffer *next;
|
||||
#endif
|
||||
|
||||
// GFXResource interface
|
||||
virtual void zombify();
|
||||
virtual void resurrect();
|
||||
};
|
||||
|
||||
inline GFXD3D9PrimitiveBuffer::GFXD3D9PrimitiveBuffer( GFXDevice *device,
|
||||
U32 indexCount,
|
||||
U32 primitiveCount,
|
||||
GFXBufferType bufferType )
|
||||
: GFXPrimitiveBuffer( device, indexCount, primitiveCount, bufferType )
|
||||
{
|
||||
mVolatileStart = 0;
|
||||
ib = NULL;
|
||||
mIsFirstLock = true;
|
||||
mLocked = false;
|
||||
#ifdef TORQUE_DEBUG
|
||||
mDebugGuardBuffer = NULL;
|
||||
mLockedBuffer = NULL;
|
||||
mLockedSize = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
106
Engine/source/gfx/D3D9/gfxD3D9QueryFence.cpp
Normal file
106
Engine/source/gfx/D3D9/gfxD3D9QueryFence.cpp
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "gfx/D3D9/gfxD3D9Device.h"
|
||||
#include "gfx/D3D9/gfxD3D9QueryFence.h"
|
||||
|
||||
GFXD3D9QueryFence::~GFXD3D9QueryFence()
|
||||
{
|
||||
SAFE_RELEASE( mQuery );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void GFXD3D9QueryFence::issue()
|
||||
{
|
||||
PROFILE_START( GFXD3D9QueryFence_issue );
|
||||
|
||||
// Create the query if we need to
|
||||
if( mQuery == NULL )
|
||||
{
|
||||
HRESULT hRes = static_cast<GFXD3D9Device *>( mDevice )->getDevice()->CreateQuery( D3DQUERYTYPE_EVENT, &mQuery );
|
||||
|
||||
AssertFatal( hRes != D3DERR_NOTAVAILABLE, "Hardware does not support D3D9 Queries, this should be caught before this fence type is created" );
|
||||
AssertISV( hRes != E_OUTOFMEMORY, "Out of memory" );
|
||||
}
|
||||
|
||||
// Issue the query
|
||||
mQuery->Issue( D3DISSUE_END );
|
||||
|
||||
PROFILE_END();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
GFXFence::FenceStatus GFXD3D9QueryFence::getStatus() const
|
||||
{
|
||||
if( mQuery == NULL )
|
||||
return GFXFence::Unset;
|
||||
|
||||
HRESULT hRes = mQuery->GetData( NULL, 0, 0 );
|
||||
|
||||
return ( hRes == S_OK ? GFXFence::Processed : GFXFence::Pending );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void GFXD3D9QueryFence::block()
|
||||
{
|
||||
PROFILE_SCOPE(GFXD3D9QueryFence_block);
|
||||
|
||||
// Calling block() before issue() is valid, catch this case
|
||||
if( mQuery == NULL )
|
||||
return;
|
||||
|
||||
HRESULT hRes;
|
||||
while( ( hRes = mQuery->GetData( NULL, 0, D3DGETDATA_FLUSH ) ) == S_FALSE )
|
||||
;
|
||||
|
||||
// Check for D3DERR_DEVICELOST, if we lost the device, the fence will get
|
||||
// re-created next issue()
|
||||
if( hRes == D3DERR_DEVICELOST )
|
||||
SAFE_RELEASE( mQuery );
|
||||
}
|
||||
|
||||
void GFXD3D9QueryFence::zombify()
|
||||
{
|
||||
// Release our query
|
||||
SAFE_RELEASE( mQuery );
|
||||
}
|
||||
|
||||
void GFXD3D9QueryFence::resurrect()
|
||||
{
|
||||
// Recreate the query
|
||||
if( mQuery == NULL )
|
||||
{
|
||||
HRESULT hRes = static_cast<GFXD3D9Device *>( mDevice )->getDevice()->CreateQuery( D3DQUERYTYPE_EVENT, &mQuery );
|
||||
|
||||
AssertFatal( hRes != D3DERR_NOTAVAILABLE, "GFXD3D9QueryFence::resurrect - Hardware does not support D3D9 Queries, this should be caught before this fence type is created" );
|
||||
AssertISV( hRes != E_OUTOFMEMORY, "GFXD3D9QueryFence::resurrect - Out of memory" );
|
||||
}
|
||||
}
|
||||
|
||||
const String GFXD3D9QueryFence::describeSelf() const
|
||||
{
|
||||
// We've got nothing
|
||||
return String();
|
||||
}
|
||||
52
Engine/source/gfx/D3D9/gfxD3D9QueryFence.h
Normal file
52
Engine/source/gfx/D3D9/gfxD3D9QueryFence.h
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GFX_D3D9_QUERYFENCE_H_
|
||||
#define _GFX_D3D9_QUERYFENCE_H_
|
||||
|
||||
#include "gfx/gfxFence.h"
|
||||
#include "gfx/gfxResource.h"
|
||||
|
||||
struct IDirect3DQuery9;
|
||||
|
||||
class GFXD3D9QueryFence : public GFXFence
|
||||
{
|
||||
private:
|
||||
mutable IDirect3DQuery9 *mQuery;
|
||||
|
||||
public:
|
||||
GFXD3D9QueryFence( GFXDevice *device ) : GFXFence( device ), mQuery( NULL ) {};
|
||||
virtual ~GFXD3D9QueryFence();
|
||||
|
||||
virtual void issue();
|
||||
virtual FenceStatus getStatus() const;
|
||||
virtual void block();
|
||||
|
||||
|
||||
|
||||
// GFXResource interface
|
||||
virtual void zombify();
|
||||
virtual void resurrect();
|
||||
virtual const String describeSelf() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
1441
Engine/source/gfx/D3D9/gfxD3D9Shader.cpp
Normal file
1441
Engine/source/gfx/D3D9/gfxD3D9Shader.cpp
Normal file
File diff suppressed because it is too large
Load diff
287
Engine/source/gfx/D3D9/gfxD3D9Shader.h
Normal file
287
Engine/source/gfx/D3D9/gfxD3D9Shader.h
Normal file
|
|
@ -0,0 +1,287 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GFXD3D9SHADER_H_
|
||||
#define _GFXD3D9SHADER_H_
|
||||
|
||||
#ifndef _PATH_H_
|
||||
#include "core/util/path.h"
|
||||
#endif
|
||||
#ifndef _TDICTIONARY_H_
|
||||
#include "core/util/tDictionary.h"
|
||||
#endif
|
||||
#ifndef _GFXSHADER_H_
|
||||
#include "gfx/gfxShader.h"
|
||||
#endif
|
||||
#ifndef _GFXRESOURCE_H_
|
||||
#include "gfx/gfxResource.h"
|
||||
#endif
|
||||
#ifndef _GENERICCONSTBUFFER_H_
|
||||
#include "gfx/genericConstBuffer.h"
|
||||
#endif
|
||||
|
||||
|
||||
class GFXD3D9Shader;
|
||||
struct IDirect3DVertexShader9;
|
||||
struct IDirect3DPixelShader9;
|
||||
struct IDirect3DDevice9;
|
||||
struct ID3DXConstantTable;
|
||||
struct ID3DXBuffer;
|
||||
struct _D3DXMACRO;
|
||||
|
||||
|
||||
class GFXD3D9ShaderBufferLayout : public GenericConstBufferLayout
|
||||
{
|
||||
protected:
|
||||
/// Set a matrix, given a base pointer
|
||||
virtual bool setMatrix(const ParamDesc& pd, const GFXShaderConstType constType, const U32 size, const void* data, U8* basePointer);
|
||||
};
|
||||
|
||||
|
||||
/// The D3D9 implementation of a shader constant handle.
|
||||
class GFXD3D9ShaderConstHandle : public GFXShaderConstHandle
|
||||
{
|
||||
public:
|
||||
|
||||
// GFXShaderConstHandle
|
||||
const String& getName() const;
|
||||
GFXShaderConstType getType() const;
|
||||
U32 getArraySize() const;
|
||||
|
||||
WeakRefPtr<GFXD3D9Shader> mShader;
|
||||
|
||||
bool mVertexConstant;
|
||||
GenericConstBufferLayout::ParamDesc mVertexHandle;
|
||||
bool mPixelConstant;
|
||||
GenericConstBufferLayout::ParamDesc mPixelHandle;
|
||||
|
||||
/// Is true if this constant is for hardware mesh instancing.
|
||||
///
|
||||
/// Note: We currently store its settings in mPixelHandle.
|
||||
///
|
||||
bool mInstancingConstant;
|
||||
|
||||
void setValid( bool valid ) { mValid = valid; }
|
||||
S32 getSamplerRegister() const;
|
||||
|
||||
// Returns true if this is a handle to a sampler register.
|
||||
bool isSampler() const
|
||||
{
|
||||
return ( mPixelConstant && mPixelHandle.constType >= GFXSCT_Sampler ) ||
|
||||
( mVertexConstant && mVertexHandle.constType >= GFXSCT_Sampler );
|
||||
}
|
||||
|
||||
/// Restore to uninitialized state.
|
||||
void clear()
|
||||
{
|
||||
mShader = NULL;
|
||||
mVertexConstant = false;
|
||||
mPixelConstant = false;
|
||||
mInstancingConstant = false;
|
||||
mVertexHandle.clear();
|
||||
mPixelHandle.clear();
|
||||
mValid = false;
|
||||
}
|
||||
|
||||
GFXD3D9ShaderConstHandle();
|
||||
};
|
||||
|
||||
|
||||
/// The D3D9 implementation of a shader constant buffer.
|
||||
class GFXD3D9ShaderConstBuffer : public GFXShaderConstBuffer
|
||||
{
|
||||
friend class GFXD3D9Shader;
|
||||
|
||||
public:
|
||||
|
||||
GFXD3D9ShaderConstBuffer( GFXD3D9Shader* shader,
|
||||
GFXD3D9ShaderBufferLayout* vertexLayoutF,
|
||||
GFXD3D9ShaderBufferLayout* vertexLayoutI,
|
||||
GFXD3D9ShaderBufferLayout* pixelLayoutF,
|
||||
GFXD3D9ShaderBufferLayout* pixelLayoutI );
|
||||
virtual ~GFXD3D9ShaderConstBuffer();
|
||||
|
||||
/// Called by GFXD3D9Device to activate this buffer.
|
||||
/// @param mPrevShaderBuffer The previously active buffer
|
||||
void activate( GFXD3D9ShaderConstBuffer *prevShaderBuffer );
|
||||
|
||||
/// Used internally by GXD3D9ShaderConstBuffer to determine if it's dirty.
|
||||
bool isDirty();
|
||||
|
||||
/// Called from GFXD3D9Shader when constants have changed and need
|
||||
/// to be the shader this buffer references is reloaded.
|
||||
void onShaderReload( GFXD3D9Shader *shader );
|
||||
|
||||
// GFXShaderConstBuffer
|
||||
virtual GFXShader* getShader();
|
||||
virtual void set(GFXShaderConstHandle* handle, const F32 fv);
|
||||
virtual void set(GFXShaderConstHandle* handle, const Point2F& fv);
|
||||
virtual void set(GFXShaderConstHandle* handle, const Point3F& fv);
|
||||
virtual void set(GFXShaderConstHandle* handle, const Point4F& fv);
|
||||
virtual void set(GFXShaderConstHandle* handle, const PlaneF& fv);
|
||||
virtual void set(GFXShaderConstHandle* handle, const ColorF& fv);
|
||||
virtual void set(GFXShaderConstHandle* handle, const S32 f);
|
||||
virtual void set(GFXShaderConstHandle* handle, const Point2I& fv);
|
||||
virtual void set(GFXShaderConstHandle* handle, const Point3I& fv);
|
||||
virtual void set(GFXShaderConstHandle* handle, const Point4I& fv);
|
||||
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<F32>& fv);
|
||||
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point2F>& fv);
|
||||
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point3F>& fv);
|
||||
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point4F>& fv);
|
||||
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<S32>& fv);
|
||||
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point2I>& fv);
|
||||
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point3I>& fv);
|
||||
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point4I>& fv);
|
||||
virtual void set(GFXShaderConstHandle* handle, const MatrixF& mat, const GFXShaderConstType matType = GFXSCT_Float4x4);
|
||||
virtual void set(GFXShaderConstHandle* handle, const MatrixF* mat, const U32 arraySize, const GFXShaderConstType matrixType = GFXSCT_Float4x4);
|
||||
|
||||
// GFXResource
|
||||
virtual const String describeSelf() const;
|
||||
virtual void zombify();
|
||||
virtual void resurrect();
|
||||
|
||||
protected:
|
||||
|
||||
template<class T>
|
||||
inline void SET_CONSTANT( GFXShaderConstHandle* handle,
|
||||
const T& fv,
|
||||
GenericConstBuffer *vBuffer,
|
||||
GenericConstBuffer *pBuffer );
|
||||
|
||||
/// A cached direct pointer to the device.
|
||||
IDirect3DDevice9 *mDevice;
|
||||
|
||||
/// We keep a weak reference to the shader
|
||||
/// because it will often be deleted.
|
||||
WeakRefPtr<GFXD3D9Shader> mShader;
|
||||
|
||||
GFXD3D9ShaderBufferLayout* mVertexConstBufferLayoutF;
|
||||
GenericConstBuffer* mVertexConstBufferF;
|
||||
GFXD3D9ShaderBufferLayout* mPixelConstBufferLayoutF;
|
||||
GenericConstBuffer* mPixelConstBufferF;
|
||||
GFXD3D9ShaderBufferLayout* mVertexConstBufferLayoutI;
|
||||
GenericConstBuffer* mVertexConstBufferI;
|
||||
GFXD3D9ShaderBufferLayout* mPixelConstBufferLayoutI;
|
||||
GenericConstBuffer* mPixelConstBufferI;
|
||||
};
|
||||
|
||||
|
||||
class _gfxD3DXInclude;
|
||||
typedef StrongRefPtr<_gfxD3DXInclude> _gfxD3DXIncludeRef;
|
||||
|
||||
/// The D3D9 implementation of a shader.
|
||||
class GFXD3D9Shader : public GFXShader
|
||||
{
|
||||
friend class GFXD3D9Device;
|
||||
friend class GFX360Device;
|
||||
friend class GFXD3D9ShaderConstBuffer;
|
||||
friend class GFX360ShaderConstBuffer;
|
||||
public:
|
||||
typedef Map<String, GFXD3D9ShaderConstHandle*> HandleMap;
|
||||
|
||||
GFXD3D9Shader();
|
||||
virtual ~GFXD3D9Shader();
|
||||
|
||||
// GFXShader
|
||||
virtual GFXShaderConstBufferRef allocConstBuffer();
|
||||
virtual const Vector<GFXShaderConstDesc>& getShaderConstDesc() const;
|
||||
virtual GFXShaderConstHandle* getShaderConstHandle(const String& name);
|
||||
virtual U32 getAlignmentValue(const GFXShaderConstType constType) const;
|
||||
virtual bool getDisassembly( String &outStr ) const;
|
||||
|
||||
// GFXResource
|
||||
virtual void zombify();
|
||||
virtual void resurrect();
|
||||
|
||||
protected:
|
||||
|
||||
virtual bool _init();
|
||||
|
||||
static const U32 smCompiledShaderTag;
|
||||
|
||||
IDirect3DDevice9 *mD3D9Device;
|
||||
|
||||
IDirect3DVertexShader9 *mVertShader;
|
||||
IDirect3DPixelShader9 *mPixShader;
|
||||
|
||||
GFXD3D9ShaderBufferLayout* mVertexConstBufferLayoutF;
|
||||
GFXD3D9ShaderBufferLayout* mPixelConstBufferLayoutF;
|
||||
GFXD3D9ShaderBufferLayout* mVertexConstBufferLayoutI;
|
||||
GFXD3D9ShaderBufferLayout* mPixelConstBufferLayoutI;
|
||||
|
||||
static _gfxD3DXIncludeRef smD3DXInclude;
|
||||
|
||||
HandleMap mHandles;
|
||||
|
||||
/// The shader disassembly from DX when this shader is compiled.
|
||||
/// We only store this data in non-release builds.
|
||||
String mDissasembly;
|
||||
|
||||
/// Vector of sampler type descriptions consolidated from _compileShader.
|
||||
Vector<GFXShaderConstDesc> mSamplerDescriptions;
|
||||
|
||||
/// Vector of descriptions (consolidated for the getShaderConstDesc call)
|
||||
Vector<GFXShaderConstDesc> mShaderConsts;
|
||||
|
||||
// These two functions are used when compiling shaders from hlsl
|
||||
virtual bool _compileShader( const Torque::Path &filePath,
|
||||
const String &target,
|
||||
const _D3DXMACRO *defines,
|
||||
GenericConstBufferLayout *bufferLayoutF,
|
||||
GenericConstBufferLayout *bufferLayoutI,
|
||||
Vector<GFXShaderConstDesc> &samplerDescriptions );
|
||||
|
||||
void _getShaderConstants( ID3DXConstantTable* table,
|
||||
GenericConstBufferLayout *bufferLayoutF,
|
||||
GenericConstBufferLayout *bufferLayoutI,
|
||||
Vector<GFXShaderConstDesc> &samplerDescriptions );
|
||||
|
||||
bool _saveCompiledOutput( const Torque::Path &filePath,
|
||||
ID3DXBuffer *buffer,
|
||||
GenericConstBufferLayout *bufferLayoutF,
|
||||
GenericConstBufferLayout *bufferLayoutI,
|
||||
Vector<GFXShaderConstDesc> &samplerDescriptions );
|
||||
|
||||
// Loads precompiled shaders
|
||||
bool _loadCompiledOutput( const Torque::Path &filePath,
|
||||
const String &target,
|
||||
GenericConstBufferLayout *bufferLayoutF,
|
||||
GenericConstBufferLayout *bufferLayoutI,
|
||||
Vector<GFXShaderConstDesc> &samplerDescriptions );
|
||||
|
||||
// This is used in both cases
|
||||
virtual void _buildShaderConstantHandles( GenericConstBufferLayout *layout, bool vertexConst );
|
||||
|
||||
virtual void _buildSamplerShaderConstantHandles( Vector<GFXShaderConstDesc> &samplerDescriptions );
|
||||
|
||||
/// Used to build the instancing shader constants from
|
||||
/// the instancing vertex format.
|
||||
void _buildInstancingShaderConstantHandles();
|
||||
};
|
||||
|
||||
inline bool GFXD3D9Shader::getDisassembly( String &outStr ) const
|
||||
{
|
||||
outStr = mDissasembly;
|
||||
return ( outStr.isNotEmpty() );
|
||||
}
|
||||
|
||||
#endif // _GFXD3D9SHADER_H_
|
||||
203
Engine/source/gfx/D3D9/gfxD3D9StateBlock.cpp
Normal file
203
Engine/source/gfx/D3D9/gfxD3D9StateBlock.cpp
Normal file
|
|
@ -0,0 +1,203 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "gfx/gfxDevice.h"
|
||||
|
||||
#if defined(TORQUE_OS_XENON)
|
||||
# include <xtl.h>
|
||||
#else
|
||||
# include <d3d9.h>
|
||||
#endif
|
||||
|
||||
#include "gfx/D3D9/gfxD3D9StateBlock.h"
|
||||
#include "gfx/D3D9/gfxD3D9EnumTranslate.h"
|
||||
|
||||
GFXD3D9StateBlock::GFXD3D9StateBlock(const GFXStateBlockDesc& desc, LPDIRECT3DDEVICE9 d3dDevice)
|
||||
{
|
||||
AssertFatal(d3dDevice, "Invalid mD3DDevice!");
|
||||
|
||||
mDesc = desc;
|
||||
mCachedHashValue = desc.getHashValue();
|
||||
mD3DDevice = d3dDevice;
|
||||
|
||||
// Color writes
|
||||
mColorMask = 0;
|
||||
mColorMask |= ( mDesc.colorWriteRed ? GFXCOLORWRITEENABLE_RED : 0 );
|
||||
mColorMask |= ( mDesc.colorWriteGreen ? GFXCOLORWRITEENABLE_GREEN : 0 );
|
||||
mColorMask |= ( mDesc.colorWriteBlue ? GFXCOLORWRITEENABLE_BLUE : 0 );
|
||||
mColorMask |= ( mDesc.colorWriteAlpha ? GFXCOLORWRITEENABLE_ALPHA : 0 );
|
||||
|
||||
// Z*bias
|
||||
mZBias = *((U32*)&mDesc.zBias);
|
||||
mZSlopeBias = *((U32*)&mDesc.zSlopeBias);
|
||||
}
|
||||
|
||||
GFXD3D9StateBlock::~GFXD3D9StateBlock()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// Returns the hash value of the desc that created this block
|
||||
U32 GFXD3D9StateBlock::getHashValue() const
|
||||
{
|
||||
return mCachedHashValue;
|
||||
}
|
||||
|
||||
/// Returns a GFXStateBlockDesc that this block represents
|
||||
const GFXStateBlockDesc& GFXD3D9StateBlock::getDesc() const
|
||||
{
|
||||
return mDesc;
|
||||
}
|
||||
|
||||
/// Called by D3D9 device to active this state block.
|
||||
/// @param oldState The current state, used to make sure we don't set redundant states on the device. Pass NULL to reset all states.
|
||||
void GFXD3D9StateBlock::activate(GFXD3D9StateBlock* oldState)
|
||||
{
|
||||
PROFILE_SCOPE( GFXD3D9StateBlock_Activate );
|
||||
|
||||
// Little macro to save some typing, SD = state diff, checks for null source state block, then
|
||||
// checks to see if the states differ
|
||||
#if defined(TORQUE_OS_XENON)
|
||||
#define SD(x, y) if (!oldState || oldState->mDesc.x != mDesc.x) \
|
||||
mD3DDevice->SetRenderState_Inline(y, mDesc.x)
|
||||
|
||||
// Same as above, but allows you to set the data
|
||||
#define SDD(x, y, z) if (!oldState || oldState->mDesc.x != mDesc.x) \
|
||||
mD3DDevice->SetRenderState_Inline(y, z)
|
||||
#else
|
||||
#define SD(x, y) if (!oldState || oldState->mDesc.x != mDesc.x) \
|
||||
mD3DDevice->SetRenderState(y, mDesc.x)
|
||||
|
||||
// Same as above, but allows you to set the data
|
||||
#define SDD(x, y, z) if (!oldState || oldState->mDesc.x != mDesc.x) \
|
||||
mD3DDevice->SetRenderState(y, z)
|
||||
#endif
|
||||
|
||||
// Blending
|
||||
SD(blendEnable, D3DRS_ALPHABLENDENABLE);
|
||||
SDD(blendSrc, D3DRS_SRCBLEND, GFXD3D9Blend[mDesc.blendSrc]);
|
||||
SDD(blendDest, D3DRS_DESTBLEND, GFXD3D9Blend[mDesc.blendDest]);
|
||||
SDD(blendOp, D3DRS_BLENDOP, GFXD3D9BlendOp[mDesc.blendOp]);
|
||||
|
||||
// Separate alpha blending
|
||||
SD(separateAlphaBlendEnable, D3DRS_SEPARATEALPHABLENDENABLE);
|
||||
SDD(separateAlphaBlendSrc, D3DRS_SRCBLENDALPHA, GFXD3D9Blend[mDesc.separateAlphaBlendSrc]);
|
||||
SDD(separateAlphaBlendDest, D3DRS_DESTBLENDALPHA, GFXD3D9Blend[mDesc.separateAlphaBlendDest]);
|
||||
SDD(separateAlphaBlendOp, D3DRS_BLENDOPALPHA, GFXD3D9BlendOp[mDesc.separateAlphaBlendOp]);
|
||||
|
||||
// Alpha test
|
||||
SD(alphaTestEnable, D3DRS_ALPHATESTENABLE);
|
||||
SDD(alphaTestFunc, D3DRS_ALPHAFUNC, GFXD3D9CmpFunc[mDesc.alphaTestFunc]);
|
||||
SD(alphaTestRef, D3DRS_ALPHAREF);
|
||||
|
||||
// Color writes
|
||||
if ((oldState == NULL) || (mColorMask != oldState->mColorMask))
|
||||
mD3DDevice->SetRenderState(D3DRS_COLORWRITEENABLE, mColorMask);
|
||||
|
||||
// Culling
|
||||
SDD(cullMode, D3DRS_CULLMODE, GFXD3D9CullMode[mDesc.cullMode]);
|
||||
|
||||
// Depth
|
||||
SD(zEnable, D3DRS_ZENABLE);
|
||||
SD(zWriteEnable, D3DRS_ZWRITEENABLE);
|
||||
SDD(zFunc, D3DRS_ZFUNC, GFXD3D9CmpFunc[mDesc.zFunc]);
|
||||
if ((!oldState) || (mZBias != oldState->mZBias))
|
||||
mD3DDevice->SetRenderState(D3DRS_DEPTHBIAS, mZBias);
|
||||
if ((!oldState) || (mZSlopeBias != oldState->mZSlopeBias))
|
||||
mD3DDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, mZSlopeBias);
|
||||
|
||||
// Stencil
|
||||
SD(stencilEnable, D3DRS_STENCILENABLE);
|
||||
SDD(stencilFailOp, D3DRS_STENCILFAIL, GFXD3D9StencilOp[mDesc.stencilFailOp]);
|
||||
SDD(stencilZFailOp, D3DRS_STENCILZFAIL, GFXD3D9StencilOp[mDesc.stencilZFailOp]);
|
||||
SDD(stencilPassOp, D3DRS_STENCILPASS, GFXD3D9StencilOp[mDesc.stencilPassOp]);
|
||||
SDD(stencilFunc, D3DRS_STENCILFUNC, GFXD3D9CmpFunc[mDesc.stencilFunc]);
|
||||
SD(stencilRef, D3DRS_STENCILREF);
|
||||
SD(stencilMask, D3DRS_STENCILMASK);
|
||||
SD(stencilWriteMask, D3DRS_STENCILWRITEMASK);
|
||||
SDD(fillMode, D3DRS_FILLMODE, GFXD3D9FillMode[mDesc.fillMode]);
|
||||
#if !defined(TORQUE_OS_XENON)
|
||||
SD(ffLighting, D3DRS_LIGHTING);
|
||||
SD(vertexColorEnable, D3DRS_COLORVERTEX);
|
||||
|
||||
static DWORD swzTemp;
|
||||
getOwningDevice()->getDeviceSwizzle32()->ToBuffer( &swzTemp, &mDesc.textureFactor, sizeof(ColorI) );
|
||||
SDD(textureFactor, D3DRS_TEXTUREFACTOR, swzTemp);
|
||||
#endif
|
||||
#undef SD
|
||||
#undef SDD
|
||||
|
||||
|
||||
// NOTE: Samplers and Stages are different things.
|
||||
//
|
||||
// The Stages were for fixed function blending. When using shaders
|
||||
// calling SetTextureStageState() is a complete waste of time. In
|
||||
// fact if this function rises to the top of profiles we should
|
||||
// refactor stateblocks to seperate the two.
|
||||
//
|
||||
// Samplers are used by both fixed function and shaders, but the
|
||||
// number of samplers is limited by shader model.
|
||||
#if !defined(TORQUE_OS_XENON)
|
||||
|
||||
#define TSS(x, y, z) if (!oldState || oldState->mDesc.samplers[i].x != mDesc.samplers[i].x) \
|
||||
mD3DDevice->SetTextureStageState(i, y, z)
|
||||
for ( U32 i = 0; i < 8; i++ )
|
||||
{
|
||||
TSS(textureColorOp, D3DTSS_COLOROP, GFXD3D9TextureOp[mDesc.samplers[i].textureColorOp]);
|
||||
TSS(colorArg1, D3DTSS_COLORARG1, mDesc.samplers[i].colorArg1);
|
||||
TSS(colorArg2, D3DTSS_COLORARG2, mDesc.samplers[i].colorArg2);
|
||||
TSS(colorArg3, D3DTSS_COLORARG0, mDesc.samplers[i].colorArg3);
|
||||
TSS(alphaOp, D3DTSS_ALPHAOP, GFXD3D9TextureOp[mDesc.samplers[i].alphaOp]);
|
||||
TSS(alphaArg1, D3DTSS_ALPHAARG1, mDesc.samplers[i].alphaArg1);
|
||||
TSS(alphaArg2, D3DTSS_ALPHAARG2, mDesc.samplers[i].alphaArg2);
|
||||
TSS(alphaArg3, D3DTSS_ALPHAARG0, mDesc.samplers[i].alphaArg3);
|
||||
TSS(textureTransform, D3DTSS_TEXTURETRANSFORMFLAGS, mDesc.samplers[i].textureTransform);
|
||||
TSS(resultArg, D3DTSS_RESULTARG, mDesc.samplers[i].resultArg);
|
||||
}
|
||||
#undef TSS
|
||||
#endif
|
||||
|
||||
#if defined(TORQUE_OS_XENON)
|
||||
#define SS(x, y, z) if (!oldState || oldState->mDesc.samplers[i].x != mDesc.samplers[i].x) \
|
||||
mD3DDevice->SetSamplerState_Inline(i, y, z)
|
||||
#else
|
||||
#define SS(x, y, z) if (!oldState || oldState->mDesc.samplers[i].x != mDesc.samplers[i].x) \
|
||||
mD3DDevice->SetSamplerState(i, y, z)
|
||||
#endif
|
||||
for ( U32 i = 0; i < getOwningDevice()->getNumSamplers(); i++ )
|
||||
{
|
||||
SS(minFilter, D3DSAMP_MINFILTER, GFXD3D9TextureFilter[mDesc.samplers[i].minFilter]);
|
||||
SS(magFilter, D3DSAMP_MAGFILTER, GFXD3D9TextureFilter[mDesc.samplers[i].magFilter]);
|
||||
SS(mipFilter, D3DSAMP_MIPFILTER, GFXD3D9TextureFilter[mDesc.samplers[i].mipFilter]);
|
||||
|
||||
F32 bias = mDesc.samplers[i].mipLODBias;
|
||||
DWORD dwBias = *( (LPDWORD)(&bias) );
|
||||
SS(mipLODBias, D3DSAMP_MIPMAPLODBIAS, dwBias);
|
||||
|
||||
SS(maxAnisotropy, D3DSAMP_MAXANISOTROPY, mDesc.samplers[i].maxAnisotropy);
|
||||
|
||||
SS(addressModeU, D3DSAMP_ADDRESSU, GFXD3D9TextureAddress[mDesc.samplers[i].addressModeU]);
|
||||
SS(addressModeV, D3DSAMP_ADDRESSV, GFXD3D9TextureAddress[mDesc.samplers[i].addressModeV]);
|
||||
SS(addressModeW, D3DSAMP_ADDRESSW, GFXD3D9TextureAddress[mDesc.samplers[i].addressModeW]);
|
||||
}
|
||||
#undef SS
|
||||
}
|
||||
73
Engine/source/gfx/D3D9/gfxD3D9StateBlock.h
Normal file
73
Engine/source/gfx/D3D9/gfxD3D9StateBlock.h
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef _GFXD3D9STATEBLOCK_H_
|
||||
#define _GFXD3D9STATEBLOCK_H_
|
||||
|
||||
#ifndef _GFXSTATEBLOCK_H_
|
||||
#include "gfx/gfxStateBlock.h"
|
||||
#endif
|
||||
|
||||
struct IDirect3DDevice9;
|
||||
class GFXD3D9StateBlock : public GFXStateBlock
|
||||
{
|
||||
public:
|
||||
//
|
||||
// GFXD3D9StateBlock interface
|
||||
//
|
||||
|
||||
GFXD3D9StateBlock(const GFXStateBlockDesc& desc, IDirect3DDevice9 *d3dDevice);
|
||||
virtual ~GFXD3D9StateBlock();
|
||||
|
||||
/// Called by D3D9 device to active this state block.
|
||||
/// @param oldState The current state, used to make sure we don't set redundant states on the device. Pass NULL to reset all states.
|
||||
void activate(GFXD3D9StateBlock* oldState);
|
||||
|
||||
|
||||
//
|
||||
// GFXStateBlock interface
|
||||
//
|
||||
|
||||
/// Returns the hash value of the desc that created this block
|
||||
virtual U32 getHashValue() const;
|
||||
|
||||
/// Returns a GFXStateBlockDesc that this block represents
|
||||
virtual const GFXStateBlockDesc& getDesc() const;
|
||||
|
||||
//
|
||||
// GFXResource
|
||||
//
|
||||
virtual void zombify() { }
|
||||
/// When called the resource should restore all device sensitive information destroyed by zombify()
|
||||
virtual void resurrect() { }
|
||||
private:
|
||||
GFXStateBlockDesc mDesc;
|
||||
U32 mCachedHashValue;
|
||||
IDirect3DDevice9 *mD3DDevice; ///< Handle for D3DDevice
|
||||
// Cached D3D specific things, these are "calculated" from GFXStateBlock
|
||||
U32 mColorMask;
|
||||
U32 mZBias;
|
||||
U32 mZSlopeBias;
|
||||
};
|
||||
|
||||
typedef StrongRefPtr<GFXD3D9StateBlock> GFXD3D9StateBlockRef;
|
||||
|
||||
#endif
|
||||
638
Engine/source/gfx/D3D9/gfxD3D9TextureManager.cpp
Normal file
638
Engine/source/gfx/D3D9/gfxD3D9TextureManager.cpp
Normal file
|
|
@ -0,0 +1,638 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable: 4996)
|
||||
#endif
|
||||
|
||||
#include "gfx/D3D9/gfxD3D9Device.h"
|
||||
#include "gfx/D3D9/gfxD3D9EnumTranslate.h"
|
||||
#include "gfx/bitmap/bitmapUtils.h"
|
||||
#include "gfx/gfxCardProfile.h"
|
||||
#include "core/strings/unicode.h"
|
||||
#include "core/util/swizzle.h"
|
||||
#include "core/util/safeDelete.h"
|
||||
#include "console/console.h"
|
||||
#include "core/resourceManager.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Utility function, valid only in this file
|
||||
#ifdef D3D_TEXTURE_SPEW
|
||||
U32 GFXD3D9TextureObject::mTexCount = 0;
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
GFXD3D9TextureManager::GFXD3D9TextureManager( LPDIRECT3DDEVICE9 d3ddevice )
|
||||
{
|
||||
mD3DDevice = d3ddevice;
|
||||
dMemset( mCurTexSet, 0, sizeof( mCurTexSet ) );
|
||||
mD3DDevice->GetDeviceCaps(&mDeviceCaps);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
GFXD3D9TextureManager::~GFXD3D9TextureManager()
|
||||
{
|
||||
// Destroy texture table now so just in case some texture objects
|
||||
// are still left, we don't crash on a pure virtual method call.
|
||||
SAFE_DELETE_ARRAY( mHashTable );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// _innerCreateTexture
|
||||
//-----------------------------------------------------------------------------
|
||||
void GFXD3D9TextureManager::_innerCreateTexture( GFXD3D9TextureObject *retTex,
|
||||
U32 height,
|
||||
U32 width,
|
||||
U32 depth,
|
||||
GFXFormat format,
|
||||
GFXTextureProfile *profile,
|
||||
U32 numMipLevels,
|
||||
bool forceMips,
|
||||
S32 antialiasLevel)
|
||||
{
|
||||
GFXD3D9Device* d3d = static_cast<GFXD3D9Device*>(GFX);
|
||||
|
||||
// Some relevant helper information...
|
||||
bool supportsAutoMips = GFX->getCardProfiler()->queryProfile("autoMipMapLevel", true);
|
||||
|
||||
DWORD usage = 0; // 0, D3DUSAGE_RENDERTARGET, or D3DUSAGE_DYNAMIC
|
||||
D3DPOOL pool = D3DPOOL_DEFAULT;
|
||||
|
||||
retTex->mProfile = profile;
|
||||
|
||||
D3DFORMAT d3dTextureFormat = GFXD3D9TextureFormat[format];
|
||||
|
||||
#ifndef TORQUE_OS_XENON
|
||||
if( retTex->mProfile->isDynamic() )
|
||||
{
|
||||
usage = D3DUSAGE_DYNAMIC;
|
||||
}
|
||||
else
|
||||
{
|
||||
usage = 0;
|
||||
pool = d3d->isD3D9Ex() ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED;
|
||||
}
|
||||
|
||||
if( retTex->mProfile->isRenderTarget() )
|
||||
{
|
||||
pool = D3DPOOL_DEFAULT;
|
||||
usage |= D3DUSAGE_RENDERTARGET;
|
||||
}
|
||||
|
||||
if(retTex->mProfile->isZTarget())
|
||||
{
|
||||
usage |= D3DUSAGE_DEPTHSTENCIL;
|
||||
pool = D3DPOOL_DEFAULT;
|
||||
}
|
||||
|
||||
if( retTex->mProfile->isSystemMemory() )
|
||||
{
|
||||
pool = D3DPOOL_SYSTEMMEM;
|
||||
}
|
||||
|
||||
if( supportsAutoMips &&
|
||||
!forceMips &&
|
||||
!retTex->mProfile->isSystemMemory() &&
|
||||
numMipLevels == 0 &&
|
||||
!(depth > 0) )
|
||||
{
|
||||
usage |= D3DUSAGE_AUTOGENMIPMAP;
|
||||
}
|
||||
#else
|
||||
if(retTex->mProfile->isRenderTarget())
|
||||
{
|
||||
d3dTextureFormat = (D3DFORMAT)MAKELEFMT(d3dTextureFormat);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Set the managed flag...
|
||||
retTex->isManaged = (pool == D3DPOOL_MANAGED) || d3d->isD3D9Ex();
|
||||
|
||||
if( depth > 0 )
|
||||
{
|
||||
#ifdef TORQUE_OS_XENON
|
||||
D3D9Assert( mD3DDevice->CreateVolumeTexture( width, height, depth, numMipLevels, 0 /* usage ignored on the 360 */,
|
||||
d3dTextureFormat, pool, retTex->get3DTexPtr(), NULL), "Failed to create volume texture" );
|
||||
#else
|
||||
D3D9Assert(
|
||||
GFXD3DX.D3DXCreateVolumeTexture(
|
||||
mD3DDevice,
|
||||
width,
|
||||
height,
|
||||
depth,
|
||||
numMipLevels,
|
||||
usage,
|
||||
d3dTextureFormat,
|
||||
pool,
|
||||
retTex->get3DTexPtr()
|
||||
), "GFXD3D9TextureManager::_createTexture - failed to create volume texture!"
|
||||
);
|
||||
#endif
|
||||
|
||||
retTex->mTextureSize.set( width, height, depth );
|
||||
retTex->mMipLevels = retTex->get3DTex()->GetLevelCount();
|
||||
// required for 3D texture support - John Kabus
|
||||
retTex->mFormat = format;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef TORQUE_OS_XENON
|
||||
D3D9Assert( mD3DDevice->CreateTexture(width, height, numMipLevels, usage, d3dTextureFormat, pool, retTex->get2DTexPtr(), NULL), "Failed to create texture" );
|
||||
retTex->mMipLevels = retTex->get2DTex()->GetLevelCount();
|
||||
#else
|
||||
// Figure out AA settings for depth and render targets
|
||||
D3DMULTISAMPLE_TYPE mstype;
|
||||
DWORD mslevel;
|
||||
|
||||
switch (antialiasLevel)
|
||||
{
|
||||
case 0 :
|
||||
mstype = D3DMULTISAMPLE_NONE;
|
||||
mslevel = 0;
|
||||
break;
|
||||
case AA_MATCH_BACKBUFFER :
|
||||
mstype = d3d->getMultisampleType();
|
||||
mslevel = d3d->getMultisampleLevel();
|
||||
break;
|
||||
default :
|
||||
{
|
||||
mstype = D3DMULTISAMPLE_NONMASKABLE;
|
||||
mslevel = antialiasLevel;
|
||||
#ifdef TORQUE_DEBUG
|
||||
DWORD MaxSampleQualities;
|
||||
d3d->getD3D()->CheckDeviceMultiSampleType(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3dTextureFormat, FALSE, D3DMULTISAMPLE_NONMASKABLE, &MaxSampleQualities);
|
||||
AssertFatal(mslevel < MaxSampleQualities, "Invalid AA level!");
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
bool fastCreate = true;
|
||||
// Check for power of 2 textures - this is a problem with FX 5xxx cards
|
||||
// with current drivers - 3/2/05
|
||||
if( !isPow2(width) || !isPow2(height) )
|
||||
{
|
||||
fastCreate = false;
|
||||
}
|
||||
|
||||
if(retTex->mProfile->isZTarget())
|
||||
{
|
||||
D3D9Assert(mD3DDevice->CreateDepthStencilSurface(width, height, d3dTextureFormat,
|
||||
mstype, mslevel, retTex->mProfile->canDiscard(), retTex->getSurfacePtr(), NULL), "Failed to create Z surface" );
|
||||
|
||||
retTex->mFormat = format; // Assigning format like this should be fine.
|
||||
}
|
||||
else
|
||||
{
|
||||
// Try to create the texture directly - should gain us a bit in high
|
||||
// performance cases where we know we're creating good stuff and we
|
||||
// don't want to bother with D3DX - slow function.
|
||||
HRESULT res = D3DERR_INVALIDCALL;
|
||||
if( fastCreate )
|
||||
{
|
||||
res = mD3DDevice->CreateTexture(width, height, numMipLevels, usage, d3dTextureFormat, pool, retTex->get2DTexPtr(), NULL);
|
||||
}
|
||||
|
||||
if( !fastCreate || (res != D3D_OK) )
|
||||
{
|
||||
D3D9Assert(
|
||||
GFXD3DX.D3DXCreateTexture(
|
||||
mD3DDevice,
|
||||
width,
|
||||
height,
|
||||
numMipLevels,
|
||||
usage,
|
||||
d3dTextureFormat,
|
||||
pool,
|
||||
retTex->get2DTexPtr()
|
||||
), "GFXD3D9TextureManager::_createTexture - failed to create texture!"
|
||||
);
|
||||
}
|
||||
|
||||
// If this is a render target, and it wants AA or wants to match the backbuffer (for example, to share the z)
|
||||
// Check the caps though, if we can't stretchrect between textures, use the old RT method. (Which hopefully means
|
||||
// that they can't force AA on us as well.)
|
||||
if (retTex->mProfile->isRenderTarget() && mslevel != 0 && (mDeviceCaps.Caps2 && D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES))
|
||||
{
|
||||
D3D9Assert(mD3DDevice->CreateRenderTarget(width, height, d3dTextureFormat,
|
||||
mstype, mslevel, false, retTex->getSurfacePtr(), NULL),
|
||||
"GFXD3D9TextureManager::_createTexture - unable to create render target");
|
||||
}
|
||||
|
||||
// All done!
|
||||
retTex->mMipLevels = retTex->get2DTex()->GetLevelCount();
|
||||
}
|
||||
#endif
|
||||
|
||||
// Get the actual size of the texture...
|
||||
D3DSURFACE_DESC probeDesc;
|
||||
ZeroMemory(&probeDesc, sizeof probeDesc);
|
||||
|
||||
if( retTex->get2DTex() != NULL )
|
||||
D3D9Assert( retTex->get2DTex()->GetLevelDesc( 0, &probeDesc ), "Failed to get surface description");
|
||||
else if( retTex->getSurface() != NULL )
|
||||
D3D9Assert( retTex->getSurface()->GetDesc( &probeDesc ), "Failed to get surface description");
|
||||
|
||||
retTex->mTextureSize.set(probeDesc.Width, probeDesc.Height, 0);
|
||||
|
||||
int fmt = probeDesc.Format;
|
||||
|
||||
#if !defined(TORQUE_OS_XENON)
|
||||
GFXREVERSE_LOOKUP( GFXD3D9TextureFormat, GFXFormat, fmt );
|
||||
retTex->mFormat = (GFXFormat)fmt;
|
||||
#else
|
||||
retTex->mFormat = format;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// createTexture
|
||||
//-----------------------------------------------------------------------------
|
||||
GFXTextureObject *GFXD3D9TextureManager::_createTextureObject( U32 height,
|
||||
U32 width,
|
||||
U32 depth,
|
||||
GFXFormat format,
|
||||
GFXTextureProfile *profile,
|
||||
U32 numMipLevels,
|
||||
bool forceMips,
|
||||
S32 antialiasLevel,
|
||||
GFXTextureObject *inTex )
|
||||
{
|
||||
GFXD3D9TextureObject *retTex;
|
||||
if ( inTex )
|
||||
{
|
||||
AssertFatal( dynamic_cast<GFXD3D9TextureObject*>( inTex ), "GFXD3D9TextureManager::_createTexture() - Bad inTex type!" );
|
||||
retTex = static_cast<GFXD3D9TextureObject*>( inTex );
|
||||
retTex->release();
|
||||
}
|
||||
else
|
||||
{
|
||||
retTex = new GFXD3D9TextureObject( GFX, profile );
|
||||
retTex->registerResourceWithDevice( GFX );
|
||||
}
|
||||
|
||||
_innerCreateTexture(retTex, height, width, depth, format, profile, numMipLevels, forceMips, antialiasLevel);
|
||||
|
||||
return retTex;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// loadTexture - GBitmap
|
||||
//-----------------------------------------------------------------------------
|
||||
bool GFXD3D9TextureManager::_loadTexture(GFXTextureObject *aTexture, GBitmap *pDL)
|
||||
{
|
||||
PROFILE_SCOPE(GFXD3D9TextureManager_loadTexture);
|
||||
|
||||
GFXD3D9TextureObject *texture = static_cast<GFXD3D9TextureObject*>(aTexture);
|
||||
|
||||
#ifdef TORQUE_OS_XENON
|
||||
// If the texture is currently bound, it needs to be unbound before modifying it
|
||||
if( texture->getTex() && texture->getTex()->IsSet( mD3DDevice ) )
|
||||
{
|
||||
mD3DDevice->SetTexture( 0, NULL );
|
||||
mD3DDevice->SetTexture( 1, NULL );
|
||||
mD3DDevice->SetTexture( 2, NULL );
|
||||
mD3DDevice->SetTexture( 3, NULL );
|
||||
mD3DDevice->SetTexture( 4, NULL );
|
||||
mD3DDevice->SetTexture( 5, NULL );
|
||||
mD3DDevice->SetTexture( 6, NULL );
|
||||
mD3DDevice->SetTexture( 7, NULL );
|
||||
}
|
||||
#endif
|
||||
|
||||
// Check with profiler to see if we can do automatic mipmap generation.
|
||||
const bool supportsAutoMips = GFX->getCardProfiler()->queryProfile("autoMipMapLevel", true);
|
||||
|
||||
// Helper bool
|
||||
const bool isCompressedTexFmt = aTexture->mFormat >= GFXFormatDXT1 && aTexture->mFormat <= GFXFormatDXT5;
|
||||
|
||||
GFXD3D9Device* dev = static_cast<GFXD3D9Device *>(GFX);
|
||||
|
||||
// Settings for mipmap generation
|
||||
U32 maxDownloadMip = pDL->getNumMipLevels();
|
||||
U32 nbMipMapLevel = pDL->getNumMipLevels();
|
||||
|
||||
if( supportsAutoMips && !isCompressedTexFmt )
|
||||
{
|
||||
maxDownloadMip = 1;
|
||||
nbMipMapLevel = aTexture->mMipLevels;
|
||||
}
|
||||
|
||||
// Fill the texture...
|
||||
for( int i = 0; i < maxDownloadMip; i++ )
|
||||
{
|
||||
LPDIRECT3DSURFACE9 surf = NULL;
|
||||
D3D9Assert(texture->get2DTex()->GetSurfaceLevel( i, &surf ), "Failed to get surface");
|
||||
|
||||
D3DLOCKED_RECT lockedRect;
|
||||
|
||||
#ifdef TORQUE_OS_XENON
|
||||
// On the 360, doing a LockRect doesn't work like it does with untiled memory
|
||||
// so instead swizzle into some temporary memory, and then later use D3DX
|
||||
// to do the upload properly.
|
||||
FrameTemp<U8> swizzleMem(pDL->getWidth(i) * pDL->getHeight(i) * pDL->getBytesPerPixel());
|
||||
lockedRect.pBits = (void*)~swizzleMem;
|
||||
#else
|
||||
U32 waterMark = 0;
|
||||
if (!dev->isD3D9Ex())
|
||||
surf->LockRect( &lockedRect, NULL, 0 );
|
||||
else
|
||||
{
|
||||
waterMark = FrameAllocator::getWaterMark();
|
||||
lockedRect.pBits = static_cast<void*>(FrameAllocator::alloc(pDL->getWidth(i) * pDL->getHeight(i) * pDL->getBytesPerPixel()));
|
||||
}
|
||||
#endif
|
||||
|
||||
switch( texture->mFormat )
|
||||
{
|
||||
case GFXFormatR8G8B8:
|
||||
{
|
||||
PROFILE_SCOPE(Swizzle24_Upload);
|
||||
AssertFatal( pDL->getFormat() == GFXFormatR8G8B8, "Assumption failed" );
|
||||
GFX->getDeviceSwizzle24()->ToBuffer( lockedRect.pBits, pDL->getBits(i),
|
||||
pDL->getWidth(i) * pDL->getHeight(i) * pDL->getBytesPerPixel() );
|
||||
}
|
||||
break;
|
||||
|
||||
case GFXFormatR8G8B8A8:
|
||||
case GFXFormatR8G8B8X8:
|
||||
{
|
||||
PROFILE_SCOPE(Swizzle32_Upload);
|
||||
GFX->getDeviceSwizzle32()->ToBuffer( lockedRect.pBits, pDL->getBits(i),
|
||||
pDL->getWidth(i) * pDL->getHeight(i) * pDL->getBytesPerPixel() );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
// Just copy the bits in no swizzle or padding
|
||||
PROFILE_SCOPE(SwizzleNull_Upload);
|
||||
AssertFatal( pDL->getFormat() == texture->mFormat, "Format mismatch" );
|
||||
dMemcpy( lockedRect.pBits, pDL->getBits(i),
|
||||
pDL->getWidth(i) * pDL->getHeight(i) * pDL->getBytesPerPixel() );
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TORQUE_OS_XENON
|
||||
RECT srcRect;
|
||||
srcRect.bottom = pDL->getHeight(i);
|
||||
srcRect.top = 0;
|
||||
srcRect.left = 0;
|
||||
srcRect.right = pDL->getWidth(i);
|
||||
|
||||
D3DXLoadSurfaceFromMemory(surf, NULL, NULL, ~swizzleMem, (D3DFORMAT)MAKELINFMT(GFXD3D9TextureFormat[pDL->getFormat()]),
|
||||
pDL->getWidth(i) * pDL->getBytesPerPixel(), NULL, &srcRect, false, 0, 0, D3DX_FILTER_NONE, 0);
|
||||
#else
|
||||
if (!dev->isD3D9Ex())
|
||||
surf->UnlockRect();
|
||||
else
|
||||
{
|
||||
RECT srcRect;
|
||||
srcRect.top = 0;
|
||||
srcRect.left = 0;
|
||||
srcRect.right = pDL->getWidth(i);
|
||||
srcRect.bottom = pDL->getHeight(i);
|
||||
D3DXLoadSurfaceFromMemory(surf, NULL, NULL, lockedRect.pBits, GFXD3D9TextureFormat[pDL->getFormat()], pDL->getBytesPerPixel() * pDL->getWidth(i), NULL, &srcRect, D3DX_DEFAULT, 0);
|
||||
FrameAllocator::setWaterMark(waterMark);
|
||||
}
|
||||
#endif
|
||||
|
||||
surf->Release();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// loadTexture - raw
|
||||
//-----------------------------------------------------------------------------
|
||||
bool GFXD3D9TextureManager::_loadTexture( GFXTextureObject *inTex, void *raw )
|
||||
{
|
||||
PROFILE_SCOPE(GFXD3D9TextureManager_loadTextureRaw);
|
||||
|
||||
GFXD3D9TextureObject *texture = (GFXD3D9TextureObject *) inTex;
|
||||
|
||||
// currently only for volume textures...
|
||||
if( texture->getDepth() < 1 ) return false;
|
||||
|
||||
|
||||
U32 bytesPerPix = 1;
|
||||
|
||||
switch( texture->mFormat )
|
||||
{
|
||||
case GFXFormatR8G8B8:
|
||||
bytesPerPix = 3;
|
||||
break;
|
||||
case GFXFormatR8G8B8A8:
|
||||
case GFXFormatR8G8B8X8:
|
||||
bytesPerPix = 4;
|
||||
break;
|
||||
}
|
||||
|
||||
U32 rowPitch = texture->getWidth() * bytesPerPix;
|
||||
U32 slicePitch = texture->getWidth() * texture->getHeight() * bytesPerPix;
|
||||
|
||||
D3DBOX box;
|
||||
box.Left = 0;
|
||||
box.Right = texture->getWidth();
|
||||
box.Front = 0;
|
||||
box.Back = texture->getDepth();
|
||||
box.Top = 0;
|
||||
box.Bottom = texture->getHeight();
|
||||
|
||||
|
||||
LPDIRECT3DVOLUME9 volume = NULL;
|
||||
D3D9Assert( texture->get3DTex()->GetVolumeLevel( 0, &volume ), "Failed to load volume" );
|
||||
|
||||
#ifdef TORQUE_OS_XENON
|
||||
D3DLOCKED_BOX lockedBox;
|
||||
volume->LockBox( &lockedBox, &box, 0 );
|
||||
|
||||
dMemcpy( lockedBox.pBits, raw, slicePitch * texture->getDepth() );
|
||||
|
||||
volume->UnlockBox();
|
||||
#else
|
||||
D3D9Assert(
|
||||
GFXD3DX.D3DXLoadVolumeFromMemory(
|
||||
volume,
|
||||
NULL,
|
||||
NULL,
|
||||
raw,
|
||||
GFXD3D9TextureFormat[texture->mFormat],
|
||||
rowPitch,
|
||||
slicePitch,
|
||||
NULL,
|
||||
&box,
|
||||
#ifdef TORQUE_OS_XENON
|
||||
false, 0, 0, 0, // Unique to Xenon -pw
|
||||
#endif
|
||||
D3DX_FILTER_NONE,
|
||||
0
|
||||
),
|
||||
"Failed to load volume texture"
|
||||
);
|
||||
#endif
|
||||
|
||||
volume->Release();
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// refreshTexture
|
||||
//-----------------------------------------------------------------------------
|
||||
bool GFXD3D9TextureManager::_refreshTexture(GFXTextureObject *texture)
|
||||
{
|
||||
U32 usedStrategies = 0;
|
||||
GFXD3D9TextureObject *realTex = static_cast<GFXD3D9TextureObject *>( texture );
|
||||
|
||||
if(texture->mProfile->doStoreBitmap())
|
||||
{
|
||||
// SAFE_RELEASE(realTex->mD3DTexture);
|
||||
// _innerCreateTexture(realTex, texture->mTextureSize.x, texture->mTextureSize.y, texture->mFormat, texture->mProfile, texture->mMipLevels);
|
||||
|
||||
if(texture->mBitmap)
|
||||
_loadTexture(texture, texture->mBitmap);
|
||||
|
||||
if(texture->mDDS)
|
||||
_loadTexture(texture, texture->mDDS);
|
||||
|
||||
usedStrategies++;
|
||||
}
|
||||
|
||||
if(texture->mProfile->isRenderTarget() || texture->mProfile->isDynamic() ||
|
||||
texture->mProfile->isZTarget())
|
||||
{
|
||||
realTex->release();
|
||||
_innerCreateTexture(realTex, texture->getHeight(), texture->getWidth(), texture->getDepth(), texture->mFormat,
|
||||
|
||||
texture->mProfile, texture->mMipLevels, false, texture->mAntialiasLevel);
|
||||
usedStrategies++;
|
||||
}
|
||||
|
||||
AssertFatal(usedStrategies < 2, "GFXD3D9TextureManager::_refreshTexture - Inconsistent profile flags!");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// freeTexture
|
||||
//-----------------------------------------------------------------------------
|
||||
bool GFXD3D9TextureManager::_freeTexture(GFXTextureObject *texture, bool zombify)
|
||||
{
|
||||
AssertFatal(dynamic_cast<GFXD3D9TextureObject *>(texture),"Not an actual d3d texture object!");
|
||||
GFXD3D9TextureObject *tex = static_cast<GFXD3D9TextureObject *>( texture );
|
||||
|
||||
// If it's a managed texture and we're zombifying, don't blast it, D3D allows
|
||||
// us to keep it.
|
||||
if(zombify && tex->isManaged)
|
||||
return true;
|
||||
|
||||
tex->release();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Load a texture from a proper DDSFile instance.
|
||||
bool GFXD3D9TextureManager::_loadTexture(GFXTextureObject *aTexture, DDSFile *dds)
|
||||
{
|
||||
PROFILE_SCOPE(GFXD3D9TextureManager_loadTextureDDS);
|
||||
|
||||
GFXD3D9TextureObject *texture = static_cast<GFXD3D9TextureObject*>(aTexture);
|
||||
|
||||
// Fill the texture...
|
||||
for( int i = 0; i < aTexture->mMipLevels; i++ )
|
||||
{
|
||||
PROFILE_SCOPE(GFXD3DTexMan_loadSurface);
|
||||
|
||||
LPDIRECT3DSURFACE9 surf = NULL;
|
||||
D3D9Assert(texture->get2DTex()->GetSurfaceLevel( i, &surf ), "Failed to get surface");
|
||||
|
||||
#if defined(TORQUE_OS_XENON)
|
||||
XGTEXTURE_DESC surfDesc;
|
||||
dMemset(&surfDesc, 0, sizeof(XGTEXTURE_DESC));
|
||||
XGGetSurfaceDesc(surf, &surfDesc);
|
||||
|
||||
RECT srcRect;
|
||||
srcRect.top = srcRect.left = 0;
|
||||
srcRect.bottom = dds->getHeight(i);
|
||||
srcRect.right = dds->getWidth(i);
|
||||
|
||||
D3DXLoadSurfaceFromMemory(surf, NULL, NULL, dds->mSurfaces[0]->mMips[i],
|
||||
(D3DFORMAT)MAKELINFMT(GFXD3D9TextureFormat[dds->mFormat]), dds->getSurfacePitch(i),
|
||||
NULL, &srcRect, false, 0, 0, D3DX_FILTER_NONE, 0);
|
||||
#else
|
||||
|
||||
GFXD3D9Device* dev = static_cast<GFXD3D9Device *>(GFX);
|
||||
|
||||
if (dev->isD3D9Ex())
|
||||
{
|
||||
RECT r;
|
||||
r.top = r.left = 0;
|
||||
r.bottom = dds->getHeight(i);
|
||||
r.right = dds->getWidth(i);
|
||||
D3DXLoadSurfaceFromMemory(surf, NULL, NULL, dds->mSurfaces[0]->mMips[i], GFXD3D9TextureFormat[dds->mFormat], dds->getSurfacePitch(i), NULL, &r, D3DX_DEFAULT, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
D3DLOCKED_RECT lockedRect;
|
||||
D3D9Assert( surf->LockRect( &lockedRect, NULL, 0 ), "Failed to lock surface level for load" );
|
||||
|
||||
AssertFatal( dds->mSurfaces.size() > 0, "Assumption failed. DDSFile has no surfaces." );
|
||||
|
||||
if ( dds->getSurfacePitch( i ) != lockedRect.Pitch )
|
||||
{
|
||||
// Do a row-by-row copy.
|
||||
U32 srcPitch = dds->getSurfacePitch( i );
|
||||
U32 srcHeight = dds->getHeight();
|
||||
U8* srcBytes = dds->mSurfaces[0]->mMips[i];
|
||||
U8* dstBytes = (U8*)lockedRect.pBits;
|
||||
for (U32 i = 0; i<srcHeight; i++)
|
||||
{
|
||||
dMemcpy( dstBytes, srcBytes, srcPitch );
|
||||
dstBytes += lockedRect.Pitch;
|
||||
srcBytes += srcPitch;
|
||||
}
|
||||
surf->UnlockRect();
|
||||
surf->Release();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
dMemcpy( lockedRect.pBits, dds->mSurfaces[0]->mMips[i], dds->getSurfaceSize(i) );
|
||||
|
||||
surf->UnlockRect();
|
||||
}
|
||||
#endif
|
||||
|
||||
surf->Release();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
72
Engine/source/gfx/D3D9/gfxD3D9TextureManager.h
Normal file
72
Engine/source/gfx/D3D9/gfxD3D9TextureManager.h
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GFXD3DTEXTUREMANAGER_H_
|
||||
#define _GFXD3DTEXTUREMANAGER_H_
|
||||
|
||||
#include "gfx/D3D9/gfxD3D9TextureObject.h"
|
||||
#include "core/util/safeRelease.h"
|
||||
|
||||
// #define D3D_TEXTURE_SPEW
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// GFX D3D Texture Manager
|
||||
//*****************************************************************************
|
||||
class GFXD3D9TextureManager : public GFXTextureManager
|
||||
{
|
||||
friend class GFXD3D9TextureObject;
|
||||
|
||||
public:
|
||||
GFXD3D9TextureManager( LPDIRECT3DDEVICE9 d3ddevice );
|
||||
virtual ~GFXD3D9TextureManager();
|
||||
|
||||
protected:
|
||||
|
||||
// GFXTextureManager
|
||||
GFXTextureObject *_createTextureObject( U32 height,
|
||||
U32 width,
|
||||
U32 depth,
|
||||
GFXFormat format,
|
||||
GFXTextureProfile *profile,
|
||||
U32 numMipLevels,
|
||||
bool forceMips = false,
|
||||
S32 antialiasLevel = 0,
|
||||
GFXTextureObject *inTex = NULL );
|
||||
bool _loadTexture(GFXTextureObject *texture, DDSFile *dds);
|
||||
bool _loadTexture(GFXTextureObject *texture, GBitmap *bmp);
|
||||
bool _loadTexture(GFXTextureObject *texture, void *raw);
|
||||
bool _refreshTexture(GFXTextureObject *texture);
|
||||
bool _freeTexture(GFXTextureObject *texture, bool zombify = false);
|
||||
|
||||
private:
|
||||
U32 mCurTexSet[TEXTURE_STAGE_COUNT];
|
||||
|
||||
LPDIRECT3DDEVICE9 mD3DDevice;
|
||||
D3DCAPS9 mDeviceCaps;
|
||||
|
||||
void _innerCreateTexture(GFXD3D9TextureObject *obj, U32 height, U32 width,
|
||||
U32 depth, GFXFormat format, GFXTextureProfile *profile, U32 numMipLevels,
|
||||
bool forceMips = false, S32 antialiasLevel = 0);
|
||||
};
|
||||
|
||||
#endif
|
||||
277
Engine/source/gfx/D3D9/gfxD3D9TextureObject.cpp
Normal file
277
Engine/source/gfx/D3D9/gfxD3D9TextureObject.cpp
Normal file
|
|
@ -0,0 +1,277 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "gfx/D3D9/gfxD3D9Device.h"
|
||||
#include "gfx/D3D9/gfxD3D9TextureObject.h"
|
||||
#include "platform/profiler.h"
|
||||
|
||||
#ifdef TORQUE_OS_XENON
|
||||
#include "gfx/D3D9/360/gfx360Device.h"
|
||||
#include "gfx/D3D9/360/gfx360Target.h"
|
||||
#include "gfx/D3D9/gfxD3D9EnumTranslate.h"
|
||||
#endif
|
||||
|
||||
U32 GFXD3D9TextureObject::mTexCount = 0;
|
||||
|
||||
//*****************************************************************************
|
||||
// GFX D3D Texture Object
|
||||
//*****************************************************************************
|
||||
GFXD3D9TextureObject::GFXD3D9TextureObject( GFXDevice * d, GFXTextureProfile *profile)
|
||||
: GFXTextureObject( d, profile )
|
||||
{
|
||||
#ifdef D3D_TEXTURE_SPEW
|
||||
mTexCount++;
|
||||
Con::printf("+ texMake %d %x", mTexCount, this);
|
||||
#endif
|
||||
|
||||
isManaged = false;
|
||||
mD3DTexture = NULL;
|
||||
mLocked = false;
|
||||
|
||||
mD3DSurface = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
GFXD3D9TextureObject::~GFXD3D9TextureObject()
|
||||
{
|
||||
kill();
|
||||
#ifdef D3D_TEXTURE_SPEW
|
||||
mTexCount--;
|
||||
Con::printf("+ texkill %d %x", mTexCount, this);
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// lock
|
||||
//-----------------------------------------------------------------------------
|
||||
GFXLockedRect *GFXD3D9TextureObject::lock(U32 mipLevel /*= 0*/, RectI *inRect /*= NULL*/)
|
||||
{
|
||||
AssertFatal( !mLocked, "GFXD3D9TextureObject::lock - The texture is already locked!" );
|
||||
|
||||
if( mProfile->isRenderTarget() )
|
||||
{
|
||||
if( !mLockTex ||
|
||||
mLockTex->getWidth() != getWidth() ||
|
||||
mLockTex->getHeight() != getHeight() )
|
||||
{
|
||||
mLockTex.set( getWidth(), getHeight(), mFormat, &GFXSystemMemProfile, avar("%s() - mLockTex (line %d)", __FUNCTION__, __LINE__) );
|
||||
}
|
||||
|
||||
PROFILE_START(GFXD3D9TextureObject_lockRT);
|
||||
|
||||
IDirect3DSurface9 *source;
|
||||
D3D9Assert( get2DTex()->GetSurfaceLevel( 0, &source ), "GFXD3D9TextureObject::lock - failed to get our own texture's surface." );
|
||||
|
||||
IDirect3DSurface9 *dest;
|
||||
GFXD3D9TextureObject *to = (GFXD3D9TextureObject *) &(*mLockTex);
|
||||
D3D9Assert( to->get2DTex()->GetSurfaceLevel( 0, &dest ), "GFXD3D9TextureObject::lock - failed to get dest texture's surface." );
|
||||
|
||||
#ifndef TORQUE_OS_XENON
|
||||
LPDIRECT3DDEVICE9 D3DDevice = dynamic_cast<GFXD3D9Device *>(GFX)->getDevice();
|
||||
HRESULT rtLockRes = D3DDevice->GetRenderTargetData( source, dest );
|
||||
#else
|
||||
AssertFatal(false, "Use different functionality on the Xbox 360 to perform this task.");
|
||||
HRESULT rtLockRes = E_FAIL;
|
||||
#endif
|
||||
source->Release();
|
||||
|
||||
if(!SUCCEEDED(rtLockRes))
|
||||
{
|
||||
// This case generally occurs if the device is lost. The lock failed
|
||||
// so clean up and return NULL.
|
||||
dest->Release();
|
||||
PROFILE_END();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
D3D9Assert( dest->LockRect( &mLockRect, NULL, D3DLOCK_READONLY ), NULL );
|
||||
dest->Release();
|
||||
mLocked = true;
|
||||
|
||||
PROFILE_END();
|
||||
}
|
||||
else
|
||||
{
|
||||
RECT r;
|
||||
|
||||
if(inRect)
|
||||
{
|
||||
r.top = inRect->point.y;
|
||||
r.left = inRect->point.x;
|
||||
r.bottom = inRect->point.y + inRect->extent.y;
|
||||
r.right = inRect->point.x + inRect->extent.x;
|
||||
}
|
||||
|
||||
D3D9Assert( get2DTex()->LockRect(mipLevel, &mLockRect, inRect ? &r : NULL, 0),
|
||||
"GFXD3D9TextureObject::lock - could not lock non-RT texture!" );
|
||||
mLocked = true;
|
||||
|
||||
}
|
||||
|
||||
// GFXLockedRect is set up to correspond to D3DLOCKED_RECT, so this is ok.
|
||||
return (GFXLockedRect*)&mLockRect;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// unLock
|
||||
//-----------------------------------------------------------------------------
|
||||
void GFXD3D9TextureObject::unlock(U32 mipLevel)
|
||||
{
|
||||
AssertFatal( mLocked, "GFXD3D9TextureObject::unlock - Attempting to unlock a surface that has not been locked" );
|
||||
|
||||
#ifndef TORQUE_OS_XENON
|
||||
if( mProfile->isRenderTarget() )
|
||||
{
|
||||
IDirect3DSurface9 *dest;
|
||||
GFXD3D9TextureObject *to = (GFXD3D9TextureObject *) &(*mLockTex);
|
||||
D3D9Assert( to->get2DTex()->GetSurfaceLevel( 0, &dest ), NULL );
|
||||
|
||||
dest->UnlockRect();
|
||||
dest->Release();
|
||||
|
||||
mLocked = false;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
D3D9Assert( get2DTex()->UnlockRect(mipLevel),
|
||||
"GFXD3D9TextureObject::unlock - could not unlock non-RT texture." );
|
||||
|
||||
mLocked = false;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void GFXD3D9TextureObject::release()
|
||||
{
|
||||
static_cast<GFXD3D9Device *>( GFX )->destroyD3DResource( mD3DTexture );
|
||||
static_cast<GFXD3D9Device *>( GFX )->destroyD3DResource( mD3DSurface );
|
||||
mD3DTexture = NULL;
|
||||
mD3DSurface = NULL;
|
||||
}
|
||||
|
||||
void GFXD3D9TextureObject::zombify()
|
||||
{
|
||||
// Managed textures are managed by D3D
|
||||
AssertFatal(!mLocked, "GFXD3D9TextureObject::zombify - Cannot zombify a locked texture!");
|
||||
if(isManaged)
|
||||
return;
|
||||
|
||||
release();
|
||||
}
|
||||
|
||||
void GFXD3D9TextureObject::resurrect()
|
||||
{
|
||||
// Managed textures are managed by D3D
|
||||
if(isManaged)
|
||||
return;
|
||||
|
||||
static_cast<GFXD3D9TextureManager*>(TEXMGR)->refreshTexture(this);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool GFXD3D9TextureObject::copyToBmp(GBitmap* bmp)
|
||||
{
|
||||
#ifdef TORQUE_OS_XENON
|
||||
// TODO: Implement Xenon version -patw
|
||||
return false;
|
||||
#else
|
||||
if (!bmp)
|
||||
return false;
|
||||
|
||||
// check format limitations
|
||||
// at the moment we only support RGBA for the source (other 4 byte formats should
|
||||
// be easy to add though)
|
||||
AssertFatal(mFormat == GFXFormatR8G8B8A8, "copyToBmp: invalid format");
|
||||
if (mFormat != GFXFormatR8G8B8A8)
|
||||
return false;
|
||||
|
||||
PROFILE_START(GFXD3D9TextureObject_copyToBmp);
|
||||
|
||||
AssertFatal(bmp->getWidth() == getWidth(), "doh");
|
||||
AssertFatal(bmp->getHeight() == getHeight(), "doh");
|
||||
U32 width = getWidth();
|
||||
U32 height = getHeight();
|
||||
|
||||
bmp->setHasTransparency(mHasTransparency);
|
||||
|
||||
// set some constants
|
||||
const U32 sourceBytesPerPixel = 4;
|
||||
U32 destBytesPerPixel = 0;
|
||||
if (bmp->getFormat() == GFXFormatR8G8B8A8)
|
||||
destBytesPerPixel = 4;
|
||||
else if (bmp->getFormat() == GFXFormatR8G8B8)
|
||||
destBytesPerPixel = 3;
|
||||
else
|
||||
// unsupported
|
||||
AssertFatal(false, "unsupported bitmap format");
|
||||
|
||||
// lock the texture
|
||||
D3DLOCKED_RECT* lockRect = (D3DLOCKED_RECT*) lock();
|
||||
|
||||
// set pointers
|
||||
U8* srcPtr = (U8*)lockRect->pBits;
|
||||
U8* destPtr = bmp->getWritableBits();
|
||||
|
||||
// we will want to skip over any D3D cache data in the source texture
|
||||
const S32 sourceCacheSize = lockRect->Pitch - width * sourceBytesPerPixel;
|
||||
AssertFatal(sourceCacheSize >= 0, "copyToBmp: cache size is less than zero?");
|
||||
|
||||
PROFILE_START(GFXD3D9TextureObject_copyToBmp_pixCopy);
|
||||
// copy data into bitmap
|
||||
for (int row = 0; row < height; ++row)
|
||||
{
|
||||
for (int col = 0; col < width; ++col)
|
||||
{
|
||||
destPtr[0] = srcPtr[2]; // red
|
||||
destPtr[1] = srcPtr[1]; // green
|
||||
destPtr[2] = srcPtr[0]; // blue
|
||||
if (destBytesPerPixel == 4)
|
||||
destPtr[3] = srcPtr[3]; // alpha
|
||||
|
||||
// go to next pixel in src
|
||||
srcPtr += sourceBytesPerPixel;
|
||||
|
||||
// go to next pixel in dest
|
||||
destPtr += destBytesPerPixel;
|
||||
}
|
||||
// skip past the cache data for this row (if any)
|
||||
srcPtr += sourceCacheSize;
|
||||
}
|
||||
PROFILE_END();
|
||||
|
||||
// assert if we stomped or underran memory
|
||||
AssertFatal(U32(destPtr - bmp->getWritableBits()) == width * height * destBytesPerPixel, "copyToBmp: doh, memory error");
|
||||
AssertFatal(U32(srcPtr - (U8*)lockRect->pBits) == height * lockRect->Pitch, "copyToBmp: doh, memory error");
|
||||
|
||||
// unlock
|
||||
unlock();
|
||||
|
||||
PROFILE_END();
|
||||
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
80
Engine/source/gfx/D3D9/gfxD3D9TextureObject.h
Normal file
80
Engine/source/gfx/D3D9/gfxD3D9TextureObject.h
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GFXD3D9TEXTUREOBJECT_H_
|
||||
#define _GFXD3D9TEXTUREOBJECT_H_
|
||||
|
||||
#ifndef _GFXTEXTUREHANDLE_H_
|
||||
#include "gfx/gfxTextureHandle.h"
|
||||
#endif
|
||||
|
||||
#ifndef _GFXTEXTUREMANAGER_H_
|
||||
#include "gfx/gfxTextureManager.h"
|
||||
#endif
|
||||
|
||||
|
||||
class GFXD3D9TextureObject : public GFXTextureObject
|
||||
{
|
||||
protected:
|
||||
static U32 mTexCount;
|
||||
GFXTexHandle mLockTex;
|
||||
D3DLOCKED_RECT mLockRect;
|
||||
bool mLocked;
|
||||
|
||||
IDirect3DBaseTexture9 *mD3DTexture;
|
||||
|
||||
// used for z buffers...
|
||||
IDirect3DSurface9 *mD3DSurface;
|
||||
|
||||
public:
|
||||
|
||||
GFXD3D9TextureObject( GFXDevice * d, GFXTextureProfile *profile);
|
||||
~GFXD3D9TextureObject();
|
||||
|
||||
IDirect3DBaseTexture9 * getTex(){ return mD3DTexture; }
|
||||
IDirect3DTexture9 * get2DTex(){ return (LPDIRECT3DTEXTURE9) mD3DTexture; }
|
||||
IDirect3DTexture9 ** get2DTexPtr(){ return (LPDIRECT3DTEXTURE9*) &mD3DTexture; }
|
||||
IDirect3DVolumeTexture9 * get3DTex(){ return (LPDIRECT3DVOLUMETEXTURE9) mD3DTexture; }
|
||||
IDirect3DVolumeTexture9 ** get3DTexPtr(){ return (LPDIRECT3DVOLUMETEXTURE9*) &mD3DTexture; }
|
||||
|
||||
void release();
|
||||
|
||||
bool isManaged;
|
||||
|
||||
virtual GFXLockedRect * lock(U32 mipLevel = 0, RectI *inRect = NULL);
|
||||
virtual void unlock(U32 mipLevel = 0 );
|
||||
|
||||
virtual bool copyToBmp(GBitmap* bmp);
|
||||
IDirect3DSurface9 *getSurface() {return mD3DSurface;}
|
||||
IDirect3DSurface9 **getSurfacePtr() {return &mD3DSurface;}
|
||||
|
||||
// GFXResource
|
||||
void zombify();
|
||||
void resurrect();
|
||||
|
||||
#ifdef TORQUE_DEBUG
|
||||
virtual void pureVirtualCrash() {};
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
230
Engine/source/gfx/D3D9/gfxD3D9VertexBuffer.cpp
Normal file
230
Engine/source/gfx/D3D9/gfxD3D9VertexBuffer.cpp
Normal file
|
|
@ -0,0 +1,230 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "gfx/D3D9/gfxD3D9VertexBuffer.h"
|
||||
|
||||
GFXD3D9VertexBuffer::~GFXD3D9VertexBuffer()
|
||||
{
|
||||
#ifdef TORQUE_DEBUG
|
||||
SAFE_DELETE( name );
|
||||
#endif
|
||||
|
||||
if (getOwningDevice() != NULL)
|
||||
{
|
||||
if (mBufferType == GFXBufferTypeDynamic)
|
||||
static_cast<GFXD3D9Device *>(getOwningDevice())->deallocVertexBuffer( this );
|
||||
else if (mBufferType != GFXBufferTypeVolatile)
|
||||
{
|
||||
static_cast<GFXD3D9Device *>(getOwningDevice())->destroyD3DResource( vb );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Lock
|
||||
//-----------------------------------------------------------------------------
|
||||
void GFXD3D9VertexBuffer::lock(U32 vertexStart, U32 vertexEnd, void **vertexPtr)
|
||||
{
|
||||
PROFILE_SCOPE(GFXD3D9VertexBuffer_lock);
|
||||
|
||||
AssertFatal(lockedVertexStart == 0 && lockedVertexEnd == 0, "Cannot lock a buffer more than once!");
|
||||
|
||||
U32 flags = 0;
|
||||
|
||||
GFXD3D9Device *d = static_cast<GFXD3D9Device *>( mDevice );
|
||||
|
||||
switch( mBufferType )
|
||||
{
|
||||
case GFXBufferTypeStatic:
|
||||
break;
|
||||
|
||||
case GFXBufferTypeDynamic:
|
||||
#ifndef TORQUE_OS_XENON
|
||||
flags |= D3DLOCK_DISCARD;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case GFXBufferTypeVolatile:
|
||||
|
||||
// Get or create the volatile buffer...
|
||||
mVolatileBuffer = d->findVBPool( &mVertexFormat, vertexEnd );
|
||||
|
||||
if( !mVolatileBuffer )
|
||||
mVolatileBuffer = d->createVBPool( &mVertexFormat, mVertexSize );
|
||||
|
||||
vb = mVolatileBuffer->vb;
|
||||
|
||||
// Get our range now...
|
||||
AssertFatal(vertexStart == 0, "Cannot get a subrange on a volatile buffer.");
|
||||
AssertFatal(vertexEnd <= MAX_DYNAMIC_VERTS, "Cannot get more than MAX_DYNAMIC_VERTS in a volatile buffer. Up the constant!");
|
||||
AssertFatal(mVolatileBuffer->lockedVertexStart == 0 && mVolatileBuffer->lockedVertexEnd == 0, "Got more than one lock on the volatile pool.");
|
||||
|
||||
// We created the pool when we requested this volatile buffer, so assume it exists...
|
||||
if( mVolatileBuffer->mNumVerts + vertexEnd > MAX_DYNAMIC_VERTS )
|
||||
{
|
||||
#ifdef TORQUE_OS_XENON
|
||||
AssertFatal( false, "This should never, ever happen. findVBPool should have returned NULL" );
|
||||
#else
|
||||
flags |= D3DLOCK_DISCARD;
|
||||
#endif
|
||||
mVolatileStart = vertexStart = 0;
|
||||
vertexEnd = vertexEnd;
|
||||
}
|
||||
else
|
||||
{
|
||||
flags |= D3DLOCK_NOOVERWRITE;
|
||||
mVolatileStart = vertexStart = mVolatileBuffer->mNumVerts;
|
||||
vertexEnd += mVolatileBuffer->mNumVerts;
|
||||
}
|
||||
|
||||
mVolatileBuffer->mNumVerts = vertexEnd+1;
|
||||
|
||||
mVolatileBuffer->lockedVertexStart = vertexStart;
|
||||
mVolatileBuffer->lockedVertexEnd = vertexEnd;
|
||||
break;
|
||||
}
|
||||
|
||||
lockedVertexStart = vertexStart;
|
||||
lockedVertexEnd = vertexEnd;
|
||||
|
||||
// Con::printf("%x: Locking %s range (%d, %d)", this, (mBufferType == GFXBufferTypeVolatile ? "volatile" : "static"), lockedVertexStart, lockedVertexEnd);
|
||||
|
||||
#ifdef TORQUE_OS_XENON
|
||||
// If the vertex buffer which we are trying to lock is held by the D3D device
|
||||
// on Xenon it will bomb. So if that is the case, then SetStreamSource to NULL
|
||||
// and also call setVertexBuffer because otherwise the state-cache will be hosed
|
||||
if( d->mCurrentVB != NULL && d->mCurrentVB->vb == vb )
|
||||
{
|
||||
d->setVertexBuffer( NULL );
|
||||
d->mD3DDevice->SetStreamSource( 0, NULL, 0, 0 );
|
||||
}
|
||||
|
||||
// As of October 2006 XDK, range locking is no longer supported. Lock the whole buffer
|
||||
// and then manually offset the pointer to simulate the subrange. -patw
|
||||
D3D9Assert( vb->Lock( 0, 0, vertexPtr, flags),
|
||||
"Unable to lock vertex buffer.");
|
||||
|
||||
U8 *tmp = (U8 *)(*vertexPtr);
|
||||
tmp += ( vertexStart * mVertexSize );
|
||||
*vertexPtr = tmp;
|
||||
#else
|
||||
|
||||
U32 sizeToLock = (vertexEnd - vertexStart) * mVertexSize;
|
||||
D3D9Assert( vb->Lock(vertexStart * mVertexSize, sizeToLock, vertexPtr, flags),
|
||||
"Unable to lock vertex buffer.");
|
||||
|
||||
#ifdef TORQUE_DEBUG
|
||||
|
||||
// Allocate a debug buffer large enough for the lock
|
||||
// plus space for over and under run guard strings.
|
||||
const U32 guardSize = sizeof( _VBGuardString );
|
||||
mDebugGuardBuffer = new U8[sizeToLock+(guardSize*2)];
|
||||
|
||||
// Setup the guard strings.
|
||||
dMemcpy( mDebugGuardBuffer, _VBGuardString, guardSize );
|
||||
dMemcpy( mDebugGuardBuffer + sizeToLock + guardSize, _VBGuardString, guardSize );
|
||||
|
||||
// Store the real lock pointer and return our debug pointer.
|
||||
mLockedBuffer = *vertexPtr;
|
||||
*vertexPtr = mDebugGuardBuffer + guardSize;
|
||||
|
||||
#endif // TORQUE_DEBUG
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void GFXD3D9VertexBuffer::unlock()
|
||||
{
|
||||
PROFILE_SCOPE(GFXD3D9VertexBuffer_unlock);
|
||||
|
||||
#ifdef TORQUE_DEBUG
|
||||
|
||||
if ( mDebugGuardBuffer )
|
||||
{
|
||||
const U32 guardSize = sizeof( _VBGuardString );
|
||||
const U32 sizeLocked = (lockedVertexEnd - lockedVertexStart) * mVertexSize;
|
||||
|
||||
// First check the guard areas for overwrites.
|
||||
AssertFatal( dMemcmp( mDebugGuardBuffer, _VBGuardString, guardSize ) == 0,
|
||||
"GFXD3D9VertexBuffer::unlock - Caught lock memory underrun!" );
|
||||
AssertFatal( dMemcmp( mDebugGuardBuffer + sizeLocked + guardSize, _VBGuardString, guardSize ) == 0,
|
||||
"GFXD3D9VertexBuffer::unlock - Caught lock memory overrun!" );
|
||||
|
||||
// Copy the debug content down to the real VB.
|
||||
dMemcpy( mLockedBuffer, mDebugGuardBuffer + guardSize, sizeLocked );
|
||||
|
||||
// Cleanup.
|
||||
delete [] mDebugGuardBuffer;
|
||||
mDebugGuardBuffer = NULL;
|
||||
mLockedBuffer = NULL;
|
||||
}
|
||||
|
||||
#endif // TORQUE_DEBUG
|
||||
|
||||
D3D9Assert( vb->Unlock(),
|
||||
"Unable to unlock vertex buffer.");
|
||||
mIsFirstLock = false;
|
||||
|
||||
// Con::printf("%x: Unlocking %s range (%d, %d)", this, (mBufferType == GFXBufferTypeVolatile ? "volatile" : "static"), lockedVertexStart, lockedVertexEnd);
|
||||
|
||||
lockedVertexEnd = lockedVertexStart = 0;
|
||||
|
||||
if(mVolatileBuffer.isValid())
|
||||
{
|
||||
mVolatileBuffer->lockedVertexStart = 0;
|
||||
mVolatileBuffer->lockedVertexEnd = 0;
|
||||
mVolatileBuffer = NULL;
|
||||
//vb->Release();
|
||||
//vb = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void GFXD3D9VertexBuffer::zombify()
|
||||
{
|
||||
AssertFatal(lockedVertexStart == 0 && lockedVertexEnd == 0, "GFXD3D9VertexBuffer::zombify - Cannot zombify a locked buffer!");
|
||||
// Static buffers are managed by D3D9 so we don't deal with them.
|
||||
if(mBufferType == GFXBufferTypeDynamic)
|
||||
{
|
||||
SAFE_RELEASE(vb);
|
||||
}
|
||||
}
|
||||
|
||||
void GFXD3D9VertexBuffer::resurrect()
|
||||
{
|
||||
// Static buffers are managed by D3D9 so we don't deal with them.
|
||||
if(mBufferType == GFXBufferTypeDynamic)
|
||||
{
|
||||
D3D9Assert(static_cast<GFXD3D9Device*>(mDevice)->mD3DDevice->CreateVertexBuffer( mVertexSize * mNumVerts,
|
||||
#ifdef TORQUE_OS_XENON
|
||||
D3DUSAGE_WRITEONLY,
|
||||
#else
|
||||
D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY,
|
||||
#endif
|
||||
0,
|
||||
D3DPOOL_DEFAULT,
|
||||
&vb,
|
||||
NULL ),
|
||||
"GFXD3D9VertexBuffer::resurrect - Failed to allocate VB" );
|
||||
}
|
||||
}
|
||||
|
||||
136
Engine/source/gfx/D3D9/gfxD3D9VertexBuffer.h
Normal file
136
Engine/source/gfx/D3D9/gfxD3D9VertexBuffer.h
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GFXD3D_VERTEXBUFFER_H_
|
||||
#define _GFXD3D_VERTEXBUFFER_H_
|
||||
|
||||
#ifndef _GFXD3D9DEVICE_H_
|
||||
#include "gfx/D3D9/gfxD3D9Device.h"
|
||||
#endif
|
||||
#ifndef _SAFEDELETE_H_
|
||||
#include "core/util/safeDelete.h"
|
||||
#endif
|
||||
|
||||
//*****************************************************************************
|
||||
// GFXD3D9VertexBuffer
|
||||
//*****************************************************************************
|
||||
class GFXD3D9VertexBuffer : public GFXVertexBuffer
|
||||
{
|
||||
public:
|
||||
IDirect3DVertexBuffer9 *vb;
|
||||
StrongRefPtr<GFXD3D9VertexBuffer> mVolatileBuffer;
|
||||
|
||||
#ifdef TORQUE_DEBUG
|
||||
#define _VBGuardString "GFX_VERTEX_BUFFER_GUARD_STRING"
|
||||
U8 *mDebugGuardBuffer;
|
||||
void *mLockedBuffer;
|
||||
#endif TORQUE_DEBUG
|
||||
|
||||
bool mIsFirstLock;
|
||||
bool mClearAtFrameEnd;
|
||||
|
||||
GFXD3D9VertexBuffer();
|
||||
GFXD3D9VertexBuffer( GFXDevice *device,
|
||||
U32 numVerts,
|
||||
const GFXVertexFormat *vertexFormat,
|
||||
U32 vertexSize,
|
||||
GFXBufferType bufferType );
|
||||
virtual ~GFXD3D9VertexBuffer();
|
||||
|
||||
void lock(U32 vertexStart, U32 vertexEnd, void **vertexPtr);
|
||||
void unlock();
|
||||
void prepare() {}
|
||||
|
||||
#ifdef TORQUE_DEBUG
|
||||
char *name;
|
||||
|
||||
/// In debug compile, the verts will be chained together and the device
|
||||
/// will examine the chain when it's destructor is called, this will
|
||||
/// allow developers to see which vertex buffers are not destroyed
|
||||
GFXD3D9VertexBuffer *next;
|
||||
#endif
|
||||
void setName( const char *n );
|
||||
|
||||
// GFXResource interface
|
||||
virtual void zombify();
|
||||
virtual void resurrect();
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This is for debugging vertex buffers and trying to track down which vbs
|
||||
// aren't getting free'd
|
||||
|
||||
inline GFXD3D9VertexBuffer::GFXD3D9VertexBuffer()
|
||||
: GFXVertexBuffer(0,0,0,0,(GFXBufferType)0)
|
||||
{
|
||||
#ifdef TORQUE_DEBUG
|
||||
name = NULL;
|
||||
#endif
|
||||
vb = NULL;
|
||||
mIsFirstLock = true;
|
||||
lockedVertexEnd = lockedVertexStart = 0;
|
||||
mClearAtFrameEnd = false;
|
||||
|
||||
#ifdef TORQUE_DEBUG
|
||||
mDebugGuardBuffer = NULL;
|
||||
mLockedBuffer = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline GFXD3D9VertexBuffer::GFXD3D9VertexBuffer( GFXDevice *device,
|
||||
U32 numVerts,
|
||||
const GFXVertexFormat *vertexFormat,
|
||||
U32 vertexSize,
|
||||
GFXBufferType bufferType )
|
||||
: GFXVertexBuffer( device, numVerts, vertexFormat, vertexSize, bufferType )
|
||||
{
|
||||
#ifdef TORQUE_DEBUG
|
||||
name = NULL;
|
||||
#endif
|
||||
vb = NULL;
|
||||
mIsFirstLock = true;
|
||||
mClearAtFrameEnd = false;
|
||||
lockedVertexEnd = lockedVertexStart = 0;
|
||||
|
||||
#ifdef TORQUE_DEBUG
|
||||
mDebugGuardBuffer = NULL;
|
||||
mLockedBuffer = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef TORQUE_DEBUG
|
||||
|
||||
inline void GFXD3D9VertexBuffer::setName( const char *n )
|
||||
{
|
||||
SAFE_DELETE( name );
|
||||
name = new char[dStrlen( n )];
|
||||
dStrcpy( name, n );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
inline void GFXD3D9VertexBuffer::setName( const char *n ) { }
|
||||
|
||||
#endif // !TORQUE_DEBUG
|
||||
|
||||
#endif // _GFXD3D_VERTEXBUFFER_H_
|
||||
|
||||
87
Engine/source/gfx/D3D9/pc/gfxD3D9Device.pc.cpp
Normal file
87
Engine/source/gfx/D3D9/pc/gfxD3D9Device.pc.cpp
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "gfx/D3D9/pc/gfxPCD3D9Device.h"
|
||||
#include "gfx/D3D9/gfxD3D9CardProfiler.h"
|
||||
#include "gfx/D3D9/gfxD3D9Shader.h"
|
||||
#include "gfx/D3D9/gfxD3D9VertexBuffer.h"
|
||||
#include "gfx/D3D9/gfxD3D9EnumTranslate.h"
|
||||
#include "core/strings/unicode.h"
|
||||
#include "console/console.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// D3DX Function binding
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool d3dxBindFunction( DLibrary *dll, void *&fnAddress, const char *name )
|
||||
{
|
||||
fnAddress = dll->bind( name );
|
||||
|
||||
if (!fnAddress)
|
||||
Con::warnf( "D3DX Loader: DLL bind failed for %s", name );
|
||||
|
||||
return fnAddress != 0;
|
||||
}
|
||||
|
||||
void GFXD3D9Device::initD3DXFnTable()
|
||||
{
|
||||
if ( smD3DX.isLoaded )
|
||||
return;
|
||||
|
||||
// We only load the d3dx version that we compiled
|
||||
// and linked against which should keep unexpected
|
||||
// problems from newer or older SDKs to a minimum.
|
||||
String d3dxVersion = String::ToString( "d3dx9_%d.dll", (S32)D3DX_SDK_VERSION );
|
||||
smD3DX.dllRef = OsLoadLibrary( d3dxVersion );
|
||||
|
||||
// If the d3dx version we requested didn't load then we have
|
||||
// a corrupt or old install of DirectX.... prompt them to update.
|
||||
if ( !smD3DX.dllRef )
|
||||
{
|
||||
Con::errorf( "Unsupported DirectX version!" );
|
||||
Platform::messageBox( Con::getVariable( "$appName" ),
|
||||
"DirectX could not be started!\r\n"
|
||||
"Please be sure you have the latest version of DirectX installed.",
|
||||
MBOk, MIStop );
|
||||
Platform::forceShutdown( -1 );
|
||||
}
|
||||
|
||||
smD3DX.isLoaded = true;
|
||||
|
||||
#define D3DX_FUNCTION(fn_name, fn_return, fn_args) \
|
||||
smD3DX.isLoaded &= d3dxBindFunction(smD3DX.dllRef, *(void**)&smD3DX.fn_name, #fn_name);
|
||||
# include "gfx/D3D9/d3dx9Functions.h"
|
||||
#undef D3DX_FUNCTION
|
||||
|
||||
AssertISV( smD3DX.isLoaded, "D3DX Failed to load all functions." );
|
||||
|
||||
// HACK: For some reason in the latest versions of
|
||||
// the D3D SDK on the PC the shader compiler will load
|
||||
// and unload the compiler DLL over and over with each
|
||||
// shader compiled.
|
||||
//
|
||||
// By loading the DLL once ourselves we keep it from
|
||||
// ever unloading it which makes shader compiling faster.
|
||||
//
|
||||
String compilerVersion = String::ToString( "D3DCompiler_%d.dll", (S32)D3DX_SDK_VERSION );
|
||||
smD3DX.compilerDllRef = OsLoadLibrary( compilerVersion );
|
||||
}
|
||||
376
Engine/source/gfx/D3D9/pc/gfxD3D9EnumTranslate.pc.cpp
Normal file
376
Engine/source/gfx/D3D9/pc/gfxD3D9EnumTranslate.pc.cpp
Normal file
|
|
@ -0,0 +1,376 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include <d3d9.h>
|
||||
#include "gfx/D3D9/gfxD3D9EnumTranslate.h"
|
||||
#include "console/console.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
_D3DFORMAT GFXD3D9IndexFormat[GFXIndexFormat_COUNT];
|
||||
_D3DSAMPLERSTATETYPE GFXD3D9SamplerState[GFXSAMP_COUNT];
|
||||
_D3DFORMAT GFXD3D9TextureFormat[GFXFormat_COUNT];
|
||||
_D3DRENDERSTATETYPE GFXD3D9RenderState[GFXRenderState_COUNT];
|
||||
_D3DTEXTUREFILTERTYPE GFXD3D9TextureFilter[GFXTextureFilter_COUNT];
|
||||
_D3DBLEND GFXD3D9Blend[GFXBlend_COUNT];
|
||||
_D3DBLENDOP GFXD3D9BlendOp[GFXBlendOp_COUNT];
|
||||
_D3DSTENCILOP GFXD3D9StencilOp[GFXStencilOp_COUNT];
|
||||
_D3DCMPFUNC GFXD3D9CmpFunc[GFXCmp_COUNT];
|
||||
_D3DCULL GFXD3D9CullMode[GFXCull_COUNT];
|
||||
_D3DFILLMODE GFXD3D9FillMode[GFXFill_COUNT];
|
||||
_D3DPRIMITIVETYPE GFXD3D9PrimType[GFXPT_COUNT];
|
||||
_D3DTEXTURESTAGESTATETYPE GFXD3D9TextureStageState[GFXTSS_COUNT];
|
||||
_D3DTEXTUREADDRESS GFXD3D9TextureAddress[GFXAddress_COUNT];
|
||||
_D3DTEXTUREOP GFXD3D9TextureOp[GFXTOP_COUNT];
|
||||
_D3DDECLTYPE GFXD3D9DeclType[GFXDeclType_COUNT];
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#define INIT_LOOKUPTABLE( tablearray, enumprefix, type ) \
|
||||
for( int i = enumprefix##_FIRST; i < enumprefix##_COUNT; i++ ) \
|
||||
tablearray##[i] = (##type##)GFX_UNINIT_VAL;
|
||||
|
||||
#define VALIDATE_LOOKUPTABLE( tablearray, enumprefix ) \
|
||||
for( int i = enumprefix##_FIRST; i < enumprefix##_COUNT; i++ ) \
|
||||
if( (int)tablearray##[i] == GFX_UNINIT_VAL ) \
|
||||
Con::warnf( "GFXD3D9EnumTranslate: Unassigned value in " #tablearray ": %i", i ); \
|
||||
else if( (int)tablearray##[i] == GFX_UNSUPPORTED_VAL ) \
|
||||
Con::warnf( "GFXD3D9EnumTranslate: Unsupported value in " #tablearray ": %i", i );
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void GFXD3D9EnumTranslate::init()
|
||||
{
|
||||
INIT_LOOKUPTABLE( GFXD3D9IndexFormat, GFXIndexFormat, _D3DFORMAT );
|
||||
GFXD3D9IndexFormat[GFXIndexFormat16] = D3DFMT_INDEX16;
|
||||
GFXD3D9IndexFormat[GFXIndexFormat32] = D3DFMT_INDEX32;
|
||||
VALIDATE_LOOKUPTABLE( GFXD3D9IndexFormat, GFXIndexFormat );
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
INIT_LOOKUPTABLE( GFXD3D9SamplerState, GFXSAMP, _D3DSAMPLERSTATETYPE );
|
||||
GFXD3D9SamplerState[GFXSAMPAddressU] = D3DSAMP_ADDRESSU;
|
||||
GFXD3D9SamplerState[GFXSAMPAddressV] = D3DSAMP_ADDRESSV;
|
||||
GFXD3D9SamplerState[GFXSAMPAddressW] = D3DSAMP_ADDRESSW;
|
||||
GFXD3D9SamplerState[GFXSAMPBorderColor] = D3DSAMP_BORDERCOLOR;
|
||||
GFXD3D9SamplerState[GFXSAMPMagFilter] = D3DSAMP_MAGFILTER;
|
||||
GFXD3D9SamplerState[GFXSAMPMinFilter] = D3DSAMP_MINFILTER;
|
||||
GFXD3D9SamplerState[GFXSAMPMipFilter] = D3DSAMP_MIPFILTER;
|
||||
GFXD3D9SamplerState[GFXSAMPMipMapLODBias] = D3DSAMP_MIPMAPLODBIAS;
|
||||
GFXD3D9SamplerState[GFXSAMPMaxMipLevel] = D3DSAMP_MAXMIPLEVEL;
|
||||
GFXD3D9SamplerState[GFXSAMPMaxAnisotropy] = D3DSAMP_MAXANISOTROPY;
|
||||
GFXD3D9SamplerState[GFXSAMPSRGBTexture] = D3DSAMP_SRGBTEXTURE;
|
||||
GFXD3D9SamplerState[GFXSAMPElementIndex] = D3DSAMP_ELEMENTINDEX;
|
||||
GFXD3D9SamplerState[GFXSAMPDMapOffset] = D3DSAMP_DMAPOFFSET;
|
||||
VALIDATE_LOOKUPTABLE( GFXD3D9SamplerState, GFXSAMP );
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
INIT_LOOKUPTABLE( GFXD3D9TextureFormat, GFXFormat, _D3DFORMAT );
|
||||
GFXD3D9TextureFormat[GFXFormatR8G8B8] = D3DFMT_R8G8B8;
|
||||
GFXD3D9TextureFormat[GFXFormatR8G8B8A8] = D3DFMT_A8R8G8B8;
|
||||
GFXD3D9TextureFormat[GFXFormatR8G8B8X8] = D3DFMT_X8R8G8B8;
|
||||
GFXD3D9TextureFormat[GFXFormatR5G6B5] = D3DFMT_R5G6B5;
|
||||
GFXD3D9TextureFormat[GFXFormatR5G5B5A1] = D3DFMT_A1R5G5B5;
|
||||
GFXD3D9TextureFormat[GFXFormatR5G5B5X1] = D3DFMT_X1R5G5B5;
|
||||
GFXD3D9TextureFormat[GFXFormatR32F] = D3DFMT_R32F;
|
||||
GFXD3D9TextureFormat[GFXFormatA4L4] = D3DFMT_A4L4;
|
||||
GFXD3D9TextureFormat[GFXFormatA8L8] = D3DFMT_A8L8;
|
||||
GFXD3D9TextureFormat[GFXFormatA8] = D3DFMT_A8;
|
||||
GFXD3D9TextureFormat[GFXFormatL8] = D3DFMT_L8;
|
||||
GFXD3D9TextureFormat[GFXFormatDXT1] = D3DFMT_DXT1;
|
||||
GFXD3D9TextureFormat[GFXFormatDXT2] = D3DFMT_DXT2;
|
||||
GFXD3D9TextureFormat[GFXFormatDXT3] = D3DFMT_DXT3;
|
||||
GFXD3D9TextureFormat[GFXFormatDXT4] = D3DFMT_DXT4;
|
||||
GFXD3D9TextureFormat[GFXFormatDXT5] = D3DFMT_DXT5;
|
||||
GFXD3D9TextureFormat[GFXFormatR32G32B32A32F] = D3DFMT_A32B32G32R32F;
|
||||
GFXD3D9TextureFormat[GFXFormatR16G16B16A16F] = D3DFMT_A16B16G16R16F;
|
||||
GFXD3D9TextureFormat[GFXFormatL16] = D3DFMT_L16;
|
||||
GFXD3D9TextureFormat[GFXFormatR16G16B16A16] = D3DFMT_A16B16G16R16;
|
||||
GFXD3D9TextureFormat[GFXFormatR16G16] = D3DFMT_G16R16;
|
||||
GFXD3D9TextureFormat[GFXFormatR16F] = D3DFMT_R16F;
|
||||
GFXD3D9TextureFormat[GFXFormatR16G16F] = D3DFMT_G16R16F;
|
||||
GFXD3D9TextureFormat[GFXFormatR10G10B10A2] = D3DFMT_A2R10G10B10;
|
||||
GFXD3D9TextureFormat[GFXFormatD32] = D3DFMT_D32;
|
||||
GFXD3D9TextureFormat[GFXFormatD24X8] = D3DFMT_D24X8;
|
||||
GFXD3D9TextureFormat[GFXFormatD24S8] = D3DFMT_D24S8;
|
||||
GFXD3D9TextureFormat[GFXFormatD24FS8] = D3DFMT_D24FS8;
|
||||
GFXD3D9TextureFormat[GFXFormatD16] = D3DFMT_D16;
|
||||
VALIDATE_LOOKUPTABLE( GFXD3D9TextureFormat, GFXFormat);
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
INIT_LOOKUPTABLE( GFXD3D9RenderState, GFXRenderState, _D3DRENDERSTATETYPE );
|
||||
GFXD3D9RenderState[GFXRSZEnable] = D3DRS_ZENABLE;
|
||||
GFXD3D9RenderState[GFXRSFillMode] = D3DRS_FILLMODE;
|
||||
GFXD3D9RenderState[GFXRSZWriteEnable] = D3DRS_ZWRITEENABLE;
|
||||
GFXD3D9RenderState[GFXRSAlphaTestEnable] = D3DRS_ALPHATESTENABLE;
|
||||
GFXD3D9RenderState[GFXRSSrcBlend] = D3DRS_SRCBLEND;
|
||||
GFXD3D9RenderState[GFXRSDestBlend] = D3DRS_DESTBLEND;
|
||||
GFXD3D9RenderState[GFXRSCullMode] = D3DRS_CULLMODE;
|
||||
GFXD3D9RenderState[GFXRSZFunc] = D3DRS_ZFUNC;
|
||||
GFXD3D9RenderState[GFXRSAlphaRef] = D3DRS_ALPHAREF;
|
||||
GFXD3D9RenderState[GFXRSAlphaFunc] = D3DRS_ALPHAFUNC;
|
||||
GFXD3D9RenderState[GFXRSAlphaBlendEnable] = D3DRS_ALPHABLENDENABLE;
|
||||
GFXD3D9RenderState[GFXRSStencilEnable] = D3DRS_STENCILENABLE;
|
||||
GFXD3D9RenderState[GFXRSStencilFail] = D3DRS_STENCILFAIL;
|
||||
GFXD3D9RenderState[GFXRSStencilZFail] = D3DRS_STENCILZFAIL;
|
||||
GFXD3D9RenderState[GFXRSStencilPass] = D3DRS_STENCILPASS;
|
||||
GFXD3D9RenderState[GFXRSStencilFunc] = D3DRS_STENCILFUNC;
|
||||
GFXD3D9RenderState[GFXRSStencilRef] = D3DRS_STENCILREF;
|
||||
GFXD3D9RenderState[GFXRSStencilMask] = D3DRS_STENCILMASK;
|
||||
GFXD3D9RenderState[GFXRSStencilWriteMask] = D3DRS_STENCILWRITEMASK;
|
||||
GFXD3D9RenderState[GFXRSWrap0] = D3DRS_WRAP0;
|
||||
GFXD3D9RenderState[GFXRSWrap1] = D3DRS_WRAP1;
|
||||
GFXD3D9RenderState[GFXRSWrap2] = D3DRS_WRAP2;
|
||||
GFXD3D9RenderState[GFXRSWrap3] = D3DRS_WRAP3;
|
||||
GFXD3D9RenderState[GFXRSWrap4] = D3DRS_WRAP4;
|
||||
GFXD3D9RenderState[GFXRSWrap5] = D3DRS_WRAP5;
|
||||
GFXD3D9RenderState[GFXRSWrap6] = D3DRS_WRAP6;
|
||||
GFXD3D9RenderState[GFXRSWrap7] = D3DRS_WRAP7;
|
||||
GFXD3D9RenderState[GFXRSClipPlaneEnable] = D3DRS_CLIPPLANEENABLE;
|
||||
GFXD3D9RenderState[GFXRSPointSize] = D3DRS_POINTSIZE;
|
||||
GFXD3D9RenderState[GFXRSPointSizeMin] = D3DRS_POINTSIZE_MIN;
|
||||
GFXD3D9RenderState[GFXRSPointSize_Max] = D3DRS_POINTSIZE_MAX;
|
||||
GFXD3D9RenderState[GFXRSPointSpriteEnable] = D3DRS_POINTSPRITEENABLE;
|
||||
GFXD3D9RenderState[GFXRSMultiSampleantiAlias] = D3DRS_MULTISAMPLEANTIALIAS;
|
||||
GFXD3D9RenderState[GFXRSMultiSampleMask] = D3DRS_MULTISAMPLEMASK;
|
||||
GFXD3D9RenderState[GFXRSShadeMode] = D3DRS_SHADEMODE;
|
||||
GFXD3D9RenderState[GFXRSLastPixel] = D3DRS_LASTPIXEL;
|
||||
GFXD3D9RenderState[GFXRSClipping] = D3DRS_CLIPPING;
|
||||
GFXD3D9RenderState[GFXRSPointScaleEnable] = D3DRS_POINTSCALEENABLE;
|
||||
GFXD3D9RenderState[GFXRSPointScale_A] = D3DRS_POINTSCALE_A;
|
||||
GFXD3D9RenderState[GFXRSPointScale_B] = D3DRS_POINTSCALE_B;
|
||||
GFXD3D9RenderState[GFXRSPointScale_C] = D3DRS_POINTSCALE_C;
|
||||
GFXD3D9RenderState[GFXRSLighting] = D3DRS_LIGHTING;
|
||||
GFXD3D9RenderState[GFXRSAmbient] = D3DRS_AMBIENT;
|
||||
GFXD3D9RenderState[GFXRSFogVertexMode] = D3DRS_FOGVERTEXMODE;
|
||||
GFXD3D9RenderState[GFXRSColorVertex] = D3DRS_COLORVERTEX;
|
||||
GFXD3D9RenderState[GFXRSLocalViewer] = D3DRS_LOCALVIEWER;
|
||||
GFXD3D9RenderState[GFXRSNormalizeNormals] = D3DRS_NORMALIZENORMALS;
|
||||
GFXD3D9RenderState[GFXRSDiffuseMaterialSource] = D3DRS_DIFFUSEMATERIALSOURCE;
|
||||
GFXD3D9RenderState[GFXRSSpecularMaterialSource] = D3DRS_SPECULARMATERIALSOURCE;
|
||||
GFXD3D9RenderState[GFXRSAmbientMaterialSource] = D3DRS_AMBIENTMATERIALSOURCE;
|
||||
GFXD3D9RenderState[GFXRSEmissiveMaterialSource] = D3DRS_EMISSIVEMATERIALSOURCE;
|
||||
GFXD3D9RenderState[GFXRSVertexBlend] = D3DRS_VERTEXBLEND;
|
||||
GFXD3D9RenderState[GFXRSFogEnable] = D3DRS_FOGENABLE;
|
||||
GFXD3D9RenderState[GFXRSSpecularEnable] = D3DRS_SPECULARENABLE;
|
||||
GFXD3D9RenderState[GFXRSFogColor] = D3DRS_FOGCOLOR;
|
||||
GFXD3D9RenderState[GFXRSFogTableMode] = D3DRS_FOGTABLEMODE;
|
||||
GFXD3D9RenderState[GFXRSFogStart] = D3DRS_FOGSTART;
|
||||
GFXD3D9RenderState[GFXRSFogEnd] = D3DRS_FOGEND;
|
||||
GFXD3D9RenderState[GFXRSFogDensity] = D3DRS_FOGDENSITY;
|
||||
GFXD3D9RenderState[GFXRSRangeFogEnable] = D3DRS_RANGEFOGENABLE;
|
||||
GFXD3D9RenderState[GFXRSDebugMonitorToken] = D3DRS_DEBUGMONITORTOKEN;
|
||||
GFXD3D9RenderState[GFXRSIndexedVertexBlendEnable] = D3DRS_INDEXEDVERTEXBLENDENABLE;
|
||||
GFXD3D9RenderState[GFXRSTweenFactor] = D3DRS_TWEENFACTOR;
|
||||
GFXD3D9RenderState[GFXRSTextureFactor] = D3DRS_TEXTUREFACTOR;
|
||||
GFXD3D9RenderState[GFXRSPatchEdgeStyle] = D3DRS_PATCHEDGESTYLE;
|
||||
GFXD3D9RenderState[GFXRSPositionDegree] = D3DRS_POSITIONDEGREE;
|
||||
GFXD3D9RenderState[GFXRSNormalDegree] = D3DRS_NORMALDEGREE;
|
||||
GFXD3D9RenderState[GFXRSAntiAliasedLineEnable] = D3DRS_ANTIALIASEDLINEENABLE;
|
||||
GFXD3D9RenderState[GFXRSAdaptiveTess_X] = D3DRS_ADAPTIVETESS_X;
|
||||
GFXD3D9RenderState[GFXRSAdaptiveTess_Y] = D3DRS_ADAPTIVETESS_Y;
|
||||
GFXD3D9RenderState[GFXRSdaptiveTess_Z] = D3DRS_ADAPTIVETESS_Z;
|
||||
GFXD3D9RenderState[GFXRSAdaptiveTess_W] = D3DRS_ADAPTIVETESS_W;
|
||||
GFXD3D9RenderState[GFXRSEnableAdaptiveTesselation] = D3DRS_ENABLEADAPTIVETESSELLATION;
|
||||
GFXD3D9RenderState[GFXRSDitherEnable] = D3DRS_DITHERENABLE;
|
||||
GFXD3D9RenderState[GFXRSColorWriteEnable] = D3DRS_COLORWRITEENABLE;
|
||||
GFXD3D9RenderState[GFXRSBlendOp] = D3DRS_BLENDOP;
|
||||
GFXD3D9RenderState[GFXRSScissorTestEnable] = D3DRS_SCISSORTESTENABLE;
|
||||
GFXD3D9RenderState[GFXRSSlopeScaleDepthBias] = D3DRS_SLOPESCALEDEPTHBIAS;
|
||||
GFXD3D9RenderState[GFXRSMinTessellationLevel] = D3DRS_MINTESSELLATIONLEVEL;
|
||||
GFXD3D9RenderState[GFXRSMaxTessellationLevel] = D3DRS_MAXTESSELLATIONLEVEL;
|
||||
GFXD3D9RenderState[GFXRSTwoSidedStencilMode] = D3DRS_TWOSIDEDSTENCILMODE;
|
||||
GFXD3D9RenderState[GFXRSCCWStencilFail] = D3DRS_CCW_STENCILFAIL;
|
||||
GFXD3D9RenderState[GFXRSCCWStencilZFail] = D3DRS_CCW_STENCILZFAIL;
|
||||
GFXD3D9RenderState[GFXRSCCWStencilPass] = D3DRS_CCW_STENCILPASS;
|
||||
GFXD3D9RenderState[GFXRSCCWStencilFunc] = D3DRS_CCW_STENCILFUNC;
|
||||
GFXD3D9RenderState[GFXRSColorWriteEnable1] = D3DRS_COLORWRITEENABLE1;
|
||||
GFXD3D9RenderState[GFXRSColorWriteEnable2] = D3DRS_COLORWRITEENABLE2;
|
||||
GFXD3D9RenderState[GFXRSolorWriteEnable3] = D3DRS_COLORWRITEENABLE3;
|
||||
GFXD3D9RenderState[GFXRSBlendFactor] = D3DRS_BLENDFACTOR;
|
||||
GFXD3D9RenderState[GFXRSSRGBWriteEnable] = D3DRS_SRGBWRITEENABLE;
|
||||
GFXD3D9RenderState[GFXRSDepthBias] = D3DRS_DEPTHBIAS;
|
||||
GFXD3D9RenderState[GFXRSWrap8] = D3DRS_WRAP8;
|
||||
GFXD3D9RenderState[GFXRSWrap9] = D3DRS_WRAP9;
|
||||
GFXD3D9RenderState[GFXRSWrap10] = D3DRS_WRAP10;
|
||||
GFXD3D9RenderState[GFXRSWrap11] = D3DRS_WRAP11;
|
||||
GFXD3D9RenderState[GFXRSWrap12] = D3DRS_WRAP12;
|
||||
GFXD3D9RenderState[GFXRSWrap13] = D3DRS_WRAP13;
|
||||
GFXD3D9RenderState[GFXRSWrap14] = D3DRS_WRAP14;
|
||||
GFXD3D9RenderState[GFXRSWrap15] = D3DRS_WRAP15;
|
||||
GFXD3D9RenderState[GFXRSSeparateAlphaBlendEnable] = D3DRS_SEPARATEALPHABLENDENABLE;
|
||||
GFXD3D9RenderState[GFXRSSrcBlendAlpha] = D3DRS_SRCBLENDALPHA;
|
||||
GFXD3D9RenderState[GFXRSDestBlendAlpha] = D3DRS_DESTBLENDALPHA;
|
||||
GFXD3D9RenderState[GFXRSBlendOpAlpha] = D3DRS_BLENDOPALPHA;
|
||||
VALIDATE_LOOKUPTABLE( GFXD3D9RenderState, GFXRenderState );
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
INIT_LOOKUPTABLE( GFXD3D9TextureFilter, GFXTextureFilter, _D3DTEXTUREFILTERTYPE );
|
||||
GFXD3D9TextureFilter[GFXTextureFilterNone] = D3DTEXF_NONE;
|
||||
GFXD3D9TextureFilter[GFXTextureFilterPoint] = D3DTEXF_POINT;
|
||||
GFXD3D9TextureFilter[GFXTextureFilterLinear] = D3DTEXF_LINEAR;
|
||||
GFXD3D9TextureFilter[GFXTextureFilterAnisotropic] = D3DTEXF_ANISOTROPIC;
|
||||
GFXD3D9TextureFilter[GFXTextureFilterPyramidalQuad] = D3DTEXF_PYRAMIDALQUAD;
|
||||
GFXD3D9TextureFilter[GFXTextureFilterGaussianQuad] = D3DTEXF_GAUSSIANQUAD;
|
||||
VALIDATE_LOOKUPTABLE( GFXD3D9TextureFilter, GFXTextureFilter );
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
INIT_LOOKUPTABLE( GFXD3D9Blend, GFXBlend, _D3DBLEND );
|
||||
GFXD3D9Blend[GFXBlendZero] = D3DBLEND_ZERO;
|
||||
GFXD3D9Blend[GFXBlendOne] = D3DBLEND_ONE;
|
||||
GFXD3D9Blend[GFXBlendSrcColor] = D3DBLEND_SRCCOLOR;
|
||||
GFXD3D9Blend[GFXBlendInvSrcColor] = D3DBLEND_INVSRCCOLOR;
|
||||
GFXD3D9Blend[GFXBlendSrcAlpha] = D3DBLEND_SRCALPHA;
|
||||
GFXD3D9Blend[GFXBlendInvSrcAlpha] = D3DBLEND_INVSRCALPHA;
|
||||
GFXD3D9Blend[GFXBlendDestAlpha] = D3DBLEND_DESTALPHA;
|
||||
GFXD3D9Blend[GFXBlendInvDestAlpha] = D3DBLEND_INVDESTALPHA;
|
||||
GFXD3D9Blend[GFXBlendDestColor] = D3DBLEND_DESTCOLOR;
|
||||
GFXD3D9Blend[GFXBlendInvDestColor] = D3DBLEND_INVDESTCOLOR;
|
||||
GFXD3D9Blend[GFXBlendSrcAlphaSat] = D3DBLEND_SRCALPHASAT;
|
||||
VALIDATE_LOOKUPTABLE( GFXD3D9Blend, GFXBlend );
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
INIT_LOOKUPTABLE( GFXD3D9BlendOp, GFXBlendOp, _D3DBLENDOP );
|
||||
GFXD3D9BlendOp[GFXBlendOpAdd] = D3DBLENDOP_ADD;
|
||||
GFXD3D9BlendOp[GFXBlendOpSubtract] = D3DBLENDOP_SUBTRACT;
|
||||
GFXD3D9BlendOp[GFXBlendOpRevSubtract] = D3DBLENDOP_REVSUBTRACT;
|
||||
GFXD3D9BlendOp[GFXBlendOpMin] = D3DBLENDOP_MIN;
|
||||
GFXD3D9BlendOp[GFXBlendOpMax] = D3DBLENDOP_MAX;
|
||||
VALIDATE_LOOKUPTABLE( GFXD3D9BlendOp, GFXBlendOp );
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
INIT_LOOKUPTABLE( GFXD3D9StencilOp, GFXStencilOp, _D3DSTENCILOP );
|
||||
GFXD3D9StencilOp[GFXStencilOpKeep] = D3DSTENCILOP_KEEP;
|
||||
GFXD3D9StencilOp[GFXStencilOpZero] = D3DSTENCILOP_ZERO;
|
||||
GFXD3D9StencilOp[GFXStencilOpReplace] = D3DSTENCILOP_REPLACE;
|
||||
GFXD3D9StencilOp[GFXStencilOpIncrSat] = D3DSTENCILOP_INCRSAT;
|
||||
GFXD3D9StencilOp[GFXStencilOpDecrSat] = D3DSTENCILOP_DECRSAT;
|
||||
GFXD3D9StencilOp[GFXStencilOpInvert] = D3DSTENCILOP_INVERT;
|
||||
GFXD3D9StencilOp[GFXStencilOpIncr] = D3DSTENCILOP_INCR;
|
||||
GFXD3D9StencilOp[GFXStencilOpDecr] = D3DSTENCILOP_DECR;
|
||||
VALIDATE_LOOKUPTABLE( GFXD3D9StencilOp, GFXStencilOp );
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
INIT_LOOKUPTABLE( GFXD3D9CmpFunc, GFXCmp, _D3DCMPFUNC );
|
||||
GFXD3D9CmpFunc[GFXCmpNever] = D3DCMP_NEVER;
|
||||
GFXD3D9CmpFunc[GFXCmpLess] = D3DCMP_LESS;
|
||||
GFXD3D9CmpFunc[GFXCmpEqual] = D3DCMP_EQUAL;
|
||||
GFXD3D9CmpFunc[GFXCmpLessEqual] = D3DCMP_LESSEQUAL;
|
||||
GFXD3D9CmpFunc[GFXCmpGreater] = D3DCMP_GREATER;
|
||||
GFXD3D9CmpFunc[GFXCmpNotEqual] = D3DCMP_NOTEQUAL;
|
||||
GFXD3D9CmpFunc[GFXCmpGreaterEqual] = D3DCMP_GREATEREQUAL;
|
||||
GFXD3D9CmpFunc[GFXCmpAlways] = D3DCMP_ALWAYS;
|
||||
VALIDATE_LOOKUPTABLE( GFXD3D9CmpFunc, GFXCmp );
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
INIT_LOOKUPTABLE( GFXD3D9CullMode, GFXCull, _D3DCULL );
|
||||
GFXD3D9CullMode[GFXCullNone] = D3DCULL_NONE;
|
||||
GFXD3D9CullMode[GFXCullCW] = D3DCULL_CW;
|
||||
GFXD3D9CullMode[GFXCullCCW] = D3DCULL_CCW;
|
||||
VALIDATE_LOOKUPTABLE( GFXD3D9CullMode, GFXCull );
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
INIT_LOOKUPTABLE( GFXD3D9FillMode, GFXFill, _D3DFILLMODE );
|
||||
GFXD3D9FillMode[GFXFillPoint] = D3DFILL_POINT;
|
||||
GFXD3D9FillMode[GFXFillWireframe] = D3DFILL_WIREFRAME;
|
||||
GFXD3D9FillMode[GFXFillSolid] = D3DFILL_SOLID;
|
||||
VALIDATE_LOOKUPTABLE( GFXD3D9FillMode, GFXFill );
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
INIT_LOOKUPTABLE( GFXD3D9PrimType, GFXPT, _D3DPRIMITIVETYPE );
|
||||
GFXD3D9PrimType[GFXPointList] = D3DPT_POINTLIST;
|
||||
GFXD3D9PrimType[GFXLineList] = D3DPT_LINELIST;
|
||||
GFXD3D9PrimType[GFXLineStrip] = D3DPT_LINESTRIP;
|
||||
GFXD3D9PrimType[GFXTriangleList] = D3DPT_TRIANGLELIST;
|
||||
GFXD3D9PrimType[GFXTriangleStrip] = D3DPT_TRIANGLESTRIP;
|
||||
GFXD3D9PrimType[GFXTriangleFan] = D3DPT_TRIANGLEFAN;
|
||||
VALIDATE_LOOKUPTABLE( GFXD3D9PrimType, GFXPT );
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
INIT_LOOKUPTABLE( GFXD3D9TextureStageState, GFXTSS, _D3DTEXTURESTAGESTATETYPE );
|
||||
GFXD3D9TextureStageState[GFXTSSColorOp] = D3DTSS_COLOROP;
|
||||
GFXD3D9TextureStageState[GFXTSSColorArg1] = D3DTSS_COLORARG1;
|
||||
GFXD3D9TextureStageState[GFXTSSColorArg2] = D3DTSS_COLORARG2;
|
||||
GFXD3D9TextureStageState[GFXTSSAlphaOp] = D3DTSS_ALPHAOP;
|
||||
GFXD3D9TextureStageState[GFXTSSAlphaArg1] = D3DTSS_ALPHAARG1;
|
||||
GFXD3D9TextureStageState[GFXTSSAlphaArg2] = D3DTSS_ALPHAARG2;
|
||||
GFXD3D9TextureStageState[GFXTSSBumpEnvMat00] = D3DTSS_BUMPENVMAT00;
|
||||
GFXD3D9TextureStageState[GFXTSSBumpEnvMat01] = D3DTSS_BUMPENVMAT01;
|
||||
GFXD3D9TextureStageState[GFXTSSBumpEnvMat10] = D3DTSS_BUMPENVMAT10;
|
||||
GFXD3D9TextureStageState[GFXTSSBumpEnvMat11] = D3DTSS_BUMPENVMAT11;
|
||||
GFXD3D9TextureStageState[GFXTSSTexCoordIndex] = D3DTSS_TEXCOORDINDEX;
|
||||
GFXD3D9TextureStageState[GFXTSSBumpEnvlScale] = D3DTSS_BUMPENVLSCALE;
|
||||
GFXD3D9TextureStageState[GFXTSSBumpEnvlOffset] = D3DTSS_BUMPENVLOFFSET;
|
||||
GFXD3D9TextureStageState[GFXTSSTextureTransformFlags] = D3DTSS_TEXTURETRANSFORMFLAGS;
|
||||
GFXD3D9TextureStageState[GFXTSSColorArg0] = D3DTSS_COLORARG0;
|
||||
GFXD3D9TextureStageState[GFXTSSAlphaArg0] = D3DTSS_ALPHAARG0;
|
||||
GFXD3D9TextureStageState[GFXTSSResultArg] = D3DTSS_RESULTARG;
|
||||
GFXD3D9TextureStageState[GFXTSSConstant] = D3DTSS_CONSTANT;
|
||||
VALIDATE_LOOKUPTABLE( GFXD3D9TextureStageState, GFXTSS );
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
INIT_LOOKUPTABLE( GFXD3D9TextureAddress, GFXAddress, _D3DTEXTUREADDRESS );
|
||||
GFXD3D9TextureAddress[GFXAddressWrap] = D3DTADDRESS_WRAP ;
|
||||
GFXD3D9TextureAddress[GFXAddressMirror] = D3DTADDRESS_MIRROR;
|
||||
GFXD3D9TextureAddress[GFXAddressClamp] = D3DTADDRESS_CLAMP;
|
||||
GFXD3D9TextureAddress[GFXAddressBorder] = D3DTADDRESS_BORDER;
|
||||
GFXD3D9TextureAddress[GFXAddressMirrorOnce] = D3DTADDRESS_MIRRORONCE;
|
||||
VALIDATE_LOOKUPTABLE(GFXD3D9TextureAddress, GFXAddress );
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
INIT_LOOKUPTABLE( GFXD3D9TextureOp, GFXTOP, _D3DTEXTUREOP );
|
||||
GFXD3D9TextureOp[GFXTOPDisable] = D3DTOP_DISABLE;
|
||||
GFXD3D9TextureOp[GFXTOPSelectARG1] = D3DTOP_SELECTARG1;
|
||||
GFXD3D9TextureOp[GFXTOPSelectARG2] = D3DTOP_SELECTARG2;
|
||||
GFXD3D9TextureOp[GFXTOPModulate] = D3DTOP_MODULATE;
|
||||
GFXD3D9TextureOp[GFXTOPModulate2X] = D3DTOP_MODULATE2X;
|
||||
GFXD3D9TextureOp[GFXTOPModulate4X] = D3DTOP_MODULATE4X;
|
||||
GFXD3D9TextureOp[GFXTOPAdd] = D3DTOP_ADD;
|
||||
GFXD3D9TextureOp[GFXTOPAddSigned] = D3DTOP_ADDSIGNED;
|
||||
GFXD3D9TextureOp[GFXTOPAddSigned2X] = D3DTOP_ADDSIGNED2X;
|
||||
GFXD3D9TextureOp[GFXTOPSubtract] = D3DTOP_SUBTRACT;
|
||||
GFXD3D9TextureOp[GFXTOPAddSmooth] = D3DTOP_ADDSMOOTH;
|
||||
GFXD3D9TextureOp[GFXTOPBlendDiffuseAlpha] = D3DTOP_BLENDDIFFUSEALPHA;
|
||||
GFXD3D9TextureOp[GFXTOPBlendTextureAlpha] = D3DTOP_BLENDTEXTUREALPHA;
|
||||
GFXD3D9TextureOp[GFXTOPBlendFactorAlpha] = D3DTOP_BLENDFACTORALPHA;
|
||||
GFXD3D9TextureOp[GFXTOPBlendTextureAlphaPM] = D3DTOP_BLENDTEXTUREALPHAPM;
|
||||
GFXD3D9TextureOp[GFXTOPBlendCURRENTALPHA] = D3DTOP_BLENDCURRENTALPHA;
|
||||
GFXD3D9TextureOp[GFXTOPPreModulate] = D3DTOP_PREMODULATE;
|
||||
GFXD3D9TextureOp[GFXTOPModulateAlphaAddColor] = D3DTOP_MODULATEALPHA_ADDCOLOR;
|
||||
GFXD3D9TextureOp[GFXTOPModulateColorAddAlpha] = D3DTOP_MODULATECOLOR_ADDALPHA;
|
||||
GFXD3D9TextureOp[GFXTOPModulateInvAlphaAddColor] = D3DTOP_MODULATEINVALPHA_ADDCOLOR;
|
||||
GFXD3D9TextureOp[GFXTOPModulateInvColorAddAlpha] = D3DTOP_MODULATEINVCOLOR_ADDALPHA;
|
||||
GFXD3D9TextureOp[GFXTOPBumpEnvMap] = D3DTOP_BUMPENVMAP;
|
||||
GFXD3D9TextureOp[GFXTOPBumpEnvMapLuminance] = D3DTOP_BUMPENVMAPLUMINANCE;
|
||||
GFXD3D9TextureOp[GFXTOPDotProduct3] = D3DTOP_DOTPRODUCT3;
|
||||
GFXD3D9TextureOp[GFXTOPLERP] = D3DTOP_LERP;
|
||||
VALIDATE_LOOKUPTABLE( GFXD3D9TextureOp, GFXTOP );
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
INIT_LOOKUPTABLE( GFXD3D9DeclType, GFXDeclType, _D3DDECLTYPE );
|
||||
GFXD3D9DeclType[GFXDeclType_Float] = D3DDECLTYPE_FLOAT1;
|
||||
GFXD3D9DeclType[GFXDeclType_Float2] = D3DDECLTYPE_FLOAT2;
|
||||
GFXD3D9DeclType[GFXDeclType_Float3] = D3DDECLTYPE_FLOAT3;
|
||||
GFXD3D9DeclType[GFXDeclType_Float4] = D3DDECLTYPE_FLOAT4;
|
||||
GFXD3D9DeclType[GFXDeclType_Color] = D3DDECLTYPE_D3DCOLOR;
|
||||
VALIDATE_LOOKUPTABLE( GFXD3D9DeclType, GFXDeclType );
|
||||
}
|
||||
|
||||
94
Engine/source/gfx/D3D9/pc/gfxD3D9PrimitiveBuffer.pc.cpp
Normal file
94
Engine/source/gfx/D3D9/pc/gfxD3D9PrimitiveBuffer.pc.cpp
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "gfx/D3D9/gfxD3D9Device.h"
|
||||
#include "gfx/D3D9/gfxD3D9PrimitiveBuffer.h"
|
||||
#include "core/util/safeRelease.h"
|
||||
|
||||
void GFXD3D9PrimitiveBuffer::lock(U32 indexStart, U32 indexEnd, void **indexPtr)
|
||||
{
|
||||
AssertFatal(!mLocked, "GFXD3D9PrimitiveBuffer::lock - Can't lock a primitive buffer more than once!");
|
||||
mLocked = true;
|
||||
U32 flags=0;
|
||||
switch(mBufferType)
|
||||
{
|
||||
case GFXBufferTypeStatic:
|
||||
// flags |= D3DLOCK_DISCARD;
|
||||
break;
|
||||
|
||||
case GFXBufferTypeDynamic:
|
||||
// Always discard the content within a locked region.
|
||||
flags |= D3DLOCK_DISCARD;
|
||||
break;
|
||||
|
||||
case GFXBufferTypeVolatile:
|
||||
// Get our range now...
|
||||
AssertFatal(indexStart == 0, "Cannot get a subrange on a volatile buffer.");
|
||||
AssertFatal(indexEnd < MAX_DYNAMIC_INDICES, "Cannot get more than MAX_DYNAMIC_INDICES in a volatile buffer. Up the constant!");
|
||||
|
||||
// Get the primtive buffer
|
||||
mVolatileBuffer = ((GFXD3D9Device*)mDevice)->mDynamicPB;
|
||||
|
||||
AssertFatal( mVolatileBuffer, "GFXD3D9PrimitiveBuffer::lock - No dynamic primitive buffer was available!");
|
||||
|
||||
// We created the pool when we requested this volatile buffer, so assume it exists...
|
||||
if( mVolatileBuffer->mIndexCount + indexEnd > MAX_DYNAMIC_INDICES )
|
||||
{
|
||||
flags |= D3DLOCK_DISCARD;
|
||||
mVolatileStart = indexStart = 0;
|
||||
indexEnd = indexEnd;
|
||||
}
|
||||
else
|
||||
{
|
||||
flags |= D3DLOCK_NOOVERWRITE;
|
||||
mVolatileStart = indexStart = mVolatileBuffer->mIndexCount;
|
||||
indexEnd += mVolatileBuffer->mIndexCount;
|
||||
}
|
||||
|
||||
mVolatileBuffer->mIndexCount = indexEnd + 1;
|
||||
ib = mVolatileBuffer->ib;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
D3D9Assert( ib->Lock(indexStart * sizeof(U16), (indexEnd - indexStart) * sizeof(U16), indexPtr, flags),
|
||||
"GFXD3D9PrimitiveBuffer::lock - Could not lock primitive buffer.");
|
||||
|
||||
#ifdef TORQUE_DEBUG
|
||||
|
||||
// Allocate a debug buffer large enough for the lock
|
||||
// plus space for over and under run guard strings.
|
||||
mLockedSize = (indexEnd - indexStart) * sizeof(U16);
|
||||
const U32 guardSize = sizeof( _PBGuardString );
|
||||
mDebugGuardBuffer = new U8[mLockedSize+(guardSize*2)];
|
||||
|
||||
// Setup the guard strings.
|
||||
dMemcpy( mDebugGuardBuffer, _PBGuardString, guardSize );
|
||||
dMemcpy( mDebugGuardBuffer + mLockedSize + guardSize, _PBGuardString, guardSize );
|
||||
|
||||
// Store the real lock pointer and return our debug pointer.
|
||||
mLockedBuffer = *indexPtr;
|
||||
*indexPtr = (U16*)( mDebugGuardBuffer + guardSize );
|
||||
|
||||
#endif // TORQUE_DEBUG
|
||||
}
|
||||
|
||||
1176
Engine/source/gfx/D3D9/pc/gfxPCD3D9Device.cpp
Normal file
1176
Engine/source/gfx/D3D9/pc/gfxPCD3D9Device.cpp
Normal file
File diff suppressed because it is too large
Load diff
81
Engine/source/gfx/D3D9/pc/gfxPCD3D9Device.h
Normal file
81
Engine/source/gfx/D3D9/pc/gfxPCD3D9Device.h
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GFX_PC_D3D9DEVICE_H_
|
||||
#define _GFX_PC_D3D9DEVICE_H_
|
||||
|
||||
#include "gfx/D3D9/gfxD3D9Device.h"
|
||||
|
||||
class PlatformWindow;
|
||||
class VideoFrameGrabberD3D9;
|
||||
|
||||
|
||||
class GFXPCD3D9Device : public GFXD3D9Device
|
||||
{
|
||||
typedef GFXD3D9Device Parent;
|
||||
|
||||
public:
|
||||
// Set to true to force nvperfhud device creation
|
||||
static bool mEnableNVPerfHUD;
|
||||
|
||||
GFXPCD3D9Device( LPDIRECT3D9 d3d, U32 index )
|
||||
: GFXD3D9Device( d3d, index ),
|
||||
mVideoFrameGrabber( NULL ) {};
|
||||
~GFXPCD3D9Device();
|
||||
|
||||
static GFXDevice *createInstance( U32 adapterIndex );
|
||||
|
||||
virtual GFXFormat selectSupportedFormat(GFXTextureProfile *profile,
|
||||
const Vector<GFXFormat> &formats, bool texture, bool mustblend, bool mustfilter);
|
||||
|
||||
static void enumerateAdapters( Vector<GFXAdapter*> &adapterList );
|
||||
|
||||
virtual void enumerateVideoModes();
|
||||
|
||||
virtual GFXWindowTarget *allocWindowTarget(PlatformWindow *window);
|
||||
virtual GFXTextureTarget *allocRenderToTextureTarget();
|
||||
virtual bool beginSceneInternal();
|
||||
|
||||
virtual void init( const GFXVideoMode &mode, PlatformWindow *window = NULL );
|
||||
|
||||
virtual void enterDebugEvent(ColorI color, const char *name);
|
||||
virtual void leaveDebugEvent();
|
||||
virtual void setDebugMarker(ColorI color, const char *name);
|
||||
|
||||
virtual void setMatrix( GFXMatrixType mtype, const MatrixF &mat );
|
||||
|
||||
virtual void initStates();
|
||||
virtual void reset( D3DPRESENT_PARAMETERS &d3dpp );
|
||||
virtual D3DPRESENT_PARAMETERS setupPresentParams( const GFXVideoMode &mode, const HWND &hwnd ) const;
|
||||
protected:
|
||||
|
||||
VideoFrameGrabberD3D9* mVideoFrameGrabber;
|
||||
|
||||
static GFXAdapter::CreateDeviceInstanceDelegate mCreateDeviceInstance;
|
||||
static void createDirect3D9(LPDIRECT3D9 &d3d9, LPDIRECT3D9EX &d3d9ex);
|
||||
HRESULT createDevice(U32 adapter, D3DDEVTYPE deviceType, HWND hFocusWindow, DWORD behaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters);
|
||||
|
||||
virtual void _setTextureStageState( U32 stage, U32 state, U32 value );
|
||||
void _validateMultisampleParams(D3DFORMAT format, D3DMULTISAMPLE_TYPE & aatype, DWORD & aalevel) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
587
Engine/source/gfx/D3D9/pc/gfxPCD3D9Target.cpp
Normal file
587
Engine/source/gfx/D3D9/pc/gfxPCD3D9Target.cpp
Normal file
|
|
@ -0,0 +1,587 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "gfx/D3D9/pc/gfxPCD3D9Target.h"
|
||||
|
||||
#include "gfx/D3D9/gfxD3D9Device.h"
|
||||
#include "gfx/D3D9/gfxD3D9TextureObject.h"
|
||||
#include "gfx/D3D9/gfxD3D9Cubemap.h"
|
||||
#include "gfx/D3D9/gfxD3D9EnumTranslate.h"
|
||||
#include "gfx/D3D9/pc/gfxPCD3D9Device.h"
|
||||
#include "gfx/gfxDebugEvent.h"
|
||||
#include "windowManager/win32/win32Window.h"
|
||||
|
||||
|
||||
GFXPCD3D9TextureTarget::GFXPCD3D9TextureTarget()
|
||||
: mTargetSize( Point2I::Zero ),
|
||||
mTargetFormat( GFXFormatR8G8B8A8 )
|
||||
{
|
||||
for(S32 i=0; i<MaxRenderSlotId; i++)
|
||||
{
|
||||
mTargets[i] = NULL;
|
||||
mResolveTargets[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
GFXPCD3D9TextureTarget::~GFXPCD3D9TextureTarget()
|
||||
{
|
||||
// Release anything we might be holding.
|
||||
for(S32 i=0; i<MaxRenderSlotId; i++)
|
||||
{
|
||||
mResolveTargets[i] = NULL;
|
||||
|
||||
if( GFXDevice::devicePresent() )
|
||||
{
|
||||
mDevice->destroyD3DResource( mTargets[i] ); // SAFE_RELEASE
|
||||
mTargets[i] = NULL;
|
||||
}
|
||||
else
|
||||
SAFE_RELEASE( mTargets[i] );
|
||||
}
|
||||
|
||||
zombify();
|
||||
}
|
||||
|
||||
void GFXPCD3D9TextureTarget::attachTexture( RenderSlot slot, GFXTextureObject *tex, U32 mipLevel/*=0*/, U32 zOffset /*= 0*/ )
|
||||
{
|
||||
GFXDEBUGEVENT_SCOPE( GFXPCD3D9TextureTarget_attachTexture, ColorI::RED );
|
||||
|
||||
AssertFatal(slot < MaxRenderSlotId, "GFXPCD3D9TextureTarget::attachTexture - out of range slot.");
|
||||
|
||||
// TODO: The way this is implemented... you can attach a texture
|
||||
// object multiple times and it will release and reset it.
|
||||
//
|
||||
// We should rework this to detect when no change has occured
|
||||
// and skip out early.
|
||||
|
||||
// Mark state as dirty so device can know to update.
|
||||
invalidateState();
|
||||
|
||||
// Release what we had, it's definitely going to change.
|
||||
mDevice->destroyD3DResource( mTargets[slot] ); // SAFE_RELEASE
|
||||
mTargets[slot] = NULL;
|
||||
mResolveTargets[slot] = NULL;
|
||||
|
||||
if(slot == Color0)
|
||||
{
|
||||
mTargetSize = Point2I::Zero;
|
||||
mTargetFormat = GFXFormatR8G8B8A8;
|
||||
}
|
||||
|
||||
// Are we clearing?
|
||||
if(!tex)
|
||||
{
|
||||
// Yup - just exit, it'll stay NULL.
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Take care of default targets
|
||||
if( tex == GFXTextureTarget::sDefaultDepthStencil )
|
||||
{
|
||||
mTargets[slot] = mDevice->mDeviceDepthStencil;
|
||||
mTargets[slot]->AddRef();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Cast the texture object to D3D...
|
||||
AssertFatal(dynamic_cast<GFXD3D9TextureObject*>(tex),
|
||||
"GFXPCD3D9TextureTarget::attachTexture - invalid texture object.");
|
||||
|
||||
GFXD3D9TextureObject *d3dto = static_cast<GFXD3D9TextureObject*>(tex);
|
||||
|
||||
// Grab the surface level.
|
||||
if( slot == DepthStencil )
|
||||
{
|
||||
mTargets[slot] = d3dto->getSurface();
|
||||
if ( mTargets[slot] )
|
||||
mTargets[slot]->AddRef();
|
||||
}
|
||||
else
|
||||
{
|
||||
// getSurface will almost always return NULL. It will only return non-NULL
|
||||
// if the surface that it needs to render to is different than the mip level
|
||||
// in the actual texture. This will happen with MSAA.
|
||||
if( d3dto->getSurface() == NULL )
|
||||
{
|
||||
D3D9Assert(d3dto->get2DTex()->GetSurfaceLevel(mipLevel, &mTargets[slot]),
|
||||
"GFXPCD3D9TextureTarget::attachTexture - could not get surface level for the passed texture!");
|
||||
}
|
||||
else
|
||||
{
|
||||
mTargets[slot] = d3dto->getSurface();
|
||||
mTargets[slot]->AddRef();
|
||||
|
||||
// Only assign resolve target if d3dto has a surface to give us.
|
||||
//
|
||||
// That usually means there is an MSAA target involved, which is why
|
||||
// the resolve is needed to get the data out of the target.
|
||||
mResolveTargets[slot] = d3dto;
|
||||
|
||||
if ( tex && slot == Color0 )
|
||||
{
|
||||
mTargetSize.set( tex->getSize().x, tex->getSize().y );
|
||||
mTargetFormat = tex->getFormat();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update surface size
|
||||
if(slot == Color0)
|
||||
{
|
||||
IDirect3DSurface9 *surface = mTargets[Color0];
|
||||
if ( surface )
|
||||
{
|
||||
D3DSURFACE_DESC sd;
|
||||
surface->GetDesc(&sd);
|
||||
mTargetSize = Point2I(sd.Width, sd.Height);
|
||||
|
||||
S32 format = sd.Format;
|
||||
GFXREVERSE_LOOKUP( GFXD3D9TextureFormat, GFXFormat, format );
|
||||
mTargetFormat = (GFXFormat)format;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GFXPCD3D9TextureTarget::attachTexture( RenderSlot slot, GFXCubemap *tex, U32 face, U32 mipLevel/*=0*/ )
|
||||
{
|
||||
GFXDEBUGEVENT_SCOPE( GFXPCD3D9TextureTarget_attachTexture_Cubemap, ColorI::RED );
|
||||
|
||||
AssertFatal(slot < MaxRenderSlotId, "GFXPCD3D9TextureTarget::attachTexture - out of range slot.");
|
||||
|
||||
// Mark state as dirty so device can know to update.
|
||||
invalidateState();
|
||||
|
||||
// Release what we had, it's definitely going to change.
|
||||
mDevice->destroyD3DResource( mTargets[slot] ); // SAFE_RELEASE
|
||||
mTargets[slot] = NULL;
|
||||
mResolveTargets[slot] = NULL;
|
||||
|
||||
// Cast the texture object to D3D...
|
||||
AssertFatal(!tex || dynamic_cast<GFXD3D9Cubemap*>(tex),
|
||||
"GFXD3DTextureTarget::attachTexture - invalid cubemap object.");
|
||||
|
||||
GFXD3D9Cubemap *cube = static_cast<GFXD3D9Cubemap*>(tex);
|
||||
|
||||
if(slot == Color0)
|
||||
{
|
||||
mTargetSize = Point2I::Zero;
|
||||
mTargetFormat = GFXFormatR8G8B8A8;
|
||||
}
|
||||
|
||||
// Are we clearing?
|
||||
if(!tex)
|
||||
{
|
||||
// Yup - just exit, it'll stay NULL.
|
||||
return;
|
||||
}
|
||||
|
||||
D3D9Assert(cube->mCubeTex->GetCubeMapSurface( (D3DCUBEMAP_FACES)face, mipLevel, &mTargets[slot] ),
|
||||
"GFXD3DTextureTarget::attachTexture - could not get surface level for the passed texture!");
|
||||
|
||||
// Update surface size
|
||||
if(slot == Color0)
|
||||
{
|
||||
IDirect3DSurface9 *surface = mTargets[Color0];
|
||||
if ( surface )
|
||||
{
|
||||
D3DSURFACE_DESC sd;
|
||||
surface->GetDesc(&sd);
|
||||
mTargetSize = Point2I(sd.Width, sd.Height);
|
||||
|
||||
S32 format = sd.Format;
|
||||
GFXREVERSE_LOOKUP( GFXD3D9TextureFormat, GFXFormat, format );
|
||||
mTargetFormat = (GFXFormat)format;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GFXPCD3D9TextureTarget::activate()
|
||||
{
|
||||
GFXDEBUGEVENT_SCOPE( GFXPCD3D9TextureTarget_activate, ColorI::RED );
|
||||
|
||||
AssertFatal( mTargets[GFXTextureTarget::Color0],
|
||||
"GFXPCD3D9TextureTarget::activate() - You can never have a NULL primary render target!" );
|
||||
|
||||
const U32 NumRenderTargets = getMin( mDevice->getNumRenderTargets(), (U32)Color4 - Color0 );
|
||||
|
||||
LPDIRECT3DDEVICE9 d3dDevice = mDevice->getDevice();
|
||||
|
||||
// Clear the state indicator.
|
||||
stateApplied();
|
||||
|
||||
IDirect3DSurface9 *depth = mTargets[GFXTextureTarget::DepthStencil];
|
||||
|
||||
// In debug lets do a complete test to be sure we don't
|
||||
// have a bad depth format for this display mode.
|
||||
#ifdef TORQUE_DEBUG
|
||||
|
||||
if ( depth && mTargets[GFXTextureTarget::Color0] )
|
||||
{
|
||||
D3DSURFACE_DESC desc;
|
||||
D3D9Assert( mTargets[GFXTextureTarget::Color0]->GetDesc( &desc ),
|
||||
"GFXPCD3D9TextureTarget::activate() - Failed to get surface description!");
|
||||
D3DFORMAT renderFormat = desc.Format;
|
||||
|
||||
D3D9Assert( depth->GetDesc( &desc ),
|
||||
"GFXPCD3D9TextureTarget::activate() - Failed to get surface description!");
|
||||
D3DFORMAT depthFormat = desc.Format;
|
||||
|
||||
HRESULT hr = mDevice->getD3D()->CheckDepthStencilMatch( D3DADAPTER_DEFAULT,
|
||||
D3DDEVTYPE_HAL,
|
||||
mDevice->mDisplayMode.Format,
|
||||
renderFormat,
|
||||
depthFormat );
|
||||
|
||||
D3D9Assert( hr, "GFXPCD3D9TextureTarget::activate() - Bad depth format for this target!" );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// First clear the non-primary targets to make the debug DX runtime happy.
|
||||
for(U32 i = 1; i < NumRenderTargets; i++)
|
||||
D3D9Assert(d3dDevice->SetRenderTarget( i, NULL ),
|
||||
avar("GFXPCD3D9TextureTarget::activate() - failed to clear texture target %d!", i) );
|
||||
|
||||
// Now set all the new surfaces into the appropriate slots.
|
||||
for(U32 i = 0; i < NumRenderTargets; i++)
|
||||
{
|
||||
IDirect3DSurface9 *target = mTargets[GFXTextureTarget::Color0 + i];
|
||||
if ( target )
|
||||
{
|
||||
D3D9Assert(d3dDevice->SetRenderTarget(i, target),
|
||||
avar("GFXPCD3D9TextureTarget::activate() - failed to set slot %d for texture target!", i) );
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: This is often the same shared depth buffer used by most
|
||||
// render targets. Are we getting performance hit from setting it
|
||||
// multiple times... aside from the function call?
|
||||
|
||||
D3D9Assert(d3dDevice->SetDepthStencilSurface( depth ),
|
||||
"GFXPCD3D9TextureTarget::activate() - failed to set depthstencil target!" );
|
||||
}
|
||||
|
||||
void GFXPCD3D9TextureTarget::deactivate()
|
||||
{
|
||||
// Nothing to do... the next activate() call will
|
||||
// set all the targets correctly.
|
||||
}
|
||||
|
||||
void GFXPCD3D9TextureTarget::resolve()
|
||||
{
|
||||
GFXDEBUGEVENT_SCOPE( GFXPCD3D9TextureTarget_resolve, ColorI::RED );
|
||||
|
||||
for (U32 i = 0; i < MaxRenderSlotId; i++)
|
||||
{
|
||||
// We use existance @ mResolveTargets as a flag that we need to copy
|
||||
// data from the rendertarget into the texture.
|
||||
if (mResolveTargets[i])
|
||||
{
|
||||
IDirect3DSurface9 *surf;
|
||||
D3D9Assert( mResolveTargets[i]->get2DTex()->GetSurfaceLevel( 0, &surf ),
|
||||
"GFXPCD3D9TextureTarget::resolve() - GetSurfaceLevel failed!" );
|
||||
|
||||
D3D9Assert( mDevice->getDevice()->StretchRect( mTargets[i], NULL, surf, NULL, D3DTEXF_NONE ),
|
||||
"GFXPCD3D9TextureTarget::resolve() - StretchRect failed!" );
|
||||
|
||||
surf->Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GFXPCD3D9TextureTarget::resolveTo( GFXTextureObject *tex )
|
||||
{
|
||||
GFXDEBUGEVENT_SCOPE( GFXPCD3D9TextureTarget_resolveTo, ColorI::RED );
|
||||
|
||||
if ( mTargets[Color0] == NULL )
|
||||
return;
|
||||
|
||||
IDirect3DSurface9 *surf;
|
||||
D3D9Assert( ((GFXD3D9TextureObject*)(tex))->get2DTex()->GetSurfaceLevel( 0, &surf ),
|
||||
"GFXPCD3D9TextureTarget::resolveTo() - GetSurfaceLevel failed!" );
|
||||
|
||||
D3D9Assert( mDevice->getDevice()->StretchRect( mTargets[Color0], NULL, surf, NULL, D3DTEXF_NONE ),
|
||||
"GFXPCD3D9TextureTarget::resolveTo() - StretchRect failed!" );
|
||||
|
||||
surf->Release();
|
||||
}
|
||||
|
||||
void GFXPCD3D9TextureTarget::zombify()
|
||||
{
|
||||
for(int i = 0; i < MaxRenderSlotId; i++)
|
||||
attachTexture(RenderSlot(i), NULL);
|
||||
}
|
||||
|
||||
void GFXPCD3D9TextureTarget::resurrect()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
GFXPCD3D9WindowTarget::GFXPCD3D9WindowTarget()
|
||||
{
|
||||
mSwapChain = NULL;
|
||||
mDepthStencil = NULL;
|
||||
mWindow = NULL;
|
||||
mDevice = NULL;
|
||||
mBackbuffer = NULL;
|
||||
mImplicit = true;
|
||||
}
|
||||
|
||||
GFXPCD3D9WindowTarget::~GFXPCD3D9WindowTarget()
|
||||
{
|
||||
SAFE_RELEASE(mSwapChain);
|
||||
SAFE_RELEASE(mDepthStencil);
|
||||
SAFE_RELEASE(mBackbuffer);
|
||||
}
|
||||
|
||||
void GFXPCD3D9WindowTarget::initPresentationParams()
|
||||
{
|
||||
// Get some video mode related info.
|
||||
GFXVideoMode vm = mWindow->getVideoMode();
|
||||
|
||||
// Do some validation...
|
||||
if(vm.fullScreen == true && mImplicit == false)
|
||||
{
|
||||
AssertISV(false,
|
||||
"GFXPCD3D9WindowTarget::initPresentationParams - Cannot go fullscreen with secondary window!");
|
||||
}
|
||||
|
||||
Win32Window *win = dynamic_cast<Win32Window*>(mWindow);
|
||||
AssertISV(win, "GFXPCD3D9WindowTarget::initPresentationParams() - got a non Win32Window window passed in! Did DX go crossplatform?");
|
||||
|
||||
HWND hwnd = win->getHWND();
|
||||
|
||||
// At some point, this will become GFXPCD3D9WindowTarget like trunk has,
|
||||
// so this cast isn't as bad as it looks. ;) BTR
|
||||
GFXPCD3D9Device* pcdevice = dynamic_cast<GFXPCD3D9Device*>(mDevice);
|
||||
mPresentationParams = pcdevice->setupPresentParams(vm, hwnd);
|
||||
|
||||
if (mImplicit)
|
||||
{
|
||||
pcdevice->mMultisampleType = mPresentationParams.MultiSampleType;
|
||||
pcdevice->mMultisampleLevel = mPresentationParams.MultiSampleQuality;
|
||||
}
|
||||
}
|
||||
|
||||
const Point2I GFXPCD3D9WindowTarget::getSize()
|
||||
{
|
||||
return mWindow->getVideoMode().resolution;
|
||||
}
|
||||
|
||||
GFXFormat GFXPCD3D9WindowTarget::getFormat()
|
||||
{
|
||||
S32 format = mPresentationParams.BackBufferFormat;
|
||||
GFXREVERSE_LOOKUP( GFXD3D9TextureFormat, GFXFormat, format );
|
||||
return (GFXFormat)format;
|
||||
}
|
||||
|
||||
bool GFXPCD3D9WindowTarget::present()
|
||||
{
|
||||
AssertFatal(mSwapChain, "GFXPCD3D9WindowTarget::present - no swap chain present to present!");
|
||||
HRESULT res = mSwapChain->Present(NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
return (res == S_OK);
|
||||
}
|
||||
|
||||
void GFXPCD3D9WindowTarget::setImplicitSwapChain()
|
||||
{
|
||||
AssertFatal(mImplicit, "Invalid swap chain type! Additional swap chains are created as needed");
|
||||
// Reacquire our swapchain & DS
|
||||
if(!mSwapChain)
|
||||
mDevice->getDevice()->GetSwapChain(0, &mSwapChain);
|
||||
if(!mDepthStencil)
|
||||
mDevice->getDevice()->GetDepthStencilSurface(&mDepthStencil);
|
||||
if (!mBackbuffer)
|
||||
mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackbuffer);
|
||||
}
|
||||
|
||||
void GFXPCD3D9WindowTarget::createAdditionalSwapChain()
|
||||
{
|
||||
AssertFatal(!mImplicit, "Invalid swap chain type! Implicit swap chains use the device");
|
||||
|
||||
// Since we're not going to do a device reset for an additional swap
|
||||
// chain, we can just release our resources and regrab them.
|
||||
SAFE_RELEASE(mSwapChain);
|
||||
SAFE_RELEASE(mDepthStencil);
|
||||
SAFE_RELEASE(mBackbuffer);
|
||||
|
||||
// If there's a fullscreen window active, don't try to create these additional swap chains.
|
||||
// CodeReview, we need to store the window target with the implicit swap chain better, this line below
|
||||
// could fail if the current render target isn't what we expect.
|
||||
GFXPCD3D9WindowTarget* currTarget = dynamic_cast<GFXPCD3D9WindowTarget*>(mDevice->getActiveRenderTarget());
|
||||
if (currTarget && currTarget->getWindow()->getVideoMode().fullScreen)
|
||||
return;
|
||||
|
||||
// Setup our presentation params.
|
||||
initPresentationParams();
|
||||
|
||||
// Create our resources!
|
||||
D3D9Assert(mDevice->getDevice()->CreateAdditionalSwapChain(&mPresentationParams, &mSwapChain),
|
||||
"GFXPCD3D9WindowTarget::createAdditionalSwapChain - couldn't reallocate additional swap chain!");
|
||||
D3D9Assert(mDevice->getDevice()->CreateDepthStencilSurface(mPresentationParams.BackBufferWidth, mPresentationParams.BackBufferHeight,
|
||||
D3DFMT_D24S8, mPresentationParams.MultiSampleType, mPresentationParams.MultiSampleQuality, false, &mDepthStencil, NULL),
|
||||
"GFXPCD3D9WindowTarget::createAdditionalSwapChain: Unable to create stencil/depth surface");
|
||||
D3D9Assert(mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackbuffer),
|
||||
"GFXPCD3D9WindowTarget::createAdditionalSwapChain: Unable to get backbuffer!");
|
||||
}
|
||||
|
||||
void GFXPCD3D9WindowTarget::resetMode()
|
||||
{
|
||||
mWindow->setSuppressReset(true);
|
||||
|
||||
if (mSwapChain)
|
||||
{
|
||||
// The current video settings.
|
||||
D3DPRESENT_PARAMETERS pp;
|
||||
mSwapChain->GetPresentParameters(&pp);
|
||||
bool ppFullscreen = !pp.Windowed;
|
||||
Point2I backbufferSize(pp.BackBufferWidth, pp.BackBufferHeight);
|
||||
|
||||
// The settings we are now applying.
|
||||
const GFXVideoMode &mode = mWindow->getVideoMode();
|
||||
|
||||
// Convert the current multisample parameters into something
|
||||
// we can compare with our GFXVideoMode.antialiasLevel value.
|
||||
U32 ppAntiAliaseLevel = 0;
|
||||
if ( pp.MultiSampleType != D3DMULTISAMPLE_NONE )
|
||||
ppAntiAliaseLevel = pp.MultiSampleQuality + 1;
|
||||
|
||||
// Early out if none of the settings which require a device reset
|
||||
// have changed.
|
||||
if ( backbufferSize == getSize() &&
|
||||
ppFullscreen == mode.fullScreen &&
|
||||
ppAntiAliaseLevel == mode.antialiasLevel )
|
||||
return;
|
||||
}
|
||||
|
||||
// So, the video mode has changed - if we're an additional swap chain
|
||||
// just kill the swapchain and reallocate to match new vid mode.
|
||||
if(mImplicit == false)
|
||||
{
|
||||
createAdditionalSwapChain();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Setup our presentation params.
|
||||
initPresentationParams();
|
||||
|
||||
// Otherwise, we have to reset the device, if we're the implicit swapchain.
|
||||
mDevice->reset(mPresentationParams);
|
||||
}
|
||||
|
||||
// Update our size, too.
|
||||
mSize = Point2I(mPresentationParams.BackBufferWidth, mPresentationParams.BackBufferHeight);
|
||||
|
||||
mWindow->setSuppressReset(false);
|
||||
}
|
||||
|
||||
void GFXPCD3D9WindowTarget::zombify()
|
||||
{
|
||||
// Release our resources
|
||||
SAFE_RELEASE(mSwapChain);
|
||||
SAFE_RELEASE(mDepthStencil);
|
||||
SAFE_RELEASE(mBackbuffer);
|
||||
}
|
||||
|
||||
void GFXPCD3D9WindowTarget::resurrect()
|
||||
{
|
||||
if(mImplicit)
|
||||
{
|
||||
setImplicitSwapChain();
|
||||
}
|
||||
else if(!mSwapChain)
|
||||
{
|
||||
createAdditionalSwapChain();
|
||||
}
|
||||
}
|
||||
|
||||
void GFXPCD3D9WindowTarget::activate()
|
||||
{
|
||||
GFXDEBUGEVENT_SCOPE( GFXPCD3D9WindowTarget_activate, ColorI::RED );
|
||||
|
||||
LPDIRECT3DDEVICE9 d3dDevice = mDevice->getDevice();
|
||||
|
||||
// In debug lets do a complete test to be sure we don't
|
||||
// have a bad depth format for this display mode.
|
||||
#ifdef TORQUE_DEBUG
|
||||
if ( mDepthStencil && mBackbuffer )
|
||||
{
|
||||
|
||||
D3DSURFACE_DESC desc;
|
||||
D3D9Assert( mBackbuffer->GetDesc( &desc ),
|
||||
"GFXPCD3D9TextureTarget::activate() - Failed to get surface description!");
|
||||
D3DFORMAT renderFormat = desc.Format;
|
||||
|
||||
D3D9Assert( mDepthStencil->GetDesc( &desc ),
|
||||
"GFXPCD3D9TextureTarget::activate() - Failed to get surface description!");
|
||||
D3DFORMAT depthFormat = desc.Format;
|
||||
|
||||
HRESULT hr = mDevice->getD3D()->CheckDepthStencilMatch( D3DADAPTER_DEFAULT,
|
||||
D3DDEVTYPE_HAL,
|
||||
mDevice->mDisplayMode.Format,
|
||||
renderFormat,
|
||||
depthFormat );
|
||||
|
||||
D3D9Assert( hr, "GFXPCD3D9WindowTarget::activate() - Bad depth format for this back buffer!" );
|
||||
}
|
||||
#endif
|
||||
|
||||
D3D9Assert( d3dDevice->SetRenderTarget( 0, mBackbuffer ),
|
||||
"GFXPCD3D9WindowTarget::activate() - Failed to set backbuffer target!" );
|
||||
|
||||
D3D9Assert( d3dDevice->SetDepthStencilSurface( mDepthStencil ),
|
||||
"GFXPCD3D9WindowTarget::activate() - Failed to set depthstencil target!" );
|
||||
|
||||
D3DPRESENT_PARAMETERS pp;
|
||||
|
||||
mSwapChain->GetPresentParameters(&pp);
|
||||
|
||||
// Update our video mode here, too.
|
||||
GFXVideoMode vm;
|
||||
vm = mWindow->getVideoMode();
|
||||
vm.resolution.x = pp.BackBufferWidth;
|
||||
vm.resolution.y = pp.BackBufferHeight;
|
||||
vm.fullScreen = !pp.Windowed;
|
||||
|
||||
mSize = vm.resolution;
|
||||
}
|
||||
|
||||
void GFXPCD3D9WindowTarget::resolveTo( GFXTextureObject *tex )
|
||||
{
|
||||
GFXDEBUGEVENT_SCOPE( GFXPCD3D9WindowTarget_resolveTo, ColorI::RED );
|
||||
|
||||
IDirect3DSurface9 *surf;
|
||||
D3D9Assert( ((GFXD3D9TextureObject*)(tex))->get2DTex()->GetSurfaceLevel( 0, &surf ),
|
||||
"GFXPCD3D9WindowTarget::resolveTo() - GetSurfaceLevel failed!" );
|
||||
|
||||
D3D9Assert( mDevice->getDevice()->StretchRect( mBackbuffer, NULL, surf, NULL, D3DTEXF_NONE ),
|
||||
"GFXPCD3D9WindowTarget::resolveTo() - StretchRect failed!" );
|
||||
|
||||
surf->Release();
|
||||
}
|
||||
130
Engine/source/gfx/D3D9/pc/gfxPCD3D9Target.h
Normal file
130
Engine/source/gfx/D3D9/pc/gfxPCD3D9Target.h
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef _GFX_D3D_GFXD3D9TARGET_H_
|
||||
#define _GFX_D3D_GFXD3D9TARGET_H_
|
||||
|
||||
#ifndef _GFXTARGET_H_
|
||||
#include "gfx/gfxTarget.h"
|
||||
#endif
|
||||
#ifndef _MPOINT3_H_
|
||||
#include "math/mPoint3.h"
|
||||
#endif
|
||||
#ifndef _MPOINT2_H_
|
||||
#include "math/mPoint2.h"
|
||||
#endif
|
||||
#include <d3d9.h>
|
||||
|
||||
struct IDirect3DSurface9;
|
||||
struct IDirect3DSwapChain9;
|
||||
class GFXD3D9TextureObject;
|
||||
|
||||
|
||||
class GFXPCD3D9TextureTarget : public GFXTextureTarget
|
||||
{
|
||||
friend class GFXPCD3D9Device;
|
||||
|
||||
// Array of target surfaces, this is given to us by attachTexture
|
||||
IDirect3DSurface9 * mTargets[MaxRenderSlotId];
|
||||
|
||||
// Array of texture objects which correspond to the target surfaces above,
|
||||
// needed for copy from RenderTarget to texture situations. Current only valid in those situations
|
||||
GFXD3D9TextureObject* mResolveTargets[MaxRenderSlotId];
|
||||
|
||||
/// Owning d3d device.
|
||||
GFXD3D9Device *mDevice;
|
||||
|
||||
Point2I mTargetSize;
|
||||
|
||||
GFXFormat mTargetFormat;
|
||||
|
||||
public:
|
||||
|
||||
GFXPCD3D9TextureTarget();
|
||||
~GFXPCD3D9TextureTarget();
|
||||
|
||||
// Public interface.
|
||||
virtual const Point2I getSize() { return mTargetSize; }
|
||||
virtual GFXFormat getFormat() { return mTargetFormat; }
|
||||
virtual void attachTexture(RenderSlot slot, GFXTextureObject *tex, U32 mipLevel=0, U32 zOffset = 0);
|
||||
virtual void attachTexture(RenderSlot slot, GFXCubemap *tex, U32 face, U32 mipLevel=0);
|
||||
virtual void resolve();
|
||||
|
||||
/// Note we always copy the Color0 RenderSlot.
|
||||
virtual void resolveTo( GFXTextureObject *tex );
|
||||
|
||||
virtual void activate();
|
||||
virtual void deactivate();
|
||||
|
||||
void zombify();
|
||||
void resurrect();
|
||||
};
|
||||
|
||||
class GFXPCD3D9WindowTarget : public GFXWindowTarget
|
||||
{
|
||||
friend class GFXPCD3D9Device;
|
||||
|
||||
/// Our depth stencil buffer, if any.
|
||||
IDirect3DSurface9 *mDepthStencil;
|
||||
|
||||
/// Our backbuffer
|
||||
IDirect3DSurface9 *mBackbuffer;
|
||||
|
||||
/// Maximum size we can render to.
|
||||
Point2I mSize;
|
||||
|
||||
/// Our swap chain, potentially the implicit device swap chain.
|
||||
IDirect3DSwapChain9 *mSwapChain;
|
||||
|
||||
/// D3D presentation info.
|
||||
D3DPRESENT_PARAMETERS mPresentationParams;
|
||||
|
||||
/// Owning d3d device.
|
||||
GFXD3D9Device *mDevice;
|
||||
|
||||
/// Is this the implicit swap chain?
|
||||
bool mImplicit;
|
||||
|
||||
/// Internal interface that notifies us we need to reset our video mode.
|
||||
void resetMode();
|
||||
|
||||
public:
|
||||
|
||||
GFXPCD3D9WindowTarget();
|
||||
~GFXPCD3D9WindowTarget();
|
||||
|
||||
virtual const Point2I getSize();
|
||||
virtual GFXFormat getFormat();
|
||||
virtual bool present();
|
||||
|
||||
void initPresentationParams();
|
||||
void setImplicitSwapChain();
|
||||
void createAdditionalSwapChain();
|
||||
|
||||
virtual void activate();
|
||||
|
||||
void zombify();
|
||||
void resurrect();
|
||||
|
||||
virtual void resolveTo( GFXTextureObject *tex );
|
||||
};
|
||||
|
||||
#endif // _GFX_D3D_GFXD3D9TARGET_H_
|
||||
110
Engine/source/gfx/D3D9/screenshotD3D9.cpp
Normal file
110
Engine/source/gfx/D3D9/screenshotD3D9.cpp
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "gfx/D3D9/screenshotD3D9.h"
|
||||
|
||||
#include "gfx/D3D9/gfxD3D9Device.h"
|
||||
|
||||
#include <d3d9.h>
|
||||
#include <d3dx9core.h>
|
||||
#include <d3dx9tex.h>
|
||||
|
||||
|
||||
GBitmap* ScreenShotD3D::_captureBackBuffer()
|
||||
{
|
||||
#ifdef TORQUE_OS_XENON
|
||||
return NULL;
|
||||
#else
|
||||
LPDIRECT3DDEVICE9 D3DDevice = dynamic_cast<GFXD3D9Device *>(GFX)->getDevice();
|
||||
|
||||
IDirect3DSurface9 * backBuffer;
|
||||
D3DDevice->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &backBuffer );
|
||||
|
||||
// Figure the size we're snagging.
|
||||
D3DSURFACE_DESC desc;
|
||||
backBuffer->GetDesc(&desc);
|
||||
|
||||
Point2I size;
|
||||
size.x = desc.Width;
|
||||
size.y = desc.Height;
|
||||
|
||||
// set up the 2 copy surfaces
|
||||
GFXTexHandle tex[2];
|
||||
IDirect3DSurface9 *surface[2];
|
||||
|
||||
tex[0].set( size.x, size.y, GFXFormatR8G8B8X8, &GFXDefaultRenderTargetProfile, avar("%s() - tex[0] (line %d)", __FUNCTION__, __LINE__) );
|
||||
tex[1].set( size.x, size.y, GFXFormatR8G8B8X8, &GFXSystemMemProfile, avar("%s() - tex[1] (line %d)", __FUNCTION__, __LINE__) );
|
||||
|
||||
// grab the top level surface of tex 0
|
||||
GFXD3D9TextureObject *to = (GFXD3D9TextureObject *) &(*tex[0]);
|
||||
D3D9Assert( to->get2DTex()->GetSurfaceLevel( 0, &surface[0] ), NULL );
|
||||
|
||||
// use StretchRect because it allows a copy from a multisample surface
|
||||
// to a normal rendertarget surface
|
||||
D3DDevice->StretchRect( backBuffer, NULL, surface[0], NULL, D3DTEXF_NONE );
|
||||
|
||||
// grab the top level surface of tex 1
|
||||
to = (GFXD3D9TextureObject *) &(*tex[1]);
|
||||
D3D9Assert( to->get2DTex()->GetSurfaceLevel( 0, &surface[1] ), NULL );
|
||||
|
||||
// copy the data from the render target to the system memory texture
|
||||
D3DDevice->GetRenderTargetData( surface[0], surface[1] );
|
||||
|
||||
// Allocate a GBitmap and copy into it.
|
||||
GBitmap *gb = new GBitmap(size.x, size.y);
|
||||
|
||||
D3DLOCKED_RECT r;
|
||||
D3DSURFACE_DESC d;
|
||||
surface[1]->GetDesc(&d);
|
||||
surface[1]->LockRect( &r, NULL, D3DLOCK_READONLY);
|
||||
|
||||
// We've got the X8 in there so we have to manually copy stuff.
|
||||
ColorI c;
|
||||
for(S32 i=0; i<size.y; i++)
|
||||
{
|
||||
const U8 *a = ((U8*)r.pBits) + i * size.x * 4;
|
||||
for(S32 j=0; j<size.x; j++)
|
||||
{
|
||||
c.blue = *(a++);
|
||||
c.green = *(a++);
|
||||
c.red = *(a++);
|
||||
a++; // Ignore X.
|
||||
|
||||
gb->setColor(j, i, c);
|
||||
}
|
||||
}
|
||||
|
||||
surface[1]->UnlockRect();
|
||||
|
||||
// Also save it out with D3DX
|
||||
//D3DXSaveSurfaceToFile( dT( "testScreen.png" ), D3DXIFF_PNG, surface[1], NULL, NULL );
|
||||
|
||||
// release the COM pointers
|
||||
surface[0]->Release();
|
||||
surface[1]->Release();
|
||||
backBuffer->Release();
|
||||
|
||||
return gb;
|
||||
#endif
|
||||
}
|
||||
|
||||
39
Engine/source/gfx/D3D9/screenshotD3D9.h
Normal file
39
Engine/source/gfx/D3D9/screenshotD3D9.h
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef _SCREENSHOTD3D_H_
|
||||
#define _SCREENSHOTD3D_H_
|
||||
|
||||
#include "gfx/screenshot.h"
|
||||
|
||||
//**************************************************************************
|
||||
// D3D implementation of screenshot
|
||||
//**************************************************************************
|
||||
class ScreenShotD3D : public ScreenShot
|
||||
{
|
||||
protected:
|
||||
|
||||
GBitmap* _captureBackBuffer();
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // _SCREENSHOTD3D_H_
|
||||
210
Engine/source/gfx/D3D9/videoCaptureD3D9.cpp
Normal file
210
Engine/source/gfx/D3D9/videoCaptureD3D9.cpp
Normal file
|
|
@ -0,0 +1,210 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "videoCaptureD3D9.h"
|
||||
#include "gfx/D3D9/gfxD3D9Device.h"
|
||||
|
||||
#include "platform/tmm_off.h"
|
||||
|
||||
#include <d3d9.h>
|
||||
#include <d3dx9core.h>
|
||||
#include <d3dx9tex.h>
|
||||
|
||||
VideoFrameGrabberD3D9::VideoFrameGrabberD3D9()
|
||||
{
|
||||
GFXDevice::getDeviceEventSignal().notify( this, &VideoFrameGrabberD3D9::_handleGFXEvent );
|
||||
mCurrentCapture = 0;
|
||||
}
|
||||
|
||||
VideoFrameGrabberD3D9::~VideoFrameGrabberD3D9()
|
||||
{
|
||||
GFXDevice::getDeviceEventSignal().remove( this, &VideoFrameGrabberD3D9::_handleGFXEvent );
|
||||
}
|
||||
|
||||
|
||||
void VideoFrameGrabberD3D9::captureBackBuffer()
|
||||
{
|
||||
AssertFatal( mCapture[mCurrentCapture].stage != eInSystemMemory, "Error! Trying to override a capture resource in \"SystemMemory\" stage!" );
|
||||
|
||||
#ifndef TORQUE_OS_XENON
|
||||
LPDIRECT3DDEVICE9 D3DDevice = dynamic_cast<GFXD3D9Device *>(GFX)->getDevice();
|
||||
|
||||
IDirect3DSurface9 * backBuffer;
|
||||
D3DDevice->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &backBuffer );
|
||||
|
||||
GFXTexHandle &vidMemTex = mCapture[mCurrentCapture].vidMemTex;
|
||||
|
||||
// Re-init video memory texture if needed
|
||||
if (vidMemTex.isNull() || vidMemTex.getWidthHeight() != mResolution)
|
||||
vidMemTex.set(mResolution.x, mResolution.y,GFXFormatR8G8B8X8, &GFXDefaultRenderTargetProfile, avar("%s() - mVidMemTex (line %d)", __FUNCTION__, __LINE__) );
|
||||
|
||||
// set up the copy surface
|
||||
IDirect3DSurface9 *surface;
|
||||
|
||||
// grab the top level surface of tex 0
|
||||
GFXD3D9TextureObject *to = (GFXD3D9TextureObject *) &(*vidMemTex);
|
||||
D3D9Assert( to->get2DTex()->GetSurfaceLevel( 0, &surface ), NULL );
|
||||
|
||||
// use StretchRect because it allows a copy from a multisample surface
|
||||
// to a normal rendertarget surface
|
||||
D3DDevice->StretchRect( backBuffer, NULL, surface, NULL, D3DTEXF_LINEAR );
|
||||
|
||||
// Reelase surfaces
|
||||
backBuffer->Release();
|
||||
surface->Release();
|
||||
|
||||
// Update the stage
|
||||
mCapture[mCurrentCapture].stage = eInVideoMemory;
|
||||
#endif
|
||||
}
|
||||
|
||||
void VideoFrameGrabberD3D9::makeBitmap()
|
||||
{
|
||||
// Advance the stages for all resources, except the one used for the last capture
|
||||
for (U32 i=0; i<eNumStages; i++)
|
||||
{
|
||||
if (i == mCurrentCapture)
|
||||
continue;
|
||||
|
||||
switch (mCapture[i].stage)
|
||||
{
|
||||
case eInVideoMemory:
|
||||
copyToSystemMemory(mCapture[i]);
|
||||
break;
|
||||
case eInSystemMemory:
|
||||
copyToBitmap(mCapture[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Change the resource being used for backbuffer captures
|
||||
mCurrentCapture = (mCurrentCapture + 1) % eNumStages;
|
||||
|
||||
AssertFatal( mCapture[mCurrentCapture].stage != eInSystemMemory, "Error! A capture resource with an invalid state was picked for making captures!" );
|
||||
}
|
||||
|
||||
void VideoFrameGrabberD3D9::releaseTextures()
|
||||
{
|
||||
for (U32 i=0; i<eNumStages; i++)
|
||||
{
|
||||
mCapture[i].sysMemTex.free();
|
||||
mCapture[i].vidMemTex.free();
|
||||
mCapture[i].stage = eReadyToCapture;
|
||||
}
|
||||
}
|
||||
|
||||
void VideoFrameGrabberD3D9::copyToSystemMemory(CaptureResource &capture)
|
||||
{
|
||||
AssertFatal( capture.stage == eInVideoMemory, "Error! copyToSystemMemory() can only work in resources in 'eInVideoMemory' stage!" );
|
||||
|
||||
#ifndef TORQUE_OS_XENON
|
||||
GFXTexHandle &vidMemTex = capture.vidMemTex;
|
||||
GFXTexHandle &sysMemTex = capture.sysMemTex;
|
||||
|
||||
// Initialize system memory texture if necessary
|
||||
Point2I size = vidMemTex.getWidthHeight();
|
||||
if (sysMemTex.isNull() || sysMemTex.getWidthHeight() != size)
|
||||
sysMemTex.set( size.x, size.y, GFXFormatR8G8B8X8, &GFXSystemMemProfile, avar("%s() - tex (line %d)", __FUNCTION__, __LINE__) );
|
||||
|
||||
// set up the 2 copy surfaces
|
||||
IDirect3DSurface9 *surface[2];
|
||||
|
||||
// grab the top level surface of tex 0
|
||||
GFXD3D9TextureObject *to = (GFXD3D9TextureObject *) &(*vidMemTex);
|
||||
D3D9Assert( to->get2DTex()->GetSurfaceLevel( 0, &surface[0] ), NULL );
|
||||
|
||||
// grab the top level surface of tex 1
|
||||
to = (GFXD3D9TextureObject *) &(*sysMemTex);
|
||||
D3D9Assert( to->get2DTex()->GetSurfaceLevel( 0, &surface[1] ), NULL );
|
||||
|
||||
// copy the data from the render target to the system memory texture
|
||||
LPDIRECT3DDEVICE9 D3DDevice = dynamic_cast<GFXD3D9Device *>(GFX)->getDevice();
|
||||
D3DDevice->GetRenderTargetData( surface[0], surface[1] );
|
||||
|
||||
// celease surfaces
|
||||
surface[0]->Release();
|
||||
surface[1]->Release();
|
||||
|
||||
// Change the resource state
|
||||
capture.stage = eInSystemMemory;
|
||||
#endif
|
||||
}
|
||||
|
||||
void VideoFrameGrabberD3D9::copyToBitmap(CaptureResource &capture)
|
||||
{
|
||||
AssertFatal( capture.stage == eInSystemMemory, "Error! copyToBitmap() can only work in resources in 'eInSystemMemory' stage!" );
|
||||
|
||||
GFXTexHandle &sysMemTex = capture.sysMemTex;
|
||||
Point2I size = sysMemTex.getWidthHeight();
|
||||
|
||||
// Setup a surface
|
||||
IDirect3DSurface9 *surface;
|
||||
|
||||
GFXD3D9TextureObject *to = (GFXD3D9TextureObject *) &(*sysMemTex);
|
||||
D3D9Assert( to->get2DTex()->GetSurfaceLevel( 0, &surface ), NULL );
|
||||
|
||||
// Lock the system memory surface
|
||||
D3DLOCKED_RECT r;
|
||||
D3DSURFACE_DESC d;
|
||||
surface->GetDesc(&d);
|
||||
surface->LockRect( &r, NULL, D3DLOCK_READONLY);
|
||||
|
||||
// Allocate a GBitmap and copy into it.
|
||||
GBitmap *gb = new GBitmap(size.x, size.y);
|
||||
|
||||
// We've got the X8 in there so we have to manually copy stuff.
|
||||
const U32* src = (const U32*)r.pBits;
|
||||
U8* dst = gb->getWritableBits();
|
||||
S32 pixels = size.x*size.y;
|
||||
for(S32 i=0; i<pixels; i++)
|
||||
{
|
||||
U32 px = *src++;
|
||||
*dst++ = px >> 16;
|
||||
*dst++ = px >> 8;
|
||||
*dst++ = px;
|
||||
}
|
||||
surface->UnlockRect();
|
||||
|
||||
// celease surfaces
|
||||
surface->Release();
|
||||
|
||||
// Push this new bitmap
|
||||
pushNewBitmap(gb);
|
||||
|
||||
// Change the resource state
|
||||
capture.stage = eReadyToCapture;
|
||||
}
|
||||
|
||||
bool VideoFrameGrabberD3D9::_handleGFXEvent( GFXDevice::GFXDeviceEventType event_ )
|
||||
{
|
||||
switch ( event_ )
|
||||
{
|
||||
case GFXDevice::deDestroy :
|
||||
releaseTextures();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
82
Engine/source/gfx/D3D9/videoCaptureD3D9.h
Normal file
82
Engine/source/gfx/D3D9/videoCaptureD3D9.h
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _VIDEOCAPTURE_H_
|
||||
#include "gfx/video/videoCapture.h"
|
||||
#endif
|
||||
|
||||
#ifndef _GFXDEVICE_H_
|
||||
#include "gfx/gfxDevice.h"
|
||||
#endif
|
||||
|
||||
|
||||
class VideoFrameGrabberD3D9 : public VideoFrameGrabber
|
||||
{
|
||||
protected:
|
||||
enum CaptureStage {
|
||||
eReadyToCapture,
|
||||
eInVideoMemory,
|
||||
eInSystemMemory,
|
||||
eNumStages
|
||||
};
|
||||
|
||||
// Contains all elements involved in single frame capture and
|
||||
// is used to spread the multiple "stages" needed to capture a bitmap
|
||||
// over various frames to keep GPU resources from locking the CPU.
|
||||
struct CaptureResource {
|
||||
GFXTexHandle vidMemTex; //Video memory texture
|
||||
GFXTexHandle sysMemTex; //System memory texture
|
||||
CaptureStage stage; //This resource's capture stage
|
||||
|
||||
CaptureResource() : stage(eReadyToCapture) {};
|
||||
~CaptureResource()
|
||||
{
|
||||
vidMemTex.free();
|
||||
sysMemTex.free();
|
||||
}
|
||||
};
|
||||
|
||||
// Capture resource array. One item for each capture pipeline stage
|
||||
CaptureResource mCapture[eNumStages];
|
||||
|
||||
// Current capture index
|
||||
S32 mCurrentCapture;
|
||||
|
||||
// Copies a capture's video memory content to system memory
|
||||
void copyToSystemMemory(CaptureResource &capture);
|
||||
|
||||
// Copies a capture's syste memory content to a new bitmap
|
||||
void copyToBitmap(CaptureResource &capture);
|
||||
|
||||
bool _handleGFXEvent(GFXDevice::GFXDeviceEventType event);
|
||||
|
||||
//------------------------------------------------
|
||||
// Overloaded from VideoFrameGrabber
|
||||
//------------------------------------------------
|
||||
void captureBackBuffer();
|
||||
void makeBitmap();
|
||||
void releaseTextures();
|
||||
|
||||
public:
|
||||
VideoFrameGrabberD3D9();
|
||||
~VideoFrameGrabberD3D9();
|
||||
};
|
||||
343
Engine/source/gfx/Null/gfxNullDevice.cpp
Normal file
343
Engine/source/gfx/Null/gfxNullDevice.cpp
Normal file
|
|
@ -0,0 +1,343 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "gfx/Null/gfxNullDevice.h"
|
||||
|
||||
#include "core/strings/stringFunctions.h"
|
||||
#include "gfx/gfxCubemap.h"
|
||||
#include "gfx/screenshot.h"
|
||||
#include "gfx/gfxPrimitiveBuffer.h"
|
||||
#include "gfx/gfxCardProfile.h"
|
||||
#include "gfx/gfxTextureManager.h"
|
||||
#include "gfx/bitmap/gBitmap.h"
|
||||
#include "core/util/safeDelete.h"
|
||||
|
||||
|
||||
GFXAdapter::CreateDeviceInstanceDelegate GFXNullDevice::mCreateDeviceInstance(GFXNullDevice::createInstance);
|
||||
|
||||
class GFXNullCardProfiler: public GFXCardProfiler
|
||||
{
|
||||
private:
|
||||
typedef GFXCardProfiler Parent;
|
||||
public:
|
||||
|
||||
///
|
||||
virtual const String &getRendererString() const { static String sRS("GFX Null Device Renderer"); return sRS; }
|
||||
|
||||
protected:
|
||||
|
||||
virtual void setupCardCapabilities() { };
|
||||
|
||||
virtual bool _queryCardCap(const String &query, U32 &foundResult){ return false; }
|
||||
virtual bool _queryFormat(const GFXFormat fmt, const GFXTextureProfile *profile, bool &inOutAutogenMips) { inOutAutogenMips = false; return false; }
|
||||
|
||||
public:
|
||||
virtual void init()
|
||||
{
|
||||
mCardDescription = "GFX Null Device Card";
|
||||
mChipSet = "NULL Device";
|
||||
mVersionString = "0";
|
||||
|
||||
Parent::init(); // other code notes that not calling this is "BAD".
|
||||
};
|
||||
};
|
||||
|
||||
class GFXNullTextureObject : public GFXTextureObject
|
||||
{
|
||||
public:
|
||||
GFXNullTextureObject(GFXDevice * aDevice, GFXTextureProfile *profile);
|
||||
~GFXNullTextureObject() { kill(); };
|
||||
|
||||
virtual void pureVirtualCrash() { };
|
||||
|
||||
virtual GFXLockedRect * lock( U32 mipLevel = 0, RectI *inRect = NULL ) { return NULL; };
|
||||
virtual void unlock( U32 mipLevel = 0) {};
|
||||
virtual bool copyToBmp(GBitmap *) { return false; };
|
||||
|
||||
virtual void zombify() {}
|
||||
virtual void resurrect() {}
|
||||
};
|
||||
|
||||
GFXNullTextureObject::GFXNullTextureObject(GFXDevice * aDevice, GFXTextureProfile *profile) :
|
||||
GFXTextureObject(aDevice, profile)
|
||||
{
|
||||
mProfile = profile;
|
||||
mTextureSize.set( 0, 0, 0 );
|
||||
}
|
||||
|
||||
class GFXNullTextureManager : public GFXTextureManager
|
||||
{
|
||||
protected:
|
||||
virtual GFXTextureObject *_createTextureObject( U32 height,
|
||||
U32 width,
|
||||
U32 depth,
|
||||
GFXFormat format,
|
||||
GFXTextureProfile *profile,
|
||||
U32 numMipLevels,
|
||||
bool forceMips = false,
|
||||
S32 antialiasLevel = 0,
|
||||
GFXTextureObject *inTex = NULL )
|
||||
{
|
||||
GFXNullTextureObject *retTex;
|
||||
if ( inTex )
|
||||
{
|
||||
AssertFatal( dynamic_cast<GFXNullTextureObject*>( inTex ), "GFXNullTextureManager::_createTexture() - Bad inTex type!" );
|
||||
retTex = static_cast<GFXNullTextureObject*>( inTex );
|
||||
}
|
||||
else
|
||||
{
|
||||
retTex = new GFXNullTextureObject( GFX, profile );
|
||||
retTex->registerResourceWithDevice( GFX );
|
||||
}
|
||||
|
||||
SAFE_DELETE( retTex->mBitmap );
|
||||
retTex->mBitmap = new GBitmap(width, height);
|
||||
return retTex;
|
||||
};
|
||||
|
||||
/// Load a texture from a proper DDSFile instance.
|
||||
virtual bool _loadTexture(GFXTextureObject *texture, DDSFile *dds){ return true; };
|
||||
|
||||
/// Load data into a texture from a GBitmap using the internal API.
|
||||
virtual bool _loadTexture(GFXTextureObject *texture, GBitmap *bmp){ return true; };
|
||||
|
||||
/// Load data into a texture from a raw buffer using the internal API.
|
||||
///
|
||||
/// Note that the size of the buffer is assumed from the parameters used
|
||||
/// for this GFXTextureObject's _createTexture call.
|
||||
virtual bool _loadTexture(GFXTextureObject *texture, void *raw){ return true; };
|
||||
|
||||
/// Refresh a texture using the internal API.
|
||||
virtual bool _refreshTexture(GFXTextureObject *texture){ return true; };
|
||||
|
||||
/// Free a texture (but do not delete the GFXTextureObject) using the internal
|
||||
/// API.
|
||||
///
|
||||
/// This is only called during zombification for textures which need it, so you
|
||||
/// don't need to do any internal safety checks.
|
||||
virtual bool _freeTexture(GFXTextureObject *texture, bool zombify=false) { return true; };
|
||||
|
||||
virtual U32 _getTotalVideoMemory() { return 0; };
|
||||
virtual U32 _getFreeVideoMemory() { return 0; };
|
||||
};
|
||||
|
||||
class GFXNullCubemap : public GFXCubemap
|
||||
{
|
||||
friend class GFXDevice;
|
||||
private:
|
||||
// should only be called by GFXDevice
|
||||
virtual void setToTexUnit( U32 tuNum ) { };
|
||||
|
||||
public:
|
||||
virtual void initStatic( GFXTexHandle *faces ) { };
|
||||
virtual void initStatic( DDSFile *dds ) { };
|
||||
virtual void initDynamic( U32 texSize, GFXFormat faceFormat = GFXFormatR8G8B8A8 ) { };
|
||||
virtual U32 getSize() const { return 0; }
|
||||
virtual GFXFormat getFormat() const { return GFXFormatR8G8B8A8; }
|
||||
|
||||
virtual ~GFXNullCubemap(){};
|
||||
|
||||
virtual void zombify() {}
|
||||
virtual void resurrect() {}
|
||||
};
|
||||
|
||||
class GFXNullVertexBuffer : public GFXVertexBuffer
|
||||
{
|
||||
unsigned char* tempBuf;
|
||||
public:
|
||||
GFXNullVertexBuffer( GFXDevice *device,
|
||||
U32 numVerts,
|
||||
const GFXVertexFormat *vertexFormat,
|
||||
U32 vertexSize,
|
||||
GFXBufferType bufferType ) :
|
||||
GFXVertexBuffer(device, numVerts, vertexFormat, vertexSize, bufferType) { };
|
||||
virtual void lock(U32 vertexStart, U32 vertexEnd, void **vertexPtr);
|
||||
virtual void unlock();
|
||||
virtual void prepare();
|
||||
|
||||
virtual void zombify() {}
|
||||
virtual void resurrect() {}
|
||||
};
|
||||
|
||||
void GFXNullVertexBuffer::lock(U32 vertexStart, U32 vertexEnd, void **vertexPtr)
|
||||
{
|
||||
tempBuf = new unsigned char[(vertexEnd - vertexStart) * mVertexSize];
|
||||
*vertexPtr = (void*) tempBuf;
|
||||
lockedVertexStart = vertexStart;
|
||||
lockedVertexEnd = vertexEnd;
|
||||
}
|
||||
|
||||
void GFXNullVertexBuffer::unlock()
|
||||
{
|
||||
delete[] tempBuf;
|
||||
tempBuf = NULL;
|
||||
}
|
||||
|
||||
void GFXNullVertexBuffer::prepare()
|
||||
{
|
||||
}
|
||||
|
||||
class GFXNullPrimitiveBuffer : public GFXPrimitiveBuffer
|
||||
{
|
||||
private:
|
||||
U16* temp;
|
||||
public:
|
||||
GFXNullPrimitiveBuffer( GFXDevice *device,
|
||||
U32 indexCount,
|
||||
U32 primitiveCount,
|
||||
GFXBufferType bufferType ) :
|
||||
GFXPrimitiveBuffer(device, indexCount, primitiveCount, bufferType), temp( NULL ) {};
|
||||
|
||||
virtual void lock(U32 indexStart, U32 indexEnd, void **indexPtr); ///< locks this primitive buffer for writing into
|
||||
virtual void unlock(); ///< unlocks this primitive buffer.
|
||||
virtual void prepare() { }; ///< prepares this primitive buffer for use on the device it was allocated on
|
||||
|
||||
virtual void zombify() {}
|
||||
virtual void resurrect() {}
|
||||
};
|
||||
|
||||
void GFXNullPrimitiveBuffer::lock(U32 indexStart, U32 indexEnd, void **indexPtr)
|
||||
{
|
||||
temp = new U16[indexEnd - indexStart];
|
||||
*indexPtr = temp;
|
||||
}
|
||||
|
||||
void GFXNullPrimitiveBuffer::unlock()
|
||||
{
|
||||
delete[] temp;
|
||||
temp = NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// GFXNullStateBlock
|
||||
//
|
||||
class GFXNullStateBlock : public GFXStateBlock
|
||||
{
|
||||
public:
|
||||
/// Returns the hash value of the desc that created this block
|
||||
virtual U32 getHashValue() const { return 0; };
|
||||
|
||||
/// Returns a GFXStateBlockDesc that this block represents
|
||||
virtual const GFXStateBlockDesc& getDesc() const { return mDefaultDesc; }
|
||||
|
||||
//
|
||||
// GFXResource
|
||||
//
|
||||
virtual void zombify() { }
|
||||
/// When called the resource should restore all device sensitive information destroyed by zombify()
|
||||
virtual void resurrect() { }
|
||||
private:
|
||||
GFXStateBlockDesc mDefaultDesc;
|
||||
};
|
||||
|
||||
//
|
||||
// GFXNullDevice
|
||||
//
|
||||
|
||||
GFXDevice *GFXNullDevice::createInstance( U32 adapterIndex )
|
||||
{
|
||||
return new GFXNullDevice();
|
||||
}
|
||||
|
||||
GFXNullDevice::GFXNullDevice()
|
||||
{
|
||||
clip.set(0, 0, 800, 800);
|
||||
|
||||
mTextureManager = new GFXNullTextureManager();
|
||||
gScreenShot = new ScreenShot();
|
||||
mCardProfiler = new GFXNullCardProfiler();
|
||||
mCardProfiler->init();
|
||||
}
|
||||
|
||||
GFXNullDevice::~GFXNullDevice()
|
||||
{
|
||||
}
|
||||
|
||||
GFXVertexBuffer *GFXNullDevice::allocVertexBuffer( U32 numVerts,
|
||||
const GFXVertexFormat *vertexFormat,
|
||||
U32 vertSize,
|
||||
GFXBufferType bufferType )
|
||||
{
|
||||
return new GFXNullVertexBuffer(GFX, numVerts, vertexFormat, vertSize, bufferType);
|
||||
}
|
||||
|
||||
GFXPrimitiveBuffer *GFXNullDevice::allocPrimitiveBuffer( U32 numIndices,
|
||||
U32 numPrimitives,
|
||||
GFXBufferType bufferType)
|
||||
{
|
||||
return new GFXNullPrimitiveBuffer(GFX, numIndices, numPrimitives, bufferType);
|
||||
}
|
||||
|
||||
GFXCubemap* GFXNullDevice::createCubemap()
|
||||
{
|
||||
return new GFXNullCubemap();
|
||||
};
|
||||
|
||||
void GFXNullDevice::enumerateAdapters( Vector<GFXAdapter*> &adapterList )
|
||||
{
|
||||
// Add the NULL renderer
|
||||
GFXAdapter *toAdd = new GFXAdapter();
|
||||
|
||||
toAdd->mIndex = 0;
|
||||
toAdd->mType = NullDevice;
|
||||
toAdd->mCreateDeviceInstanceDelegate = mCreateDeviceInstance;
|
||||
|
||||
GFXVideoMode vm;
|
||||
vm.bitDepth = 32;
|
||||
vm.resolution.set(800,600);
|
||||
toAdd->mAvailableModes.push_back(vm);
|
||||
|
||||
dStrcpy(toAdd->mName, "GFX Null Device");
|
||||
|
||||
adapterList.push_back(toAdd);
|
||||
}
|
||||
|
||||
void GFXNullDevice::setLightInternal(U32 lightStage, const GFXLightInfo light, bool lightEnable)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void GFXNullDevice::init( const GFXVideoMode &mode, PlatformWindow *window )
|
||||
{
|
||||
mCardProfiler = new GFXNullCardProfiler();
|
||||
mCardProfiler->init();
|
||||
}
|
||||
|
||||
GFXStateBlockRef GFXNullDevice::createStateBlockInternal(const GFXStateBlockDesc& desc)
|
||||
{
|
||||
return new GFXNullStateBlock();
|
||||
}
|
||||
|
||||
//
|
||||
// Register this device with GFXInit
|
||||
//
|
||||
class GFXNullRegisterDevice
|
||||
{
|
||||
public:
|
||||
GFXNullRegisterDevice()
|
||||
{
|
||||
GFXInit::getRegisterDeviceSignal().notify(&GFXNullDevice::enumerateAdapters);
|
||||
}
|
||||
};
|
||||
|
||||
static GFXNullRegisterDevice pNullRegisterDevice;
|
||||
185
Engine/source/gfx/Null/gfxNullDevice.h
Normal file
185
Engine/source/gfx/Null/gfxNullDevice.h
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GFXNullDevice_H_
|
||||
#define _GFXNullDevice_H_
|
||||
|
||||
#include "platform/platform.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "gfx/gfxDevice.h"
|
||||
#include "gfx/gfxInit.h"
|
||||
#include "gfx/gfxFence.h"
|
||||
|
||||
class GFXNullWindowTarget : public GFXWindowTarget
|
||||
{
|
||||
public:
|
||||
virtual bool present()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual const Point2I getSize()
|
||||
{
|
||||
// Return something stupid.
|
||||
return Point2I(1,1);
|
||||
}
|
||||
|
||||
virtual GFXFormat getFormat() { return GFXFormatR8G8B8A8; }
|
||||
|
||||
virtual void resetMode()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
virtual void zombify() {};
|
||||
virtual void resurrect() {};
|
||||
|
||||
};
|
||||
|
||||
class GFXNullDevice : public GFXDevice
|
||||
{
|
||||
public:
|
||||
GFXNullDevice();
|
||||
virtual ~GFXNullDevice();
|
||||
|
||||
static GFXDevice *createInstance( U32 adapterIndex );
|
||||
|
||||
static void enumerateAdapters( Vector<GFXAdapter*> &adapterList );
|
||||
|
||||
void init( const GFXVideoMode &mode, PlatformWindow *window = NULL );
|
||||
|
||||
virtual void activate() { };
|
||||
virtual void deactivate() { };
|
||||
virtual GFXAdapterType getAdapterType() { return NullDevice; };
|
||||
|
||||
/// @name Debug Methods
|
||||
/// @{
|
||||
virtual void enterDebugEvent(ColorI color, const char *name) { };
|
||||
virtual void leaveDebugEvent() { };
|
||||
virtual void setDebugMarker(ColorI color, const char *name) { };
|
||||
/// @}
|
||||
|
||||
/// Enumerates the supported video modes of the device
|
||||
virtual void enumerateVideoModes() { };
|
||||
|
||||
/// Sets the video mode for the device
|
||||
virtual void setVideoMode( const GFXVideoMode &mode ) { };
|
||||
protected:
|
||||
static GFXAdapter::CreateDeviceInstanceDelegate mCreateDeviceInstance;
|
||||
|
||||
/// Called by GFXDevice to create a device specific stateblock
|
||||
virtual GFXStateBlockRef createStateBlockInternal(const GFXStateBlockDesc& desc);
|
||||
/// Called by GFXDevice to actually set a stateblock.
|
||||
virtual void setStateBlockInternal(GFXStateBlock* block, bool force) { };
|
||||
/// @}
|
||||
|
||||
/// Called by base GFXDevice to actually set a const buffer
|
||||
virtual void setShaderConstBufferInternal(GFXShaderConstBuffer* buffer) { };
|
||||
|
||||
virtual void setTextureInternal(U32 textureUnit, const GFXTextureObject*texture) { };
|
||||
|
||||
virtual void setLightInternal(U32 lightStage, const GFXLightInfo light, bool lightEnable);
|
||||
virtual void setLightMaterialInternal(const GFXLightMaterial mat) { };
|
||||
virtual void setGlobalAmbientInternal(ColorF color) { };
|
||||
|
||||
/// @name State Initalization.
|
||||
/// @{
|
||||
|
||||
/// State initalization. This MUST BE CALLED in setVideoMode after the device
|
||||
/// is created.
|
||||
virtual void initStates() { };
|
||||
|
||||
virtual void setMatrix( GFXMatrixType mtype, const MatrixF &mat ) { };
|
||||
|
||||
virtual GFXVertexBuffer *allocVertexBuffer( U32 numVerts,
|
||||
const GFXVertexFormat *vertexFormat,
|
||||
U32 vertSize,
|
||||
GFXBufferType bufferType );
|
||||
virtual GFXPrimitiveBuffer *allocPrimitiveBuffer( U32 numIndices,
|
||||
U32 numPrimitives,
|
||||
GFXBufferType bufferType );
|
||||
|
||||
virtual GFXVertexDecl* allocVertexDecl( const GFXVertexFormat *vertexFormat ) { return NULL; }
|
||||
virtual void setVertexDecl( const GFXVertexDecl *decl ) { }
|
||||
virtual void setVertexStream( U32 stream, GFXVertexBuffer *buffer ) { }
|
||||
virtual void setVertexStreamFrequency( U32 stream, U32 frequency ) { }
|
||||
|
||||
public:
|
||||
virtual GFXCubemap * createCubemap();
|
||||
|
||||
virtual F32 getFillConventionOffset() const { return 0.0f; };
|
||||
|
||||
///@}
|
||||
|
||||
virtual GFXTextureTarget *allocRenderToTextureTarget(){return NULL;};
|
||||
virtual GFXWindowTarget *allocWindowTarget(PlatformWindow *window)
|
||||
{
|
||||
return new GFXNullWindowTarget();
|
||||
};
|
||||
|
||||
virtual void _updateRenderTargets(){};
|
||||
|
||||
virtual F32 getPixelShaderVersion() const { return 0.0f; };
|
||||
virtual void setPixelShaderVersion( F32 version ) { };
|
||||
virtual U32 getNumSamplers() const { return 0; };
|
||||
virtual U32 getNumRenderTargets() const { return 0; };
|
||||
|
||||
virtual GFXShader* createShader() { return NULL; };
|
||||
|
||||
|
||||
virtual void clear( U32 flags, ColorI color, F32 z, U32 stencil ) { };
|
||||
virtual bool beginSceneInternal() { return true; };
|
||||
virtual void endSceneInternal() { };
|
||||
|
||||
virtual void drawPrimitive( GFXPrimitiveType primType, U32 vertexStart, U32 primitiveCount ) { };
|
||||
virtual void drawIndexedPrimitive( GFXPrimitiveType primType,
|
||||
U32 startVertex,
|
||||
U32 minIndex,
|
||||
U32 numVerts,
|
||||
U32 startIndex,
|
||||
U32 primitiveCount ) { };
|
||||
|
||||
virtual void setClipRect( const RectI &rect ) { };
|
||||
virtual const RectI &getClipRect() const { return clip; };
|
||||
|
||||
virtual void preDestroy() { Parent::preDestroy(); };
|
||||
|
||||
virtual U32 getMaxDynamicVerts() { return 16384; };
|
||||
virtual U32 getMaxDynamicIndices() { return 16384; };
|
||||
|
||||
virtual GFXFormat selectSupportedFormat( GFXTextureProfile *profile,
|
||||
const Vector<GFXFormat> &formats,
|
||||
bool texture,
|
||||
bool mustblend,
|
||||
bool mustfilter ) { return GFXFormatR8G8B8A8; };
|
||||
|
||||
GFXFence *createFence() { return new GFXGeneralFence( this ); }
|
||||
GFXOcclusionQuery* createOcclusionQuery() { return NULL; }
|
||||
|
||||
private:
|
||||
typedef GFXDevice Parent;
|
||||
RectI clip;
|
||||
};
|
||||
|
||||
#endif
|
||||
284
Engine/source/gfx/bitmap/bitmapUtils.cpp
Normal file
284
Engine/source/gfx/bitmap/bitmapUtils.cpp
Normal file
|
|
@ -0,0 +1,284 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "gfx/bitmap/bitmapUtils.h"
|
||||
|
||||
#include "platform/platform.h"
|
||||
|
||||
|
||||
void bitmapExtrude5551_c(const void *srcMip, void *mip, U32 srcHeight, U32 srcWidth)
|
||||
{
|
||||
const U16 *src = (const U16 *) srcMip;
|
||||
U16 *dst = (U16 *) mip;
|
||||
U32 stride = srcHeight != 1 ? srcWidth : 0;
|
||||
|
||||
U32 width = srcWidth >> 1;
|
||||
U32 height = srcHeight >> 1;
|
||||
if (width == 0) width = 1;
|
||||
if (height == 0) height = 1;
|
||||
|
||||
if (srcWidth != 1)
|
||||
{
|
||||
for(U32 y = 0; y < height; y++)
|
||||
{
|
||||
for(U32 x = 0; x < width; x++)
|
||||
{
|
||||
U32 a = src[0];
|
||||
U32 b = src[1];
|
||||
U32 c = src[stride];
|
||||
U32 d = src[stride+1];
|
||||
#if defined(TORQUE_BIG_ENDIAN)
|
||||
dst[x] = ((( (a >> 10) + (b >> 10) + (c >> 10) + (d >> 10)) >> 2) << 10) |
|
||||
((( ((a >> 5) & 0x1F) + ((b >> 5) & 0x1F) + ((c >> 5) & 0x1F) + ((d >> 5) & 0x1F)) >> 2) << 5) |
|
||||
((( ((a >> 0) & 0x1F) + ((b >> 0) & 0x1F) + ((c >> 0) & 0x1F) + ((d >> 0) & 0x1F)) >> 2) << 0);
|
||||
#else
|
||||
dst[x] = ((( (a >> 11) + (b >> 11) + (c >> 11) + (d >> 11)) >> 2) << 11) |
|
||||
((( ((a >> 6) & 0x1F) + ((b >> 6) & 0x1F) + ((c >> 6) & 0x1F) + ((d >> 6) & 0x1F)) >> 2) << 6) |
|
||||
((( ((a >> 1) & 0x1F) + ((b >> 1) & 0x1F) + ((c >> 1) & 0x1F) + ((d >> 1) & 0x1F)) >> 2) << 1);
|
||||
#endif
|
||||
src += 2;
|
||||
}
|
||||
src += stride;
|
||||
dst += width;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(U32 y = 0; y < height; y++)
|
||||
{
|
||||
U32 a = src[0];
|
||||
U32 c = src[stride];
|
||||
#if defined(TORQUE_OS_MAC)
|
||||
dst[y] = ((( (a >> 10) + (c >> 10)) >> 1) << 10) |
|
||||
((( ((a >> 5) & 0x1F) + ((c >> 5) & 0x1f)) >> 1) << 5) |
|
||||
((( ((a >> 0) & 0x1F) + ((c >> 0) & 0x1f)) >> 1) << 0);
|
||||
#else
|
||||
dst[y] = ((( (a >> 11) + (c >> 11)) >> 1) << 11) |
|
||||
((( ((a >> 6) & 0x1f) + ((c >> 6) & 0x1f)) >> 1) << 6) |
|
||||
((( ((a >> 1) & 0x1F) + ((c >> 1) & 0x1f)) >> 1) << 1);
|
||||
#endif
|
||||
src += 1 + stride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void bitmapExtrudeRGB_c(const void *srcMip, void *mip, U32 srcHeight, U32 srcWidth)
|
||||
{
|
||||
const U8 *src = (const U8 *) srcMip;
|
||||
U8 *dst = (U8 *) mip;
|
||||
U32 stride = srcHeight != 1 ? (srcWidth) * 3 : 0;
|
||||
|
||||
U32 width = srcWidth >> 1;
|
||||
U32 height = srcHeight >> 1;
|
||||
if (width == 0) width = 1;
|
||||
if (height == 0) height = 1;
|
||||
|
||||
if (srcWidth != 1)
|
||||
{
|
||||
for(U32 y = 0; y < height; y++)
|
||||
{
|
||||
for(U32 x = 0; x < width; x++)
|
||||
{
|
||||
*dst++ = (U32(*src) + U32(src[3]) + U32(src[stride]) + U32(src[stride+3]) + 2) >> 2;
|
||||
src++;
|
||||
*dst++ = (U32(*src) + U32(src[3]) + U32(src[stride]) + U32(src[stride+3]) + 2) >> 2;
|
||||
src++;
|
||||
*dst++ = (U32(*src) + U32(src[3]) + U32(src[stride]) + U32(src[stride+3]) + 2) >> 2;
|
||||
src += 4;
|
||||
}
|
||||
src += stride; // skip
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(U32 y = 0; y < height; y++)
|
||||
{
|
||||
*dst++ = (U32(*src) + U32(src[stride]) + 1) >> 1;
|
||||
src++;
|
||||
*dst++ = (U32(*src) + U32(src[stride]) + 1) >> 1;
|
||||
src++;
|
||||
*dst++ = (U32(*src) + U32(src[stride]) + 1) >> 1;
|
||||
src += 4;
|
||||
|
||||
src += stride; // skip
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void bitmapExtrudeRGBA_c(const void *srcMip, void *mip, U32 srcHeight, U32 srcWidth)
|
||||
{
|
||||
const U8 *src = (const U8 *) srcMip;
|
||||
U8 *dst = (U8 *) mip;
|
||||
U32 stride = srcHeight != 1 ? (srcWidth) * 4 : 0;
|
||||
|
||||
U32 width = srcWidth >> 1;
|
||||
U32 height = srcHeight >> 1;
|
||||
if (width == 0) width = 1;
|
||||
if (height == 0) height = 1;
|
||||
|
||||
if (srcWidth != 1)
|
||||
{
|
||||
for(U32 y = 0; y < height; y++)
|
||||
{
|
||||
for(U32 x = 0; x < width; x++)
|
||||
{
|
||||
*dst++ = (U32(*src) + U32(src[4]) + U32(src[stride]) + U32(src[stride+4]) + 2) >> 2;
|
||||
src++;
|
||||
*dst++ = (U32(*src) + U32(src[4]) + U32(src[stride]) + U32(src[stride+4]) + 2) >> 2;
|
||||
src++;
|
||||
*dst++ = (U32(*src) + U32(src[4]) + U32(src[stride]) + U32(src[stride+4]) + 2) >> 2;
|
||||
src++;
|
||||
*dst++ = (U32(*src) + U32(src[4]) + U32(src[stride]) + U32(src[stride+4]) + 2) >> 2;
|
||||
src += 5;
|
||||
}
|
||||
src += stride; // skip
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(U32 y = 0; y < height; y++)
|
||||
{
|
||||
*dst++ = (U32(*src) + U32(src[stride]) + 1) >> 1;
|
||||
src++;
|
||||
*dst++ = (U32(*src) + U32(src[stride]) + 1) >> 1;
|
||||
src++;
|
||||
*dst++ = (U32(*src) + U32(src[stride]) + 1) >> 1;
|
||||
src++;
|
||||
*dst++ = (U32(*src) + U32(src[stride]) + 1) >> 1;
|
||||
src += 5;
|
||||
|
||||
src += stride; // skip
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void (*bitmapExtrude5551)(const void *srcMip, void *mip, U32 height, U32 width) = bitmapExtrude5551_c;
|
||||
void (*bitmapExtrudeRGB)(const void *srcMip, void *mip, U32 srcHeight, U32 srcWidth) = bitmapExtrudeRGB_c;
|
||||
void (*bitmapExtrudeRGBA)(const void *srcMip, void *mip, U32 srcHeight, U32 srcWidth) = bitmapExtrudeRGBA_c;
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void bitmapConvertRGB_to_1555_c(U8 *src, U32 pixels)
|
||||
{
|
||||
U16 *dst = (U16 *)src;
|
||||
for(U32 j = 0; j < pixels; j++)
|
||||
{
|
||||
U32 r = src[0] >> 3;
|
||||
U32 g = src[1] >> 3;
|
||||
U32 b = src[2] >> 3;
|
||||
|
||||
#if defined(TORQUE_OS_MAC)
|
||||
*dst++ = 0x8000 | (b << 10) | (g << 5) | (r << 0);
|
||||
#else
|
||||
*dst++ = b | (g << 5) | (r << 10) | 0x8000;
|
||||
#endif
|
||||
src += 3;
|
||||
}
|
||||
}
|
||||
|
||||
void (*bitmapConvertRGB_to_1555)(U8 *src, U32 pixels) = bitmapConvertRGB_to_1555_c;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void bitmapConvertRGB_to_5551_c(U8 *src, U32 pixels)
|
||||
{
|
||||
U16 *dst = (U16 *)src;
|
||||
for(U32 j = 0; j < pixels; j++)
|
||||
{
|
||||
U32 r = src[0] >> 3;
|
||||
U32 g = src[1] >> 3;
|
||||
U32 b = src[2] >> 3;
|
||||
|
||||
#if defined(TORQUE_OS_MAC)
|
||||
*dst++ = (1 << 15) | (b << 10) | (g << 5) | (r << 0);
|
||||
#else
|
||||
*dst++ = (b << 1) | (g << 6) | (r << 11) | 1;
|
||||
#endif
|
||||
src += 3;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void (*bitmapConvertRGB_to_5551)(U8 *src, U32 pixels) = bitmapConvertRGB_to_5551_c;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void bitmapConvertRGB_to_RGBX_c( U8 **src, U32 pixels )
|
||||
{
|
||||
const U8 *oldBits = *src;
|
||||
U8 *newBits = new U8[pixels * 4];
|
||||
dMemset( newBits, 0xFF, pixels * 4 ); // This is done to set alpha values -patw
|
||||
|
||||
// Copy the bits over to the new memory
|
||||
for( U32 i = 0; i < pixels; i++ )
|
||||
dMemcpy( &newBits[i * 4], &oldBits[i * 3], sizeof(U8) * 3 );
|
||||
|
||||
// Now hose the old bits
|
||||
delete [] *src;
|
||||
*src = newBits;
|
||||
}
|
||||
|
||||
void (*bitmapConvertRGB_to_RGBX)( U8 **src, U32 pixels ) = bitmapConvertRGB_to_RGBX_c;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void bitmapConvertRGBX_to_RGB_c( U8 **src, U32 pixels )
|
||||
{
|
||||
const U8 *oldBits = *src;
|
||||
U8 *newBits = new U8[pixels * 3];
|
||||
|
||||
// Copy the bits over to the new memory
|
||||
for( U32 i = 0; i < pixels; i++ )
|
||||
dMemcpy( &newBits[i * 3], &oldBits[i * 4], sizeof(U8) * 3 );
|
||||
|
||||
// Now hose the old bits
|
||||
delete [] *src;
|
||||
*src = newBits;
|
||||
}
|
||||
|
||||
void (*bitmapConvertRGBX_to_RGB)( U8 **src, U32 pixels ) = bitmapConvertRGBX_to_RGB_c;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void bitmapConvertA8_to_RGBA_c( U8 **src, U32 pixels )
|
||||
{
|
||||
const U8 *oldBits = *src;
|
||||
U8 *newBits = new U8[pixels * 4];
|
||||
|
||||
// Zero new bits
|
||||
dMemset( newBits, 0, pixels * 4 );
|
||||
|
||||
// Copy Alpha values
|
||||
for( U32 i = 0; i < pixels; i++ )
|
||||
newBits[i * 4 + 3] = oldBits[i];
|
||||
|
||||
// Now hose the old bits
|
||||
delete [] *src;
|
||||
*src = newBits;
|
||||
}
|
||||
|
||||
void (*bitmapConvertA8_to_RGBA)( U8 **src, U32 pixels ) = bitmapConvertA8_to_RGBA_c;
|
||||
41
Engine/source/gfx/bitmap/bitmapUtils.h
Normal file
41
Engine/source/gfx/bitmap/bitmapUtils.h
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _BITMAPUTILS_H_
|
||||
#define _BITMAPUTILS_H_
|
||||
|
||||
#ifndef _TORQUE_TYPES_H_
|
||||
#include "platform/types.h"
|
||||
#endif
|
||||
|
||||
extern void (*bitmapExtrude5551)(const void *srcMip, void *mip, U32 height, U32 width);
|
||||
extern void (*bitmapExtrudeRGB)(const void *srcMip, void *mip, U32 height, U32 width);
|
||||
extern void (*bitmapExtrudeRGBA)(const void *srcMip, void *mip, U32 height, U32 width);
|
||||
extern void (*bitmapConvertRGB_to_5551)(U8 *src, U32 pixels);
|
||||
extern void (*bitmapConvertRGB_to_1555)(U8 *src, U32 pixels);
|
||||
extern void (*bitmapConvertRGB_to_RGBX)( U8 **src, U32 pixels );
|
||||
extern void (*bitmapConvertRGBX_to_RGB)( U8 **src, U32 pixels );
|
||||
extern void (*bitmapConvertA8_to_RGBA)( U8 **src, U32 pixels );
|
||||
|
||||
void bitmapExtrudeRGB_c(const void *srcMip, void *mip, U32 height, U32 width);
|
||||
|
||||
#endif //_BITMAPUTILS_H_
|
||||
205
Engine/source/gfx/bitmap/ddsFile.h
Normal file
205
Engine/source/gfx/bitmap/ddsFile.h
Normal file
|
|
@ -0,0 +1,205 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _DDSFILE_H_
|
||||
#define _DDSFILE_H_
|
||||
|
||||
#ifndef _GFXSTRUCTS_H_
|
||||
#include "gfx/gfxStructs.h"
|
||||
#endif
|
||||
#ifndef _BITSET_H_
|
||||
#include "core/bitSet.h"
|
||||
#endif
|
||||
#ifndef _TVECTOR_H_
|
||||
#include "core/util/tVector.h"
|
||||
#endif
|
||||
#ifndef __RESOURCE_H__
|
||||
#include "core/resource.h"
|
||||
#endif
|
||||
|
||||
class Stream;
|
||||
class GBitmap;
|
||||
|
||||
|
||||
struct DDSFile
|
||||
{
|
||||
enum DDSFlags
|
||||
{
|
||||
ComplexFlag = BIT(0), ///< Indicates this includes a mipchain, cubemap, or
|
||||
/// volume texture, ie, isn't a plain old bitmap.
|
||||
MipMapsFlag = BIT(1), ///< Indicates we have a mipmap chain in the file.
|
||||
CubeMapFlag = BIT(2), ///< Indicates we are a cubemap. Requires all six faces.
|
||||
VolumeFlag = BIT(3), ///< Indicates we are a volume texture.
|
||||
|
||||
PitchSizeFlag = BIT(4), ///< Cue as to how to interpret our pitchlinear value.
|
||||
LinearSizeFlag = BIT(5), ///< Cue as to how to interpret our pitchlinear value.
|
||||
|
||||
RGBData = BIT(6), ///< Indicates that this is straight out RGBA data.
|
||||
CompressedData = BIT(7), ///< Indicates that this is compressed or otherwise
|
||||
/// exotic data.
|
||||
|
||||
/// These are the flags for which cubemap
|
||||
/// surfaces are included in the file.
|
||||
CubeMap_PosX_Flag = BIT(8),
|
||||
CubeMap_NegX_Flag = BIT(9),
|
||||
CubeMap_PosY_Flag = BIT(10),
|
||||
CubeMap_NegY_Flag = BIT(11),
|
||||
CubeMap_PosZ_Flag = BIT(12),
|
||||
CubeMap_NegZ_Flag = BIT(13),
|
||||
};
|
||||
|
||||
/// The index into mSurfaces for each
|
||||
/// cubemap face.
|
||||
enum
|
||||
{
|
||||
Cubemap_Surface_PosX,
|
||||
Cubemap_Surface_NegX,
|
||||
Cubemap_Surface_PosY,
|
||||
Cubemap_Surface_NegY,
|
||||
Cubemap_Surface_PosZ,
|
||||
Cubemap_Surface_NegZ,
|
||||
Cubemap_Surface_Count,
|
||||
};
|
||||
|
||||
BitSet32 mFlags;
|
||||
U32 mHeight;
|
||||
U32 mWidth;
|
||||
U32 mDepth;
|
||||
U32 mPitchOrLinearSize;
|
||||
U32 mMipMapCount;
|
||||
|
||||
GFXFormat mFormat;
|
||||
U32 mBytesPerPixel; ///< Ignored if we're a compressed texture.
|
||||
U32 mFourCC;
|
||||
String mCacheString;
|
||||
Torque::Path mSourcePath;
|
||||
|
||||
bool mHasTransparency;
|
||||
|
||||
// This is ugly... but it allows us to pass the number of
|
||||
// mips to drop into the ResourceManager loading process.
|
||||
static U32 smDropMipCount;
|
||||
|
||||
struct SurfaceData
|
||||
{
|
||||
SurfaceData()
|
||||
{
|
||||
VECTOR_SET_ASSOCIATION( mMips );
|
||||
}
|
||||
|
||||
~SurfaceData()
|
||||
{
|
||||
// Free our mips!
|
||||
for(S32 i=0; i<mMips.size(); i++)
|
||||
delete[] mMips[i];
|
||||
}
|
||||
|
||||
Vector<U8*> mMips;
|
||||
|
||||
// Helper function to read in a mipchain.
|
||||
bool readMipChain();
|
||||
|
||||
void dumpImage(DDSFile *dds, U32 mip, const char *file);
|
||||
|
||||
/// Helper for reading a mip level.
|
||||
void readNextMip(DDSFile *dds, Stream &s, U32 height, U32 width, U32 mipLevel, bool skip);
|
||||
|
||||
/// Helper for writing a mip level.
|
||||
void writeNextMip(DDSFile *dds, Stream &s, U32 height, U32 width, U32 mipLevel);
|
||||
};
|
||||
|
||||
Vector<SurfaceData*> mSurfaces;
|
||||
|
||||
/// Clear all our information; used before reading.
|
||||
void clear();
|
||||
|
||||
/// Reads a DDS file from the stream.
|
||||
bool read(Stream &s, U32 dropMipCount);
|
||||
|
||||
/// Called from read() to read in the DDS header.
|
||||
bool readHeader(Stream &s);
|
||||
|
||||
/// Writes this DDS file to the stream.
|
||||
bool write(Stream &s);
|
||||
|
||||
/// Called from write() to write the DDS header.
|
||||
bool writeHeader(Stream &s);
|
||||
|
||||
/// For our current format etc., what is the size of a surface with the
|
||||
/// given dimensions?
|
||||
U32 getSurfaceSize( U32 mipLevel = 0 ) const { return getSurfaceSize( mHeight, mWidth, mipLevel ); }
|
||||
U32 getSurfaceSize( U32 height, U32 width, U32 mipLevel = 0 ) const;
|
||||
|
||||
// Helper for getting the size in bytes of a compressed DDS texture.
|
||||
static U32 getSizeInBytes( GFXFormat format, U32 height, U32 width, U32 mipLevels );
|
||||
|
||||
/// Returns the total video memory size of the texture
|
||||
/// including all mipmaps and compression settings.
|
||||
U32 getSizeInBytes() const;
|
||||
|
||||
U32 getWidth( U32 mipLevel = 0 ) const { return getMax( U32(1), mWidth >> mipLevel ); }
|
||||
U32 getHeight( U32 mipLevel = 0 ) const { return getMax(U32(1), mHeight >> mipLevel); }
|
||||
U32 getDepth( U32 mipLevel = 0 ) const { return getMax(U32(1), mDepth >> mipLevel); }
|
||||
|
||||
U32 getMipLevels() const { return mMipMapCount; }
|
||||
|
||||
bool getHasTransparency() const { return mHasTransparency; }
|
||||
|
||||
bool isCubemap() const { return mFlags.test( CubeMapFlag ); }
|
||||
|
||||
GFXFormat getFormat() const { return mFormat; }
|
||||
|
||||
U32 getSurfacePitch( U32 mipLevel = 0 ) const;
|
||||
|
||||
const Torque::Path &getSourcePath() const { return mSourcePath; }
|
||||
const String &getTextureCacheString() const { return mCacheString; }
|
||||
|
||||
static Resource<DDSFile> load( const Torque::Path &path, U32 dropMipCount );
|
||||
|
||||
// For debugging fun!
|
||||
static S32 smActiveCopies;
|
||||
|
||||
DDSFile()
|
||||
{
|
||||
VECTOR_SET_ASSOCIATION( mSurfaces );
|
||||
smActiveCopies++;
|
||||
|
||||
mHasTransparency = false;
|
||||
}
|
||||
|
||||
DDSFile( const DDSFile &dds );
|
||||
|
||||
~DDSFile()
|
||||
{
|
||||
smActiveCopies--;
|
||||
|
||||
// Free our surfaces!
|
||||
for(S32 i=0; i<mSurfaces.size(); i++)
|
||||
delete mSurfaces[i];
|
||||
|
||||
mSurfaces.clear();
|
||||
}
|
||||
|
||||
static DDSFile *createDDSFileFromGBitmap( const GBitmap *gbmp );
|
||||
};
|
||||
|
||||
#endif // _DDSFILE_H_
|
||||
922
Engine/source/gfx/bitmap/ddsLoader.cpp
Normal file
922
Engine/source/gfx/bitmap/ddsLoader.cpp
Normal file
|
|
@ -0,0 +1,922 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "gfx/bitmap/ddsFile.h"
|
||||
|
||||
#include "gfx/gfxDevice.h"
|
||||
#include "core/util/fourcc.h"
|
||||
#include "console/console.h"
|
||||
#include "core/resourceManager.h"
|
||||
#include "core/stream/fileStream.h"
|
||||
#include "gfx/bitmap/gBitmap.h"
|
||||
#include "console/engineAPI.h"
|
||||
|
||||
|
||||
|
||||
S32 DDSFile::smActiveCopies = 0;
|
||||
U32 DDSFile::smDropMipCount = 0;
|
||||
|
||||
// These were copied from the DX9 docs. The names are changed
|
||||
// from the "real" defines since not all platforms have them.
|
||||
enum DDSSurfaceDescFlags
|
||||
{
|
||||
DDSDCaps = 0x00000001l,
|
||||
DDSDHeight = 0x00000002l,
|
||||
DDSDWidth = 0x00000004l,
|
||||
DDSDPitch = 0x00000008l,
|
||||
DDSDPixelFormat = 0x00001000l,
|
||||
DDSDMipMapCount = 0x00020000l,
|
||||
DDSDLinearSize = 0x00080000l,
|
||||
DDSDDepth = 0x00800000l,
|
||||
};
|
||||
|
||||
enum DDSPixelFormatFlags
|
||||
{
|
||||
DDPFAlphaPixels = 0x00000001,
|
||||
DDPFFourCC = 0x00000004,
|
||||
DDPFRGB = 0x00000040,
|
||||
DDPFLUMINANCE = 0x00020000
|
||||
};
|
||||
|
||||
|
||||
enum DDSCapFlags
|
||||
{
|
||||
DDSCAPSComplex = 0x00000008,
|
||||
DDSCAPSTexture = 0x00001000,
|
||||
DDSCAPSMipMap = 0x00400000,
|
||||
|
||||
DDSCAPS2Cubemap = 0x00000200,
|
||||
DDSCAPS2Cubemap_POSITIVEX = 0x00000400,
|
||||
DDSCAPS2Cubemap_NEGATIVEX = 0x00000800,
|
||||
DDSCAPS2Cubemap_POSITIVEY = 0x00001000,
|
||||
DDSCAPS2Cubemap_NEGATIVEY = 0x00002000,
|
||||
DDSCAPS2Cubemap_POSITIVEZ = 0x00004000,
|
||||
DDSCAPS2Cubemap_NEGATIVEZ = 0x00008000,
|
||||
DDSCAPS2Volume = 0x00200000,
|
||||
};
|
||||
|
||||
#define FOURCC_DXT1 (MakeFourCC('D','X','T','1'))
|
||||
#define FOURCC_DXT2 (MakeFourCC('D','X','T','2'))
|
||||
#define FOURCC_DXT3 (MakeFourCC('D','X','T','3'))
|
||||
#define FOURCC_DXT4 (MakeFourCC('D','X','T','4'))
|
||||
#define FOURCC_DXT5 (MakeFourCC('D','X','T','5'))
|
||||
|
||||
DDSFile::DDSFile( const DDSFile &dds )
|
||||
: mFlags( dds.mFlags ),
|
||||
mHeight( dds.mHeight ),
|
||||
mWidth( dds.mWidth ),
|
||||
mDepth( dds.mDepth ),
|
||||
mPitchOrLinearSize( dds.mPitchOrLinearSize ),
|
||||
mMipMapCount( dds.mMipMapCount ),
|
||||
mFormat( dds.mFormat ),
|
||||
mBytesPerPixel( dds.mBytesPerPixel ),
|
||||
mFourCC( dds.mFourCC ),
|
||||
mCacheString( dds.mCacheString ),
|
||||
mSourcePath( dds.mSourcePath ),
|
||||
mHasTransparency( dds.mHasTransparency )
|
||||
{
|
||||
VECTOR_SET_ASSOCIATION( mSurfaces );
|
||||
smActiveCopies++;
|
||||
|
||||
for ( U32 i=0; i < dds.mSurfaces.size(); i++ )
|
||||
{
|
||||
SurfaceData *surface = NULL;
|
||||
if ( dds.mSurfaces[i] )
|
||||
surface = new SurfaceData;
|
||||
|
||||
mSurfaces.push_back( surface );
|
||||
|
||||
if ( !surface )
|
||||
continue;
|
||||
|
||||
for ( U32 m=0; m < dds.mSurfaces[i]->mMips.size(); m++ )
|
||||
{
|
||||
U32 size = dds.getSurfaceSize( m );
|
||||
surface->mMips.push_back(new U8[size]);
|
||||
dMemcpy( surface->mMips.last(), dds.mSurfaces[i]->mMips[m], size );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DDSFile::clear()
|
||||
{
|
||||
mFlags = 0;
|
||||
mHeight = mWidth = mDepth = mPitchOrLinearSize = mMipMapCount = 0;
|
||||
mFormat = GFXFormatR8G8B8;
|
||||
}
|
||||
|
||||
U32 DDSFile::getSurfacePitch( U32 mipLevel ) const
|
||||
{
|
||||
if(mFlags.test(CompressedData))
|
||||
{
|
||||
U32 sizeMultiple = 0;
|
||||
|
||||
switch(mFormat)
|
||||
{
|
||||
case GFXFormatDXT1:
|
||||
sizeMultiple = 8;
|
||||
break;
|
||||
case GFXFormatDXT2:
|
||||
case GFXFormatDXT3:
|
||||
case GFXFormatDXT4:
|
||||
case GFXFormatDXT5:
|
||||
sizeMultiple = 16;
|
||||
break;
|
||||
default:
|
||||
AssertISV(false, "DDSFile::getPitch - invalid compressed texture format, we only support DXT1-5 right now.");
|
||||
break;
|
||||
}
|
||||
|
||||
// Maybe need to be DWORD aligned?
|
||||
U32 align = getMax(U32(1), getWidth(mipLevel)/4) * sizeMultiple;
|
||||
align += 3; align >>=2; align <<=2;
|
||||
return align;
|
||||
|
||||
}
|
||||
else
|
||||
return getWidth(mipLevel) * mBytesPerPixel;
|
||||
}
|
||||
|
||||
U32 DDSFile::getSurfaceSize( U32 height, U32 width, U32 mipLevel ) const
|
||||
{
|
||||
// Bump by the mip level.
|
||||
height = getMax(U32(1), height >> mipLevel);
|
||||
width = getMax(U32(1), width >> mipLevel);
|
||||
|
||||
if(mFlags.test(CompressedData))
|
||||
{
|
||||
// From the directX docs:
|
||||
// max(1, width ÷ 4) x max(1, height ÷ 4) x 8(DXT1) or 16(DXT2-5)
|
||||
|
||||
U32 sizeMultiple = 0;
|
||||
|
||||
switch(mFormat)
|
||||
{
|
||||
case GFXFormatDXT1:
|
||||
sizeMultiple = 8;
|
||||
break;
|
||||
case GFXFormatDXT2:
|
||||
case GFXFormatDXT3:
|
||||
case GFXFormatDXT4:
|
||||
case GFXFormatDXT5:
|
||||
sizeMultiple = 16;
|
||||
break;
|
||||
default:
|
||||
AssertISV(false, "DDSFile::getSurfaceSize - invalid compressed texture format, we only support DXT1-5 right now.");
|
||||
break;
|
||||
}
|
||||
|
||||
return getMax(U32(1), width/4) * getMax(U32(1), height/4) * sizeMultiple;
|
||||
}
|
||||
else
|
||||
{
|
||||
return height * width* mBytesPerPixel;
|
||||
}
|
||||
}
|
||||
|
||||
U32 DDSFile::getSizeInBytes() const
|
||||
{
|
||||
// TODO: This doesn't take mDepth into account, so
|
||||
// it doesn't work right for volume or cubemap textures!
|
||||
|
||||
U32 bytes = 0;
|
||||
for ( U32 i=0; i < mMipMapCount; i++ )
|
||||
bytes += getSurfaceSize( mHeight, mWidth, i );
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
U32 DDSFile::getSizeInBytes( GFXFormat format, U32 height, U32 width, U32 mipLevels )
|
||||
{
|
||||
AssertFatal( format >= GFXFormatDXT1 && format <= GFXFormatDXT5,
|
||||
"DDSFile::getSizeInBytes - Must be a DXT format!" );
|
||||
|
||||
// From the directX docs:
|
||||
// max(1, width ÷ 4) x max(1, height ÷ 4) x 8(DXT1) or 16(DXT2-5)
|
||||
|
||||
U32 sizeMultiple = 0;
|
||||
if ( format == GFXFormatDXT1 )
|
||||
sizeMultiple = 8;
|
||||
else
|
||||
sizeMultiple = 16;
|
||||
|
||||
U32 mipHeight, mipWidth;
|
||||
U32 bytes = 0;
|
||||
for ( U32 m=0; m < mipLevels; m++ )
|
||||
{
|
||||
mipHeight = getMax( U32(1), height >> m );
|
||||
mipWidth = getMax( U32(1), width >> m );
|
||||
|
||||
bytes += getMax( U32(1), mipWidth / 4 ) *
|
||||
getMax( U32(1), mipHeight / 4 ) * sizeMultiple;
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
bool DDSFile::readHeader(Stream &s)
|
||||
{
|
||||
U32 tmp;
|
||||
|
||||
// Read the FOURCC
|
||||
s.read(&tmp);
|
||||
|
||||
if(tmp != MakeFourCC('D', 'D', 'S', ' '))
|
||||
{
|
||||
Con::errorf("DDSFile::readHeader - unexpected magic number, wanted 'DDS '!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read the size of the header.
|
||||
s.read(&tmp);
|
||||
|
||||
if(tmp != 124)
|
||||
{
|
||||
Con::errorf("DDSFile::readHeader - incorrect header size. Expected 124 bytes.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read some flags...
|
||||
U32 ddsdFlags;
|
||||
s.read(&ddsdFlags);
|
||||
|
||||
// "Always include DDSD_CAPS, DDSD_PIXELFORMAT, DDSD_WIDTH, DDSD_HEIGHT."
|
||||
if(!(ddsdFlags & (DDSDCaps | DDSDPixelFormat | DDSDWidth | DDSDHeight)))
|
||||
{
|
||||
Con::errorf("DDSFile::readHeader - incorrect surface description flags.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read height and width (always present)
|
||||
s.read(&mHeight);
|
||||
s.read(&mWidth);
|
||||
|
||||
// Read pitch or linear size.
|
||||
|
||||
// First make sure we have valid flags (either linear size or pitch).
|
||||
if((ddsdFlags & (DDSDLinearSize | DDSDPitch)) == (DDSDLinearSize | DDSDPitch))
|
||||
{
|
||||
// Both are invalid!
|
||||
Con::errorf("DDSFile::readHeader - encountered both DDSD_LINEARSIZE and DDSD_PITCH!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ok, some flags are set, so let's do some reading.
|
||||
s.read(&mPitchOrLinearSize);
|
||||
|
||||
if(ddsdFlags & DDSDLinearSize)
|
||||
{
|
||||
mFlags.set(LinearSizeFlag); // ( mHeight / 4 ) * ( mWidth / 4 ) * DDSSIZE
|
||||
}
|
||||
else if (ddsdFlags & DDSDPitch)
|
||||
{
|
||||
mFlags.set(PitchSizeFlag); // ( mWidth / 4 ) * DDSSIZE ???
|
||||
}
|
||||
else
|
||||
{
|
||||
// Neither set! This appears to be depressingly common.
|
||||
// Con::warnf("DDSFile::readHeader - encountered neither DDSD_LINEARSIZE nor DDSD_PITCH!");
|
||||
}
|
||||
|
||||
// Do we need to read depth? If so, we are a volume texture!
|
||||
s.read(&mDepth);
|
||||
|
||||
if(ddsdFlags & DDSDDepth)
|
||||
{
|
||||
mFlags.set(VolumeFlag);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Wipe it if the flag wasn't set!
|
||||
mDepth = 0;
|
||||
}
|
||||
|
||||
// Deal with mips!
|
||||
s.read(&mMipMapCount);
|
||||
|
||||
if(ddsdFlags & DDSDMipMapCount)
|
||||
{
|
||||
mFlags.set(MipMapsFlag);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Wipe it if the flag wasn't set!
|
||||
mMipMapCount = 1;
|
||||
}
|
||||
|
||||
// Deal with 11 DWORDS of reserved space (this reserved space brought to
|
||||
// you by DirectDraw and the letters F and U).
|
||||
for(U32 i=0; i<11; i++)
|
||||
s.read(&tmp);
|
||||
|
||||
// Now we're onto the pixel format!
|
||||
s.read(&tmp);
|
||||
|
||||
if(tmp != 32)
|
||||
{
|
||||
Con::errorf("DDSFile::readHeader - pixel format chunk has unexpected size!");
|
||||
return false;
|
||||
}
|
||||
|
||||
U32 ddpfFlags;
|
||||
|
||||
s.read(&ddpfFlags);
|
||||
|
||||
// Read the next few values so we can deal with them all in one go.
|
||||
U32 pfFourCC, pfBitCount, pfRMask, pfGMask, pfBMask, pfAlphaMask;
|
||||
|
||||
s.read(&pfFourCC);
|
||||
s.read(&pfBitCount);
|
||||
s.read(&pfRMask);
|
||||
s.read(&pfGMask);
|
||||
s.read(&pfBMask);
|
||||
s.read(&pfAlphaMask);
|
||||
|
||||
// Sanity check flags...
|
||||
if(!(ddpfFlags & (DDPFRGB | DDPFFourCC | DDPFLUMINANCE)))
|
||||
{
|
||||
Con::errorf("DDSFile::readHeader - incoherent pixel flags, neither RGB, FourCC, or Luminance!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// For now let's just dump the header info.
|
||||
if(ddpfFlags & DDPFLUMINANCE)
|
||||
{
|
||||
mFlags.set(RGBData);
|
||||
|
||||
mBytesPerPixel = pfBitCount / 8;
|
||||
|
||||
bool hasAlpha = ddpfFlags & DDPFAlphaPixels;
|
||||
|
||||
mHasTransparency = hasAlpha;
|
||||
|
||||
// Try to match a format.
|
||||
if(hasAlpha)
|
||||
{
|
||||
// If it has alpha it is one of...
|
||||
// GFXFormatA8L8
|
||||
// GFXFormatA4L4
|
||||
|
||||
if(pfBitCount == 16)
|
||||
mFormat = GFXFormatA8L8;
|
||||
else if(pfBitCount == 8)
|
||||
mFormat = GFXFormatA4L4;
|
||||
else
|
||||
{
|
||||
Con::errorf("DDSFile::readHeader - unable to match alpha Luminance format!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise it is one of...
|
||||
// GFXFormatL16
|
||||
// GFXFormatL8
|
||||
|
||||
if(pfBitCount == 16)
|
||||
mFormat = GFXFormatL16;
|
||||
else if(pfBitCount == 8)
|
||||
mFormat = GFXFormatL8;
|
||||
else
|
||||
{
|
||||
Con::errorf("DDSFile::readHeader - unable to match non-alpha Luminance format!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(ddpfFlags & DDPFRGB)
|
||||
{
|
||||
mFlags.set(RGBData);
|
||||
|
||||
//Con::printf("RGB Pixel format of DDS:");
|
||||
//Con::printf(" bitcount = %d (16, 24, 32)", pfBitCount);
|
||||
mBytesPerPixel = pfBitCount / 8;
|
||||
//Con::printf(" red mask = %x", pfRMask);
|
||||
//Con::printf(" green mask = %x", pfGMask);
|
||||
//Con::printf(" blue mask = %x", pfBMask);
|
||||
|
||||
bool hasAlpha = false;
|
||||
|
||||
if(ddpfFlags & DDPFAlphaPixels)
|
||||
{
|
||||
hasAlpha = true;
|
||||
//Con::printf(" alpha mask = %x", pfAlphaMask);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Con::printf(" no alpha.");
|
||||
}
|
||||
|
||||
mHasTransparency = hasAlpha;
|
||||
|
||||
// Try to match a format.
|
||||
if(hasAlpha)
|
||||
{
|
||||
// If it has alpha it is one of...
|
||||
// GFXFormatR8G8B8A8
|
||||
// GFXFormatR5G5B5A1
|
||||
// GFXFormatA8
|
||||
|
||||
if(pfBitCount == 32)
|
||||
mFormat = GFXFormatR8G8B8A8;
|
||||
else if(pfBitCount == 16)
|
||||
mFormat = GFXFormatR5G5B5A1;
|
||||
else if(pfBitCount == 8)
|
||||
mFormat = GFXFormatA8;
|
||||
else
|
||||
{
|
||||
Con::errorf("DDSFile::readHeader - unable to match alpha RGB format!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise it is one of...
|
||||
// GFXFormatR8G8B8
|
||||
// GFXFormatR8G8B8X8
|
||||
// GFXFormatR5G6B5
|
||||
// GFXFormatL8
|
||||
|
||||
if(pfBitCount == 24)
|
||||
mFormat = GFXFormatR8G8B8;
|
||||
else if(pfBitCount == 32)
|
||||
mFormat = GFXFormatR8G8B8X8;
|
||||
else if(pfBitCount == 16)
|
||||
mFormat = GFXFormatR5G6B5;
|
||||
else if(pfBitCount == 8)
|
||||
{
|
||||
// luminance
|
||||
mFormat = GFXFormatL8;
|
||||
}
|
||||
else
|
||||
{
|
||||
Con::errorf("DDSFile::readHeader - unable to match non-alpha RGB format!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Sweet, all done.
|
||||
}
|
||||
else if (ddpfFlags & DDPFFourCC)
|
||||
{
|
||||
mHasTransparency = (ddpfFlags & DDPFAlphaPixels);
|
||||
mFlags.set(CompressedData);
|
||||
|
||||
/* Con::printf("FourCC Pixel format of DDS:");
|
||||
Con::printf(" fourcc = '%c%c%c%c'", ((U8*)&pfFourCC)[0], ((U8*)&pfFourCC)[1], ((U8*)&pfFourCC)[2], ((U8*)&pfFourCC)[3]); */
|
||||
|
||||
// Ok, make a format determination.
|
||||
switch(pfFourCC)
|
||||
{
|
||||
case FOURCC_DXT1:
|
||||
mFormat = GFXFormatDXT1;
|
||||
break;
|
||||
case FOURCC_DXT2:
|
||||
mFormat = GFXFormatDXT2;
|
||||
break;
|
||||
case FOURCC_DXT3:
|
||||
mFormat = GFXFormatDXT3;
|
||||
break;
|
||||
case FOURCC_DXT4:
|
||||
mFormat = GFXFormatDXT4;
|
||||
break;
|
||||
case FOURCC_DXT5:
|
||||
mFormat = GFXFormatDXT5;
|
||||
break;
|
||||
default:
|
||||
Con::errorf("DDSFile::readHeader - unknown fourcc = '%c%c%c%c'", ((U8*)&pfFourCC)[0], ((U8*)&pfFourCC)[1], ((U8*)&pfFourCC)[2], ((U8*)&pfFourCC)[3]);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Deal with final caps bits... Is this really necessary?
|
||||
|
||||
U32 caps1, caps2;
|
||||
s.read(&caps1);
|
||||
s.read(&caps2);
|
||||
s.read(&tmp);
|
||||
s.read(&tmp); // More icky reserved space.
|
||||
|
||||
// Screw caps1.
|
||||
// if(!(caps1 & DDSCAPS_TEXTURE)))
|
||||
// {
|
||||
// }
|
||||
|
||||
// Caps2 has cubemap/volume info. Care about that.
|
||||
if(caps2 & DDSCAPS2Cubemap)
|
||||
{
|
||||
mFlags.set(CubeMapFlag);
|
||||
|
||||
// Store the face flags too.
|
||||
if ( caps2 & DDSCAPS2Cubemap_POSITIVEX ) mFlags.set( CubeMap_PosX_Flag );
|
||||
if ( caps2 & DDSCAPS2Cubemap_NEGATIVEX ) mFlags.set( CubeMap_NegX_Flag );
|
||||
if ( caps2 & DDSCAPS2Cubemap_POSITIVEY ) mFlags.set( CubeMap_PosY_Flag );
|
||||
if ( caps2 & DDSCAPS2Cubemap_NEGATIVEY ) mFlags.set( CubeMap_NegY_Flag );
|
||||
if ( caps2 & DDSCAPS2Cubemap_POSITIVEZ ) mFlags.set( CubeMap_PosZ_Flag );
|
||||
if ( caps2 & DDSCAPS2Cubemap_NEGATIVEZ ) mFlags.set( CubeMap_NegZ_Flag );
|
||||
}
|
||||
|
||||
// MS has ANOTHER reserved word here. This one particularly sucks.
|
||||
s.read(&tmp);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DDSFile::read(Stream &s, U32 dropMipCount)
|
||||
{
|
||||
if( !readHeader(s) || mMipMapCount == 0 )
|
||||
{
|
||||
Con::errorf("DDSFile::read - error reading header!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we're droping mips then make sure we have enough.
|
||||
dropMipCount = getMin( dropMipCount, mMipMapCount - 1 );
|
||||
|
||||
// At this point we know what sort of image we contain. So we should
|
||||
// allocate some buffers, and read it in.
|
||||
|
||||
// How many surfaces are we talking about?
|
||||
if(mFlags.test(CubeMapFlag))
|
||||
{
|
||||
mSurfaces.setSize( Cubemap_Surface_Count );
|
||||
|
||||
for ( U32 i=0; i < Cubemap_Surface_Count; i++ )
|
||||
{
|
||||
// Does the cubemap contain this surface?
|
||||
if ( mFlags.test( CubeMap_PosX_Flag + ( i << 1 ) ) )
|
||||
mSurfaces[i] = new SurfaceData();
|
||||
else
|
||||
{
|
||||
mSurfaces[i] = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Load all the mips.
|
||||
for(S32 l=0; l<mMipMapCount; l++)
|
||||
mSurfaces[i]->readNextMip(this, s, mHeight, mWidth, l, l < dropMipCount );
|
||||
}
|
||||
|
||||
}
|
||||
else if (mFlags.test(VolumeFlag))
|
||||
{
|
||||
// Do something with volume
|
||||
}
|
||||
else
|
||||
{
|
||||
// It's a plain old texture.
|
||||
|
||||
// First allocate a SurfaceData to stick this in.
|
||||
mSurfaces.push_back(new SurfaceData());
|
||||
|
||||
// Load however many mips there are.
|
||||
for(S32 i=0; i<mMipMapCount; i++)
|
||||
mSurfaces.last()->readNextMip(this, s, mHeight, mWidth, i, i < dropMipCount);
|
||||
|
||||
// Ok, we're done.
|
||||
}
|
||||
|
||||
// If we're dropping mips then fix up the stats.
|
||||
if ( dropMipCount > 0 )
|
||||
{
|
||||
// Fix up the pitch and/or linear size.
|
||||
if( mFlags.test( LinearSizeFlag ) )
|
||||
mPitchOrLinearSize = getSurfaceSize( dropMipCount );
|
||||
else if ( mFlags.test( PitchSizeFlag ) )
|
||||
mPitchOrLinearSize = getSurfacePitch( dropMipCount );
|
||||
else
|
||||
mPitchOrLinearSize = mPitchOrLinearSize; // Do nothing?
|
||||
|
||||
// Now fix up the rest of the
|
||||
mMipMapCount = getMax( (U32)1, mMipMapCount - dropMipCount );
|
||||
mHeight = getHeight( dropMipCount );
|
||||
mWidth = getWidth( dropMipCount );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DDSFile::writeHeader( Stream &s )
|
||||
{
|
||||
// Read the FOURCC
|
||||
s.write( 4, "DDS " );
|
||||
|
||||
U32 tmp = 0;
|
||||
|
||||
// Read the size of the header.
|
||||
s.write( 124 );
|
||||
|
||||
// Read some flags...
|
||||
U32 ddsdFlags = DDSDCaps | DDSDPixelFormat | DDSDWidth | DDSDHeight;
|
||||
|
||||
if ( mFlags.test( CompressedData ) )
|
||||
ddsdFlags |= DDSDLinearSize;
|
||||
else
|
||||
ddsdFlags |= DDSDPitch;
|
||||
|
||||
if ( mMipMapCount > 0 )
|
||||
ddsdFlags |= DDSDMipMapCount;
|
||||
|
||||
s.write( ddsdFlags );
|
||||
|
||||
// Read height and width (always present)
|
||||
s.write( mHeight );
|
||||
s.write( mWidth );
|
||||
|
||||
// Ok, some flags are set, so let's do some reading.
|
||||
s.write( mPitchOrLinearSize );
|
||||
|
||||
// Do we need to read depth? If so, we are a volume texture!
|
||||
s.write( mDepth );
|
||||
|
||||
// Deal with mips!
|
||||
s.write( mMipMapCount );
|
||||
|
||||
// Deal with 11 DWORDS of reserved space (this reserved space brought to
|
||||
// you by DirectDraw and the letters F and U).
|
||||
for(U32 i=0; i<11; i++)
|
||||
s.write( tmp ); // is this right?
|
||||
|
||||
// Now we're onto the pixel format!
|
||||
|
||||
// This is the size, in bits,
|
||||
// of the pixel format data.
|
||||
tmp = 32;
|
||||
s.write( tmp );
|
||||
|
||||
U32 ddpfFlags;
|
||||
|
||||
U32 fourCC = 0;
|
||||
|
||||
if ( mFlags.test( CompressedData ) )
|
||||
{
|
||||
ddpfFlags = DDPFFourCC;
|
||||
if (mFormat == GFXFormatDXT1)
|
||||
fourCC = FOURCC_DXT1;
|
||||
if (mFormat == GFXFormatDXT3)
|
||||
fourCC = FOURCC_DXT3;
|
||||
if (mFormat == GFXFormatDXT5)
|
||||
fourCC = FOURCC_DXT5;
|
||||
}
|
||||
else
|
||||
ddpfFlags = mBytesPerPixel == 4 ? DDPFRGB | DDPFAlphaPixels : DDPFRGB;
|
||||
|
||||
s.write( ddpfFlags );
|
||||
|
||||
// Read the next few values so we can deal with them all in one go.
|
||||
//U32 pfFourCC, pfBitCount, pfRMask, pfGMask, pfBMask, pfAlphaMask;
|
||||
|
||||
s.write( fourCC );
|
||||
s.write( mBytesPerPixel * 8 );
|
||||
s.write( 0x000000FF );
|
||||
s.write( 0x00FF0000 );
|
||||
s.write( 0x0000FF00 );
|
||||
s.write( 0xFF000000 );
|
||||
|
||||
// Deal with final caps bits... Is this really necessary?
|
||||
|
||||
U32 caps1 = DDSCAPSTexture;
|
||||
if ( mMipMapCount > 0 )
|
||||
caps1 |= DDSCAPSComplex | DDSCAPSMipMap;
|
||||
|
||||
tmp = 0;
|
||||
|
||||
s.write( caps1 );
|
||||
s.write( tmp );
|
||||
s.write( tmp );
|
||||
s.write( tmp );// More icky reserved space.
|
||||
|
||||
// MS has ANOTHER reserved word here. This one particularly sucks.
|
||||
s.write( tmp );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DDSFile::write( Stream &s )
|
||||
{
|
||||
if(!writeHeader(s))
|
||||
{
|
||||
Con::errorf("DDSFile::write - error writing header!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// At this point we know what sort of image we contain. So we should
|
||||
// allocate some buffers, and read it in.
|
||||
|
||||
// How many surfaces are we talking about?
|
||||
if(mFlags.test(CubeMapFlag))
|
||||
{
|
||||
// Do something with cubemaps.
|
||||
}
|
||||
else if (mFlags.test(VolumeFlag))
|
||||
{
|
||||
// Do something with volume
|
||||
}
|
||||
else
|
||||
{
|
||||
// It's a plain old texture.
|
||||
|
||||
// Load however many mips there are.
|
||||
for ( S32 i = 0; i < mMipMapCount; i++ )
|
||||
mSurfaces.last()->writeNextMip(this, s, mHeight, mWidth, i);
|
||||
|
||||
// Ok, we're done.
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DDSFile::SurfaceData::dumpImage(DDSFile *dds, U32 mip, const char *file)
|
||||
{
|
||||
GBitmap *foo = new GBitmap(dds->mWidth >> mip, dds->mHeight >> mip, false, dds->mFormat);
|
||||
|
||||
// Copy our data in.
|
||||
dMemcpy(foo->getWritableBits(), mMips[mip], dds->getSurfaceSize(dds->mHeight, dds->mWidth, mip) );
|
||||
|
||||
FileStream stream;
|
||||
|
||||
stream.open( file, Torque::FS::File::Write );
|
||||
|
||||
if ( stream.getStatus() == Stream::Ok )
|
||||
{
|
||||
// Write it out.
|
||||
foo->writeBitmap("png", stream);
|
||||
}
|
||||
|
||||
// Clean up.
|
||||
delete foo;
|
||||
}
|
||||
|
||||
void DDSFile::SurfaceData::readNextMip(DDSFile *dds, Stream &s, U32 height, U32 width, U32 mipLevel, bool skip)
|
||||
{
|
||||
U32 size = dds->getSurfaceSize(height, width, mipLevel);
|
||||
|
||||
// If we're skipping this mip then seek forward.
|
||||
if ( skip )
|
||||
s.setPosition( s.getPosition() + size );
|
||||
else
|
||||
{
|
||||
mMips.push_back(new U8[size]);
|
||||
if(!s.read(size, mMips.last()))
|
||||
Con::errorf("DDSFile::SurfaceData::addNextMip - failed to read mip!");
|
||||
}
|
||||
}
|
||||
|
||||
void DDSFile::SurfaceData::writeNextMip(DDSFile *dds, Stream &s, U32 height, U32 width, U32 mipLevel)
|
||||
{
|
||||
U32 size = dds->getSurfaceSize(height, width, mipLevel);
|
||||
if(!s.write(size, mMips[mipLevel]))
|
||||
Con::errorf("DDSFile::SurfaceData::writeNextMip - failed to write mip!");
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<> void *Resource<DDSFile>::create( const Torque::Path &path )
|
||||
{
|
||||
#ifdef TORQUE_DEBUG_RES_MANAGER
|
||||
Con::printf( "Resource<DDSFile>::create - [%s]", path.getFullPath().c_str() );
|
||||
#endif
|
||||
|
||||
FileStream stream;
|
||||
|
||||
stream.open( path.getFullPath(), Torque::FS::File::Read );
|
||||
|
||||
if ( stream.getStatus() != Stream::Ok )
|
||||
return NULL;
|
||||
|
||||
DDSFile *retDDS = new DDSFile;
|
||||
|
||||
if( !retDDS->read( stream, DDSFile::smDropMipCount ) )
|
||||
{
|
||||
delete retDDS;
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set source file name
|
||||
retDDS->mSourcePath = path;
|
||||
retDDS->mCacheString = Torque::Path::Join( path.getRoot(), ':', path.getPath() );
|
||||
retDDS->mCacheString = Torque::Path::Join( retDDS->mCacheString, '/', path.getFileName() );
|
||||
}
|
||||
|
||||
return retDDS;
|
||||
}
|
||||
|
||||
template<> ResourceBase::Signature Resource<DDSFile>::signature()
|
||||
{
|
||||
return MakeFourCC('D','D','S',' '); // Direct Draw Surface
|
||||
}
|
||||
|
||||
Resource<DDSFile> DDSFile::load( const Torque::Path &path, U32 dropMipCount )
|
||||
{
|
||||
PROFILE_SCOPE( DDSFile_load );
|
||||
|
||||
// HACK: It sucks that we cannot pass parameters into
|
||||
// the resource manager loading system.
|
||||
DDSFile::smDropMipCount = dropMipCount;
|
||||
Resource<DDSFile> ret = ResourceManager::get().load( path );
|
||||
DDSFile::smDropMipCount = 0;
|
||||
|
||||
// Any kind of error checking or path stepping can happen here
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
DDSFile *DDSFile::createDDSFileFromGBitmap( const GBitmap *gbmp )
|
||||
{
|
||||
if( gbmp == NULL )
|
||||
return NULL;
|
||||
|
||||
DDSFile *ret = new DDSFile;
|
||||
|
||||
// Set up the DDSFile properties that matter. Since this is a GBitmap, there
|
||||
// are assumptions that can be made
|
||||
ret->mHeight = gbmp->getHeight();
|
||||
ret->mWidth = gbmp->getWidth();
|
||||
ret->mDepth = 0;
|
||||
ret->mFormat = gbmp->getFormat();
|
||||
ret->mFlags.set(RGBData);
|
||||
ret->mBytesPerPixel = gbmp->getBytesPerPixel();
|
||||
ret->mMipMapCount = gbmp->getNumMipLevels();
|
||||
ret->mHasTransparency = gbmp->getHasTransparency();
|
||||
|
||||
// ASSUMPTION!!!
|
||||
// This _most likely_ does not belong here, but it is safe to assume that if
|
||||
// a GBitmap is 24-bit, and it's being converted to a DDS, it is most likely
|
||||
// going to be either:
|
||||
// a) Uploaded as a 32-bit texture, and just needs to be padded to RGBX
|
||||
// b) Uploaded as a compressed format, and needs to be padded to 32-bits anyway
|
||||
if( ret->mFormat == GFXFormatR8G8B8 )
|
||||
{
|
||||
ret->mFormat = GFXFormatR8G8B8X8;
|
||||
ret->mBytesPerPixel = 4;
|
||||
}
|
||||
|
||||
if( ret->mMipMapCount > 1 )
|
||||
ret->mFlags.set(MipMapsFlag);
|
||||
|
||||
// One surface per GBitmap
|
||||
ret->mSurfaces.push_back( new SurfaceData() );
|
||||
|
||||
// Load the mips
|
||||
for( int i = 0; i < ret->mMipMapCount; i++ )
|
||||
{
|
||||
const U32 mipSz = ret->getSurfaceSize(i);
|
||||
ret->mSurfaces.last()->mMips.push_back( new U8[mipSz] );
|
||||
|
||||
U8 *mipMem = ret->mSurfaces.last()->mMips.last();
|
||||
|
||||
// If this is a straight copy, just do it, otherwise (ugh)
|
||||
if( ret->mFormat == gbmp->getFormat() )
|
||||
dMemcpy( mipMem, gbmp->getBits(i), mipSz );
|
||||
else
|
||||
{
|
||||
// Assumption:
|
||||
AssertFatal( gbmp->getBytesPerPixel() + 1 == ret->mBytesPerPixel, "Assumption failed, not 24->32 bit straight convert." );
|
||||
|
||||
for( int pxl = 0; pxl < gbmp->getWidth(i) * gbmp->getHeight(i); pxl++ )
|
||||
{
|
||||
U8 *dst = &mipMem[pxl * ret->mBytesPerPixel];
|
||||
const U8 *src = &gbmp->getBits(i)[pxl * gbmp->getBytesPerPixel()];
|
||||
dMemcpy( dst, src, gbmp->getBytesPerPixel() * sizeof(U8) );
|
||||
dst[ret->mBytesPerPixel - 1] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
// Uncomment to debug-dump each mip level
|
||||
//ret->mSurfaces.last()->dumpImage( ret, i, avar( "%d_Gbmp_xmip%d", ret, i ) );
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
DefineEngineFunction( getActiveDDSFiles, S32, (),,
|
||||
"Returns the count of active DDSs files in memory.\n"
|
||||
"@ingroup Rendering\n" )
|
||||
{
|
||||
return DDSFile::smActiveCopies;
|
||||
}
|
||||
116
Engine/source/gfx/bitmap/ddsUtils.cpp
Normal file
116
Engine/source/gfx/bitmap/ddsUtils.cpp
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "squish/squish.h"
|
||||
#include "gfx/bitmap/ddsFile.h"
|
||||
#include "gfx/bitmap/ddsUtils.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// If false is returned, from this method, the source DDS is not modified
|
||||
bool DDSUtil::squishDDS( DDSFile *srcDDS, const GFXFormat dxtFormat )
|
||||
{
|
||||
// Sanity check
|
||||
if( srcDDS->mBytesPerPixel != 4 )
|
||||
{
|
||||
AssertFatal( false, "Squish wants 32-bit source data" );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Build flags, start with fast compress
|
||||
U32 squishFlags = squish::kColourRangeFit;
|
||||
|
||||
// Flag which format we are using
|
||||
switch( dxtFormat )
|
||||
{
|
||||
case GFXFormatDXT1:
|
||||
squishFlags |= squish::kDxt1;
|
||||
break;
|
||||
|
||||
case GFXFormatDXT2:
|
||||
case GFXFormatDXT3:
|
||||
squishFlags |= squish::kDxt3;
|
||||
break;
|
||||
|
||||
case GFXFormatDXT4:
|
||||
case GFXFormatDXT5:
|
||||
squishFlags |= squish::kDxt5;
|
||||
break;
|
||||
|
||||
default:
|
||||
AssertFatal( false, "Assumption failed" );
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
// We got this far, so assume we can finish (gosh I hope so)
|
||||
srcDDS->mFormat = dxtFormat;
|
||||
srcDDS->mFlags.set( DDSFile::CompressedData );
|
||||
|
||||
// If this has alpha, set the flag
|
||||
if( srcDDS->mFormat == GFXFormatR8G8B8A8 )
|
||||
squishFlags |= squish::kWeightColourByAlpha;
|
||||
|
||||
// The source surface is the original surface of the file
|
||||
DDSFile::SurfaceData *srcSurface = srcDDS->mSurfaces.last();
|
||||
|
||||
// Create a new surface, this will be the DXT compressed surface. Once we
|
||||
// are done, we can discard the old surface, and replace it with this one.
|
||||
DDSFile::SurfaceData *newSurface = new DDSFile::SurfaceData();
|
||||
|
||||
for( int i = 0; i < srcDDS->mMipMapCount; i++ )
|
||||
{
|
||||
const U8 *srcBits = srcSurface->mMips[i];
|
||||
|
||||
const U32 mipSz = srcDDS->getSurfaceSize(i);
|
||||
U8 *dstBits = new U8[mipSz];
|
||||
newSurface->mMips.push_back( dstBits );
|
||||
|
||||
PROFILE_START(SQUISH_DXT_COMPRESS);
|
||||
|
||||
// Compress with Squish
|
||||
//
|
||||
// squish::CompressImageOMP will call squish::CompressImage if OpenMP is
|
||||
// not enabled.
|
||||
squish::CompressImageOMP( srcBits, srcDDS->getWidth(i), srcDDS->getHeight(i),
|
||||
dstBits, squishFlags );
|
||||
|
||||
PROFILE_END();
|
||||
}
|
||||
|
||||
// Now delete the source surface, and return.
|
||||
srcDDS->mSurfaces.pop_back();
|
||||
delete srcSurface;
|
||||
srcDDS->mSurfaces.push_back( newSurface );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void DDSUtil::swizzleDDS( DDSFile *srcDDS, const Swizzle<U8, 4> &swizzle )
|
||||
{
|
||||
for( int i = 0; i < srcDDS->mMipMapCount; i++ )
|
||||
{
|
||||
swizzle.InPlace( srcDDS->mSurfaces.last()->mMips[i], srcDDS->getSurfaceSize( i ) );
|
||||
}
|
||||
}
|
||||
34
Engine/source/gfx/bitmap/ddsUtils.h
Normal file
34
Engine/source/gfx/bitmap/ddsUtils.h
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _DDS_UTILS_H_
|
||||
#define _DDS_UTILS_H_
|
||||
|
||||
struct DDSFile;
|
||||
|
||||
namespace DDSUtil
|
||||
{
|
||||
bool squishDDS( DDSFile *srcDDS, const GFXFormat dxtFormat );
|
||||
void swizzleDDS( DDSFile *srcDDS, const Swizzle<U8, 4> &swizzle );
|
||||
};
|
||||
|
||||
#endif
|
||||
1184
Engine/source/gfx/bitmap/gBitmap.cpp
Normal file
1184
Engine/source/gfx/bitmap/gBitmap.cpp
Normal file
File diff suppressed because it is too large
Load diff
327
Engine/source/gfx/bitmap/gBitmap.h
Normal file
327
Engine/source/gfx/bitmap/gBitmap.h
Normal file
|
|
@ -0,0 +1,327 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GBITMAP_H_
|
||||
#define _GBITMAP_H_
|
||||
|
||||
#ifndef __RESOURCE_H__
|
||||
#include "core/resource.h"
|
||||
#endif
|
||||
|
||||
#ifndef _SWIZZLE_H_
|
||||
#include "core/util/swizzle.h"
|
||||
#endif
|
||||
|
||||
#ifndef _TVECTOR_H_
|
||||
#include "core/util/tVector.h"
|
||||
#endif
|
||||
|
||||
#ifndef _GFXENUMS_H_
|
||||
#include "gfx/gfxEnums.h" // For the format
|
||||
#endif
|
||||
|
||||
//-------------------------------------- Forward decls.
|
||||
class Stream;
|
||||
class RectI;
|
||||
class Point2I;
|
||||
class ColorI;
|
||||
class ColorF;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//-------------------------------------- GBitmap
|
||||
|
||||
class GBitmap
|
||||
{
|
||||
public:
|
||||
enum Constants
|
||||
{
|
||||
/// The maximum mipmap levels we support. The current
|
||||
/// value lets us support up to 4096 x 4096 images.
|
||||
c_maxMipLevels = 13
|
||||
};
|
||||
|
||||
struct Registration
|
||||
{
|
||||
/// The read function prototype.
|
||||
typedef bool(*ReadFunc)(Stream &stream, GBitmap *bitmap);
|
||||
|
||||
/// The write function prototype. Compression levels are image-specific - see their registration declaration for details.
|
||||
typedef bool(*WriteFunc)(GBitmap *bitmap, Stream &stream, U32 compressionLevel);
|
||||
|
||||
/// Used to sort the registrations so that
|
||||
/// lookups occur in a fixed order.
|
||||
U32 priority;
|
||||
|
||||
Vector<String> extensions; ///< the list of file extensions for this bitmap type [these should be lower case]
|
||||
|
||||
ReadFunc readFunc; ///< the read function to call for this bitmap type
|
||||
WriteFunc writeFunc; ///< the write function to call for this bitmap type
|
||||
U32 defaultCompression; ///< the default compression level [levels are image-specific - see their registration declaration for details]
|
||||
|
||||
Registration()
|
||||
{
|
||||
priority = 0;
|
||||
VECTOR_SET_ASSOCIATION( extensions );
|
||||
}
|
||||
};
|
||||
|
||||
/// Load the given bitmap file. It will try known file
|
||||
/// extensions if one is not specified. If all else fails
|
||||
/// it will look up the folder hierarchy for a match.
|
||||
///
|
||||
/// Important: Don't do something like this...
|
||||
///
|
||||
/// @code
|
||||
/// GBitmap* bitmap; // WRONG TYPE!
|
||||
/// bitmap = GBitmap::load( filename );
|
||||
/// @endcode
|
||||
///
|
||||
/// Resources are reference-counted and the smart pointer conversion will
|
||||
/// release the bitmap and thus render the resulting bitmap pointer invalid!
|
||||
/// The right way is like this:
|
||||
///
|
||||
/// @code
|
||||
/// Resource<GBitmap> bitmap; // Correct!
|
||||
/// bitmap = GBitmap::load( filename );
|
||||
/// @endcode
|
||||
///
|
||||
static Resource<GBitmap> load(const Torque::Path &path);
|
||||
|
||||
protected:
|
||||
|
||||
static Resource<GBitmap> _load(const Torque::Path &path);
|
||||
static Resource<GBitmap> _search(const Torque::Path &path);
|
||||
|
||||
public:
|
||||
GBitmap();
|
||||
GBitmap(const GBitmap&);
|
||||
|
||||
GBitmap(const U32 in_width,
|
||||
const U32 in_height,
|
||||
const bool in_extrudeMipLevels = false,
|
||||
const GFXFormat in_format = GFXFormatR8G8B8 );
|
||||
|
||||
// This builds a GBitmap with the R8G8B8A8 format using the passed in
|
||||
// data (assumes that there is width * height * 4 U8's in data)
|
||||
GBitmap(const U32 in_width,
|
||||
const U32 in_height,
|
||||
const U8* data );
|
||||
|
||||
virtual ~GBitmap();
|
||||
|
||||
|
||||
static void sRegisterFormat( const Registration ® );
|
||||
static const Registration* sFindRegInfo( const String &extension );
|
||||
|
||||
/// Find the first file matching the registered extensions
|
||||
/// skipping the original.
|
||||
static bool sFindFile( const Torque::Path &path, Torque::Path *outPath );
|
||||
|
||||
/// Given a path to a file, try all known extensions. If the file exists on disk, fill in path
|
||||
/// with the correct extension and return true. Otherwise, return false.
|
||||
static bool sFindFiles( const Torque::Path &path, Vector<Torque::Path> *outFoundPaths );
|
||||
|
||||
/// Returns a space separated string of all registered extensions.
|
||||
static String sGetExtensionList();
|
||||
|
||||
void allocateBitmap(const U32 in_width,
|
||||
const U32 in_height,
|
||||
const bool in_extrudeMipLevels = false,
|
||||
const GFXFormat in_format = GFXFormatR8G8B8 );
|
||||
|
||||
void extrudeMipLevels(bool clearBorders = false);
|
||||
void extrudeMipLevelsDetail();
|
||||
|
||||
U32 getNumMipLevels() const { return mNumMipLevels; }
|
||||
|
||||
GBitmap *createPaddedBitmap() const;
|
||||
GBitmap *createPow2Bitmap() const;
|
||||
|
||||
/// Copies a color channel by index into the first channel
|
||||
/// of the output bitmap. The output bitmap must be the same
|
||||
/// dimensions as the source.
|
||||
void copyChannel( U32 index, GBitmap *outBitmap ) const;
|
||||
|
||||
void copyRect(const GBitmap *in, const RectI &srcRect, const Point2I &dstPoint, const U32 srcMipLevel = 0, const U32 dstMipLevel = 0);
|
||||
|
||||
GFXFormat getFormat() const { return mInternalFormat; }
|
||||
bool setFormat(GFXFormat fmt);
|
||||
|
||||
U32 getWidth(const U32 in_mipLevel = 0) const;
|
||||
U32 getHeight(const U32 in_mipLevel = 0) const;
|
||||
U32 getDepth(const U32 in_mipLevel = 0) const;
|
||||
|
||||
U8* getAddress(const S32 in_x, const S32 in_y, const U32 mipLevel = 0);
|
||||
const U8* getAddress(const S32 in_x, const S32 in_y, const U32 mipLevel = 0) const;
|
||||
|
||||
const U8* getBits(const U32 in_mipLevel = 0) const;
|
||||
U8* getWritableBits(const U32 in_mipLevel = 0);
|
||||
|
||||
U32 getByteSize() const { return mByteSize; }
|
||||
U32 getBytesPerPixel() const { return mBytesPerPixel; }
|
||||
|
||||
/// Use these functions to set and get the mHasTransparency value
|
||||
/// This is used to indicate that this bitmap has pixels that have
|
||||
/// an alpha value less than 255 (used by the auto-Material mapper)
|
||||
bool getHasTransparency() const { return mHasTransparency; }
|
||||
void setHasTransparency(bool hasTransparency) { mHasTransparency = hasTransparency; }
|
||||
|
||||
/// In general you will want to use this function if there is not a
|
||||
/// good spot in the bitmap loader(s) to check the alpha value of
|
||||
/// the pixels. This function uses the texture format to loop over
|
||||
/// the bitmap bits and to check for alpha values less than 255
|
||||
bool checkForTransparency();
|
||||
|
||||
ColorF sampleTexel(F32 u, F32 v) const;
|
||||
bool getColor(const U32 x, const U32 y, ColorI& rColor) const;
|
||||
bool setColor(const U32 x, const U32 y, const ColorI& rColor);
|
||||
|
||||
/// This method will combine bitmapA and bitmapB using the operation specified
|
||||
/// by combineOp. The result will be stored in the bitmap that this method is
|
||||
/// called on. The size of the resulting bitmap will be the larger of A and B.
|
||||
/// The format of the resulting bitmap will be the format of A or B, whichever
|
||||
/// has a larger byte size.
|
||||
///
|
||||
/// @note There are some restrictions on ops and formats that will probably change
|
||||
/// based on how we use this function.
|
||||
bool combine( const GBitmap *bitmapA, const GBitmap *bitmapB, const GFXTextureOp combineOp );
|
||||
|
||||
/// Fills the first mip level of the bitmap with the specified color.
|
||||
void fill( const ColorI &rColor );
|
||||
|
||||
/// An optimized version of fill().
|
||||
void fillWhite();
|
||||
|
||||
//-------------------------------------- Internal data/operators
|
||||
|
||||
void deleteImage();
|
||||
|
||||
//-------------------------------------- Input/Output interface
|
||||
|
||||
/// Read a bitmap from a stream
|
||||
/// @param bmType This is a file extension to describe the type of the data [i.e. "png" for PNG file, etc]
|
||||
/// @param ioStream The stream to read from
|
||||
bool readBitmap( const String &bmType, Stream &ioStream );
|
||||
|
||||
/// Write a bitmap to a stream
|
||||
/// @param bmType This is a file extension to describe the type of the data [i.e. "png" for PNG file, etc]
|
||||
/// @param ioStream The stream to read from
|
||||
/// @param compressionLevel Image format-specific compression level. If set to U32_MAX, we use the default compression defined when the format was registered.
|
||||
bool writeBitmap( const String &bmType, Stream &ioStream, U32 compressionLevel = U32_MAX );
|
||||
|
||||
bool readMNG(Stream& io_rStream); // located in bitmapMng.cc
|
||||
bool writeMNG(Stream& io_rStream) const;
|
||||
|
||||
bool read(Stream& io_rStream);
|
||||
bool write(Stream& io_rStream) const;
|
||||
|
||||
template<class T, dsize_t mapLength>
|
||||
void swizzle(const Swizzle<T,mapLength> *s);
|
||||
|
||||
static Vector<Registration> sRegistrations;
|
||||
|
||||
private:
|
||||
GFXFormat mInternalFormat;
|
||||
|
||||
U8* mBits; // Master bytes
|
||||
U32 mByteSize;
|
||||
U32 mWidth;
|
||||
U32 mHeight;
|
||||
U32 mBytesPerPixel;
|
||||
|
||||
U32 mNumMipLevels;
|
||||
U32 mMipLevelOffsets[c_maxMipLevels];
|
||||
|
||||
bool mHasTransparency;
|
||||
|
||||
static const U32 csFileVersion;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//-------------------------------------- Inlines
|
||||
//
|
||||
|
||||
inline U32 GBitmap::getWidth(const U32 in_mipLevel) const
|
||||
{
|
||||
AssertFatal(in_mipLevel < mNumMipLevels,
|
||||
avar("GBitmap::getWidth: mip level out of range: (%d, %d)",
|
||||
in_mipLevel, mNumMipLevels));
|
||||
|
||||
U32 retVal = mWidth >> in_mipLevel;
|
||||
|
||||
return (retVal != 0) ? retVal : 1;
|
||||
}
|
||||
|
||||
inline U32 GBitmap::getHeight(const U32 in_mipLevel) const
|
||||
{
|
||||
AssertFatal(in_mipLevel < mNumMipLevels,
|
||||
avar("Bitmap::getHeight: mip level out of range: (%d, %d)",
|
||||
in_mipLevel, mNumMipLevels));
|
||||
|
||||
U32 retVal = mHeight >> in_mipLevel;
|
||||
|
||||
return (retVal != 0) ? retVal : 1;
|
||||
}
|
||||
|
||||
inline const U8* GBitmap::getBits(const U32 in_mipLevel) const
|
||||
{
|
||||
AssertFatal(in_mipLevel < mNumMipLevels,
|
||||
avar("GBitmap::getBits: mip level out of range: (%d, %d)",
|
||||
in_mipLevel, mNumMipLevels));
|
||||
|
||||
return &mBits[mMipLevelOffsets[in_mipLevel]];
|
||||
}
|
||||
|
||||
inline U8* GBitmap::getWritableBits(const U32 in_mipLevel)
|
||||
{
|
||||
AssertFatal(in_mipLevel < mNumMipLevels,
|
||||
avar("GBitmap::getWritableBits: mip level out of range: (%d, %d)",
|
||||
in_mipLevel, mNumMipLevels));
|
||||
|
||||
return &mBits[mMipLevelOffsets[in_mipLevel]];
|
||||
}
|
||||
|
||||
inline U8* GBitmap::getAddress(const S32 in_x, const S32 in_y, const U32 mipLevel)
|
||||
{
|
||||
return (getWritableBits(mipLevel) + ((in_y * getWidth(mipLevel)) + in_x) * mBytesPerPixel);
|
||||
}
|
||||
|
||||
inline const U8* GBitmap::getAddress(const S32 in_x, const S32 in_y, const U32 mipLevel) const
|
||||
{
|
||||
return (getBits(mipLevel) + ((in_y * getWidth(mipLevel)) + in_x) * mBytesPerPixel);
|
||||
}
|
||||
|
||||
template<class T, dsize_t mapLength>
|
||||
void GBitmap::swizzle(const Swizzle<T,mapLength> *s )
|
||||
{
|
||||
const U32 memSize = getWidth() * getHeight() * mBytesPerPixel;
|
||||
|
||||
void *b = dMalloc(memSize);
|
||||
|
||||
s->ToBuffer(b, getWritableBits(), memSize);
|
||||
|
||||
dMemcpy(getWritableBits(), b, memSize);
|
||||
|
||||
dFree(b);
|
||||
}
|
||||
|
||||
#endif //_GBITMAP_H_
|
||||
245
Engine/source/gfx/bitmap/loaders/bitmapBmp.cpp
Normal file
245
Engine/source/gfx/bitmap/loaders/bitmapBmp.cpp
Normal file
|
|
@ -0,0 +1,245 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "core/stream/stream.h"
|
||||
|
||||
#include "gfx/bitmap/gBitmap.h"
|
||||
|
||||
|
||||
static bool sReadBMP(Stream &stream, GBitmap *bitmap);
|
||||
static bool sWriteBMP(GBitmap *bitmap, Stream &stream, U32 compressionLevel);
|
||||
|
||||
static struct _privateRegisterBMP
|
||||
{
|
||||
_privateRegisterBMP()
|
||||
{
|
||||
GBitmap::Registration reg;
|
||||
|
||||
reg.extensions.push_back( "bmp" );
|
||||
|
||||
reg.readFunc = sReadBMP;
|
||||
reg.writeFunc = sWriteBMP;
|
||||
|
||||
GBitmap::sRegisterFormat( reg );
|
||||
}
|
||||
} sStaticRegisterBMP;
|
||||
|
||||
|
||||
// structures mirror those defined by the win32 API
|
||||
|
||||
struct RGBQUAD
|
||||
{
|
||||
U8 rgbBlue;
|
||||
U8 rgbGreen;
|
||||
U8 rgbRed;
|
||||
U8 rgbReserved;
|
||||
};
|
||||
|
||||
struct BITMAPFILEHEADER
|
||||
{
|
||||
U16 bfType;
|
||||
U32 bfSize;
|
||||
U16 bfReserved1;
|
||||
U16 bfReserved2;
|
||||
U32 bfOffBits;
|
||||
};
|
||||
|
||||
struct BITMAPINFOHEADER
|
||||
{
|
||||
U32 biSize;
|
||||
S32 biWidth;
|
||||
S32 biHeight;
|
||||
U16 biPlanes;
|
||||
U16 biBitCount;
|
||||
U32 biCompression;
|
||||
U32 biSizeImage;
|
||||
S32 biXPelsPerMeter;
|
||||
S32 biYPelsPerMeter;
|
||||
U32 biClrUsed;
|
||||
U32 biClrImportant;
|
||||
};
|
||||
|
||||
// constants for the biCompression field
|
||||
#define BI_RGB 0L
|
||||
#define BI_RLE8 1L
|
||||
#define BI_RLE4 2L
|
||||
#define BI_BITFIELDS 3L
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//-------------------------------------- Supplementary I/O (Partially located in
|
||||
// bitmapPng.cc)
|
||||
//
|
||||
|
||||
static bool sReadBMP(Stream &stream, GBitmap *bitmap)
|
||||
{
|
||||
BITMAPINFOHEADER bi;
|
||||
BITMAPFILEHEADER bf;
|
||||
RGBQUAD rgb[256];
|
||||
|
||||
stream.read(&bf.bfType);
|
||||
stream.read(&bf.bfSize);
|
||||
stream.read(&bf.bfReserved1);
|
||||
stream.read(&bf.bfReserved2);
|
||||
stream.read(&bf.bfOffBits);
|
||||
|
||||
stream.read(&bi.biSize);
|
||||
stream.read(&bi.biWidth);
|
||||
stream.read(&bi.biHeight);
|
||||
stream.read(&bi.biPlanes);
|
||||
stream.read(&bi.biBitCount);
|
||||
stream.read(&bi.biCompression);
|
||||
stream.read(&bi.biSizeImage);
|
||||
stream.read(&bi.biXPelsPerMeter);
|
||||
stream.read(&bi.biYPelsPerMeter);
|
||||
stream.read(&bi.biClrUsed);
|
||||
stream.read(&bi.biClrImportant);
|
||||
|
||||
GFXFormat fmt = GFXFormatR8G8B8;
|
||||
if(bi.biBitCount == 8)
|
||||
{
|
||||
// read in texture palette
|
||||
if(!bi.biClrUsed)
|
||||
bi.biClrUsed = 256;
|
||||
stream.read(sizeof(RGBQUAD) * bi.biClrUsed, rgb);
|
||||
}
|
||||
bitmap->allocateBitmap(bi.biWidth, bi.biHeight, false, fmt);
|
||||
U32 width = bitmap->getWidth();
|
||||
U32 height = bitmap->getHeight();
|
||||
U32 bytesPerPixel = bitmap->getBytesPerPixel();
|
||||
|
||||
for(U32 i = 0; i < bi.biHeight; i++)
|
||||
{
|
||||
U8 *rowDest = bitmap->getAddress(0, height - i - 1);
|
||||
if (bi.biBitCount == 8)
|
||||
{
|
||||
// use palette...don't worry about being slow
|
||||
for (S32 j=0; j<width; j++)
|
||||
{
|
||||
U8 palIdx;
|
||||
stream.read(&palIdx);
|
||||
U8 * pixelLocation = &rowDest[j*bytesPerPixel];
|
||||
pixelLocation[0] = rgb[palIdx].rgbRed;
|
||||
pixelLocation[1] = rgb[palIdx].rgbGreen;
|
||||
pixelLocation[2] = rgb[palIdx].rgbBlue;
|
||||
if (bytesPerPixel==3)
|
||||
pixelLocation[3] = 255;
|
||||
}
|
||||
}
|
||||
else
|
||||
stream.read(bytesPerPixel * width, rowDest);
|
||||
}
|
||||
|
||||
if(bytesPerPixel == 3 && bi.biBitCount != 8) // do BGR swap
|
||||
{
|
||||
U8 *ptr = bitmap->getAddress(0,0);
|
||||
for(int i = 0; i < width * height; i++)
|
||||
{
|
||||
U8 tmp = ptr[0];
|
||||
ptr[0] = ptr[2];
|
||||
ptr[2] = tmp;
|
||||
ptr += 3;
|
||||
}
|
||||
}
|
||||
|
||||
// We know BMP's don't have any transparency
|
||||
bitmap->setHasTransparency(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool sWriteBMP(GBitmap *bitmap, Stream &stream, U32 compressionLevel)
|
||||
{
|
||||
TORQUE_UNUSED( compressionLevel ); // BMP does not use compression
|
||||
|
||||
BITMAPINFOHEADER bi;
|
||||
BITMAPFILEHEADER bf;
|
||||
|
||||
bi.biSize = sizeof(BITMAPINFOHEADER);
|
||||
bi.biWidth = bitmap->getWidth();
|
||||
bi.biHeight = bitmap->getHeight(); //our data is top-down
|
||||
bi.biPlanes = 1;
|
||||
|
||||
if(bitmap->getFormat() == GFXFormatR8G8B8)
|
||||
{
|
||||
bi.biBitCount = 24;
|
||||
bi.biCompression = BI_RGB;
|
||||
bi.biClrUsed = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
bi.biBitCount = 0;
|
||||
bi.biCompression = BI_RGB; // Removes warning C4701 on line
|
||||
AssertISV(false, "GBitmap::writeMSBmp - only support R8G8B8 formats!");
|
||||
}
|
||||
|
||||
U32 width = bitmap->getWidth();
|
||||
U32 height = bitmap->getHeight();
|
||||
|
||||
U32 bytesPP = bi.biBitCount >> 3;
|
||||
bi.biSizeImage = width * height * bytesPP;
|
||||
bi.biXPelsPerMeter = 0;
|
||||
bi.biYPelsPerMeter = 0;
|
||||
bi.biClrUsed = 0;
|
||||
bi.biClrImportant = 0;
|
||||
|
||||
bf.bfType = makeFourCCTag('B','M',0,0); //Type of file 'BM'
|
||||
bf.bfOffBits= sizeof(BITMAPINFOHEADER)
|
||||
+ sizeof(BITMAPFILEHEADER)
|
||||
+ (sizeof(RGBQUAD)*bi.biClrUsed);
|
||||
bf.bfSize = bf.bfOffBits + bi.biSizeImage;
|
||||
bf.bfReserved1 = 0;
|
||||
bf.bfReserved2 = 0;
|
||||
|
||||
stream.write(bf.bfType);
|
||||
stream.write(bf.bfSize);
|
||||
stream.write(bf.bfReserved1);
|
||||
stream.write(bf.bfReserved2);
|
||||
stream.write(bf.bfOffBits);
|
||||
|
||||
stream.write(bi.biSize);
|
||||
stream.write(bi.biWidth);
|
||||
stream.write(bi.biHeight);
|
||||
stream.write(bi.biPlanes);
|
||||
stream.write(bi.biBitCount);
|
||||
stream.write(bi.biCompression);
|
||||
stream.write(bi.biSizeImage);
|
||||
stream.write(bi.biXPelsPerMeter);
|
||||
stream.write(bi.biYPelsPerMeter);
|
||||
stream.write(bi.biClrUsed);
|
||||
stream.write(bi.biClrImportant);
|
||||
|
||||
//write the bitmap bits
|
||||
U8* pMSUpsideDownBits = new U8[bi.biSizeImage];
|
||||
for (U32 i = 0; i < height; i++)
|
||||
{
|
||||
const U8* pSrc = bitmap->getAddress(0, i);
|
||||
U8* pDst = pMSUpsideDownBits + (height - i - 1) * width * bytesPP;
|
||||
|
||||
dMemcpy(pDst, pSrc, width * bytesPP);
|
||||
}
|
||||
|
||||
stream.write(bi.biSizeImage, pMSUpsideDownBits);
|
||||
delete [] pMSUpsideDownBits;
|
||||
|
||||
return stream.getStatus() == Stream::Ok;
|
||||
}
|
||||
231
Engine/source/gfx/bitmap/loaders/bitmapGif.cpp
Normal file
231
Engine/source/gfx/bitmap/loaders/bitmapGif.cpp
Normal file
|
|
@ -0,0 +1,231 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
|
||||
#include "core/stream/fileStream.h"
|
||||
#include "core/util/path.h"
|
||||
|
||||
#include "gfx/bitmap/gBitmap.h"
|
||||
|
||||
// This must come after our headers due to a conflicting definition of VoidPtr
|
||||
#include "lungif/gif_lib.h"
|
||||
|
||||
|
||||
using namespace Torque;
|
||||
|
||||
static bool sReadGIF(Stream &stream, GBitmap *bitmap);
|
||||
static bool sWriteGIF(GBitmap *bitmap, Stream &stream, U32 compressionLevel);
|
||||
|
||||
static struct _privateRegisterGIF
|
||||
{
|
||||
_privateRegisterGIF()
|
||||
{
|
||||
GBitmap::Registration reg;
|
||||
|
||||
reg.extensions.push_back( "gif" );
|
||||
|
||||
reg.readFunc = sReadGIF;
|
||||
reg.writeFunc = sWriteGIF;
|
||||
|
||||
GBitmap::sRegisterFormat( reg );
|
||||
}
|
||||
} sStaticRegisterGIF;
|
||||
|
||||
//-------------------------------------- Replacement I/O for standard LIBjpeg
|
||||
// functions. we don't wanna use
|
||||
// FILE*'s...
|
||||
static int gifReadDataFn(GifFileType *gifinfo, GifByteType *data, int length)
|
||||
{
|
||||
Stream *stream = (Stream*)gifinfo->UserData;
|
||||
AssertFatal(stream != NULL, "gifReadDataFn::No stream.");
|
||||
int pos = stream->getPosition();
|
||||
if (stream->read(length, data))
|
||||
return length;
|
||||
|
||||
if (stream->getStatus() == Stream::EOS)
|
||||
return (stream->getPosition()-pos);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------
|
||||
#if 0
|
||||
// CodeReview - until we can write these, get rid of warning by disabling method.
|
||||
static int gifWriteDataFn(GifFileType *gifinfo, GifByteType *data, int length)
|
||||
{
|
||||
Stream *stream = (Stream*)gifinfo->UserData;
|
||||
AssertFatal(stream != NULL, "gifWriteDataFn::No stream.");
|
||||
if (stream->write(length, data))
|
||||
return length;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
//--------------------------------------
|
||||
static bool sReadGIF( Stream &stream, GBitmap *bitmap )
|
||||
{
|
||||
GifFileType *gifinfo = DGifOpen( (void*)&stream, gifReadDataFn);
|
||||
if (!gifinfo)
|
||||
return false;
|
||||
|
||||
GifRecordType recordType;
|
||||
do
|
||||
{
|
||||
if (DGifGetRecordType(gifinfo, &recordType) == GIF_ERROR)
|
||||
break;
|
||||
|
||||
if (recordType == IMAGE_DESC_RECORD_TYPE)
|
||||
{
|
||||
if (DGifGetImageDesc(gifinfo) == GIF_ERROR)
|
||||
break;
|
||||
|
||||
GFXFormat format = (gifinfo->SBackGroundColor == 0 ) ? GFXFormatR8G8B8 : GFXFormatR8G8B8A8;
|
||||
bitmap->allocateBitmap(gifinfo->SWidth, gifinfo->SHeight, false, format);
|
||||
|
||||
// Assume no transparency until proven otherwise
|
||||
bitmap->setHasTransparency(false);
|
||||
|
||||
U32 gwidth = gifinfo->Image.Width ? gifinfo->Image.Width : bitmap->getWidth();
|
||||
U32 gheight= gifinfo->Image.Height ? gifinfo->Image.Height : bitmap->getHeight();
|
||||
U32 gifSize = gwidth * gheight;
|
||||
U8 *data = new U8[gifSize];
|
||||
|
||||
if (DGifGetLine(gifinfo, data, gifSize) != GIF_ERROR)
|
||||
{
|
||||
// use the global or local color table ?
|
||||
GifColorType *color = NULL;
|
||||
if (gifinfo->Image.ColorMap)
|
||||
color = gifinfo->Image.ColorMap->Colors;
|
||||
else if (gifinfo->SColorMap)
|
||||
color = gifinfo->SColorMap->Colors;
|
||||
|
||||
if (color)
|
||||
{
|
||||
U8 *dst = bitmap->getAddress(gifinfo->Image.Left, gifinfo->Image.Top);
|
||||
U8 *src = data;
|
||||
U32 right = gifinfo->Image.Left + gwidth;
|
||||
U32 bottom = gifinfo->Image.Top + gheight;
|
||||
U32 next = (bitmap->getWidth() - gwidth) * bitmap->getBytesPerPixel();
|
||||
|
||||
if (format == GFXFormatR8G8B8A8)
|
||||
{
|
||||
for (U32 y=gifinfo->Image.Top; y<bottom; y++)
|
||||
{
|
||||
for (U32 x=gifinfo->Image.Left; x<right; x++, src++)
|
||||
{
|
||||
if (*src == gifinfo->SBackGroundColor)
|
||||
{
|
||||
// this is a transparent pixel
|
||||
dst[0] = 0; // red
|
||||
dst[1] = 0; // green
|
||||
dst[2] = 0; // blue
|
||||
dst[3] = 0; // alpha
|
||||
|
||||
bitmap->setHasTransparency(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[0] = color[*src].Red;
|
||||
dst[1] = color[*src].Green;
|
||||
dst[2] = color[*src].Blue;
|
||||
dst[3] = 0; // alpha
|
||||
}
|
||||
dst += bitmap->getBytesPerPixel();
|
||||
}
|
||||
dst += next;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (U32 y=gifinfo->Image.Top; y<bottom; y++)
|
||||
{
|
||||
for (U32 x=gifinfo->Image.Left; x<right; x++, src++)
|
||||
{
|
||||
dst[0] = color[*src].Red;
|
||||
dst[1] = color[*src].Green;
|
||||
dst[2] = color[*src].Blue;
|
||||
dst += bitmap->getBytesPerPixel();
|
||||
}
|
||||
dst += next;
|
||||
}
|
||||
}
|
||||
delete [] data;
|
||||
DGifCloseFile(gifinfo);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// failure
|
||||
delete [] data;
|
||||
break;
|
||||
}
|
||||
else if (recordType == EXTENSION_RECORD_TYPE)
|
||||
{
|
||||
GifByteType *extension;
|
||||
S32 extCode;
|
||||
|
||||
// Skip any extension blocks in file
|
||||
if (DGifGetExtension(gifinfo, &extCode, &extension) != GIF_ERROR)
|
||||
{
|
||||
while (extension != NULL)
|
||||
{
|
||||
if (DGifGetExtensionNext(gifinfo, &extension) == GIF_ERROR)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// There used to be a break right here. This caused the while condition to
|
||||
// never get processed, and so it never looped through all the records in
|
||||
// the GIF. I took a quick peek back at TGB and TGE histories and I am not
|
||||
// sure where this change got made, but I can't figure out why the loading
|
||||
// worked at all, ever, with that break in there. The only case I can think
|
||||
// of is if the first record in the GIF was the bitmap data.
|
||||
// [6/6/2007 Pat]
|
||||
|
||||
}while (recordType != TERMINATE_RECORD_TYPE);
|
||||
|
||||
|
||||
DGifCloseFile(gifinfo);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
static bool sWriteGIF(GBitmap *bitmap, Stream &stream, U32 compressionLevel)
|
||||
{
|
||||
TORQUE_UNUSED( bitmap );
|
||||
TORQUE_UNUSED( stream );
|
||||
TORQUE_UNUSED( compressionLevel );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
250
Engine/source/gfx/bitmap/loaders/bitmapJpeg.cpp
Normal file
250
Engine/source/gfx/bitmap/loaders/bitmapJpeg.cpp
Normal file
|
|
@ -0,0 +1,250 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "ljpeg/jpeglib.h"
|
||||
|
||||
#include "core/stream/stream.h"
|
||||
|
||||
#include "gfx/bitmap/gBitmap.h"
|
||||
|
||||
|
||||
static bool sReadJPG(Stream &stream, GBitmap *bitmap);
|
||||
static bool sWriteJPG(GBitmap *bitmap, Stream &stream, U32 compressionLevel);
|
||||
|
||||
static struct _privateRegisterJPG
|
||||
{
|
||||
_privateRegisterJPG()
|
||||
{
|
||||
GBitmap::Registration reg;
|
||||
|
||||
reg.priority = 50;
|
||||
reg.extensions.push_back( "jpeg" );
|
||||
reg.extensions.push_back( "jpg" );
|
||||
|
||||
reg.readFunc = sReadJPG;
|
||||
reg.writeFunc = sWriteJPG;
|
||||
|
||||
GBitmap::sRegisterFormat( reg );
|
||||
}
|
||||
} sStaticRegisterJPG;
|
||||
|
||||
//-------------------------------------- Replacement I/O for standard LIBjpeg
|
||||
// functions. we don't wanna use
|
||||
// FILE*'s...
|
||||
static int jpegReadDataFn(void *client_data, unsigned char *data, int length)
|
||||
{
|
||||
Stream *stream = (Stream*)client_data;
|
||||
AssertFatal(stream != NULL, "jpegReadDataFn::No stream.");
|
||||
int pos = stream->getPosition();
|
||||
if (stream->read(length, data))
|
||||
return length;
|
||||
|
||||
if (stream->getStatus() == Stream::EOS)
|
||||
return (stream->getPosition()-pos);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------
|
||||
static int jpegWriteDataFn(void *client_data, unsigned char *data, int length)
|
||||
{
|
||||
Stream *stream = (Stream*)client_data;
|
||||
AssertFatal(stream != NULL, "jpegWriteDataFn::No stream.");
|
||||
if (stream->write(length, data))
|
||||
return length;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------
|
||||
static int jpegFlushDataFn(void *)
|
||||
{
|
||||
// do nothing since we can't flush the stream object
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------
|
||||
static int jpegErrorFn(void *client_data)
|
||||
{
|
||||
Stream *stream = (Stream*)client_data;
|
||||
AssertFatal(stream != NULL, "jpegErrorFn::No stream.");
|
||||
return (stream->getStatus() != Stream::Ok);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------
|
||||
static bool sReadJPG(Stream &stream, GBitmap *bitmap)
|
||||
{
|
||||
JFREAD = jpegReadDataFn;
|
||||
JFERROR = jpegErrorFn;
|
||||
|
||||
jpeg_decompress_struct cinfo;
|
||||
jpeg_error_mgr jerr;
|
||||
|
||||
// We set up the normal JPEG error routines, then override error_exit.
|
||||
//cinfo.err = jpeg_std_error(&jerr.pub);
|
||||
//jerr.pub.error_exit = my_error_exit;
|
||||
|
||||
// if (setjmp(jerr.setjmp_buffer))
|
||||
// {
|
||||
// // If we get here, the JPEG code has signaled an error.
|
||||
// // We need to clean up the JPEG object, close the input file, and return.
|
||||
// jpeg_destroy_decompress(&cinfo);
|
||||
// return false;
|
||||
// }
|
||||
|
||||
|
||||
cinfo.err = jpeg_std_error(&jerr); // set up the normal JPEG error routines.
|
||||
cinfo.client_data = (void*)&stream; // set the stream into the client_data
|
||||
|
||||
// Now we can initialize the JPEG decompression object.
|
||||
jpeg_create_decompress(&cinfo);
|
||||
|
||||
jpeg_stdio_src(&cinfo);
|
||||
|
||||
// Read file header, set default decompression parameters
|
||||
jpeg_read_header(&cinfo, true);
|
||||
|
||||
GFXFormat format;
|
||||
switch (cinfo.out_color_space)
|
||||
{
|
||||
case JCS_GRAYSCALE: format = GFXFormatA8; break;
|
||||
case JCS_RGB: format = GFXFormatR8G8B8; break;
|
||||
default:
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Start decompressor
|
||||
jpeg_start_decompress(&cinfo);
|
||||
|
||||
// allocate the bitmap space and init internal variables...
|
||||
bitmap->allocateBitmap(cinfo.output_width, cinfo.output_height, false, format);
|
||||
|
||||
// Set up the row pointers...
|
||||
U32 rowBytes = cinfo.output_width * cinfo.output_components;
|
||||
|
||||
U8* pBase = (U8*)bitmap->getBits();
|
||||
for (U32 i = 0; i < bitmap->getHeight(); i++)
|
||||
{
|
||||
JSAMPROW rowPointer = pBase + (i * rowBytes);
|
||||
jpeg_read_scanlines(&cinfo, &rowPointer, 1);
|
||||
}
|
||||
|
||||
// Finish decompression
|
||||
jpeg_finish_decompress(&cinfo);
|
||||
|
||||
// Release JPEG decompression object
|
||||
// This is an important step since it will release a good deal of memory.
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
|
||||
// We know JPEG's don't have any transparency
|
||||
bitmap->setHasTransparency(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
static bool sWriteJPG(GBitmap *bitmap, Stream &stream, U32 compressionLevel)
|
||||
{
|
||||
TORQUE_UNUSED(compressionLevel); // compression level not currently hooked up
|
||||
|
||||
GFXFormat format = bitmap->getFormat();
|
||||
|
||||
// JPEG format does not support transparency so any image
|
||||
// in Alpha format should be saved as a grayscale which coincides
|
||||
// with how the readJPEG function will read-in a JPEG. So the
|
||||
// only formats supported are RGB and Alpha, not RGBA.
|
||||
AssertFatal(format == GFXFormatR8G8B8 || format == GFXFormatA8,
|
||||
"GBitmap::writeJPEG: ONLY RGB bitmap writing supported at this time.");
|
||||
if (format != GFXFormatR8G8B8 && format != GFXFormatA8)
|
||||
return false;
|
||||
|
||||
// maximum image size allowed
|
||||
#define MAX_HEIGHT 4096
|
||||
if (bitmap->getHeight() > MAX_HEIGHT)
|
||||
return false;
|
||||
|
||||
// Bind our own stream writing, error, and memory flush functions
|
||||
// to the jpeg library interface
|
||||
JFWRITE = jpegWriteDataFn;
|
||||
JFFLUSH = jpegFlushDataFn;
|
||||
JFERROR = jpegErrorFn;
|
||||
|
||||
// Allocate and initialize our jpeg compression structure and error manager
|
||||
jpeg_compress_struct cinfo;
|
||||
jpeg_error_mgr jerr;
|
||||
|
||||
cinfo.err = jpeg_std_error(&jerr); // set up the normal JPEG error routines.
|
||||
cinfo.client_data = (void*)&stream; // set the stream into the client_data
|
||||
jpeg_create_compress(&cinfo); // allocates a small amount of memory
|
||||
|
||||
// specify the destination for the compressed data(our stream)
|
||||
jpeg_stdio_dest(&cinfo);
|
||||
|
||||
// set the image properties
|
||||
cinfo.image_width = bitmap->getWidth(); // image width
|
||||
cinfo.image_height = bitmap->getHeight(); // image height
|
||||
cinfo.input_components = bitmap->getBytesPerPixel(); // samples per pixel(RGB:3, Alpha:1)
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case GFXFormatA8: // no alpha support in JPEG format, so turn it into a grayscale
|
||||
cinfo.in_color_space = JCS_GRAYSCALE;
|
||||
break;
|
||||
case GFXFormatR8G8B8: // otherwise we are writing in RGB format
|
||||
cinfo.in_color_space = JCS_RGB;
|
||||
break;
|
||||
default:
|
||||
AssertFatal( false, "Format not handled in GBitmap::writeJPEG() switch" );
|
||||
break;
|
||||
}
|
||||
// use default compression params(75% compression)
|
||||
jpeg_set_defaults(&cinfo);
|
||||
|
||||
// begin JPEG compression cycle
|
||||
jpeg_start_compress(&cinfo, true);
|
||||
|
||||
// Set up the row pointers...
|
||||
U32 rowBytes = cinfo.image_width * cinfo.input_components;
|
||||
|
||||
U8* pBase = (U8*)bitmap->getBits();
|
||||
for (U32 i = 0; i < bitmap->getHeight(); i++)
|
||||
{
|
||||
// write the image data
|
||||
JSAMPROW rowPointer = pBase + (i * rowBytes);
|
||||
jpeg_write_scanlines(&cinfo, &rowPointer, 1);
|
||||
}
|
||||
|
||||
// complete the compression cycle
|
||||
jpeg_finish_compress(&cinfo);
|
||||
|
||||
// release the JPEG compression object
|
||||
jpeg_destroy_compress(&cinfo);
|
||||
|
||||
// return success
|
||||
return true;
|
||||
}
|
||||
421
Engine/source/gfx/bitmap/loaders/bitmapMng.cpp
Normal file
421
Engine/source/gfx/bitmap/loaders/bitmapMng.cpp
Normal file
|
|
@ -0,0 +1,421 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "core/stream/stream.h"
|
||||
|
||||
#include "gfx/bitmap/gBitmap.h"
|
||||
|
||||
#include "core/color.h"
|
||||
|
||||
#define MNG_NO_CMS
|
||||
#define MNG_SUPPORT_READ
|
||||
#define MNG_SUPPORT_WRITE
|
||||
#define MNG_SUPPORT_DISPLAY
|
||||
#define MNG_STORE_CHUNKS
|
||||
#define MNG_ACCESS_CHUNKS
|
||||
|
||||
#include "lmng/libmng.h"
|
||||
|
||||
|
||||
|
||||
static bool sReadMNG(Stream &stream, GBitmap *bitmap);
|
||||
static bool sWriteMNG(GBitmap *bitmap, Stream &stream, U32 compressionLevel);
|
||||
|
||||
static struct _privateRegisterMNG
|
||||
{
|
||||
_privateRegisterMNG()
|
||||
{
|
||||
GBitmap::Registration reg;
|
||||
|
||||
reg.extensions.push_back( "jng" );
|
||||
reg.extensions.push_back( "mng" );
|
||||
|
||||
reg.readFunc = sReadMNG;
|
||||
reg.writeFunc = sWriteMNG;
|
||||
|
||||
GBitmap::sRegisterFormat( reg );
|
||||
}
|
||||
} sStaticRegisterMNG;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GBitmap* image;
|
||||
Stream* stream;
|
||||
} mngstuff;
|
||||
|
||||
static mng_ptr mngMallocFn(mng_size_t size)
|
||||
{
|
||||
mng_ptr data = dMalloc(size);
|
||||
return dMemset(data, 0, size);
|
||||
}
|
||||
|
||||
static void mngFreeFn(mng_ptr p, mng_size_t size)
|
||||
{
|
||||
dFree(p);
|
||||
}
|
||||
|
||||
static mng_bool mngOpenDataFn(mng_handle mng)
|
||||
{
|
||||
return MNG_TRUE;
|
||||
}
|
||||
|
||||
static mng_bool mngCloseDataFn(mng_handle mng)
|
||||
{
|
||||
return MNG_TRUE;
|
||||
}
|
||||
|
||||
static mng_bool mngReadDataFn(mng_handle mng, mng_ptr data, mng_uint32 length, mng_uint32 *bytesread)
|
||||
{
|
||||
mngstuff *mymng = (mngstuff *)mng_get_userdata(mng);
|
||||
AssertFatal(mymng->stream != NULL, "No stream?");
|
||||
|
||||
bool success = mymng->stream->read(length, data);
|
||||
*bytesread = length; // stupid hack
|
||||
|
||||
AssertFatal(success, "MNG read catastrophic error!");
|
||||
if(success)
|
||||
return MNG_TRUE;
|
||||
else
|
||||
return MNG_FALSE;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// CodeReview - until we can write these, get rid of warning by disabling method.
|
||||
static mng_bool mngWriteDataFn(mng_handle mng, mng_ptr data, mng_uint32 length, mng_uint32 *iWritten)
|
||||
{
|
||||
mngstuff *mymng = (mngstuff *)mng_get_userdata(mng);
|
||||
AssertFatal(mymng->stream != NULL, "No stream?");
|
||||
|
||||
bool success = mymng->stream->write(length, data);
|
||||
*iWritten = length; // stupid hack
|
||||
|
||||
AssertFatal(success, "MNG write catastrophic error!");
|
||||
if(success)
|
||||
return MNG_TRUE;
|
||||
else
|
||||
return MNG_FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static mng_bool mngProcessHeaderFn(mng_handle mng, mng_uint32 width, mng_uint32 height)
|
||||
{
|
||||
mngstuff *mymng = (mngstuff *)mng_get_userdata(mng);
|
||||
|
||||
GFXFormat format;
|
||||
mng_uint8 colorType = mng_get_colortype(mng);
|
||||
mng_uint8 alphaDepth = mng_get_alphadepth(mng);
|
||||
switch(colorType)
|
||||
{
|
||||
case MNG_COLORTYPE_GRAY:
|
||||
case MNG_COLORTYPE_JPEGGRAY:
|
||||
format = GFXFormatR8G8B8;
|
||||
mng_set_canvasstyle(mng, MNG_CANVAS_RGB8);
|
||||
break;
|
||||
|
||||
case MNG_COLORTYPE_INDEXED:
|
||||
if(alphaDepth >= 1)
|
||||
{
|
||||
format = GFXFormatR8G8B8A8;
|
||||
mng_set_canvasstyle(mng, MNG_CANVAS_RGBA8);
|
||||
}
|
||||
else
|
||||
{
|
||||
format = GFXFormatR8G8B8;
|
||||
mng_set_canvasstyle(mng, MNG_CANVAS_RGB8);
|
||||
}
|
||||
|
||||
case MNG_COLORTYPE_RGB:
|
||||
case MNG_COLORTYPE_JPEGCOLOR:
|
||||
if(alphaDepth >= 1)
|
||||
{
|
||||
format = GFXFormatR8G8B8A8;
|
||||
mng_set_canvasstyle(mng, MNG_CANVAS_RGBA8);
|
||||
}
|
||||
else
|
||||
{
|
||||
format = GFXFormatR8G8B8;
|
||||
mng_set_canvasstyle(mng, MNG_CANVAS_RGB8);
|
||||
}
|
||||
break;
|
||||
|
||||
case MNG_COLORTYPE_RGBA:
|
||||
case MNG_COLORTYPE_JPEGCOLORA:
|
||||
format = GFXFormatR8G8B8A8;
|
||||
mng_set_canvasstyle(mng, MNG_CANVAS_RGBA8);
|
||||
break;
|
||||
|
||||
default:
|
||||
// This case should never get hit, however it resolves a compiler
|
||||
// warning
|
||||
format = GFXFormat_FIRST;
|
||||
AssertISV( false, "Unknown color format in bitmap MNG Loading" );
|
||||
}
|
||||
|
||||
mymng->image->allocateBitmap(width, height, false, format);
|
||||
return MNG_TRUE;
|
||||
}
|
||||
|
||||
static mng_ptr mngCanvasLineFn(mng_handle mng, mng_uint32 line)
|
||||
{
|
||||
mngstuff *mymng = (mngstuff *)mng_get_userdata(mng);
|
||||
return (mng_ptr) mymng->image->getAddress(0, line);
|
||||
}
|
||||
|
||||
static mng_bool mngRefreshFn(mng_handle mng, mng_uint32 x, mng_uint32 y, mng_uint32 w, mng_uint32 h)
|
||||
{
|
||||
return MNG_TRUE;
|
||||
}
|
||||
|
||||
static mng_uint32 mngGetTicksFn(mng_handle mng)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static mng_bool mngSetTimerFn(mng_handle mng, mng_uint32 msecs)
|
||||
{
|
||||
return MNG_TRUE;
|
||||
}
|
||||
|
||||
static mng_bool mngFatalErrorFn(mng_handle mng, mng_int32 code, mng_int8 severity, mng_chunkid chunktype, mng_uint32 chunkseq, mng_int32 extra1, mng_int32 extra2, mng_pchar text)
|
||||
{
|
||||
mng_cleanup(&mng);
|
||||
|
||||
AssertISV(false, avar("Error reading MNG file:\n %s", (const char*)text));
|
||||
return MNG_FALSE;
|
||||
}
|
||||
|
||||
static bool sReadMNG(Stream &stream, GBitmap *bitmap)
|
||||
{
|
||||
mngstuff mnginfo;
|
||||
dMemset(&mnginfo, 0, sizeof(mngstuff));
|
||||
|
||||
mng_handle mng = mng_initialize(&mnginfo, mngMallocFn, mngFreeFn, MNG_NULL);
|
||||
if(mng == NULL)
|
||||
return false;
|
||||
|
||||
// setup the callbacks
|
||||
mng_setcb_errorproc(mng, mngFatalErrorFn);
|
||||
mng_setcb_openstream(mng, mngOpenDataFn);
|
||||
mng_setcb_closestream(mng, mngCloseDataFn);
|
||||
mng_setcb_readdata(mng, mngReadDataFn);
|
||||
mng_setcb_processheader(mng, mngProcessHeaderFn);
|
||||
mng_setcb_getcanvasline(mng, mngCanvasLineFn);
|
||||
mng_setcb_refresh(mng, mngRefreshFn);
|
||||
mng_setcb_gettickcount(mng, mngGetTicksFn);
|
||||
mng_setcb_settimer(mng, mngSetTimerFn);
|
||||
|
||||
mnginfo.image = bitmap;
|
||||
mnginfo.stream = &stream;
|
||||
|
||||
mng_read(mng);
|
||||
mng_display(mng);
|
||||
|
||||
// hacks :(
|
||||
// libmng doesn't support returning data in gray/gray alpha format,
|
||||
// so we grab as RGB/RGBA and just cut off the g and b
|
||||
mng_uint8 colorType = mng_get_colortype(mng);
|
||||
switch(colorType)
|
||||
{
|
||||
case MNG_COLORTYPE_GRAY:
|
||||
case MNG_COLORTYPE_JPEGGRAY:
|
||||
{
|
||||
GBitmap temp(*bitmap);
|
||||
bitmap->deleteImage();
|
||||
bitmap->allocateBitmap(temp.getWidth(), temp.getHeight(), false, GFXFormatA8);
|
||||
|
||||
// force getColor to read in in the same color value for each channel
|
||||
// since the gray colortype has the real alpha in the first channel
|
||||
temp.setFormat( GFXFormatA8 );
|
||||
|
||||
ColorI color;
|
||||
for(U32 row = 0; row < bitmap->getHeight(); row++)
|
||||
{
|
||||
for(U32 col = 0; col < bitmap->getWidth(); col++)
|
||||
{
|
||||
temp.getColor(col, row, color);
|
||||
bitmap->setColor(col, row, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
mng_cleanup(&mng);
|
||||
|
||||
// Check this bitmap for transparency
|
||||
bitmap->checkForTransparency();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool sWriteMNG(GBitmap *bitmap, Stream &stream, U32 compressionLevel)
|
||||
{
|
||||
TORQUE_UNUSED( bitmap );
|
||||
TORQUE_UNUSED( stream );
|
||||
TORQUE_UNUSED( compressionLevel );
|
||||
|
||||
return false;
|
||||
#if 0
|
||||
// ONLY RGB bitmap writing supported at this time!
|
||||
AssertFatal(getFormat() == GFXFormatR8G8B8 || getFormat() == GFXFormatR8G8B8A8 || getFormat() == GFXFormatA8, "GBitmap::writeMNG: ONLY RGB bitmap writing supported at this time.");
|
||||
if(getFormat() != GFXFormatR8G8B8 && getFormat() != GFXFormatR8G8B8A8 && getFormat() != GFXFormatA8)
|
||||
return (false);
|
||||
|
||||
// maximum image size allowed
|
||||
#define MAX_HEIGHT 4096
|
||||
if(getHeight() >= MAX_HEIGHT)
|
||||
return false;
|
||||
|
||||
mngstuff mnginfo;
|
||||
dMemset(&mnginfo, 0, sizeof(mngstuff));
|
||||
mng_handle mng = mng_initialize(&mnginfo, mngMallocFn, mngFreeFn, MNG_NULL);
|
||||
if(mng == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// setup the callbacks
|
||||
mng_setcb_openstream(mng, mngOpenDataFn);
|
||||
mng_setcb_closestream(mng, mngCloseDataFn);
|
||||
mng_setcb_writedata(mng, mngWriteDataFn);
|
||||
|
||||
// create the file in memory
|
||||
mng_create(mng);
|
||||
|
||||
mng_putchunk_defi(mng, 0, 0, 0, MNG_FALSE, 0, 0, MNG_FALSE, 0, getWidth(), 0, getHeight());
|
||||
|
||||
mnginfo.image = (GBitmap*)this;
|
||||
mnginfo.stream = &stream;
|
||||
|
||||
switch(getFormat()) {
|
||||
case GFXFormatA8:
|
||||
mng_putchunk_ihdr(mng, getWidth(), getHeight(),
|
||||
MNG_BITDEPTH_8,
|
||||
MNG_COLORTYPE_GRAY,
|
||||
MNG_COMPRESSION_DEFLATE,
|
||||
MNG_FILTER_ADAPTIVE,
|
||||
MNG_INTERLACE_NONE);
|
||||
|
||||
// not implemented in lib yet
|
||||
//mng_putimgdata_ihdr(mng, getWidth(), getHeight(),
|
||||
// MNG_COLORTYPE_GRAY,
|
||||
// MNG_BITDEPTH_8,
|
||||
// MNG_COMPRESSION_DEFLATE,
|
||||
// MNG_FILTER_ADAPTIVE,
|
||||
// MNG_INTERLACE_NONE,
|
||||
// MNG_CANVAS_GRAY8, mngCanvasLineFn);
|
||||
break;
|
||||
case GFXFormatR8G8B8:
|
||||
mng_putchunk_ihdr(mng, getWidth(), getHeight(),
|
||||
MNG_BITDEPTH_8,
|
||||
MNG_COLORTYPE_RGB,
|
||||
MNG_COMPRESSION_DEFLATE,
|
||||
MNG_FILTER_ADAPTIVE,
|
||||
MNG_INTERLACE_NONE);
|
||||
|
||||
// not implemented in lib yet
|
||||
//mng_putimgdata_ihdr(mng, getWidth(), getHeight(),
|
||||
// MNG_COLORTYPE_RGB,
|
||||
// MNG_BITDEPTH_8,
|
||||
// MNG_COMPRESSION_DEFLATE,
|
||||
// MNG_FILTER_ADAPTIVE,
|
||||
// MNG_INTERLACE_NONE,
|
||||
// MNG_CANVAS_RGB8, mngCanvasLineFn);
|
||||
break;
|
||||
case GFXFormatR8G8B8A8:
|
||||
mng_putchunk_ihdr(mng, getWidth(), getHeight(),
|
||||
MNG_BITDEPTH_8,
|
||||
MNG_COLORTYPE_RGBA,
|
||||
MNG_COMPRESSION_DEFLATE,
|
||||
MNG_FILTER_ADAPTIVE,
|
||||
MNG_INTERLACE_NONE);
|
||||
|
||||
// not implemented in lib yet
|
||||
//mng_putimgdata_ihdr(mng, getWidth(), getHeight(),
|
||||
// MNG_COLORTYPE_RGBA,
|
||||
// MNG_BITDEPTH_8,
|
||||
// MNG_COMPRESSION_DEFLATE,
|
||||
// MNG_FILTER_ADAPTIVE,
|
||||
// MNG_INTERLACE_NONE,
|
||||
// MNG_CANVAS_RGBA8, mngCanvasLineFn);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// below is a hack until libmng is mature enough to handle this itself
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
U8 *tmpbuffer = new U8[this->byteSize + getHeight()];
|
||||
if(tmpbuffer == 0)
|
||||
{
|
||||
mng_cleanup(&mng);
|
||||
return false;
|
||||
}
|
||||
|
||||
// transfer data, add filterbyte
|
||||
U32 effwdt = getWidth() * this->bytesPerPixel;
|
||||
for(U32 Row = 0; Row < getHeight(); Row++)
|
||||
{
|
||||
// first Byte in each scanline is filterbyte: currently 0 -> no filter
|
||||
tmpbuffer[Row * (effwdt + 1)] = 0;
|
||||
|
||||
// copy the scanline
|
||||
dMemcpy(tmpbuffer + Row * (effwdt + 1) + 1, getAddress(0, Row), effwdt);
|
||||
}
|
||||
|
||||
// compress data with zlib
|
||||
U8 *dstbuffer = new U8[this->byteSize + getHeight()];
|
||||
if(dstbuffer == 0)
|
||||
{
|
||||
delete [] tmpbuffer;
|
||||
mng_cleanup(&mng);
|
||||
return false;
|
||||
}
|
||||
|
||||
U32 dstbufferSize = this->byteSize + getHeight();
|
||||
if(Z_OK != compress2((Bytef*)dstbuffer,(uLongf*)&dstbufferSize, (const Bytef*)tmpbuffer, dstbufferSize, 9))
|
||||
{
|
||||
delete [] tmpbuffer;
|
||||
delete [] dstbuffer;
|
||||
mng_cleanup(&mng);
|
||||
return false;
|
||||
}
|
||||
|
||||
mng_putchunk_idat(mng, dstbufferSize, (mng_ptr*)dstbuffer);
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
mng_putchunk_iend(mng);
|
||||
|
||||
delete [] tmpbuffer;
|
||||
delete [] dstbuffer;
|
||||
|
||||
mng_write(mng);
|
||||
mng_cleanup(&mng);
|
||||
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
647
Engine/source/gfx/bitmap/loaders/bitmapPng.cpp
Normal file
647
Engine/source/gfx/bitmap/loaders/bitmapPng.cpp
Normal file
|
|
@ -0,0 +1,647 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
|
||||
#include "core/stream/fileStream.h"
|
||||
#include "core/stream/memStream.h"
|
||||
#include "core/strings/stringFunctions.h"
|
||||
|
||||
#include "gfx/bitmap/gBitmap.h"
|
||||
#include "gfx/bitmap/pngUtils.h"
|
||||
|
||||
#define PNG_INTERNAL 1
|
||||
#include <time.h>
|
||||
#include "lpng/png.h"
|
||||
#include "zlib/zlib.h"
|
||||
|
||||
#ifdef NULL
|
||||
#undef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
|
||||
static bool sReadPNG(Stream &stream, GBitmap *bitmap);
|
||||
|
||||
/// Compression levels for PNGs range from 0-9.
|
||||
/// A value outside that range will cause the write routine to look for the best compression for a given PNG. This can be slow.
|
||||
static bool sWritePNG(GBitmap *bitmap, Stream &stream, U32 compressionLevel);
|
||||
static bool _writePNG(GBitmap *bitmap, Stream &stream, U32 compressionLevel, U32 strategy, U32 filter);
|
||||
|
||||
static struct _privateRegisterPNG
|
||||
{
|
||||
_privateRegisterPNG()
|
||||
{
|
||||
GBitmap::Registration reg;
|
||||
|
||||
reg.priority = 100;
|
||||
reg.extensions.push_back( "png" );
|
||||
|
||||
reg.readFunc = sReadPNG;
|
||||
reg.writeFunc = sWritePNG;
|
||||
reg.defaultCompression = 6;
|
||||
|
||||
GBitmap::sRegisterFormat( reg );
|
||||
}
|
||||
} sStaticRegisterPNG;
|
||||
|
||||
|
||||
//-------------------------------------- Replacement I/O for standard LIBPng
|
||||
// functions. we don't wanna use
|
||||
// FILE*'s...
|
||||
static void pngReadDataFn(png_structp png_ptr,
|
||||
png_bytep data,
|
||||
png_size_t length)
|
||||
{
|
||||
AssertFatal(png_ptr->io_ptr != NULL, "No stream?");
|
||||
|
||||
Stream *strm = (Stream*)png_ptr->io_ptr;
|
||||
bool success = strm->read(length, data);
|
||||
AssertFatal(success, "pngReadDataFn - failed to read from stream!");
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------
|
||||
static void pngWriteDataFn(png_structp png_ptr,
|
||||
png_bytep data,
|
||||
png_size_t length)
|
||||
{
|
||||
AssertFatal(png_ptr->io_ptr != NULL, "No stream?");
|
||||
|
||||
Stream *strm = (Stream*)png_ptr->io_ptr;
|
||||
bool success = strm->write(length, data);
|
||||
AssertFatal(success, "pngWriteDataFn - failed to write to stream!");
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------
|
||||
static void pngFlushDataFn(png_structp /*png_ptr*/)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
static png_voidp pngMallocFn(png_structp /*png_ptr*/, png_size_t size)
|
||||
{
|
||||
return FrameAllocator::alloc(size);
|
||||
}
|
||||
|
||||
static void pngFreeFn(png_structp /*png_ptr*/, png_voidp /*mem*/)
|
||||
{
|
||||
}
|
||||
|
||||
static png_voidp pngRealMallocFn(png_structp /*png_ptr*/, png_size_t size)
|
||||
{
|
||||
return (png_voidp)dMalloc(size);
|
||||
}
|
||||
|
||||
static void pngRealFreeFn(png_structp /*png_ptr*/, png_voidp mem)
|
||||
{
|
||||
dFree(mem);
|
||||
}
|
||||
|
||||
//--------------------------------------
|
||||
static void pngFatalErrorFn(png_structp /*png_ptr*/,
|
||||
png_const_charp pMessage)
|
||||
{
|
||||
AssertISV(false, avar("Error reading PNG file:\n %s", pMessage));
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------
|
||||
static void pngWarningFn(png_structp, png_const_charp /*pMessage*/)
|
||||
{
|
||||
// AssertWarn(false, avar("Warning reading PNG file:\n %s", pMessage));
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------
|
||||
static bool sReadPNG(Stream &stream, GBitmap *bitmap)
|
||||
{
|
||||
static const U32 cs_headerBytesChecked = 8;
|
||||
|
||||
U8 header[cs_headerBytesChecked];
|
||||
stream.read(cs_headerBytesChecked, header);
|
||||
|
||||
bool isPng = png_check_sig(header, cs_headerBytesChecked) != 0;
|
||||
if (isPng == false)
|
||||
{
|
||||
AssertWarn(false, "GBitmap::readPNG: stream doesn't contain a PNG");
|
||||
return false;
|
||||
}
|
||||
|
||||
U32 prevWaterMark = FrameAllocator::getWaterMark();
|
||||
png_structp png_ptr = png_create_read_struct_2(PNG_LIBPNG_VER_STRING,
|
||||
NULL,
|
||||
pngFatalErrorFn,
|
||||
pngWarningFn,
|
||||
NULL,
|
||||
pngRealMallocFn,
|
||||
pngRealFreeFn);
|
||||
|
||||
if (png_ptr == NULL)
|
||||
{
|
||||
FrameAllocator::setWaterMark(prevWaterMark);
|
||||
return false;
|
||||
}
|
||||
|
||||
png_infop info_ptr = png_create_info_struct(png_ptr);
|
||||
if (info_ptr == NULL)
|
||||
{
|
||||
png_destroy_read_struct(&png_ptr,
|
||||
(png_infopp)NULL,
|
||||
(png_infopp)NULL);
|
||||
|
||||
FrameAllocator::setWaterMark(prevWaterMark);
|
||||
return false;
|
||||
}
|
||||
|
||||
png_infop end_info = png_create_info_struct(png_ptr);
|
||||
if (end_info == NULL)
|
||||
{
|
||||
png_destroy_read_struct(&png_ptr,
|
||||
&info_ptr,
|
||||
(png_infopp)NULL);
|
||||
|
||||
FrameAllocator::setWaterMark(prevWaterMark);
|
||||
return false;
|
||||
}
|
||||
|
||||
png_set_read_fn(png_ptr, &stream, pngReadDataFn);
|
||||
|
||||
// Read off the info on the image.
|
||||
png_set_sig_bytes(png_ptr, cs_headerBytesChecked);
|
||||
png_read_info(png_ptr, info_ptr);
|
||||
|
||||
// OK, at this point, if we have reached it ok, then we can reset the
|
||||
// image to accept the new data...
|
||||
//
|
||||
bitmap->deleteImage();
|
||||
|
||||
png_uint_32 width;
|
||||
png_uint_32 height;
|
||||
S32 bit_depth;
|
||||
S32 color_type;
|
||||
|
||||
png_get_IHDR(png_ptr, info_ptr,
|
||||
&width, &height, // obv.
|
||||
&bit_depth, &color_type, // obv.
|
||||
NULL, // interlace
|
||||
NULL, // compression_type
|
||||
NULL); // filter_type
|
||||
|
||||
// First, handle the color transformations. We need this to read in the
|
||||
// data as RGB or RGBA, _always_, with a maximal channel width of 8 bits.
|
||||
//
|
||||
bool transAlpha = false;
|
||||
GFXFormat format = GFXFormatR8G8B8;
|
||||
|
||||
// Strip off any 16 bit info
|
||||
//
|
||||
if (bit_depth == 16 && color_type != PNG_COLOR_TYPE_GRAY)
|
||||
{
|
||||
png_set_strip_16(png_ptr);
|
||||
}
|
||||
|
||||
// Expand a transparency channel into a full alpha channel...
|
||||
//
|
||||
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
|
||||
{
|
||||
png_set_expand(png_ptr);
|
||||
transAlpha = true;
|
||||
}
|
||||
|
||||
if (color_type == PNG_COLOR_TYPE_PALETTE)
|
||||
{
|
||||
png_set_expand(png_ptr);
|
||||
format = transAlpha ? GFXFormatR8G8B8A8 : GFXFormatR8G8B8;
|
||||
}
|
||||
else if (color_type == PNG_COLOR_TYPE_GRAY)
|
||||
{
|
||||
png_set_expand(png_ptr);
|
||||
|
||||
if (bit_depth == 16)
|
||||
format = GFXFormatR5G6B5;
|
||||
else
|
||||
format = GFXFormatA8;
|
||||
}
|
||||
else if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
||||
{
|
||||
png_set_expand(png_ptr);
|
||||
png_set_gray_to_rgb(png_ptr);
|
||||
format = GFXFormatR8G8B8A8;
|
||||
}
|
||||
else if (color_type == PNG_COLOR_TYPE_RGB)
|
||||
{
|
||||
format = transAlpha ? GFXFormatR8G8B8A8 : GFXFormatR8G8B8;
|
||||
png_set_expand(png_ptr);
|
||||
}
|
||||
else if (color_type == PNG_COLOR_TYPE_RGB_ALPHA)
|
||||
{
|
||||
png_set_expand(png_ptr);
|
||||
format = GFXFormatR8G8B8A8;
|
||||
}
|
||||
|
||||
// Update the info pointer with the result of the transformations
|
||||
// above...
|
||||
png_read_update_info(png_ptr, info_ptr);
|
||||
|
||||
png_uint_32 rowBytes = png_get_rowbytes(png_ptr, info_ptr);
|
||||
if (format == GFXFormatR8G8B8)
|
||||
{
|
||||
AssertFatal(rowBytes == width * 3,
|
||||
"Error, our rowbytes are incorrect for this transform... (3)");
|
||||
}
|
||||
else if (format == GFXFormatR8G8B8A8)
|
||||
{
|
||||
AssertFatal(rowBytes == width * 4,
|
||||
"Error, our rowbytes are incorrect for this transform... (4)");
|
||||
}
|
||||
else if (format == GFXFormatR5G6B5)
|
||||
{
|
||||
AssertFatal(rowBytes == width * 2,
|
||||
"Error, our rowbytes are incorrect for this transform... (2)");
|
||||
}
|
||||
|
||||
// actually allocate the bitmap space...
|
||||
bitmap->allocateBitmap(width, height,
|
||||
false, // don't extrude miplevels...
|
||||
format); // use determined format...
|
||||
|
||||
// Set up the row pointers...
|
||||
png_bytep* rowPointers = new png_bytep[ height ];
|
||||
U8* pBase = (U8*)bitmap->getBits();
|
||||
|
||||
for (U32 i = 0; i < height; i++)
|
||||
rowPointers[i] = pBase + (i * rowBytes);
|
||||
|
||||
// And actually read the image!
|
||||
png_read_image(png_ptr, rowPointers);
|
||||
|
||||
// We're outta here, destroy the png structs, and release the lock
|
||||
// as quickly as possible...
|
||||
//png_read_end(png_ptr, end_info);
|
||||
delete [] rowPointers;
|
||||
png_read_end(png_ptr, NULL);
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
|
||||
|
||||
// Ok, the image is read in, now we need to finish up the initialization,
|
||||
// which means: setting up the detailing members, init'ing the palette
|
||||
// key, etc...
|
||||
//
|
||||
// actually, all of that was handled by allocateBitmap, so we're outta here
|
||||
//
|
||||
|
||||
// Check this bitmap for transparency
|
||||
bitmap->checkForTransparency();
|
||||
|
||||
FrameAllocator::setWaterMark(prevWaterMark);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
static bool _writePNG(GBitmap *bitmap, Stream &stream, U32 compressionLevel, U32 strategy, U32 filter)
|
||||
{
|
||||
GFXFormat format = bitmap->getFormat();
|
||||
|
||||
// ONLY RGB bitmap writing supported at this time!
|
||||
AssertFatal( format == GFXFormatR8G8B8 ||
|
||||
format == GFXFormatR8G8B8A8 ||
|
||||
format == GFXFormatR8G8B8X8 ||
|
||||
format == GFXFormatA8 ||
|
||||
format == GFXFormatR5G6B5, "_writePNG: ONLY RGB bitmap writing supported at this time.");
|
||||
|
||||
if ( format != GFXFormatR8G8B8 &&
|
||||
format != GFXFormatR8G8B8A8 &&
|
||||
format != GFXFormatR8G8B8X8 &&
|
||||
format != GFXFormatA8 &&
|
||||
format != GFXFormatR5G6B5 )
|
||||
return false;
|
||||
|
||||
png_structp png_ptr = png_create_write_struct_2(PNG_LIBPNG_VER_STRING,
|
||||
NULL,
|
||||
pngFatalErrorFn,
|
||||
pngWarningFn,
|
||||
NULL,
|
||||
pngMallocFn,
|
||||
pngFreeFn);
|
||||
if (png_ptr == NULL)
|
||||
return (false);
|
||||
|
||||
png_infop info_ptr = png_create_info_struct(png_ptr);
|
||||
if (info_ptr == NULL)
|
||||
{
|
||||
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
png_set_write_fn(png_ptr, &stream, pngWriteDataFn, pngFlushDataFn);
|
||||
|
||||
// Set the compression level, image filters, and compression strategy...
|
||||
png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_STRATEGY;
|
||||
png_ptr->zlib_strategy = strategy;
|
||||
png_set_compression_window_bits(png_ptr, 15);
|
||||
png_set_compression_level(png_ptr, compressionLevel);
|
||||
png_set_filter(png_ptr, 0, filter);
|
||||
|
||||
// Set the image information here. Width and height are up to 2^31,
|
||||
// bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on
|
||||
// the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY,
|
||||
// PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB,
|
||||
// or PNG_COLOR_TYPE_RGB_ALPHA. interlace is either PNG_INTERLACE_NONE or
|
||||
// PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST
|
||||
// currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED
|
||||
|
||||
U32 width = bitmap->getWidth();
|
||||
U32 height = bitmap->getHeight();
|
||||
|
||||
if (format == GFXFormatR8G8B8)
|
||||
{
|
||||
png_set_IHDR(png_ptr, info_ptr,
|
||||
width, height, // the width & height
|
||||
8, PNG_COLOR_TYPE_RGB, // bit_depth, color_type,
|
||||
NULL, // no interlace
|
||||
NULL, // compression type
|
||||
NULL); // filter type
|
||||
}
|
||||
else if (format == GFXFormatR8G8B8A8 || format == GFXFormatR8G8B8X8)
|
||||
{
|
||||
png_set_IHDR(png_ptr, info_ptr,
|
||||
width, height, // the width & height
|
||||
8, PNG_COLOR_TYPE_RGB_ALPHA, // bit_depth, color_type,
|
||||
NULL, // no interlace
|
||||
NULL, // compression type
|
||||
NULL); // filter type
|
||||
}
|
||||
else if (format == GFXFormatA8)
|
||||
{
|
||||
png_set_IHDR(png_ptr, info_ptr,
|
||||
width, height, // the width & height
|
||||
8, PNG_COLOR_TYPE_GRAY, // bit_depth, color_type,
|
||||
NULL, // no interlace
|
||||
NULL, // compression type
|
||||
NULL); // filter type
|
||||
}
|
||||
else if (format == GFXFormatR5G6B5)
|
||||
{
|
||||
png_set_IHDR(png_ptr, info_ptr,
|
||||
width, height, // the width & height
|
||||
16, PNG_COLOR_TYPE_GRAY, // bit_depth, color_type,
|
||||
PNG_INTERLACE_NONE, // no interlace
|
||||
PNG_COMPRESSION_TYPE_DEFAULT, // compression type
|
||||
PNG_FILTER_TYPE_DEFAULT); // filter type
|
||||
|
||||
png_color_8_struct sigBit = { 0 };
|
||||
sigBit.gray = 16;
|
||||
png_set_sBIT(png_ptr, info_ptr, &sigBit );
|
||||
|
||||
png_set_swap( png_ptr );
|
||||
}
|
||||
|
||||
png_write_info(png_ptr, info_ptr);
|
||||
FrameAllocatorMarker marker;
|
||||
png_bytep* row_pointers = (png_bytep*)marker.alloc( height * sizeof( png_bytep ) );
|
||||
for (U32 i=0; i<height; i++)
|
||||
row_pointers[i] = const_cast<png_bytep>(bitmap->getAddress(0, i));
|
||||
|
||||
png_write_image(png_ptr, row_pointers);
|
||||
|
||||
// Write S3TC data if present...
|
||||
// Write FXT1 data if present...
|
||||
|
||||
png_write_end(png_ptr, info_ptr);
|
||||
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
static bool sWritePNG(GBitmap *bitmap, Stream &stream, U32 compressionLevel)
|
||||
{
|
||||
U32 waterMark = FrameAllocator::getWaterMark();
|
||||
|
||||
if ( compressionLevel < 10 )
|
||||
{
|
||||
bool retVal = _writePNG(bitmap, stream, compressionLevel, 0, PNG_ALL_FILTERS);
|
||||
FrameAllocator::setWaterMark(waterMark);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
// check all our methods of compression to find the best one and use it
|
||||
U8* buffer = new U8[1 << 22]; // 4 Megs. Should be enough...
|
||||
MemStream* pMemStream = new MemStream(1 << 22, buffer, false, true);
|
||||
|
||||
const U32 zStrategies[] = { Z_DEFAULT_STRATEGY,
|
||||
Z_FILTERED };
|
||||
const U32 pngFilters[] = { PNG_FILTER_NONE,
|
||||
PNG_FILTER_SUB,
|
||||
PNG_FILTER_UP,
|
||||
PNG_FILTER_AVG,
|
||||
PNG_FILTER_PAETH,
|
||||
PNG_ALL_FILTERS };
|
||||
|
||||
U32 minSize = 0xFFFFFFFF;
|
||||
U32 bestStrategy = 0xFFFFFFFF;
|
||||
U32 bestFilter = 0xFFFFFFFF;
|
||||
U32 bestCLevel = 0xFFFFFFFF;
|
||||
|
||||
for (U32 cl = 0; cl <=9; cl++)
|
||||
{
|
||||
for (U32 zs = 0; zs < 2; zs++)
|
||||
{
|
||||
for (U32 pf = 0; pf < 6; pf++)
|
||||
{
|
||||
pMemStream->setPosition(0);
|
||||
|
||||
U32 waterMarkInner = FrameAllocator::getWaterMark();
|
||||
|
||||
if (_writePNG(bitmap, *pMemStream, cl, zStrategies[zs], pngFilters[pf]) == false)
|
||||
AssertFatal(false, "Handle this error!");
|
||||
|
||||
FrameAllocator::setWaterMark(waterMarkInner);
|
||||
|
||||
if (pMemStream->getPosition() < minSize)
|
||||
{
|
||||
minSize = pMemStream->getPosition();
|
||||
bestStrategy = zs;
|
||||
bestFilter = pf;
|
||||
bestCLevel = cl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
AssertFatal(minSize != 0xFFFFFFFF, "Error, no best found?");
|
||||
|
||||
delete pMemStream;
|
||||
delete [] buffer;
|
||||
|
||||
|
||||
bool retVal = _writePNG(bitmap, stream,
|
||||
bestCLevel,
|
||||
zStrategies[bestStrategy],
|
||||
pngFilters[bestFilter]);
|
||||
FrameAllocator::setWaterMark(waterMark);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Stores PNG stream data
|
||||
struct DeferredPNGWriterData {
|
||||
png_structp png_ptr;
|
||||
png_infop info_ptr;
|
||||
U32 width;
|
||||
U32 height;
|
||||
};
|
||||
DeferredPNGWriter::DeferredPNGWriter() :
|
||||
mData( NULL ),
|
||||
mActive(false)
|
||||
{
|
||||
mData = new DeferredPNGWriterData();
|
||||
}
|
||||
DeferredPNGWriter::~DeferredPNGWriter()
|
||||
{
|
||||
delete mData;
|
||||
}
|
||||
|
||||
bool DeferredPNGWriter::begin( GFXFormat format, S32 width, S32 height, Stream &stream, U32 compressionLevel )
|
||||
{
|
||||
// ONLY RGB bitmap writing supported at this time!
|
||||
AssertFatal( format == GFXFormatR8G8B8 ||
|
||||
format == GFXFormatR8G8B8A8 ||
|
||||
format == GFXFormatR8G8B8X8 ||
|
||||
format == GFXFormatA8 ||
|
||||
format == GFXFormatR5G6B5, "_writePNG: ONLY RGB bitmap writing supported at this time.");
|
||||
|
||||
if ( format != GFXFormatR8G8B8 &&
|
||||
format != GFXFormatR8G8B8A8 &&
|
||||
format != GFXFormatR8G8B8X8 &&
|
||||
format != GFXFormatA8 &&
|
||||
format != GFXFormatR5G6B5 )
|
||||
return false;
|
||||
|
||||
mData->png_ptr = png_create_write_struct_2(PNG_LIBPNG_VER_STRING,
|
||||
NULL,
|
||||
pngFatalErrorFn,
|
||||
pngWarningFn,
|
||||
NULL,
|
||||
pngRealMallocFn,
|
||||
pngRealFreeFn);
|
||||
if (mData->png_ptr == NULL)
|
||||
return (false);
|
||||
|
||||
mData->info_ptr = png_create_info_struct(mData->png_ptr);
|
||||
if (mData->info_ptr == NULL)
|
||||
{
|
||||
png_destroy_write_struct(&mData->png_ptr, (png_infopp)NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
png_set_write_fn(mData->png_ptr, &stream, pngWriteDataFn, pngFlushDataFn);
|
||||
|
||||
// Set the compression level, image filters, and compression strategy...
|
||||
mData->png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_STRATEGY;
|
||||
mData->png_ptr->zlib_strategy = 0;
|
||||
png_set_compression_window_bits(mData->png_ptr, 15);
|
||||
png_set_compression_level(mData->png_ptr, compressionLevel);
|
||||
png_set_filter(mData->png_ptr, 0, PNG_ALL_FILTERS);
|
||||
|
||||
// Set the image information here. Width and height are up to 2^31,
|
||||
// bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on
|
||||
// the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY,
|
||||
// PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB,
|
||||
// or PNG_COLOR_TYPE_RGB_ALPHA. interlace is either PNG_INTERLACE_NONE or
|
||||
// PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST
|
||||
// currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED
|
||||
|
||||
if (format == GFXFormatR8G8B8)
|
||||
{
|
||||
png_set_IHDR(mData->png_ptr, mData->info_ptr,
|
||||
width, height, // the width & height
|
||||
8, PNG_COLOR_TYPE_RGB, // bit_depth, color_type,
|
||||
NULL, // no interlace
|
||||
NULL, // compression type
|
||||
NULL); // filter type
|
||||
}
|
||||
else if (format == GFXFormatR8G8B8A8 || format == GFXFormatR8G8B8X8)
|
||||
{
|
||||
png_set_IHDR(mData->png_ptr, mData->info_ptr,
|
||||
width, height, // the width & height
|
||||
8, PNG_COLOR_TYPE_RGB_ALPHA, // bit_depth, color_type,
|
||||
NULL, // no interlace
|
||||
NULL, // compression type
|
||||
NULL); // filter type
|
||||
}
|
||||
else if (format == GFXFormatA8)
|
||||
{
|
||||
png_set_IHDR(mData->png_ptr, mData->info_ptr,
|
||||
width, height, // the width & height
|
||||
8, PNG_COLOR_TYPE_GRAY, // bit_depth, color_type,
|
||||
NULL, // no interlace
|
||||
NULL, // compression type
|
||||
NULL); // filter type
|
||||
}
|
||||
else if (format == GFXFormatR5G6B5)
|
||||
{
|
||||
png_set_IHDR(mData->png_ptr, mData->info_ptr,
|
||||
width, height, // the width & height
|
||||
16, PNG_COLOR_TYPE_GRAY, // bit_depth, color_type,
|
||||
PNG_INTERLACE_NONE, // no interlace
|
||||
PNG_COMPRESSION_TYPE_DEFAULT, // compression type
|
||||
PNG_FILTER_TYPE_DEFAULT); // filter type
|
||||
|
||||
png_color_8_struct sigBit = { 0 };
|
||||
sigBit.gray = 16;
|
||||
png_set_sBIT(mData->png_ptr, mData->info_ptr, &sigBit );
|
||||
|
||||
png_set_swap( mData->png_ptr );
|
||||
}
|
||||
|
||||
png_write_info(mData->png_ptr, mData->info_ptr);
|
||||
|
||||
mActive = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
void DeferredPNGWriter::append( GBitmap* bitmap, U32 rows)
|
||||
{
|
||||
AssertFatal(mActive, "Cannot append to an inactive DeferredPNGWriter!");
|
||||
|
||||
U32 height = getMin( bitmap->getHeight(), rows);
|
||||
|
||||
FrameAllocatorMarker marker;
|
||||
png_bytep* row_pointers = (png_bytep*)marker.alloc( height * sizeof( png_bytep ) );
|
||||
for (U32 i=0; i<height; i++)
|
||||
row_pointers[i] = const_cast<png_bytep>(bitmap->getAddress(0, i));
|
||||
|
||||
png_write_rows(mData->png_ptr, row_pointers, height);
|
||||
}
|
||||
void DeferredPNGWriter::end()
|
||||
{
|
||||
AssertFatal(mActive, "Cannot end an inactive DeferredPNGWriter!");
|
||||
|
||||
png_write_end(mData->png_ptr, mData->info_ptr);
|
||||
png_destroy_write_struct(&mData->png_ptr, (png_infopp)NULL);
|
||||
|
||||
mActive = false;
|
||||
}
|
||||
489
Engine/source/gfx/bitmap/loaders/bitmapTga.cpp
Normal file
489
Engine/source/gfx/bitmap/loaders/bitmapTga.cpp
Normal file
|
|
@ -0,0 +1,489 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "core/stream/stream.h"
|
||||
|
||||
#include "gfx/bitmap/gBitmap.h"
|
||||
|
||||
|
||||
static bool sReadTGA(Stream &stream, GBitmap *bitmap);
|
||||
static bool sWriteTGA(GBitmap *bitmap, Stream &stream, U32 compressionLevel);
|
||||
|
||||
static struct _privateRegisterTGA
|
||||
{
|
||||
_privateRegisterTGA()
|
||||
{
|
||||
GBitmap::Registration reg;
|
||||
|
||||
reg.extensions.push_back( "tga" );
|
||||
|
||||
reg.readFunc = sReadTGA;
|
||||
reg.writeFunc = sWriteTGA;
|
||||
|
||||
GBitmap::sRegisterFormat( reg );
|
||||
}
|
||||
} sStaticRegisterTGA;
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//-------------------------------------- Supplementary I/O
|
||||
//
|
||||
|
||||
enum eImageType
|
||||
{
|
||||
TypeNoData = 0,
|
||||
TypeUncPaletted = 1,
|
||||
TypeUncTruecolor = 2,
|
||||
TypeUncGrayscale = 3,
|
||||
TypeRlePaletted = 9,
|
||||
TypeRleTruecolor = 10,
|
||||
TypeRleGrayscale = 11
|
||||
};
|
||||
|
||||
enum ePixelMap
|
||||
{
|
||||
MapLowerLeft = 0,
|
||||
MapLowerRight = 1,
|
||||
MapUpperLeft = 2,
|
||||
MapUpperRight = 3,
|
||||
};
|
||||
|
||||
static void tga_write_pixel_to_mem( U8 * dat, U8 img_spec, U32 number,
|
||||
U32 w, U32 h, U32 pixel, U32 bppOut )
|
||||
{
|
||||
// write the pixel to the data regarding how the
|
||||
// header says the data is ordered.
|
||||
|
||||
U32 x, y;
|
||||
|
||||
switch( (img_spec & 0x30) >> 4 )
|
||||
{
|
||||
case MapLowerRight:
|
||||
x = w - 1 - (number % w);
|
||||
y = h - 1 - (number / w);
|
||||
break;
|
||||
|
||||
case MapUpperLeft:
|
||||
x = number % w;
|
||||
y = number / w;
|
||||
break;
|
||||
|
||||
case MapUpperRight:
|
||||
x = w - 1 - (number % w);
|
||||
y = number / w;
|
||||
break;
|
||||
|
||||
case MapLowerLeft:
|
||||
default:
|
||||
x = number % w;
|
||||
y = h - 1 - (number / w);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
U32 addy = (y * w + x) * bppOut;
|
||||
for ( U32 j = 0; j < bppOut; j++ )
|
||||
dat[addy + j] = (U8)((pixel >> (j * 8)) & 0xFF);
|
||||
}
|
||||
|
||||
static U32 tga_get_pixel( Stream& stream, U8 bppIn,
|
||||
U8 * colormap, U8 cmapBytesEntry )
|
||||
{
|
||||
/* get the image data value out */
|
||||
|
||||
U32 tmp_int32 = 0;
|
||||
|
||||
for ( U32 j = 0; j < bppIn; j++ )
|
||||
{
|
||||
U8 tmp_byte;
|
||||
if ( !stream.read( &tmp_byte ) )
|
||||
tmp_int32 = 0;
|
||||
else
|
||||
tmp_int32 += tmp_byte << (j * 8);
|
||||
}
|
||||
|
||||
/* byte-order correct the thing */
|
||||
switch( bppIn )
|
||||
{
|
||||
case 2:
|
||||
tmp_int32 = convertLEndianToHost( (U16)tmp_int32 );
|
||||
break;
|
||||
|
||||
case 3: /* intentional fall-thru */
|
||||
case 4:
|
||||
tmp_int32 = convertLEndianToHost( tmp_int32 );
|
||||
break;
|
||||
}
|
||||
|
||||
U32 tmp_col;
|
||||
|
||||
if ( colormap )
|
||||
{
|
||||
/* need to look up value to get real color */
|
||||
tmp_col = 0;
|
||||
for ( U32 j = 0; j < cmapBytesEntry; j++ )
|
||||
tmp_col += colormap[cmapBytesEntry * tmp_int32 + j] << (8 * j);
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp_col = tmp_int32;
|
||||
}
|
||||
|
||||
return tmp_col;
|
||||
}
|
||||
|
||||
static U32 tga_convert_color( U32 pixel, U32 bppIn, U8 alphabits, U32 bppOut )
|
||||
{
|
||||
// this is not only responsible for converting from different depths
|
||||
// to other depths, it also switches BGR to RGB.
|
||||
|
||||
// this thing will also premultiply alpha, on a pixel by pixel basis.
|
||||
|
||||
U8 r, g, b, a;
|
||||
|
||||
switch( bppIn )
|
||||
{
|
||||
case 32:
|
||||
if ( alphabits == 0 )
|
||||
goto is_24_bit_in_disguise;
|
||||
// 32-bit to 32-bit -- nop.
|
||||
break;
|
||||
|
||||
case 24:
|
||||
is_24_bit_in_disguise:
|
||||
// 24-bit to 32-bit; (only force alpha to full)
|
||||
pixel |= 0xFF000000;
|
||||
break;
|
||||
|
||||
case 15:
|
||||
is_15_bit_in_disguise:
|
||||
r = (U8)(((F32)((pixel & 0x7C00) >> 10)) * 8.2258f);
|
||||
g = (U8)(((F32)((pixel & 0x03E0) >> 5 )) * 8.2258f);
|
||||
b = (U8)(((F32)(pixel & 0x001F)) * 8.2258f);
|
||||
// 15-bit to 32-bit; (force alpha to full)
|
||||
pixel = 0xFF000000 + (r << 16) + (g << 8) + b;
|
||||
break;
|
||||
|
||||
case 16:
|
||||
if ( alphabits == 1 )
|
||||
goto is_15_bit_in_disguise;
|
||||
|
||||
// 16-bit to 32-bit; (force alpha to full)
|
||||
r = (U8)(((F32)((pixel & 0xF800) >> 11)) * 8.2258f);
|
||||
g = (U8)(((F32)((pixel & 0x07E0) >> 5 )) * 4.0476f);
|
||||
b = (U8)(((F32)(pixel & 0x001F)) * 8.2258f);
|
||||
pixel = 0xFF000000 + (r << 16) + (g << 8) + b;
|
||||
break;
|
||||
}
|
||||
|
||||
// convert the 32-bit pixel from BGR to RGB.
|
||||
pixel = (pixel & 0xFF00FF00) + ((pixel & 0xFF) << 16) + ((pixel & 0xFF0000) >> 16);
|
||||
|
||||
r = pixel & 0x000000FF;
|
||||
g = (pixel & 0x0000FF00) >> 8;
|
||||
b = (pixel & 0x00FF0000) >> 16;
|
||||
a = (pixel & 0xFF000000) >> 24;
|
||||
|
||||
// not premultiplied alpha -- multiply.
|
||||
r = (U8)(((F32)r / 255.0f) * ((F32)a / 255.0f) * 255.0f);
|
||||
g = (U8)(((F32)g / 255.0f) * ((F32)a / 255.0f) * 255.0f);
|
||||
b = (U8)(((F32)b / 255.0f) * ((F32)a / 255.0f) * 255.0f);
|
||||
|
||||
pixel = r + (g << 8) + (b << 16) + (a << 24);
|
||||
|
||||
/* now convert from 32-bit to whatever they want. */
|
||||
switch( bppOut )
|
||||
{
|
||||
case 4:
|
||||
// 32 to 32 -- nop.
|
||||
break;
|
||||
|
||||
case 3:
|
||||
// 32 to 24 -- discard alpha.
|
||||
pixel &= 0x00FFFFFF;
|
||||
break;
|
||||
}
|
||||
|
||||
return pixel;
|
||||
}
|
||||
|
||||
static bool sReadTGA(Stream &stream, GBitmap *bitmap)
|
||||
{
|
||||
struct Header
|
||||
{
|
||||
U8 idLength; // length of the image_id string below.
|
||||
U8 cmapType; // paletted image <=> cmapType
|
||||
U8 imageType; // can be any of the IMG_TYPE constants above.
|
||||
U16 cmapFirst; //
|
||||
U16 cmapLength; // how long the colormap is
|
||||
U8 cmapEntrySize; // how big a palette entry is.
|
||||
U16 xOrigin; // the x origin of the image in the image data.
|
||||
U16 yOrigin; // the y origin of the image in the image data.
|
||||
U16 width; // the width of the image.
|
||||
U16 height; // the height of the image.
|
||||
U8 pixelDepth; // the depth of a pixel in the image.
|
||||
U8 imageDesc; // the image descriptor.
|
||||
};
|
||||
|
||||
// Read header
|
||||
Header header;
|
||||
stream.read( &header.idLength );
|
||||
stream.read( &header.cmapType );
|
||||
stream.read( &header.imageType );
|
||||
stream.read( &header.cmapFirst );
|
||||
stream.read( &header.cmapLength );
|
||||
stream.read( &header.cmapEntrySize );
|
||||
stream.read( &header.xOrigin );
|
||||
stream.read( &header.yOrigin );
|
||||
stream.read( &header.width );
|
||||
stream.read( &header.height );
|
||||
stream.read( &header.pixelDepth );
|
||||
stream.read( &header.imageDesc );
|
||||
|
||||
U32 numPixels = header.width * header.height;
|
||||
if ( numPixels == 0 )
|
||||
{
|
||||
//Con::errorf( "Texture has width and/or height set to 0" );
|
||||
return false;
|
||||
}
|
||||
|
||||
U8 alphabits = header.imageDesc & 0x0F;
|
||||
|
||||
/* seek past the image id, if there is one */
|
||||
if ( header.idLength )
|
||||
{
|
||||
if ( !stream.setPosition( stream.getPosition() + header.idLength ) )
|
||||
{
|
||||
//Con::errorf( "Unexpected end of stream encountered" );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* if this is a 'nodata' image, just jump out. */
|
||||
if ( header.imageType == TypeNoData )
|
||||
{
|
||||
//Con::errorf( "Texture contains no data" );
|
||||
return false;
|
||||
}
|
||||
|
||||
/* deal with the colormap, if there is one. */
|
||||
U8* colormap = NULL;
|
||||
U32 cmapBytes = 0;
|
||||
U8 cmapBytesEntry = 0;
|
||||
|
||||
if ( header.cmapType )
|
||||
{
|
||||
switch( header.imageType )
|
||||
{
|
||||
case TypeUncPaletted:
|
||||
case TypeRlePaletted:
|
||||
break;
|
||||
|
||||
case TypeUncTruecolor:
|
||||
case TypeRleTruecolor:
|
||||
// this should really be an error, but some really old
|
||||
// crusty targas might actually be like this (created by TrueVision, no less!)
|
||||
// so, we'll hack our way through it.
|
||||
break;
|
||||
|
||||
case TypeUncGrayscale:
|
||||
case TypeRleGrayscale:
|
||||
//Con::errorf( "Found colormap for a grayscale image" );
|
||||
return false;
|
||||
}
|
||||
|
||||
/* ensure colormap entry size is something we support */
|
||||
if ( !(header.cmapEntrySize == 15 ||
|
||||
header.cmapEntrySize == 16 ||
|
||||
header.cmapEntrySize == 24 ||
|
||||
header.cmapEntrySize == 32) )
|
||||
{
|
||||
//Con::errorf( "Unsupported colormap entry size" );
|
||||
return false;
|
||||
}
|
||||
|
||||
/* allocate memory for a colormap */
|
||||
if ( header.cmapEntrySize & 0x07 )
|
||||
cmapBytesEntry = (((8 - (header.cmapEntrySize & 0x07)) + header.cmapEntrySize) >> 3);
|
||||
else
|
||||
cmapBytesEntry = (header.cmapEntrySize >> 3);
|
||||
|
||||
cmapBytes = cmapBytesEntry * header.cmapLength;
|
||||
colormap = new U8[ cmapBytes ];
|
||||
|
||||
for ( U32 i = 0; i < header.cmapLength; i++ )
|
||||
{
|
||||
/* seek ahead to first entry used */
|
||||
if ( header.cmapFirst != 0 )
|
||||
stream.setPosition( stream.getPosition() + header.cmapFirst * cmapBytesEntry );
|
||||
|
||||
U32 tmp_int32 = 0;
|
||||
for ( U32 j = 0; j < cmapBytesEntry; j++ )
|
||||
{
|
||||
U8 tmp_byte;
|
||||
if ( !stream.read( &tmp_byte ) )
|
||||
{
|
||||
delete [] colormap;
|
||||
//Con::errorf( "Bad colormap" );
|
||||
return false;
|
||||
}
|
||||
tmp_int32 += tmp_byte << (j * 8);
|
||||
}
|
||||
|
||||
// byte order correct.
|
||||
tmp_int32 = convertLEndianToHost( tmp_int32 );
|
||||
|
||||
for ( U32 j = 0; j < cmapBytesEntry; j++ )
|
||||
colormap[i * cmapBytesEntry + j] = (tmp_int32 >> (8 * j)) & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
// compute number of bytes in an image data unit (either index or BGR triple)
|
||||
U8 inBytesPerPixel = 0;
|
||||
if ( header.pixelDepth & 0x07 )
|
||||
inBytesPerPixel = (((8 - (header.pixelDepth & 0x07)) + header.pixelDepth) >> 3);
|
||||
else
|
||||
inBytesPerPixel = (header.pixelDepth >> 3);
|
||||
|
||||
/* assume that there's one byte per pixel */
|
||||
if ( inBytesPerPixel == 0 )
|
||||
inBytesPerPixel = 1;
|
||||
|
||||
GFXFormat gfxFmt;
|
||||
U32 outBytesPerPixel;
|
||||
switch ( header.pixelDepth )
|
||||
{
|
||||
case 32:
|
||||
gfxFmt = GFXFormatR8G8B8A8;
|
||||
outBytesPerPixel = 4;
|
||||
break;
|
||||
|
||||
case 24:
|
||||
default:
|
||||
gfxFmt = GFXFormatR8G8B8;
|
||||
outBytesPerPixel = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
bitmap->allocateBitmap( header.width, header.height, false, gfxFmt );
|
||||
|
||||
// compute the true number of bits per pixel
|
||||
U8 trueBitsPerPixel = header.cmapType ? header.cmapEntrySize : header.pixelDepth;
|
||||
|
||||
// Override the number of alpha bits if necessary
|
||||
// Some apps generate transparent TGAs with alphabits set to 0 in the image descriptor
|
||||
if ( ( trueBitsPerPixel == 32 ) && ( alphabits == 0 ) )
|
||||
alphabits = 8;
|
||||
|
||||
switch( header.imageType )
|
||||
{
|
||||
case TypeUncTruecolor:
|
||||
case TypeUncGrayscale:
|
||||
case TypeUncPaletted:
|
||||
|
||||
/* FIXME: support grayscale */
|
||||
|
||||
for ( U32 i = 0; i < numPixels; i++ )
|
||||
{
|
||||
// get the color value.
|
||||
U32 tmp_col = tga_get_pixel( stream, inBytesPerPixel, colormap, cmapBytesEntry );
|
||||
tmp_col = tga_convert_color( tmp_col, trueBitsPerPixel, alphabits, outBytesPerPixel );
|
||||
|
||||
// now write the data out.
|
||||
tga_write_pixel_to_mem( bitmap->getAddress( 0, 0 ), header.imageDesc,
|
||||
i, header.width, header.height, tmp_col, outBytesPerPixel );
|
||||
}
|
||||
break;
|
||||
|
||||
case TypeRleTruecolor:
|
||||
case TypeRleGrayscale:
|
||||
case TypeRlePaletted:
|
||||
|
||||
// FIXME: handle grayscale..
|
||||
|
||||
for ( U32 i = 0; i < numPixels; )
|
||||
{
|
||||
/* a bit of work to do to read the data.. */
|
||||
U8 packet_header;
|
||||
if ( !stream.read( 1, &packet_header ) )
|
||||
{
|
||||
// well, just let them fill the rest with null pixels then...
|
||||
packet_header = 1;
|
||||
}
|
||||
|
||||
if ( packet_header & 0x80 )
|
||||
{
|
||||
/* run length packet */
|
||||
U32 tmp_col = tga_get_pixel( stream, inBytesPerPixel, colormap, cmapBytesEntry );
|
||||
tmp_col = tga_convert_color( tmp_col, trueBitsPerPixel, alphabits, outBytesPerPixel );
|
||||
|
||||
U8 repcount = (packet_header & 0x7F) + 1;
|
||||
|
||||
/* write all the data out */
|
||||
for ( U32 j = 0; j < repcount; j++ )
|
||||
{
|
||||
tga_write_pixel_to_mem( bitmap->getAddress( 0, 0 ), header.imageDesc,
|
||||
i + j, header.width, header.height, tmp_col, outBytesPerPixel );
|
||||
}
|
||||
|
||||
i += repcount;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* raw packet */
|
||||
/* get pixel from file */
|
||||
U8 repcount = (packet_header & 0x7F) + 1;
|
||||
|
||||
for ( U32 j = 0; j < repcount; j++ )
|
||||
{
|
||||
U32 tmp_col = tga_get_pixel( stream, inBytesPerPixel, colormap, cmapBytesEntry );
|
||||
tmp_col = tga_convert_color( tmp_col, trueBitsPerPixel, alphabits, outBytesPerPixel );
|
||||
|
||||
tga_write_pixel_to_mem( bitmap->getAddress( 0, 0 ), header.imageDesc,
|
||||
i + j, header.width, header.height, tmp_col, outBytesPerPixel );
|
||||
}
|
||||
|
||||
i += repcount;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
//Con::errorf( "Unknown image type" );
|
||||
return false;
|
||||
}
|
||||
|
||||
delete [] colormap;
|
||||
|
||||
// 32-bit tgas have an alpha channel
|
||||
bitmap->setHasTransparency( header.pixelDepth == 32 );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool sWriteTGA(GBitmap *bitmap, Stream &stream, U32 compressionLevel)
|
||||
{
|
||||
AssertISV(false, "GBitmap::writeTGA - doesn't support writing tga files!")
|
||||
|
||||
return false;
|
||||
}
|
||||
49
Engine/source/gfx/bitmap/pngUtils.h
Normal file
49
Engine/source/gfx/bitmap/pngUtils.h
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _PNG_UTILS_H_
|
||||
#define _PNG_UTILS_H_
|
||||
|
||||
#ifndef _GFXENUMS_H_
|
||||
#include "gfx/gfxEnums.h"
|
||||
#endif
|
||||
|
||||
struct DeferredPNGWriterData; // This is used to avoid including png.h in this header
|
||||
class GBitmap;
|
||||
class Stream;
|
||||
|
||||
/// This class is used to write PNGs in row batches
|
||||
class DeferredPNGWriter {
|
||||
protected:
|
||||
DeferredPNGWriterData *mData;
|
||||
bool mActive;
|
||||
|
||||
public:
|
||||
DeferredPNGWriter();
|
||||
~DeferredPNGWriter();
|
||||
|
||||
bool begin( GFXFormat format, S32 width, S32 height, Stream &stream, U32 compressionLevel );
|
||||
void append( GBitmap* bitmap, U32 rows );
|
||||
void end();
|
||||
};
|
||||
|
||||
#endif
|
||||
1289
Engine/source/gfx/gFont.cpp
Normal file
1289
Engine/source/gfx/gFont.cpp
Normal file
File diff suppressed because it is too large
Load diff
194
Engine/source/gfx/gFont.h
Normal file
194
Engine/source/gfx/gFont.h
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GFONT_H_
|
||||
#define _GFONT_H_
|
||||
|
||||
//Includes
|
||||
#ifndef _RESOURCE_H_
|
||||
#include "core/resource.h"
|
||||
#endif
|
||||
#ifndef _PLATFORMFONT_H_
|
||||
#include "platform/platformFont.h"
|
||||
#endif
|
||||
#ifndef _GBITMAP_H_
|
||||
#include "gfx/bitmap/gBitmap.h"
|
||||
#endif
|
||||
#ifndef _GFXDEVICE_H_
|
||||
#include "gfx/gfxDevice.h"
|
||||
#endif
|
||||
#ifndef _GFXTEXTUREHANDLE_H_
|
||||
#include "gfx/gfxTextureHandle.h"
|
||||
#endif
|
||||
|
||||
|
||||
GFX_DeclareTextureProfile(GFXFontTextureProfile);
|
||||
|
||||
class GFont
|
||||
{
|
||||
public:
|
||||
enum Constants
|
||||
{
|
||||
TabWidthInSpaces = 3,
|
||||
TextureSheetSize = 256,
|
||||
};
|
||||
|
||||
public:
|
||||
GFont();
|
||||
virtual ~GFont();
|
||||
|
||||
static Resource<GFont> create(const String &faceName, U32 size, const char *cacheDirectory = 0, U32 charset = TGE_ANSI_CHARSET);
|
||||
|
||||
GFXTexHandle getTextureHandle(S32 index) const { return mTextureSheets[index]; }
|
||||
|
||||
const PlatformFont::CharInfo& getCharInfo(const UTF16 in_charIndex);
|
||||
static const PlatformFont::CharInfo& getDefaultCharInfo();
|
||||
|
||||
U32 getCharHeight(const UTF16 in_charIndex);
|
||||
U32 getCharWidth(const UTF16 in_charIndex);
|
||||
U32 getCharXIncrement(const UTF16 in_charIndex);
|
||||
|
||||
bool isValidChar(const UTF16 in_charIndex) const;
|
||||
|
||||
const U32 getHeight() const { return mHeight; }
|
||||
const U32 getBaseline() const { return mBaseline; }
|
||||
const U32 getAscent() const { return mAscent; }
|
||||
const U32 getDescent() const { return mDescent; }
|
||||
|
||||
U32 getBreakPos(const UTF16 *string, U32 strlen, U32 width, bool breakOnWhitespace);
|
||||
|
||||
/// These are the preferred width functions.
|
||||
U32 getStrNWidth(const UTF16*, U32 n);
|
||||
U32 getStrNWidthPrecise(const UTF16*, U32 n);
|
||||
|
||||
/// These UTF8 versions of the width functions will be deprecated, please avoid them.
|
||||
U32 getStrWidth(const UTF8*); // Note: ignores c/r
|
||||
U32 getStrNWidth(const UTF8*, U32 n);
|
||||
U32 getStrWidthPrecise(const UTF8*); // Note: ignores c/r
|
||||
U32 getStrNWidthPrecise(const UTF8*, U32 n);
|
||||
void wrapString(const UTF8 *string, U32 width, Vector<U32> &startLineOffset, Vector<U32> &lineLen);
|
||||
|
||||
/// Dump information about this font to the console.
|
||||
void dumpInfo() const;
|
||||
|
||||
/// Export to an image strip for image processing.
|
||||
void exportStrip(const char *fileName, U32 padding, U32 kerning);
|
||||
|
||||
/// Import an image strip generated with exportStrip, make sure parameters match!
|
||||
void importStrip(const char *fileName, U32 padding, U32 kerning);
|
||||
|
||||
void setPlatformFont(PlatformFont *inPlatformFont);
|
||||
|
||||
/// Query as to presence of platform font. If absent, we cannot generate more
|
||||
/// chars!
|
||||
const bool hasPlatformFont() const
|
||||
{
|
||||
return mPlatformFont != NULL;
|
||||
}
|
||||
|
||||
/// Query to determine if we should use add or modulate (as A8 textures
|
||||
/// are treated as having 0 for RGB).
|
||||
bool isAlphaOnly() const
|
||||
{
|
||||
return mTextureSheets[0]->getBitmap()->getFormat() == GFXFormatA8;
|
||||
}
|
||||
|
||||
/// Get the filename for a cached font.
|
||||
static String getFontCacheFilename(const String &faceName, U32 faceSize);
|
||||
|
||||
/// Get the face name of the font.
|
||||
String getFontFaceName() const { return mFaceName; };
|
||||
U32 getFontSize() const { return mSize; }
|
||||
U32 getFontCharSet() const { return mCharSet; }
|
||||
|
||||
bool read(Stream& io_rStream);
|
||||
bool write(Stream& io_rStream);
|
||||
|
||||
static GFont* load( const Torque::Path& path );
|
||||
|
||||
protected:
|
||||
bool loadCharInfo(const UTF16 ch);
|
||||
void addBitmap(PlatformFont::CharInfo &charInfo);
|
||||
void addSheet(void);
|
||||
void assignSheet(S32 sheetNum, GBitmap *bmp);
|
||||
|
||||
void *mMutex;
|
||||
|
||||
private:
|
||||
static const U32 csm_fileVersion;
|
||||
|
||||
PlatformFont *mPlatformFont;
|
||||
Vector<GFXTexHandle>mTextureSheets;
|
||||
|
||||
S32 mCurX;
|
||||
S32 mCurY;
|
||||
S32 mCurSheet;
|
||||
|
||||
bool mNeedSave;
|
||||
Torque::Path mGFTFile;
|
||||
String mFaceName;
|
||||
U32 mSize;
|
||||
U32 mCharSet;
|
||||
|
||||
U32 mHeight;
|
||||
U32 mBaseline;
|
||||
U32 mAscent;
|
||||
U32 mDescent;
|
||||
|
||||
/// List of character info structures, must be accessed through the
|
||||
/// getCharInfo(U32) function to account for remapping.
|
||||
Vector<PlatformFont::CharInfo> mCharInfoList;
|
||||
|
||||
/// Index remapping
|
||||
S32 mRemapTable[65536];
|
||||
};
|
||||
|
||||
inline U32 GFont::getCharXIncrement(const UTF16 in_charIndex)
|
||||
{
|
||||
const PlatformFont::CharInfo& rChar = getCharInfo(in_charIndex);
|
||||
return rChar.xIncrement;
|
||||
}
|
||||
|
||||
inline U32 GFont::getCharWidth(const UTF16 in_charIndex)
|
||||
{
|
||||
const PlatformFont::CharInfo& rChar = getCharInfo(in_charIndex);
|
||||
return rChar.width;
|
||||
}
|
||||
|
||||
inline U32 GFont::getCharHeight(const UTF16 in_charIndex)
|
||||
{
|
||||
const PlatformFont::CharInfo& rChar = getCharInfo(in_charIndex);
|
||||
return rChar.height;
|
||||
}
|
||||
|
||||
inline bool GFont::isValidChar(const UTF16 in_charIndex) const
|
||||
{
|
||||
if(mRemapTable[in_charIndex] != -1)
|
||||
return true;
|
||||
|
||||
if(mPlatformFont)
|
||||
return mPlatformFont->isValidChar(in_charIndex);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif //_GFONT_H_
|
||||
284
Engine/source/gfx/genericConstBuffer.cpp
Normal file
284
Engine/source/gfx/genericConstBuffer.cpp
Normal file
|
|
@ -0,0 +1,284 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "gfx/genericConstBuffer.h"
|
||||
|
||||
#include "platform/profiler.h"
|
||||
#include "core/stream/stream.h"
|
||||
|
||||
|
||||
GenericConstBufferLayout::GenericConstBufferLayout()
|
||||
{
|
||||
VECTOR_SET_ASSOCIATION( mParams );
|
||||
|
||||
mBufferSize = 0;
|
||||
mCurrentIndex = 0;
|
||||
mTimesCleared = 0;
|
||||
}
|
||||
|
||||
void GenericConstBufferLayout::addParameter(const String& name, const GFXShaderConstType constType, const U32 offset, const U32 size, const U32 arraySize, const U32 alignValue)
|
||||
{
|
||||
#ifdef TORQUE_DEBUG
|
||||
// Make sure we don't have overlapping parameters
|
||||
S32 start = offset;
|
||||
S32 end = offset + size;
|
||||
for (Params::iterator i = mParams.begin(); i != mParams.end(); i++)
|
||||
{
|
||||
const ParamDesc& dp = *i;
|
||||
S32 pstart = dp.offset;
|
||||
S32 pend = pstart + dp.size;
|
||||
pstart -= start;
|
||||
pend -= end;
|
||||
// This is like a minkowski sum for two line segments, if the newly formed line contains
|
||||
// the origin, then they intersect
|
||||
bool intersect = ((pstart >= 0 && 0 >= pend) || ((pend >= 0 && 0 >= pstart)));
|
||||
AssertFatal(!intersect, "Overlapping shader parameter!");
|
||||
}
|
||||
#endif
|
||||
ParamDesc desc;
|
||||
desc.name = name;
|
||||
desc.constType = constType;
|
||||
desc.offset = offset;
|
||||
desc.size = size;
|
||||
desc.arraySize = arraySize;
|
||||
desc.alignValue = alignValue;
|
||||
desc.index = mCurrentIndex++;
|
||||
mParams.push_back(desc);
|
||||
mBufferSize = getMax(desc.offset + desc.size, mBufferSize);
|
||||
AssertFatal(mBufferSize, "Empty constant buffer!");
|
||||
}
|
||||
|
||||
bool GenericConstBufferLayout::set(const ParamDesc& pd, const GFXShaderConstType constType, const U32 size, const void* data, U8* basePointer)
|
||||
{
|
||||
PROFILE_SCOPE(GenericConstBufferLayout_set);
|
||||
|
||||
// Shader compilers like to optimize float4x4 uniforms into float3x3s.
|
||||
// So long as the real paramater is a matrix of-some-type and the data
|
||||
// passed in is a MatrixF ( which is will be ), we DO NOT have a
|
||||
// mismatched const type.
|
||||
AssertFatal( pd.constType == constType ||
|
||||
(
|
||||
( pd.constType == GFXSCT_Float2x2 ||
|
||||
pd.constType == GFXSCT_Float3x3 ||
|
||||
pd.constType == GFXSCT_Float4x4 ) &&
|
||||
( constType == GFXSCT_Float2x2 ||
|
||||
constType == GFXSCT_Float3x3 ||
|
||||
constType == GFXSCT_Float4x4 )
|
||||
), "Mismatched const type!" );
|
||||
|
||||
// This "cute" bit of code allows us to support 2x3 and 3x3 matrices in shader constants but use our MatrixF class. Yes, a hack. -BTR
|
||||
switch (pd.constType)
|
||||
{
|
||||
case GFXSCT_Float2x2 :
|
||||
case GFXSCT_Float3x3 :
|
||||
case GFXSCT_Float4x4 :
|
||||
return setMatrix(pd, constType, size, data, basePointer);
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
|
||||
AssertFatal(pd.size >= size, "Not enough room in the buffer for this data!");
|
||||
|
||||
// Ok, we only set data if it's different than the data we already have, this maybe more expensive than just setting the data, but
|
||||
// we'll have to do some timings to see. For example, the lighting shader constants rarely change, but we can't assume that at the
|
||||
// renderInstMgr level, but we can check down here. -BTR
|
||||
if (dMemcmp(basePointer+pd.offset, data, size) != 0)
|
||||
{
|
||||
dMemcpy(basePointer+pd.offset, data, size);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GenericConstBufferLayout::setMatrix(const ParamDesc& pd, const GFXShaderConstType constType, const U32 size, const void* data, U8* basePointer)
|
||||
{
|
||||
PROFILE_SCOPE(GenericConstBufferLayout_setMatrix);
|
||||
|
||||
// We're generic, so just copy the full MatrixF in
|
||||
AssertFatal(pd.size >= size, "Not enough room in the buffer for this data!");
|
||||
|
||||
// Matrices are an annoying case because of the alignment issues. There are alignment issues in the matrix itself, and then potential inter matrices alignment issues.
|
||||
// So GL and DX will need to derive their own GenericConstBufferLayout classes and override this method to deal with that stuff. For GenericConstBuffer, copy the whole
|
||||
// 4x4 matrix regardless of the target case.
|
||||
|
||||
if (dMemcmp(basePointer+pd.offset, data, size) != 0)
|
||||
{
|
||||
dMemcpy(basePointer+pd.offset, data, size);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GenericConstBufferLayout::getDesc(const String& name, ParamDesc& param) const
|
||||
{
|
||||
for (U32 i = 0; i < mParams.size(); i++)
|
||||
{
|
||||
if (mParams[i].name.equal(name))
|
||||
{
|
||||
param = mParams[i];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GenericConstBufferLayout::getDesc(const U32 index, ParamDesc& param) const
|
||||
{
|
||||
if ( index < mParams.size() )
|
||||
{
|
||||
param = mParams[index];
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GenericConstBufferLayout::write(Stream* s)
|
||||
{
|
||||
// Write out the size of the ParamDesc structure as a sanity check.
|
||||
if (!s->write((U32) sizeof(ParamDesc)))
|
||||
return false;
|
||||
// Next, write out the number of elements we've got.
|
||||
if (!s->write(mParams.size()))
|
||||
return false;
|
||||
for (U32 i = 0; i < mParams.size(); i++)
|
||||
{
|
||||
s->write(mParams[i].name);
|
||||
|
||||
if (!s->write(mParams[i].offset))
|
||||
return false;
|
||||
if (!s->write(mParams[i].size))
|
||||
return false;
|
||||
U32 t = (U32) mParams[i].constType;
|
||||
if (!s->write(t))
|
||||
return false;
|
||||
if (!s->write(mParams[i].arraySize))
|
||||
return false;
|
||||
if (!s->write(mParams[i].alignValue))
|
||||
return false;
|
||||
if (!s->write(mParams[i].index))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Load this layout from a stream
|
||||
bool GenericConstBufferLayout::read(Stream* s)
|
||||
{
|
||||
U32 structSize;
|
||||
if (!s->read(&structSize))
|
||||
return false;
|
||||
if (structSize != sizeof(ParamDesc))
|
||||
{
|
||||
AssertFatal(false, "Invalid shader layout structure size!");
|
||||
return false;
|
||||
}
|
||||
U32 numParams;
|
||||
if (!s->read(&numParams))
|
||||
return false;
|
||||
mParams.setSize(numParams);
|
||||
mBufferSize = 0;
|
||||
mCurrentIndex = 0;
|
||||
for (U32 i = 0; i < mParams.size(); i++)
|
||||
{
|
||||
s->read(&mParams[i].name);
|
||||
if (!s->read(&mParams[i].offset))
|
||||
return false;
|
||||
if (!s->read(&mParams[i].size))
|
||||
return false;
|
||||
U32 t;
|
||||
if (!s->read(&t))
|
||||
return false;
|
||||
mParams[i].constType = (GFXShaderConstType) t;
|
||||
if (!s->read(&mParams[i].arraySize))
|
||||
return false;
|
||||
if (!s->read(&mParams[i].alignValue))
|
||||
return false;
|
||||
if (!s->read(&mParams[i].index))
|
||||
return false;
|
||||
mBufferSize = getMax(mParams[i].offset + mParams[i].size, mBufferSize);
|
||||
mCurrentIndex = getMax(mParams[i].index, mCurrentIndex);
|
||||
}
|
||||
mCurrentIndex++;
|
||||
return true;
|
||||
}
|
||||
|
||||
void GenericConstBufferLayout::clear()
|
||||
{
|
||||
mParams.clear();
|
||||
mBufferSize = 0;
|
||||
mCurrentIndex = 0;
|
||||
mTimesCleared++;
|
||||
}
|
||||
|
||||
|
||||
GenericConstBuffer::GenericConstBuffer(GenericConstBufferLayout* layout)
|
||||
: mBuffer( NULL ),
|
||||
mLayout( layout ),
|
||||
mDirtyStart( U32_MAX ),
|
||||
mDirtyEnd( 0 )
|
||||
{
|
||||
if ( layout && layout->getBufferSize() > 0 )
|
||||
{
|
||||
mBuffer = new U8[mLayout->getBufferSize()];
|
||||
|
||||
// Always set a default value, that way our isEqual checks
|
||||
// will work in release as well.
|
||||
dMemset( mBuffer, 0xFFFF, mLayout->getBufferSize() );
|
||||
|
||||
#ifdef TORQUE_DEBUG
|
||||
|
||||
// Clear the debug assignment tracking.
|
||||
mWasAssigned.setSize( layout->getParameterCount() );
|
||||
dMemset( mWasAssigned.address(), 0, mWasAssigned.memSize() );
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
GenericConstBuffer::~GenericConstBuffer()
|
||||
{
|
||||
delete [] mBuffer;
|
||||
}
|
||||
|
||||
#ifdef TORQUE_DEBUG
|
||||
|
||||
void GenericConstBuffer::assertUnassignedConstants( const char *shaderName )
|
||||
{
|
||||
for ( U32 i=0; i < mWasAssigned.size(); i++ )
|
||||
{
|
||||
if ( mWasAssigned[i] )
|
||||
continue;
|
||||
|
||||
GenericConstBufferLayout::ParamDesc pd;
|
||||
mLayout->getDesc( i, pd );
|
||||
|
||||
// Assert on the unassigned constant.
|
||||
AssertFatal( false, avar( "The '%s' shader constant in shader '%s' was unassigned!",
|
||||
pd.name.c_str(), shaderName ) );
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
360
Engine/source/gfx/genericConstBuffer.h
Normal file
360
Engine/source/gfx/genericConstBuffer.h
Normal file
|
|
@ -0,0 +1,360 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GENERICCONSTBUFFER_H_
|
||||
#define _GENERICCONSTBUFFER_H_
|
||||
|
||||
#ifndef _TORQUE_STRING_H_
|
||||
#include "core/util/str.h"
|
||||
#endif
|
||||
#ifndef _TDICTIONARY_H_
|
||||
#include "core/util/tDictionary.h"
|
||||
#endif
|
||||
#ifndef _TVECTOR_H_
|
||||
#include "core/util/tVector.h"
|
||||
#endif
|
||||
#ifndef _ALIGNEDARRAY_H_
|
||||
#include "core/util/tAlignedArray.h"
|
||||
#endif
|
||||
#ifndef _COLOR_H_
|
||||
#include "core/color.h"
|
||||
#endif
|
||||
#ifndef _MMATRIX_H_
|
||||
#include "math/mMatrix.h"
|
||||
#endif
|
||||
#ifndef _MPOINT2_H_
|
||||
#include "math/mPoint2.h"
|
||||
#endif
|
||||
#ifndef _GFXENUMS_H_
|
||||
#include "gfx/gfxEnums.h"
|
||||
#endif
|
||||
|
||||
class Stream;
|
||||
|
||||
|
||||
/// This class defines the memory layout for a GenericConstBuffer.
|
||||
class GenericConstBufferLayout
|
||||
{
|
||||
public:
|
||||
/// Describes the parameters we contain
|
||||
struct ParamDesc
|
||||
{
|
||||
ParamDesc()
|
||||
: name(),
|
||||
offset( 0 ),
|
||||
size( 0 ),
|
||||
constType( GFXSCT_Float ),
|
||||
arraySize( 0 ),
|
||||
alignValue( 0 ),
|
||||
index( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
name = String::EmptyString;
|
||||
offset = 0;
|
||||
size = 0;
|
||||
constType = GFXSCT_Float;
|
||||
arraySize = 0;
|
||||
alignValue = 0;
|
||||
index = 0;
|
||||
}
|
||||
|
||||
/// Parameter name
|
||||
String name;
|
||||
|
||||
/// Offset into the memory block
|
||||
U32 offset;
|
||||
|
||||
/// Size of the block
|
||||
U32 size;
|
||||
|
||||
/// Type of data
|
||||
GFXShaderConstType constType;
|
||||
|
||||
// For arrays, how many elements
|
||||
U32 arraySize;
|
||||
|
||||
// Array element alignment value
|
||||
U32 alignValue;
|
||||
|
||||
/// 0 based index of this param, in order of addParameter calls.
|
||||
U32 index;
|
||||
};
|
||||
|
||||
GenericConstBufferLayout();
|
||||
virtual ~GenericConstBufferLayout() {}
|
||||
|
||||
/// Add a parameter to the buffer
|
||||
void addParameter(const String& name, const GFXShaderConstType constType, const U32 offset, const U32 size, const U32 arraySize, const U32 alignValue);
|
||||
|
||||
/// Get the size of the buffer
|
||||
inline U32 getBufferSize() const { return mBufferSize; }
|
||||
|
||||
/// Get the number of parameters
|
||||
inline U32 getParameterCount() const { return mParams.size(); }
|
||||
|
||||
/// Returns the ParamDesc of a parameter
|
||||
bool getDesc(const String& name, ParamDesc& param) const;
|
||||
|
||||
/// Returns the ParamDesc of a parameter
|
||||
bool getDesc(const U32 index, ParamDesc& param) const;
|
||||
|
||||
/// Set a parameter, given a base pointer
|
||||
virtual bool set(const ParamDesc& pd, const GFXShaderConstType constType, const U32 size, const void* data, U8* basePointer);
|
||||
|
||||
/// Save this layout to a stream
|
||||
bool write(Stream* s);
|
||||
|
||||
/// Load this layout from a stream
|
||||
bool read(Stream* s);
|
||||
|
||||
/// Restore to initial state.
|
||||
void clear();
|
||||
|
||||
protected:
|
||||
|
||||
/// Set a matrix, given a base pointer.
|
||||
virtual bool setMatrix(const ParamDesc& pd, const GFXShaderConstType constType, const U32 size, const void* data, U8* basePointer);
|
||||
|
||||
/// Vector of parameter descriptions.
|
||||
typedef Vector<ParamDesc> Params;
|
||||
|
||||
/// Vector of parameter descriptions.
|
||||
Params mParams;
|
||||
U32 mBufferSize;
|
||||
U32 mCurrentIndex;
|
||||
|
||||
// This if for debugging shader reloading and can be removed later.
|
||||
U32 mTimesCleared;
|
||||
};
|
||||
|
||||
|
||||
/// This class manages shader constant data in a system memory buffer. It is
|
||||
/// used by device specific classes for batching together many constant changes
|
||||
/// which are then copied to the device thru a single API call.
|
||||
///
|
||||
/// @see GenericConstBufferLayout
|
||||
///
|
||||
class GenericConstBuffer
|
||||
{
|
||||
public:
|
||||
GenericConstBuffer(GenericConstBufferLayout* layout);
|
||||
~GenericConstBuffer();
|
||||
|
||||
/// @name Set shader constant values
|
||||
/// @{
|
||||
/// Actually set shader constant values
|
||||
/// @param name Name of the constant, this should be a name contained in the array returned in getShaderConstDesc,
|
||||
/// if an invalid name is used, its ignored, but it's not an error.
|
||||
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const F32 f) { internalSet(pd, GFXSCT_Float, sizeof(F32), &f); }
|
||||
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const Point2F& fv) { internalSet(pd, GFXSCT_Float2, sizeof(Point2F), &fv); }
|
||||
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const Point3F& fv) { internalSet(pd, GFXSCT_Float3, sizeof(Point3F), &fv); }
|
||||
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const Point4F& fv) { internalSet(pd, GFXSCT_Float4, sizeof(Point4F), &fv); }
|
||||
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const PlaneF& fv) { internalSet(pd, GFXSCT_Float4, sizeof(PlaneF), &fv); }
|
||||
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const ColorF& fv) { internalSet(pd, GFXSCT_Float4, sizeof(Point4F), &fv); }
|
||||
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const S32 f) { internalSet(pd, GFXSCT_Int, sizeof(S32), &f); }
|
||||
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const Point2I& fv) { internalSet(pd, GFXSCT_Int2, sizeof(Point2I), &fv); }
|
||||
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const Point3I& fv) { internalSet(pd, GFXSCT_Int3, sizeof(Point3I), &fv); }
|
||||
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const Point4I& fv) { internalSet(pd, GFXSCT_Int4, sizeof(Point4I), &fv); }
|
||||
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const AlignedArray<F32>& fv) { internalSet(pd, GFXSCT_Float, fv.getElementSize() * fv.size(), fv.getBuffer()); }
|
||||
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const AlignedArray<Point2F>& fv) { internalSet(pd, GFXSCT_Float2, fv.getElementSize() * fv.size(), fv.getBuffer()); }
|
||||
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const AlignedArray<Point3F>& fv) { internalSet(pd, GFXSCT_Float3, fv.getElementSize() * fv.size(), fv.getBuffer()); }
|
||||
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const AlignedArray<Point4F>& fv) { internalSet(pd, GFXSCT_Float4, fv.getElementSize() * fv.size(), fv.getBuffer()); }
|
||||
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const AlignedArray<S32>& fv) { internalSet(pd, GFXSCT_Int, fv.getElementSize() * fv.size(), fv.getBuffer()); }
|
||||
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const AlignedArray<Point2I>& fv) { internalSet(pd, GFXSCT_Int2, fv.getElementSize() * fv.size(), fv.getBuffer()); }
|
||||
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const AlignedArray<Point3I>& fv) { internalSet(pd, GFXSCT_Int3, fv.getElementSize() * fv.size(), fv.getBuffer()); }
|
||||
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const AlignedArray<Point4I>& fv) { internalSet(pd, GFXSCT_Int4, fv.getElementSize() * fv.size(), fv.getBuffer()); }
|
||||
|
||||
inline void set( const GenericConstBufferLayout::ParamDesc& pd, const MatrixF& mat, const GFXShaderConstType matrixType )
|
||||
{
|
||||
AssertFatal( matrixType == GFXSCT_Float2x2 ||
|
||||
matrixType == GFXSCT_Float3x3 ||
|
||||
matrixType == GFXSCT_Float4x4,
|
||||
"GenericConstBuffer::set() - Invalid matrix type!" );
|
||||
|
||||
internalSet( pd, matrixType, sizeof(MatrixF), &mat );
|
||||
}
|
||||
|
||||
inline void set( const GenericConstBufferLayout::ParamDesc& pd, const MatrixF* mat, const U32 arraySize, const GFXShaderConstType matrixType )
|
||||
{
|
||||
AssertFatal( matrixType == GFXSCT_Float2x2 ||
|
||||
matrixType == GFXSCT_Float3x3 ||
|
||||
matrixType == GFXSCT_Float4x4,
|
||||
"GenericConstBuffer::set() - Invalid matrix type!" );
|
||||
|
||||
internalSet( pd, matrixType, sizeof(MatrixF)*arraySize, mat );
|
||||
}
|
||||
|
||||
/// Gets the dirty buffer range and clears the dirty
|
||||
/// state at the same time.
|
||||
inline const U8* getDirtyBuffer( U32 *start, U32 *size );
|
||||
|
||||
/// Sets the entire buffer as dirty or clears the dirty state.
|
||||
inline void setDirty( bool dirty );
|
||||
|
||||
/// Returns true if the buffer has been modified since the
|
||||
/// last call to getDirtyBuffer or setDirty. The buffer is
|
||||
/// not dirty on initial creation.
|
||||
///
|
||||
/// @see getDirtyBuffer
|
||||
/// @see setDirty
|
||||
inline bool isDirty() const { return mDirtyEnd != 0; }
|
||||
|
||||
/// Returns true if have the same layout and hold the same
|
||||
/// data as the input buffer.
|
||||
inline bool isEqual( const GenericConstBuffer *buffer ) const;
|
||||
|
||||
/// Returns our layout object.
|
||||
inline GenericConstBufferLayout* getLayout() const { return mLayout; }
|
||||
|
||||
#ifdef TORQUE_DEBUG
|
||||
|
||||
/// Helper function used to assert on unset constants.
|
||||
void assertUnassignedConstants( const char *shaderName );
|
||||
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
||||
/// Returns a pointer to the raw buffer
|
||||
inline const U8* getBuffer() const { return mBuffer; }
|
||||
|
||||
/// Called by the inlined set functions above to do the
|
||||
/// real dirty work of copying the data to the right location
|
||||
/// within the buffer.
|
||||
inline void internalSet( const GenericConstBufferLayout::ParamDesc &pd,
|
||||
const GFXShaderConstType constType,
|
||||
const U32 size,
|
||||
const void *data );
|
||||
|
||||
/// The buffer layout.
|
||||
GenericConstBufferLayout *mLayout;
|
||||
|
||||
/// The pointer to the contant store or
|
||||
/// NULL if the layout is empty.
|
||||
U8 *mBuffer;
|
||||
|
||||
/// The byte offset to the start of the dirty
|
||||
/// range within the buffer or U32_MAX if the
|
||||
/// buffer is not dirty.
|
||||
U32 mDirtyStart;
|
||||
|
||||
/// The btye offset to the end of the dirty
|
||||
/// range within the buffer or 0 if the buffer
|
||||
/// is not dirty.
|
||||
U32 mDirtyEnd;
|
||||
|
||||
|
||||
#ifdef TORQUE_DEBUG
|
||||
|
||||
/// A vector used to keep track if a constant
|
||||
/// has beed assigned a value or not.
|
||||
///
|
||||
/// @see assertUnassignedConstants
|
||||
Vector<bool> mWasAssigned;
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
// NOTE: These inlines below are here to get the very best possible
|
||||
// performance when setting the device shader constants and can be
|
||||
// called 4000-8000 times per frame or more.
|
||||
//
|
||||
// You need a very good reason to consider changing them.
|
||||
|
||||
inline void GenericConstBuffer::internalSet( const GenericConstBufferLayout::ParamDesc &pd,
|
||||
const GFXShaderConstType constType,
|
||||
const U32 size,
|
||||
const void *data )
|
||||
{
|
||||
// NOTE: We should have never gotten here if the buffer
|
||||
// was null as no valid shader constant could have been
|
||||
// assigned.
|
||||
//
|
||||
// If this happens its a bug in another part of the code.
|
||||
//
|
||||
AssertFatal( mBuffer, "GenericConstBuffer::internalSet - The buffer is NULL!" );
|
||||
|
||||
if ( mLayout->set( pd, constType, size, data, mBuffer ) )
|
||||
{
|
||||
#ifdef TORQUE_DEBUG
|
||||
|
||||
// Update the debug assignment tracking.
|
||||
mWasAssigned[ pd.index ] = true;
|
||||
|
||||
#endif
|
||||
|
||||
// Keep track of the dirty range so it can be queried
|
||||
// later in GenericConstBuffer::getDirtyBuffer.
|
||||
mDirtyStart = getMin( pd.offset, mDirtyStart );
|
||||
mDirtyEnd = getMax( pd.offset + pd.size, mDirtyEnd );
|
||||
}
|
||||
}
|
||||
|
||||
inline void GenericConstBuffer::setDirty( bool dirty )
|
||||
{
|
||||
if ( !mBuffer )
|
||||
return;
|
||||
|
||||
if ( dirty )
|
||||
{
|
||||
mDirtyStart = 0;
|
||||
mDirtyEnd = mLayout->getBufferSize();
|
||||
}
|
||||
else if ( !dirty )
|
||||
{
|
||||
mDirtyStart = U32_MAX;
|
||||
mDirtyEnd = 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline const U8* GenericConstBuffer::getDirtyBuffer( U32 *start, U32 *size )
|
||||
{
|
||||
AssertFatal( isDirty(), "GenericConstBuffer::getDirtyBuffer() - Buffer is not dirty!" );
|
||||
AssertFatal( mDirtyEnd > mDirtyStart, "GenericConstBuffer::getDirtyBuffer() - Dirty range is invalid!" );
|
||||
AssertFatal( mBuffer, "GenericConstBuffer::getDirtyBuffer() - Buffer is empty!" );
|
||||
|
||||
// Use the area we calculated during internalSet.
|
||||
*size = mDirtyEnd - mDirtyStart;
|
||||
*start = mDirtyStart;
|
||||
const U8 *buffer = mBuffer + mDirtyStart;
|
||||
|
||||
// Clear the dirty state while we're here.
|
||||
mDirtyStart = U32_MAX;
|
||||
mDirtyEnd = 0;
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
inline bool GenericConstBuffer::isEqual( const GenericConstBuffer *buffer ) const
|
||||
{
|
||||
U32 bsize = mLayout->getBufferSize();
|
||||
if ( bsize != buffer->mLayout->getBufferSize() )
|
||||
return false;
|
||||
|
||||
return dMemcmp( mBuffer, buffer->getBuffer(), bsize ) == 0;
|
||||
}
|
||||
|
||||
#endif // _GENERICCONSTBUFFER_H_
|
||||
247
Engine/source/gfx/gfxAPI.cpp
Normal file
247
Engine/source/gfx/gfxAPI.cpp
Normal file
|
|
@ -0,0 +1,247 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "gfx/gfxAPI.h"
|
||||
|
||||
|
||||
IMPLEMENT_SCOPE( GFXAPI, GFX,,
|
||||
"Graphics subystem." );
|
||||
|
||||
IMPLEMENT_STRUCT( GFXVideoMode,
|
||||
GFXVideoMode, GFXAPI,
|
||||
"Descriptor for a specific video mode." )
|
||||
FIELD( resolution, resolution, 1, "Width and height of the mode's resolution in pixels." )
|
||||
FIELD( bitDepth, bitDepth, 1, "Bits per pixel." )
|
||||
FIELD( refreshRate, refreshRate, 1, "Frequency at which the screen is refreshed (in Hertz)." )
|
||||
FIELD( fullScreen, fullScreen, 1, "Whether this is a fullscreen or windowed mode." )
|
||||
FIELD( wideScreen, wideScreen, 1, "Whether this is a widescreen display mode." )
|
||||
FIELD( antialiasLevel, antialiasLevel, 1, "Maximum or desired antialiasing level." )
|
||||
END_IMPLEMENT_STRUCT;
|
||||
|
||||
ImplementEnumType( GFXAdapterType,
|
||||
"Back-end graphics API used by the GFX subsystem.\n\n"
|
||||
"@ingroup GFX" )
|
||||
{ OpenGL, "OpenGL", "OpenGL." },
|
||||
{ Direct3D8, "D3D8", "Direct3D 8." },
|
||||
{ Direct3D9, "D3D9", "Direct3D 9." },
|
||||
{ NullDevice, "NullDevice", "Null device for dedicated servers." },
|
||||
{ Direct3D9_360, "Xenon", "Direct3D 9 on Xbox 360." }
|
||||
EndImplementEnumType;
|
||||
|
||||
ImplementEnumType( GFXBlend,
|
||||
"The supported blend modes.\n"
|
||||
"@ingroup GFX" )
|
||||
|
||||
{ GFXBlendZero, "GFXBlendZero", "(0, 0, 0, 0)" },
|
||||
{ GFXBlendOne, "GFXBlendOne", "(1, 1, 1, 1)" },
|
||||
{ GFXBlendSrcColor, "GFXBlendSrcColor", "(Rs, Gs, Bs, As)" },
|
||||
{ GFXBlendInvSrcColor, "GFXBlendInvSrcColor", "(1 - Rs, 1 - Gs, 1 - Bs, 1 - As)" },
|
||||
{ GFXBlendSrcAlpha, "GFXBlendSrcAlpha", "(As, As, As, As)" },
|
||||
{ GFXBlendInvSrcAlpha, "GFXBlendInvSrcAlpha", "( 1 - As, 1 - As, 1 - As, 1 - As)" },
|
||||
{ GFXBlendDestAlpha, "GFXBlendDestAlpha", "(Ad Ad Ad Ad)" },
|
||||
{ GFXBlendInvDestAlpha, "GFXBlendInvDestAlpha", "(1 - Ad 1 - Ad 1 - Ad 1 - Ad)" },
|
||||
{ GFXBlendDestColor, "GFXBlendDestColor", "(Rd, Gd, Bd, Ad)" },
|
||||
{ GFXBlendInvDestColor, "GFXBlendInvDestColor", "(1 - Rd, 1 - Gd, 1 - Bd, 1 - Ad)" },
|
||||
{ GFXBlendSrcAlphaSat, "GFXBlendSrcAlphaSat", "(f, f, f, 1) where f = min(As, 1 - Ad)" }
|
||||
|
||||
EndImplementEnumType;
|
||||
|
||||
ImplementEnumType( GFXCmpFunc,
|
||||
"The supported comparison functions.\n"
|
||||
"@ingroup GFX" )
|
||||
|
||||
{ GFXCmpNever, "GFXCmpNever" },
|
||||
{ GFXCmpLess, "GFXCmpLess" },
|
||||
{ GFXCmpEqual, "GFXCmpEqual" },
|
||||
{ GFXCmpLessEqual, "GFXCmpLessEqual" },
|
||||
{ GFXCmpGreater, "GFXCmpGreater" },
|
||||
{ GFXCmpNotEqual, "GFXCmpNotEqual" },
|
||||
{ GFXCmpGreaterEqual, "GFXCmpGreaterEqual" },
|
||||
{ GFXCmpAlways, "GFXCmpAlways" },
|
||||
|
||||
EndImplementEnumType;
|
||||
|
||||
ImplementEnumType( GFXTextureAddressMode,
|
||||
"The texture address modes.\n"
|
||||
"@ingroup GFX" )
|
||||
|
||||
{ GFXAddressWrap, "GFXAddressWrap" },
|
||||
{ GFXAddressMirror, "GFXAddressMirror" },
|
||||
{ GFXAddressClamp, "GFXAddressClamp" },
|
||||
{ GFXAddressBorder, "GFXAddressBorder" },
|
||||
{ GFXAddressMirrorOnce, "GFXAddressMirrorOnce" }
|
||||
|
||||
EndImplementEnumType;
|
||||
|
||||
ImplementEnumType( GFXTextureFilterType,
|
||||
"The texture filter types.\n"
|
||||
"@ingroup GFX" )
|
||||
|
||||
{ GFXTextureFilterNone, "GFXTextureFilterNone" },
|
||||
{ GFXTextureFilterPoint, "GFXTextureFilterPoint" },
|
||||
{ GFXTextureFilterLinear, "GFXTextureFilterLinear" },
|
||||
{ GFXTextureFilterAnisotropic, "GFXTextureFilterAnisotropic" },
|
||||
{ GFXTextureFilterPyramidalQuad, "GFXTextureFilterPyramidalQuad" },
|
||||
{ GFXTextureFilterGaussianQuad, "GFXTextureFilterGaussianQuad" }
|
||||
|
||||
EndImplementEnumType;
|
||||
|
||||
ImplementEnumType( GFXTextureOp,
|
||||
"The texture operators.\n"
|
||||
"@ingroup GFX" )
|
||||
|
||||
{ GFXTOPDisable, "GFXTOPDisable" },
|
||||
{ GFXTOPSelectARG1, "GFXTOPSelectARG1" },
|
||||
{ GFXTOPSelectARG2, "GFXTOPSelectARG2" },
|
||||
{ GFXTOPModulate, "GFXTOPModulate" },
|
||||
{ GFXTOPModulate2X, "GFXTOPModulate2X" },
|
||||
{ GFXTOPModulate4X, "GFXTOPModulate4X" },
|
||||
{ GFXTOPAdd, "GFXTOPAdd" },
|
||||
{ GFXTOPAddSigned, "GFXTOPAddSigned" },
|
||||
{ GFXTOPAddSigned2X, "GFXTOPAddSigned2X" },
|
||||
{ GFXTOPSubtract, "GFXTOPSubtract" },
|
||||
{ GFXTOPAddSmooth, "GFXTOPAddSmooth" },
|
||||
{ GFXTOPBlendDiffuseAlpha, "GFXTOPBlendDiffuseAlpha" },
|
||||
{ GFXTOPBlendTextureAlpha, "GFXTOPBlendTextureAlpha" },
|
||||
{ GFXTOPBlendFactorAlpha, "GFXTOPBlendFactorAlpha" },
|
||||
{ GFXTOPBlendTextureAlphaPM, "GFXTOPBlendTextureAlphaPM" },
|
||||
{ GFXTOPBlendCURRENTALPHA, "GFXTOPBlendCURRENTALPHA" },
|
||||
{ GFXTOPPreModulate, "GFXTOPPreModulate" },
|
||||
{ GFXTOPModulateAlphaAddColor, "GFXTOPModulateAlphaAddColor" },
|
||||
{ GFXTOPModulateColorAddAlpha, "GFXTOPModulateColorAddAlpha" },
|
||||
{ GFXTOPModulateInvAlphaAddColor, "GFXTOPModulateInvAlphaAddColor" },
|
||||
{ GFXTOPModulateInvColorAddAlpha, "GFXTOPModulateInvColorAddAlpha" },
|
||||
{ GFXTOPBumpEnvMap, "GFXTOPBumpEnvMap" },
|
||||
{ GFXTOPBumpEnvMapLuminance, "GFXTOPBumpEnvMapLuminance" },
|
||||
{ GFXTOPDotProduct3, "GFXTOPDotProduct3" },
|
||||
{ GFXTOPLERP, "GFXTOPLERP" }
|
||||
|
||||
EndImplementEnumType;
|
||||
|
||||
ImplementEnumType( GFXTextureArgument,
|
||||
"The texture arguments.\n"
|
||||
"@ingroup GFX" )
|
||||
|
||||
{ GFXTADiffuse, "GFXTADiffuse" },
|
||||
{ GFXTACurrent, "GFXTACurrent" },
|
||||
{ GFXTATexture, "GFXTATexture" },
|
||||
{ GFXTATFactor, "GFXTATFactor" },
|
||||
{ GFXTASpecular, "GFXTASpecular" },
|
||||
{ GFXTATemp, "GFXTATemp" },
|
||||
{ GFXTAConstant, "GFXTAConstant" },
|
||||
|
||||
{ GFXTAComplement, "OneMinus" },
|
||||
{ GFXTAAlphaReplicate, "AlphaReplicate" }
|
||||
|
||||
EndImplementEnumType;
|
||||
|
||||
ImplementEnumType( GFXTextureTransformFlags,
|
||||
"The texture transform state flags.\n"
|
||||
"@ingroup GFX" )
|
||||
|
||||
{ GFXTTFFDisable, "GFXTTFDisable" },
|
||||
{ GFXTTFFCoord1D, "GFXTTFFCoord1D" },
|
||||
{ GFXTTFFCoord2D, "GFXTTFFCoord2D" },
|
||||
{ GFXTTFFCoord3D, "GFXTTFFCoord3D" },
|
||||
{ GFXTTFFCoord4D, "GFXTTFFCoord4D" },
|
||||
{ GFXTTFFProjected, "GFXTTFProjected" }
|
||||
|
||||
EndImplementEnumType;
|
||||
|
||||
|
||||
ImplementEnumType( GFXFormat,
|
||||
"The texture formats.\n"
|
||||
"@note Not all formats are supported on all platforms.\n"
|
||||
"@ingroup GFX" )
|
||||
|
||||
{ GFXFormatR8G8B8, "GFXFormatR8G8B8" },
|
||||
{ GFXFormatR8G8B8A8, "GFXFormatR8G8B8A8" },
|
||||
{ GFXFormatR8G8B8X8, "GFXFormatR8G8B8X8" },
|
||||
{ GFXFormatR32F, "GFXFormatR32F" },
|
||||
{ GFXFormatR5G6B5, "GFXFormatR5G6B5" },
|
||||
{ GFXFormatR5G5B5A1, "GFXFormatR5G5B5A1" },
|
||||
{ GFXFormatR5G5B5X1, "GFXFormatR5G5B5X1" },
|
||||
{ GFXFormatA4L4, "GFXFormatA4L4" },
|
||||
{ GFXFormatA8L8, "GFXFormatA8L8" },
|
||||
{ GFXFormatA8, "GFXFormatA8" },
|
||||
{ GFXFormatL8, "GFXFormatL8" },
|
||||
{ GFXFormatDXT1, "GFXFormatDXT1" },
|
||||
{ GFXFormatDXT2, "GFXFormatDXT2" },
|
||||
{ GFXFormatDXT3, "GFXFormatDXT3" },
|
||||
{ GFXFormatDXT4, "GFXFormatDXT4" },
|
||||
{ GFXFormatDXT5, "GFXFormatDXT5" },
|
||||
{ GFXFormatD32, "GFXFormatD32" },
|
||||
{ GFXFormatD24X8, "GFXFormatD24X8" },
|
||||
{ GFXFormatD24S8, "GFXFormatD24S8" },
|
||||
{ GFXFormatD24FS8, "GFXFormatD24FS8" },
|
||||
{ GFXFormatD16, "GFXFormatD16" },
|
||||
|
||||
{ GFXFormatR32G32B32A32F, "GFXFormatR32G32B32A32F" },
|
||||
{ GFXFormatR16G16B16A16F, "GFXFormatR16G16B16A16F" },
|
||||
{ GFXFormatL16, "GFXFormatL16" },
|
||||
{ GFXFormatR16G16B16A16, "GFXFormatR16G16B16A16" },
|
||||
{ GFXFormatR16G16, "GFXFormatR16G16" },
|
||||
{ GFXFormatR16F, "GFXFormatR16F" },
|
||||
{ GFXFormatR16G16F, "GFXFormatR16G16F" },
|
||||
{ GFXFormatR10G10B10A2, "GFXFormatR10G10B10A2" },
|
||||
|
||||
EndImplementEnumType;
|
||||
|
||||
|
||||
ImplementEnumType( GFXCullMode,
|
||||
"The render cull modes.\n"
|
||||
"@ingroup GFX" )
|
||||
|
||||
{ GFXCullNone, "GFXCullNone" },
|
||||
{ GFXCullCW, "GFXCullCW" },
|
||||
{ GFXCullCCW, "GFXCullCCW" }
|
||||
|
||||
EndImplementEnumType;
|
||||
|
||||
|
||||
ImplementEnumType( GFXStencilOp,
|
||||
"The stencil operators.\n"
|
||||
"@ingroup GFX" )
|
||||
|
||||
{ GFXStencilOpKeep, "GFXStencilOpKeep" },
|
||||
{ GFXStencilOpZero, "GFXStencilOpZero" },
|
||||
{ GFXStencilOpReplace, "GFXStencilOpReplace" },
|
||||
{ GFXStencilOpIncrSat, "GFXStencilOpIncrSat" },
|
||||
{ GFXStencilOpDecrSat, "GFXStencilOpDecrSat" },
|
||||
{ GFXStencilOpInvert, "GFXStencilOpInvert" },
|
||||
{ GFXStencilOpIncr, "GFXStencilOpIncr" },
|
||||
{ GFXStencilOpDecr, "GFXStencilOpDecr" },
|
||||
|
||||
EndImplementEnumType;
|
||||
|
||||
|
||||
ImplementEnumType( GFXBlendOp,
|
||||
"The blend operators.\n"
|
||||
"@ingroup GFX" )
|
||||
|
||||
{ GFXBlendOpAdd, "GFXBlendOpAdd" },
|
||||
{ GFXBlendOpSubtract, "GFXBlendOpSubtract" },
|
||||
{ GFXBlendOpRevSubtract, "GFXBlendOpRevSubtract" },
|
||||
{ GFXBlendOpMin, "GFXBlendOpMin" },
|
||||
{ GFXBlendOpMax, "GFXBlendOpMax" }
|
||||
|
||||
EndImplementEnumType;
|
||||
67
Engine/source/gfx/gfxAPI.h
Normal file
67
Engine/source/gfx/gfxAPI.h
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GFXAPI_H_
|
||||
#define _GFXAPI_H_
|
||||
|
||||
#ifndef _ENGINEAPI_H_
|
||||
#include "console/engineAPI.h"
|
||||
#endif
|
||||
#ifndef _GFXSTRUCTS_H_
|
||||
#include "gfx/gfxStructs.h"
|
||||
#endif
|
||||
#ifndef _GFXENUMS_H_
|
||||
#include "gfx/gfxEnums.h"
|
||||
#endif
|
||||
|
||||
|
||||
DECLARE_SCOPE( GFXAPI );
|
||||
|
||||
DefineEnumType( GFXBlend );
|
||||
DefineEnumType( GFXCmpFunc );
|
||||
DefineEnumType( GFXTextureAddressMode );
|
||||
DefineEnumType( GFXFormat );
|
||||
DefineEnumType( GFXTextureTransformFlags );
|
||||
DefineEnumType( GFXTextureFilterType );
|
||||
DefineEnumType( GFXTextureOp );
|
||||
DefineEnumType( GFXTextureArgument );
|
||||
DefineEnumType( GFXCullMode );
|
||||
DefineEnumType( GFXStencilOp );
|
||||
DefineEnumType( GFXBlendOp );
|
||||
DefineEnumType( GFXAdapterType );
|
||||
|
||||
DECLARE_STRUCT( GFXVideoMode );
|
||||
|
||||
DefineConsoleType( TypeGFXAdapterType, GFXAdapterType );
|
||||
DefineConsoleType( TypeGFXBlend, GFXBlend );
|
||||
DefineConsoleType( TypeGFXCmpFunc, GFXCmpFunc );
|
||||
DefineConsoleType( TypeGFXTextureAddressMode, GFXTextureAddressMode );
|
||||
DefineConsoleType( TypeGFXFormat, GFXFormat );
|
||||
DefineConsoleType( TypeGFXTextureTransformFlags, GFXTextureTransformFlags );
|
||||
DefineConsoleType( TypeGFXTextureFilterType, GFXTextureFilterType );
|
||||
DefineConsoleType( TypeGFXTextureOp, GFXTextureOp );
|
||||
DefineConsoleType( TypeGFXTextureArgument, GFXTextureArgument );
|
||||
DefineConsoleType( TypeGFXCullMode, GFXCullMode );
|
||||
DefineConsoleType( TypeGFXStencilOp, GFXStencilOp );
|
||||
DefineConsoleType( TypeGFXBlendOp, GFXBlendOp );
|
||||
|
||||
#endif // !_GFXAPI_H_
|
||||
80
Engine/source/gfx/gfxAdapter.h
Normal file
80
Engine/source/gfx/gfxAdapter.h
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GFXADAPTER_H_
|
||||
#define _GFXADAPTER_H_
|
||||
|
||||
#ifndef _GFXSTRUCTS_H_
|
||||
#include "gfx/gfxStructs.h"
|
||||
#endif
|
||||
|
||||
#ifndef _TVECTOR_H_
|
||||
#include "core/util/tVector.h"
|
||||
#endif
|
||||
|
||||
#ifndef _UTIL_DELEGATE_H_
|
||||
#include "core/util/delegate.h"
|
||||
#endif
|
||||
|
||||
struct GFXAdapter
|
||||
{
|
||||
public:
|
||||
typedef Delegate<GFXDevice* (U32 adapterIndex)> CreateDeviceInstanceDelegate;
|
||||
|
||||
enum
|
||||
{
|
||||
MaxAdapterNameLen = 512,
|
||||
};
|
||||
|
||||
char mName[MaxAdapterNameLen];
|
||||
|
||||
/// List of available full-screen modes. Windows can be any size,
|
||||
/// so we do not enumerate them here.
|
||||
Vector<GFXVideoMode> mAvailableModes;
|
||||
|
||||
/// Supported shader model. 0.f means none supported.
|
||||
F32 mShaderModel;
|
||||
|
||||
const char * getName() const { return mName; }
|
||||
GFXAdapterType mType;
|
||||
U32 mIndex;
|
||||
CreateDeviceInstanceDelegate mCreateDeviceInstanceDelegate;
|
||||
|
||||
GFXAdapter()
|
||||
{
|
||||
VECTOR_SET_ASSOCIATION( mAvailableModes );
|
||||
|
||||
mName[0] = 0;
|
||||
mShaderModel = 0.f;
|
||||
mIndex = 0;
|
||||
}
|
||||
|
||||
~GFXAdapter()
|
||||
{
|
||||
mAvailableModes.clear();
|
||||
}
|
||||
private:
|
||||
// Disallow copying to prevent mucking with our data above.
|
||||
GFXAdapter(const GFXAdapter&);
|
||||
};
|
||||
|
||||
#endif // _GFXADAPTER_H_
|
||||
233
Engine/source/gfx/gfxCardProfile.cpp
Normal file
233
Engine/source/gfx/gfxCardProfile.cpp
Normal file
|
|
@ -0,0 +1,233 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "gfx/gfxCardProfile.h"
|
||||
|
||||
#include "console/console.h"
|
||||
#include "console/engineAPI.h"
|
||||
#include "core/volume.h"
|
||||
|
||||
// NOTE: The script class docs are in
|
||||
// Documentation\scriptDocs\docs\classGFXCardProfiler.txt
|
||||
|
||||
|
||||
void GFXCardProfiler::loadProfileScript(const char* aScriptName)
|
||||
{
|
||||
const String profilePath = Con::getVariable( "$pref::Video::profilePath" );
|
||||
String scriptName = !profilePath.isEmpty() ? profilePath.c_str() : "profile";
|
||||
scriptName += "/";
|
||||
scriptName += aScriptName;
|
||||
|
||||
void *data = NULL;
|
||||
U32 dataSize = 0;
|
||||
|
||||
Torque::FS::ReadFile( scriptName.c_str(), data, dataSize, true );
|
||||
|
||||
if(data == NULL)
|
||||
{
|
||||
Con::warnf(" - No card profile %s exists", scriptName.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
const char *script = static_cast<const char *>(data);
|
||||
|
||||
Con::printf(" - Loaded card profile %s", scriptName.c_str());
|
||||
|
||||
Con::executef("eval", script);
|
||||
delete[] script;
|
||||
}
|
||||
|
||||
void GFXCardProfiler::loadProfileScripts(const String& render, const String& vendor, const String& card, const String& version)
|
||||
{
|
||||
String script = render + ".cs";
|
||||
loadProfileScript(script);
|
||||
|
||||
script = render + "." + vendor + ".cs";
|
||||
loadProfileScript(script);
|
||||
|
||||
script = render + "." + vendor + "." + card + ".cs";
|
||||
loadProfileScript(script);
|
||||
|
||||
script = render + "." + vendor + "." + card + "." + version + ".cs";
|
||||
loadProfileScript(script);
|
||||
}
|
||||
|
||||
GFXCardProfiler::GFXCardProfiler() : mVideoMemory( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
GFXCardProfiler::~GFXCardProfiler()
|
||||
{
|
||||
mCapDictionary.clear();
|
||||
}
|
||||
|
||||
String GFXCardProfiler::strippedString(const char *string)
|
||||
{
|
||||
String res = "";
|
||||
|
||||
// And fill it with the stripped string...
|
||||
const char *a=string;
|
||||
while(*a)
|
||||
{
|
||||
if(isalnum(*a))
|
||||
{
|
||||
res += *a;
|
||||
}
|
||||
a++;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void GFXCardProfiler::init()
|
||||
{
|
||||
// Spew a bit...
|
||||
Con::printf("Initializing GFXCardProfiler (%s)", getRendererString().c_str());
|
||||
Con::printf(" o Chipset : '%s'", getChipString().c_str());
|
||||
Con::printf(" o Card : '%s'", getCardString().c_str());
|
||||
Con::printf(" o Version : '%s'", getVersionString().c_str());
|
||||
|
||||
// Do card-specific setup...
|
||||
Con::printf(" - Scanning card capabilities...");
|
||||
|
||||
setupCardCapabilities();
|
||||
|
||||
// And finally, load stuff up...
|
||||
String render = strippedString(getRendererString());
|
||||
String chipset = strippedString(getChipString());
|
||||
String card = strippedString(getCardString());
|
||||
String version = strippedString(getVersionString());
|
||||
|
||||
Con::printf(" - Loading card profiles...");
|
||||
loadProfileScripts(render, chipset, card, version);
|
||||
}
|
||||
|
||||
U32 GFXCardProfiler::queryProfile(const String &cap)
|
||||
{
|
||||
U32 res;
|
||||
if( _queryCardCap( cap, res ) )
|
||||
return res;
|
||||
|
||||
if(mCapDictionary.contains(cap))
|
||||
return mCapDictionary[cap];
|
||||
|
||||
Con::errorf( "GFXCardProfiler (%s) - Unknown capability '%s'.", getRendererString().c_str(), cap.c_str() );
|
||||
return 0;
|
||||
}
|
||||
|
||||
U32 GFXCardProfiler::queryProfile(const String &cap, U32 defaultValue)
|
||||
{
|
||||
PROFILE_SCOPE( GFXCardProfiler_queryProfile );
|
||||
|
||||
U32 res;
|
||||
if( _queryCardCap( cap, res ) )
|
||||
return res;
|
||||
|
||||
if( mCapDictionary.contains( cap ) )
|
||||
return mCapDictionary[cap];
|
||||
else
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
void GFXCardProfiler::setCapability(const String &cap, U32 value)
|
||||
{
|
||||
// Check for dups.
|
||||
if( mCapDictionary.contains( cap ) )
|
||||
{
|
||||
Con::warnf( "GFXCardProfiler (%s) - Setting capability '%s' multiple times.", getRendererString().c_str(), cap.c_str() );
|
||||
mCapDictionary[cap] = value;
|
||||
return;
|
||||
}
|
||||
|
||||
// Insert value as necessary.
|
||||
Con::printf( "GFXCardProfiler (%s) - Setting capability '%s' to %d.", getRendererString().c_str(), cap.c_str(), value );
|
||||
mCapDictionary.insert( cap, value );
|
||||
}
|
||||
|
||||
bool GFXCardProfiler::checkFormat( const GFXFormat fmt, const GFXTextureProfile *profile, bool &inOutAutogenMips )
|
||||
{
|
||||
return _queryFormat( fmt, profile, inOutAutogenMips );
|
||||
}
|
||||
|
||||
DECLARE_SCOPE( GFXCardProfilerAPI );
|
||||
IMPLEMENT_SCOPE( GFXCardProfilerAPI, GFXCardProfiler,, "");
|
||||
ConsoleDoc(
|
||||
"@class GFXCardProfilerAPI\n"
|
||||
"@brief This class is the interface between TorqueScript and GFXCardProfiler.\n\n"
|
||||
"You will not actually declare GFXCardProfilerAPI in TorqueScript. It exists solely "
|
||||
"to give access to the GFXCardProfiler's querying functions, such as GFXCardProfiler::getRenderer.\n\n"
|
||||
"@tsexample\n"
|
||||
"// Example of accessing GFXCardProfiler function from script\n"
|
||||
"// Notice you are not using the API version\n"
|
||||
"%videoMem = GFXCardProfiler::getVideoMemoryMB();\n"
|
||||
"@endtsexample\n\n"
|
||||
"@see GFXCardProfiler for more information\n\n"
|
||||
"@ingroup GFX\n"
|
||||
);
|
||||
|
||||
DefineEngineStaticMethod( GFXCardProfilerAPI, getVersion, String, (),,
|
||||
"Returns the driver version string." )
|
||||
{
|
||||
return GFX->getCardProfiler()->getVersionString();
|
||||
}
|
||||
|
||||
DefineEngineStaticMethod( GFXCardProfilerAPI, getCard, String, (),,
|
||||
"Returns the card name." )
|
||||
{
|
||||
return GFX->getCardProfiler()->getCardString();
|
||||
}
|
||||
|
||||
DefineEngineStaticMethod( GFXCardProfilerAPI, getVendor, String, (),,
|
||||
"Returns the card vendor name." )
|
||||
{
|
||||
// TODO: Fix all of this vendor crap, it's not consistent
|
||||
return GFX->getCardProfiler()->getChipString();
|
||||
}
|
||||
|
||||
DefineEngineStaticMethod( GFXCardProfilerAPI, getRenderer, String, (),,
|
||||
"Returns the renderer name. For example D3D9 or OpenGL." )
|
||||
{
|
||||
return GFX->getCardProfiler()->getRendererString();
|
||||
}
|
||||
|
||||
DefineEngineStaticMethod( GFXCardProfilerAPI, getVideoMemoryMB, S32, (),,
|
||||
"Returns the amount of video memory in megabytes." )
|
||||
{
|
||||
return GFX->getCardProfiler()->getVideoMemoryInMB();
|
||||
}
|
||||
|
||||
DefineEngineStaticMethod( GFXCardProfilerAPI, setCapability, void, ( const char *name, S32 value ),,
|
||||
"Used to set the value for a specific card capability.\n"
|
||||
"@param name The name of the capability being set.\n"
|
||||
"@param value The value to set for that capability." )
|
||||
{
|
||||
GFX->getCardProfiler()->setCapability( name, (U32)value );
|
||||
}
|
||||
|
||||
DefineEngineStaticMethod( GFXCardProfilerAPI, queryProfile, S32, ( const char *name, S32 defaultValue ),,
|
||||
"Used to query the value of a specific card capability.\n"
|
||||
"@param name The name of the capability being queried.\n"
|
||||
"@param defaultValue The value to return if the capability is not defined." )
|
||||
{
|
||||
return (S32)GFX->getCardProfiler()->queryProfile( name, (U32)defaultValue );
|
||||
}
|
||||
153
Engine/source/gfx/gfxCardProfile.h
Normal file
153
Engine/source/gfx/gfxCardProfile.h
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GFXCARDPROFILE_H_
|
||||
#define _GFXCARDPROFILE_H_
|
||||
|
||||
#ifndef _TDICTIONARY_H_
|
||||
#include "core/util/tDictionary.h"
|
||||
#endif
|
||||
#ifndef _GFXDEVICE_H_
|
||||
#include "gfx/gfxDevice.h"
|
||||
#endif
|
||||
#ifndef _TORQUE_STRING_H_
|
||||
#include "core/util/str.h"
|
||||
#endif
|
||||
|
||||
|
||||
/// GFXCardProfiler provides a device independent wrapper around both the
|
||||
/// capabilities reported by the card/drivers and the exceptions recorded
|
||||
/// in various scripts.
|
||||
///
|
||||
/// See the Torque Scripting Manual for more details.
|
||||
///
|
||||
class GFXCardProfiler
|
||||
{
|
||||
/// @name icpi Internal Card Profile Interface
|
||||
///
|
||||
/// This is the interface implemented by subclasses of this class in order
|
||||
/// to provide implementation-specific information about the current
|
||||
/// card/drivers.
|
||||
///
|
||||
/// Basically, the implementation needs to provide some unique strings:
|
||||
/// - mVersionString indicating the current driver version of the
|
||||
/// card in question. (For instance, "53.36")
|
||||
/// - mCardDescription indicating the name of the card ("Radeon 8500")
|
||||
/// - getRendererString() indicating the name of the renderer ("DX9", "GL1.2").
|
||||
/// Each card profiler subclass must return a unique constant so we can keep
|
||||
/// data separate. Bear in mind that punctuation is stripped from filenames.
|
||||
///
|
||||
/// The profiler also needs to implement setupCardCapabilities(), which is responsible
|
||||
/// for querying the active device and setting defaults based on the reported capabilities,
|
||||
/// and _queryCardCap, which is responsible for recognizing and responding to
|
||||
/// device-specific capability queries.
|
||||
///
|
||||
/// @{
|
||||
|
||||
public:
|
||||
|
||||
///
|
||||
const String &getVersionString() const { return mVersionString; }
|
||||
const String &getCardString() const { return mCardDescription; }
|
||||
const String &getChipString() const { return mChipSet; }
|
||||
U32 getVideoMemoryInMB() const { return mVideoMemory; }
|
||||
|
||||
virtual const String &getRendererString() const = 0;
|
||||
|
||||
protected:
|
||||
|
||||
String mVersionString;
|
||||
String mCardDescription;
|
||||
String mChipSet;
|
||||
U32 mVideoMemory;
|
||||
|
||||
virtual void setupCardCapabilities()=0;
|
||||
|
||||
/// Implementation specific query code.
|
||||
///
|
||||
/// This function is meant to be overridden by the specific implementation class.
|
||||
///
|
||||
/// Some query strings are handled by the external implementation while others must
|
||||
/// be done by the specific implementation. This is given first chance to return
|
||||
/// a result, then the generic rules are applied.
|
||||
///
|
||||
/// @param query Capability being queried.
|
||||
/// @param foundResult Result to return to the caller. If the function returns true
|
||||
/// then this value is returned as the result of the query.
|
||||
virtual bool _queryCardCap(const String &query, U32 &foundResult)=0;
|
||||
|
||||
virtual bool _queryFormat( const GFXFormat fmt, const GFXTextureProfile *profile, bool &inOutAutogenMips ) = 0;
|
||||
/// @}
|
||||
|
||||
/// @name helpergroup Helper Functions
|
||||
///
|
||||
/// Various helper functions.
|
||||
|
||||
/// Load a specified script file from the profiles directory, if it exists.
|
||||
void loadProfileScript(const char* scriptName);
|
||||
|
||||
/// Load the script files in order for the specified card profile tuple.
|
||||
void loadProfileScripts(const String& render, const String& vendor, const String& card, const String& version);
|
||||
|
||||
String strippedString(const char*string);
|
||||
|
||||
/// @}
|
||||
|
||||
/// Capability dictionary.
|
||||
Map<String, U32> mCapDictionary;
|
||||
|
||||
public:
|
||||
|
||||
/// @name ecpi External Card Profile Interface
|
||||
///
|
||||
/// @{
|
||||
|
||||
/// Called for a profile for a given device.
|
||||
GFXCardProfiler();
|
||||
virtual ~GFXCardProfiler();
|
||||
|
||||
/// Set load script files and generally initialize things.
|
||||
virtual void init()=0;
|
||||
|
||||
/// Called to query a capability. Given a query string it returns a
|
||||
/// bool indicating whether or not the capability holds. If you call
|
||||
/// this and cap isn't recognized then it returns false and prints
|
||||
/// a console error.
|
||||
U32 queryProfile(const String &cap);
|
||||
|
||||
/// Same as queryProfile(), but a default can be specified to indicate
|
||||
/// what value should be returned if the profiler doesn't know anything
|
||||
/// about it. If cap is not recognized, defaultValue is returned and
|
||||
/// no error is reported.
|
||||
U32 queryProfile(const String &cap, U32 defaultValue);
|
||||
|
||||
/// Set the specified capability to the specified value.
|
||||
void setCapability(const String &cap, U32 value);
|
||||
|
||||
/// Queries support for the specified texture format, and texture profile
|
||||
bool checkFormat( const GFXFormat fmt, const GFXTextureProfile *profile, bool &inOutAutogenMips );
|
||||
|
||||
/// @}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
109
Engine/source/gfx/gfxCubemap.cpp
Normal file
109
Engine/source/gfx/gfxCubemap.cpp
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "gfx/gfxCubemap.h"
|
||||
#include "gfx/gfxDevice.h"
|
||||
#include "gfx/bitmap/gBitmap.h"
|
||||
#include "gfx/gfxTextureManager.h"
|
||||
|
||||
|
||||
GFXCubemap::~GFXCubemap()
|
||||
{
|
||||
// If we're not dynamic and we were loaded from a
|
||||
// file then give the texture manager a chance to
|
||||
// remove us from the cache.
|
||||
if ( mPath.isNotEmpty() )
|
||||
TEXMGR->releaseCubemap( this );
|
||||
}
|
||||
|
||||
void GFXCubemap::initNormalize( U32 size )
|
||||
{
|
||||
Point3F axis[6] =
|
||||
{Point3F(1.0, 0.0, 0.0), Point3F(-1.0, 0.0, 0.0),
|
||||
Point3F(0.0, 1.0, 0.0), Point3F( 0.0, -1.0, 0.0),
|
||||
Point3F(0.0, 0.0, 1.0), Point3F( 0.0, 0.0, -1.0),};
|
||||
Point3F s[6] =
|
||||
{Point3F(0.0, 0.0, -1.0), Point3F( 0.0, 0.0, 1.0),
|
||||
Point3F(1.0, 0.0, 0.0), Point3F( 1.0, 0.0, 0.0),
|
||||
Point3F(1.0, 0.0, 0.0), Point3F(-1.0, 0.0, 0.0),};
|
||||
Point3F t[6] =
|
||||
{Point3F(0.0, -1.0, 0.0), Point3F(0.0, -1.0, 0.0),
|
||||
Point3F(0.0, 0.0, 1.0), Point3F(0.0, 0.0, -1.0),
|
||||
Point3F(0.0, -1.0, 0.0), Point3F(0.0, -1.0, 0.0),};
|
||||
|
||||
F32 span = 2.0;
|
||||
F32 start = -1.0;
|
||||
|
||||
F32 stride = span / F32(size - 1);
|
||||
GFXTexHandle faces[6];
|
||||
|
||||
for(U32 i=0; i<6; i++)
|
||||
{
|
||||
GFXTexHandle &tex = faces[i];
|
||||
GBitmap *bitmap = new GBitmap(size, size);
|
||||
|
||||
// fill in...
|
||||
for(U32 v=0; v<size; v++)
|
||||
{
|
||||
for(U32 u=0; u<size; u++)
|
||||
{
|
||||
Point3F vector;
|
||||
vector = axis[i] +
|
||||
((F32(u) * stride) + start) * s[i] +
|
||||
((F32(v) * stride) + start) * t[i];
|
||||
vector.normalizeSafe();
|
||||
vector = ((vector * 0.5) + Point3F(0.5, 0.5, 0.5)) * 255.0;
|
||||
vector.x = mClampF(vector.x, 0.0f, 255.0f);
|
||||
vector.y = mClampF(vector.y, 0.0f, 255.0f);
|
||||
vector.z = mClampF(vector.z, 0.0f, 255.0f);
|
||||
// easy way to avoid knowledge of the format (RGB, RGBA, RGBX, ...)...
|
||||
U8 *bits = bitmap->getAddress(u, v);
|
||||
bits[0] = U8(vector.x);
|
||||
bits[1] = U8(vector.y);
|
||||
bits[2] = U8(vector.z);
|
||||
}
|
||||
}
|
||||
|
||||
tex.set(bitmap, &GFXDefaultStaticDiffuseProfile, true, "Cubemap");
|
||||
}
|
||||
|
||||
initStatic(faces);
|
||||
}
|
||||
|
||||
const String GFXCubemap::describeSelf() const
|
||||
{
|
||||
// We've got nothing
|
||||
return String();
|
||||
}
|
||||
|
||||
|
||||
bool GFXCubemapHandle::set( const String &cubemapDDS )
|
||||
{
|
||||
/// Free the previous handle to give us
|
||||
/// back any texture memory when it can.
|
||||
free();
|
||||
|
||||
// Let the texture manager find this for us.
|
||||
StrongRefPtr<GFXCubemap>::set( TEXMGR->createCubemap( cubemapDDS ) );
|
||||
|
||||
return isValid();
|
||||
}
|
||||
96
Engine/source/gfx/gfxCubemap.h
Normal file
96
Engine/source/gfx/gfxCubemap.h
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GFXCUBEMAP_H_
|
||||
#define _GFXCUBEMAP_H_
|
||||
|
||||
#ifndef _GFXTEXTUREHANDLE_H_
|
||||
#include "gfx/gfxTextureHandle.h"
|
||||
#endif
|
||||
|
||||
class GFXDevice;
|
||||
struct DDSFile;
|
||||
|
||||
///
|
||||
class GFXCubemap : public StrongRefBase, public GFXResource
|
||||
{
|
||||
friend class GFXDevice;
|
||||
friend class GFXTextureManager;
|
||||
|
||||
protected:
|
||||
|
||||
// should only be called by GFXDevice
|
||||
virtual void setToTexUnit( U32 tuNum ) = 0;
|
||||
|
||||
/// The path to the cubemap file.
|
||||
String mPath;
|
||||
|
||||
/// Sets the cubemap file path.
|
||||
void _setPath( const String &path ) { mPath = path; }
|
||||
|
||||
public:
|
||||
|
||||
/// Create a static cubemap from a list of 6 face textures.
|
||||
virtual void initStatic( GFXTexHandle *faces ) = 0;
|
||||
|
||||
/// Create a static cubemap from a DDS cubemap file.
|
||||
virtual void initStatic( DDSFile *dds ) = 0;
|
||||
|
||||
///
|
||||
virtual void initDynamic( U32 texSize, GFXFormat faceFormat = GFXFormatR8G8B8A8 ) = 0;
|
||||
|
||||
void initNormalize(U32 size);
|
||||
|
||||
virtual ~GFXCubemap();
|
||||
|
||||
/// Returns the size of the faces.
|
||||
virtual U32 getSize() const = 0;
|
||||
|
||||
/// Returns the face texture format.
|
||||
virtual GFXFormat getFormat() const = 0;
|
||||
|
||||
/// Returns the cubemap file path set at creation.
|
||||
const String& getPath() const { return mPath; }
|
||||
|
||||
// GFXResource interface
|
||||
/// The resource should put a description of itself (number of vertices, size/width of texture, etc.) in buffer
|
||||
virtual const String describeSelf() const;
|
||||
};
|
||||
|
||||
|
||||
/// A reference counted handle to a cubemap resource.
|
||||
class GFXCubemapHandle : public StrongRefPtr<GFXCubemap>
|
||||
{
|
||||
public:
|
||||
GFXCubemapHandle() {}
|
||||
GFXCubemapHandle( GFXCubemap *cubemap ) { StrongRefPtr<GFXCubemap>::set( cubemap ); }
|
||||
GFXCubemapHandle( const String &cubemapDDS ) { set( cubemapDDS ); }
|
||||
|
||||
/// Set a cubemap from a DDS cubemap texture file.
|
||||
bool set( const String &cubemapDDS );
|
||||
|
||||
/// Releases the texture handle.
|
||||
void free() { StrongObjectRef::set( NULL ); }
|
||||
};
|
||||
|
||||
|
||||
#endif // GFXCUBEMAP
|
||||
83
Engine/source/gfx/gfxDebugEvent.h
Normal file
83
Engine/source/gfx/gfxDebugEvent.h
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GFXDEBUGEVENT_H_
|
||||
#define _GFXDEBUGEVENT_H_
|
||||
|
||||
#ifndef _GFXDEVICE_H_
|
||||
#include "gfx/gfxDevice.h"
|
||||
#endif
|
||||
|
||||
/// See TorqueConfig.h to enable this.
|
||||
#ifdef TORQUE_ENABLE_GFXDEBUGEVENTS
|
||||
|
||||
|
||||
/// You shouldn't use this class directly... use the
|
||||
/// following macros:
|
||||
///
|
||||
/// GFXDEBUGEVENT_START / GFXDEBUGEVENT_END
|
||||
/// GFXDEBUGEVENT_SCOPE
|
||||
///
|
||||
class GFXDebugEventScope
|
||||
{
|
||||
public:
|
||||
GFXDebugEventScope( const char* name, const ColorI &color )
|
||||
{
|
||||
GFX->enterDebugEvent( color, name );
|
||||
}
|
||||
|
||||
~GFXDebugEventScope()
|
||||
{
|
||||
GFX->leaveDebugEvent();
|
||||
}
|
||||
};
|
||||
|
||||
#define GFXDEBUGEVENT_START( name, color ) GFX->enterDebugEvent( color, #name )
|
||||
|
||||
#define GFXDEBUGEVENT_END() GFX->leaveDebugEvent()
|
||||
|
||||
#define GFXDEBUGEVENT_MARKER( name, color ) GFX->setDebugMarker( color, #name )
|
||||
|
||||
|
||||
///
|
||||
/// Will add start/end GFX debug events around the
|
||||
/// current scope.
|
||||
///
|
||||
/// @param name The unquoted name for the event.
|
||||
/// @param color A ColorI to associate with the event.
|
||||
///
|
||||
#define GFXDEBUGEVENT_SCOPE( name, color ) GFXDebugEventScope GFXDebugEventScope##name##Obj( #name, color )
|
||||
#define GFXDEBUGEVENT_SCOPE_EX( name, color, desc ) GFXDebugEventScope GFXDebugEventScope##name##Obj( desc, color )
|
||||
|
||||
#else // !TORQUE_ENABLE_GFXDEBUGEVENTS
|
||||
|
||||
/// These are disabled in shipping builds or maybe you
|
||||
/// forgot to include "platform/platform.h" first?
|
||||
#define GFXDEBUGEVENT_START(n,c)
|
||||
#define GFXDEBUGEVENT_END()
|
||||
#define GFXDEBUGEVENT_MARKER(n,c)
|
||||
#define GFXDEBUGEVENT_SCOPE(n,c)
|
||||
#define GFXDEBUGEVENT_SCOPE_EX(n,c,d)
|
||||
|
||||
#endif
|
||||
|
||||
#endif // _GFXDEBUGEVENT_H_
|
||||
1304
Engine/source/gfx/gfxDevice.cpp
Normal file
1304
Engine/source/gfx/gfxDevice.cpp
Normal file
File diff suppressed because it is too large
Load diff
1074
Engine/source/gfx/gfxDevice.h
Normal file
1074
Engine/source/gfx/gfxDevice.h
Normal file
File diff suppressed because it is too large
Load diff
74
Engine/source/gfx/gfxDeviceStatistics.cpp
Normal file
74
Engine/source/gfx/gfxDeviceStatistics.cpp
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "gfx/gfxDeviceStatistics.h"
|
||||
#include "platform/platform.h"
|
||||
#include "console/console.h"
|
||||
|
||||
GFXDeviceStatistics::GFXDeviceStatistics()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
void GFXDeviceStatistics::setPrefix(const String& prefix)
|
||||
{
|
||||
// This is a bit silly, but we don't want to construct these
|
||||
// strings every frame.
|
||||
vnPolyCount = prefix + "polyCount";
|
||||
vnDrawCalls = prefix + "drawCalls";
|
||||
vnRenderTargetChanges = prefix + "renderTargetChanges";
|
||||
}
|
||||
|
||||
/// Clear stats
|
||||
void GFXDeviceStatistics::clear()
|
||||
{
|
||||
mPolyCount = 0;
|
||||
mDrawCalls = 0;
|
||||
mRenderTargetChanges = 0;
|
||||
}
|
||||
|
||||
/// Copy from source (should just be a memcpy, but that may change later) used in
|
||||
/// conjunction with end to get a subset of statistics. For example, statistics
|
||||
/// for a particular render bin.
|
||||
void GFXDeviceStatistics::start(GFXDeviceStatistics * source)
|
||||
{
|
||||
mPolyCount = source->mPolyCount;
|
||||
mDrawCalls = source->mDrawCalls;
|
||||
mRenderTargetChanges = source->mRenderTargetChanges;
|
||||
}
|
||||
|
||||
/// Used with start to get a subset of stats on a device. Basically will do
|
||||
/// this->mPolyCount = source->mPolyCount - this->mPolyCount. (Fancy!)
|
||||
void GFXDeviceStatistics::end(GFXDeviceStatistics * source)
|
||||
{
|
||||
mPolyCount = source->mPolyCount - mPolyCount;
|
||||
mDrawCalls = source->mDrawCalls - mDrawCalls;
|
||||
mRenderTargetChanges = source->mRenderTargetChanges - mRenderTargetChanges;
|
||||
}
|
||||
|
||||
/// Exports the stats to the console
|
||||
void GFXDeviceStatistics::exportToConsole()
|
||||
{
|
||||
Con::setIntVariable(vnPolyCount, mPolyCount);
|
||||
Con::setIntVariable(vnDrawCalls, mDrawCalls);
|
||||
Con::setIntVariable(vnRenderTargetChanges, mRenderTargetChanges);
|
||||
}
|
||||
62
Engine/source/gfx/gfxDeviceStatistics.h
Normal file
62
Engine/source/gfx/gfxDeviceStatistics.h
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef _GFXDEVICESTATISTICS_H_
|
||||
#define _GFXDEVICESTATISTICS_H_
|
||||
|
||||
#ifndef _TORQUE_STRING_H_
|
||||
#include "core/util/str.h"
|
||||
#endif
|
||||
|
||||
// A class that hold a simple set of device stats.
|
||||
class GFXDeviceStatistics
|
||||
{
|
||||
public:
|
||||
// Actual stats
|
||||
S32 mPolyCount;
|
||||
S32 mDrawCalls;
|
||||
S32 mRenderTargetChanges;
|
||||
|
||||
GFXDeviceStatistics();
|
||||
|
||||
void setPrefix(const String& prefix);
|
||||
|
||||
/// Clear stats
|
||||
void clear();
|
||||
|
||||
/// Copy from source (should just be a memcpy, but that may change later) used in
|
||||
/// conjunction with end to get a subset of statistics. For example, statistics
|
||||
/// for a particular render bin.
|
||||
void start(GFXDeviceStatistics * source);
|
||||
|
||||
/// Used with start to get a subset of stats on a device. Basically will do
|
||||
/// this->mPolyCount = source->mPolyCount - this->mPolyCount. (Fancy!)
|
||||
void end(GFXDeviceStatistics * source);
|
||||
|
||||
/// Exports the stats to the console
|
||||
void exportToConsole();
|
||||
private:
|
||||
String vnPolyCount;
|
||||
String vnDrawCalls;
|
||||
String vnRenderTargetChanges;
|
||||
};
|
||||
|
||||
#endif
|
||||
1577
Engine/source/gfx/gfxDrawUtil.cpp
Normal file
1577
Engine/source/gfx/gfxDrawUtil.cpp
Normal file
File diff suppressed because it is too large
Load diff
181
Engine/source/gfx/gfxDrawUtil.h
Normal file
181
Engine/source/gfx/gfxDrawUtil.h
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GFX_GFXDRAWER_H_
|
||||
#define _GFX_GFXDRAWER_H_
|
||||
|
||||
#ifndef _GFXDEVICE_H_
|
||||
#include "gfx/gfxDevice.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MPOLYHEDRON_H_
|
||||
#include "math/mPolyhedron.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
class FontRenderBatcher;
|
||||
class Frustum;
|
||||
|
||||
|
||||
/// Helper class containing utility functions for useful drawing routines
|
||||
/// (line, box, rect, billboard, text).
|
||||
class GFXDrawUtil
|
||||
{
|
||||
public:
|
||||
GFXDrawUtil(GFXDevice *);
|
||||
~GFXDrawUtil();
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Draw Rectangles
|
||||
//-----------------------------------------------------------------------------
|
||||
void drawRect( const Point2F &upperLeft, const Point2F &lowerRight, const ColorI &color );
|
||||
void drawRect( const RectF &rect, const ColorI &color );
|
||||
void drawRect( const Point2I &upperLeft, const Point2I &lowerRight, const ColorI &color );
|
||||
void drawRect( const RectI &rect, const ColorI &color );
|
||||
|
||||
void drawRectFill( const Point2F &upperL, const Point2F &lowerR, const ColorI &color );
|
||||
void drawRectFill( const RectF &rect, const ColorI &color );
|
||||
void drawRectFill( const Point2I &upperLeft, const Point2I &lowerRight, const ColorI &color );
|
||||
void drawRectFill( const RectI &rect, const ColorI &color );
|
||||
|
||||
void draw2DSquare( const Point2F &screenPoint, F32 width, F32 spinAngle );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Draw Lines
|
||||
//-----------------------------------------------------------------------------
|
||||
void drawLine( const Point3F &startPt, const Point3F &endPt, const ColorI &color );
|
||||
void drawLine( const Point2F &startPt, const Point2F &endPt, const ColorI &color );
|
||||
void drawLine( const Point2I &startPt, const Point2I &endPt, const ColorI &color );
|
||||
void drawLine( F32 x1, F32 y1, F32 x2, F32 y2, const ColorI &color );
|
||||
void drawLine( F32 x1, F32 y1, F32 z1, F32 x2, F32 y2, F32 z2, const ColorI &color );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Draw Text
|
||||
//-----------------------------------------------------------------------------
|
||||
U32 drawText( GFont *font, const Point2I &ptDraw, const UTF8 *in_string, const ColorI *colorTable = NULL, const U32 maxColorIndex = 9, F32 rot = 0.f );
|
||||
U32 drawTextN( GFont *font, const Point2I &ptDraw, const UTF8 *in_string, U32 n, const ColorI *colorTable = NULL, const U32 maxColorIndex = 9, F32 rot = 0.f );
|
||||
U32 drawText( GFont *font, const Point2I &ptDraw, const UTF16 *in_string, const ColorI *colorTable = NULL, const U32 maxColorIndex = 9, F32 rot = 0.f );
|
||||
U32 drawTextN( GFont *font, const Point2I &ptDraw, const UTF16 *in_string, U32 n, const ColorI *colorTable = NULL, const U32 maxColorIndex = 9, F32 rot = 0.f );
|
||||
|
||||
U32 drawText( GFont *font, const Point2F &ptDraw, const UTF8 *in_string, const ColorI *colorTable = NULL, const U32 maxColorIndex = 9, F32 rot = 0.f );
|
||||
U32 drawTextN( GFont *font, const Point2F &ptDraw, const UTF8 *in_string, U32 n, const ColorI *colorTable = NULL, const U32 maxColorIndex = 9, F32 rot = 0.f );
|
||||
U32 drawText( GFont *font, const Point2F &ptDraw, const UTF16 *in_string, const ColorI *colorTable = NULL, const U32 maxColorIndex = 9, F32 rot = 0.f );
|
||||
U32 drawTextN( GFont *font, const Point2F &ptDraw, const UTF16 *in_string, U32 n, const ColorI *colorTable = NULL, const U32 maxColorIndex = 9, F32 rot = 0.f );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Color Modulation
|
||||
//-----------------------------------------------------------------------------
|
||||
void setBitmapModulation( const ColorI &modColor );
|
||||
void setTextAnchorColor( const ColorI &ancColor );
|
||||
void clearBitmapModulation();
|
||||
void getBitmapModulation( ColorI *color );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Draw Bitmaps
|
||||
//-----------------------------------------------------------------------------
|
||||
void drawBitmap( GFXTextureObject*texture, const Point2F &in_rAt, const GFXBitmapFlip in_flip = GFXBitmapFlip_None, const GFXTextureFilterType filter = GFXTextureFilterPoint , bool in_wrap = true );
|
||||
void drawBitmapSR( GFXTextureObject*texture, const Point2F &in_rAt, const RectF &srcRect, const GFXBitmapFlip in_flip = GFXBitmapFlip_None, const GFXTextureFilterType filter = GFXTextureFilterPoint , bool in_wrap = true );
|
||||
void drawBitmapStretch( GFXTextureObject*texture, const RectF &dstRect, const GFXBitmapFlip in_flip = GFXBitmapFlip_None, const GFXTextureFilterType filter = GFXTextureFilterPoint , bool in_wrap = true );
|
||||
void drawBitmapStretchSR( GFXTextureObject*texture, const RectF &dstRect, const RectF &srcRect, const GFXBitmapFlip in_flip = GFXBitmapFlip_None, const GFXTextureFilterType filter = GFXTextureFilterPoint , bool in_wrap = true );
|
||||
|
||||
void drawBitmap( GFXTextureObject*texture, const Point2I &in_rAt, const GFXBitmapFlip in_flip = GFXBitmapFlip_None, const GFXTextureFilterType filter = GFXTextureFilterPoint , bool in_wrap = true );
|
||||
void drawBitmapSR( GFXTextureObject*texture, const Point2I &in_rAt, const RectI &srcRect, const GFXBitmapFlip in_flip = GFXBitmapFlip_None, const GFXTextureFilterType filter = GFXTextureFilterPoint , bool in_wrap = true );
|
||||
void drawBitmapStretch( GFXTextureObject*texture, const RectI &dstRect, const GFXBitmapFlip in_flip = GFXBitmapFlip_None, const GFXTextureFilterType filter = GFXTextureFilterPoint , bool in_wrap = true );
|
||||
void drawBitmapStretchSR( GFXTextureObject*texture, const RectI &dstRect, const RectI &srcRect, const GFXBitmapFlip in_flip = GFXBitmapFlip_None, const GFXTextureFilterType filter = GFXTextureFilterPoint , bool in_wrap = true );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Draw 3D Shapes
|
||||
//-----------------------------------------------------------------------------
|
||||
void drawTriangle( const GFXStateBlockDesc &desc, const Point3F &p0, const Point3F &p1, const Point3F &p2, const ColorI &color, const MatrixF *xfm = NULL );
|
||||
void drawPolygon( const GFXStateBlockDesc& desc, const Point3F* points, U32 numPoints, const ColorI& color, const MatrixF* xfm = NULL );
|
||||
void drawCube( const GFXStateBlockDesc &desc, const Point3F &size, const Point3F &pos, const ColorI &color, const MatrixF *xfm = NULL );
|
||||
void drawCube( const GFXStateBlockDesc &desc, const Box3F &box, const ColorI &color, const MatrixF *xfm = NULL );
|
||||
void drawObjectBox( const GFXStateBlockDesc &desc, const Point3F &size, const Point3F &pos, const MatrixF &objMat, const ColorI &color );
|
||||
void drawSphere( const GFXStateBlockDesc &desc, F32 radius, const Point3F &pos, const ColorI &color, bool drawTop = true, bool drawBottom = true, const MatrixF *xfm = NULL );
|
||||
void drawCapsule( const GFXStateBlockDesc &desc, const Point3F ¢er, F32 radius, F32 height, const ColorI &color, const MatrixF *xfm = NULL );
|
||||
void drawCone( const GFXStateBlockDesc &desc, const Point3F &basePnt, const Point3F &tipPnt, F32 baseRadius, const ColorI &color );
|
||||
void drawCylinder( const GFXStateBlockDesc &desc, const Point3F &basePnt, const Point3F &tipPnt, F32 baseRadius, const ColorI &color );
|
||||
void drawArrow( const GFXStateBlockDesc &desc, const Point3F &start, const Point3F &end, const ColorI &color );
|
||||
void drawFrustum( const Frustum& f, const ColorI &color );
|
||||
|
||||
/// Draw a solid or wireframe (depending on fill mode of @a desc) polyhedron with the given color.
|
||||
///
|
||||
/// @param desc Render state description.
|
||||
/// @param poly Polyhedron.
|
||||
/// @param color Color.
|
||||
/// @param xfm Optional matrix to transform all vertices of the given polyhedron by.
|
||||
void drawPolyhedron( const GFXStateBlockDesc &desc, const AnyPolyhedron &poly, const ColorI &color, const MatrixF *xfm = NULL );
|
||||
|
||||
/// Draws a solid XY plane centered on the point with the specified dimensions.
|
||||
void drawSolidPlane( const GFXStateBlockDesc &desc, const Point3F &pos, const Point2F &size, const ColorI &color );
|
||||
|
||||
enum Plane
|
||||
{
|
||||
PlaneXY,
|
||||
PlaneXZ,
|
||||
PlaneYZ
|
||||
};
|
||||
|
||||
/// Draws a grid on XY, XZ, or YZ plane centered on the point with the specified size and step size.
|
||||
void drawPlaneGrid( const GFXStateBlockDesc &desc, const Point3F &pos, const Point2F &size, const Point2F &step, const ColorI &color, Plane plane = PlaneXY );
|
||||
|
||||
/// Draws axis lines representing the passed matrix.
|
||||
/// If scale is NULL axes will be drawn the length they exist within the MatrixF.
|
||||
/// If colors is NULL the default colors are RED, GREEEN, BLUE ( x, y, z ).
|
||||
void drawTransform( const GFXStateBlockDesc &desc, const MatrixF &mat, const Point3F *scale = NULL, const ColorI colors[3] = NULL );
|
||||
|
||||
protected:
|
||||
|
||||
void _setupStateBlocks();
|
||||
void _drawWireTriangle( const GFXStateBlockDesc &desc, const Point3F &p0, const Point3F &p1, const Point3F &p2, const ColorI &color, const MatrixF *xfm = NULL );
|
||||
void _drawSolidTriangle( const GFXStateBlockDesc &desc, const Point3F &p0, const Point3F &p1, const Point3F &p2, const ColorI &color, const MatrixF *xfm = NULL );
|
||||
void _drawWireCube( const GFXStateBlockDesc &desc, const Point3F &size, const Point3F &pos, const ColorI &color, const MatrixF *xfm = NULL );
|
||||
void _drawSolidCube( const GFXStateBlockDesc &desc, const Point3F &size, const Point3F &pos, const ColorI &color, const MatrixF *xfm = NULL );
|
||||
void _drawWireCapsule( const GFXStateBlockDesc &desc, const Point3F ¢er, F32 radius, F32 height, const ColorI &color, const MatrixF *xfm = NULL );
|
||||
void _drawSolidCapsule( const GFXStateBlockDesc &desc, const Point3F ¢er, F32 radius, F32 height, const ColorI &color, const MatrixF *xfm = NULL );
|
||||
void _drawWirePolyhedron( const GFXStateBlockDesc &desc, const AnyPolyhedron &poly, const ColorI &color, const MatrixF *xfm = NULL );
|
||||
void _drawSolidPolyhedron( const GFXStateBlockDesc &desc, const AnyPolyhedron &poly, const ColorI &color, const MatrixF *xfm = NULL );
|
||||
|
||||
protected:
|
||||
|
||||
/// The device we're rendering to.
|
||||
GFXDevice *mDevice;
|
||||
|
||||
/// Bitmap modulation color; bitmaps are multiplied by this color when
|
||||
/// drawn.
|
||||
GFXVertexColor mBitmapModulation;
|
||||
|
||||
/// Base text color; what color text is drawn at when no other color is
|
||||
/// specified.
|
||||
GFXVertexColor mTextAnchorColor;
|
||||
|
||||
GFXStateBlockRef mBitmapStretchSB;
|
||||
GFXStateBlockRef mBitmapStretchLinearSB;
|
||||
GFXStateBlockRef mBitmapStretchWrapSB;
|
||||
GFXStateBlockRef mBitmapStretchWrapLinearSB;
|
||||
GFXStateBlockRef mRectFillSB;
|
||||
|
||||
FontRenderBatcher* mFontRenderBatcher;
|
||||
};
|
||||
|
||||
#endif // _GFX_GFXDRAWER_H_
|
||||
624
Engine/source/gfx/gfxEnums.h
Normal file
624
Engine/source/gfx/gfxEnums.h
Normal file
|
|
@ -0,0 +1,624 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GFXENUMS_H_
|
||||
#define _GFXENUMS_H_
|
||||
|
||||
#include "core/util/fourcc.h"
|
||||
|
||||
// These are for the enum translation. It will help with porting to other platforms
|
||||
// and API's.
|
||||
#define GFX_UNSUPPORTED_VAL 0xDEADBEEF
|
||||
#define GFX_UNINIT_VAL 0xDECAFBAD
|
||||
|
||||
// Adjust these pools to your app's needs. Be aware dynamic vertices are much more
|
||||
// expensive than static vertices. These are in gfxEnums because they should be
|
||||
// consistant across all APIs/platforms so that the dynamic buffer performance
|
||||
// and behavior is also consistant. -patw
|
||||
#define MAX_DYNAMIC_VERTS (8192*2)
|
||||
#define MAX_DYNAMIC_INDICES (8192*4)
|
||||
|
||||
enum GFXBufferType
|
||||
{
|
||||
GFXBufferTypeStatic, ///< Static vertex buffers are created and filled one time.
|
||||
///< incur a performance penalty. Resizing a static vertex buffer is not
|
||||
///< allowed.
|
||||
GFXBufferTypeDynamic, ///< Dynamic vertex buffers are meant for vertices that can be changed
|
||||
///< often. Vertices written into dynamic vertex buffers will remain valid
|
||||
///< until the dynamic vertex buffer is released. Resizing a dynamic vertex buffer is not
|
||||
///< allowed.
|
||||
GFXBufferTypeVolatile, ///< Volatile vertex or index buffers are meant for vertices or indices that are essentially
|
||||
///< only used once. They can be resized without any performance penalty.
|
||||
|
||||
GFXBufferType_COUNT ///< Number of buffer types.
|
||||
};
|
||||
|
||||
enum GFXTexCallbackCode
|
||||
{
|
||||
GFXZombify,
|
||||
GFXResurrect,
|
||||
};
|
||||
|
||||
|
||||
enum GFXPrimitiveType
|
||||
{
|
||||
GFXPT_FIRST = 0,
|
||||
GFXPointList = 0,
|
||||
GFXLineList,
|
||||
GFXLineStrip,
|
||||
GFXTriangleList,
|
||||
GFXTriangleStrip,
|
||||
GFXTriangleFan,
|
||||
GFXPT_COUNT
|
||||
};
|
||||
|
||||
enum GFXTextureType
|
||||
{
|
||||
GFXTextureType_Normal,
|
||||
GFXTextureType_KeepBitmap,
|
||||
GFXTextureType_Dynamic,
|
||||
GFXTextureType_RenderTarget,
|
||||
GFXTextureType_Count
|
||||
};
|
||||
|
||||
enum GFXBitmapFlip
|
||||
{
|
||||
GFXBitmapFlip_None = 0,
|
||||
GFXBitmapFlip_X = 1 << 0,
|
||||
GFXBitmapFlip_Y = 1 << 1,
|
||||
GFXBitmapFlip_XY = GFXBitmapFlip_X | GFXBitmapFlip_Y
|
||||
};
|
||||
|
||||
enum GFXTextureOp
|
||||
{
|
||||
GFXTOP_FIRST = 0,
|
||||
GFXTOPDisable = 0,
|
||||
GFXTOPSelectARG1,
|
||||
GFXTOPSelectARG2,
|
||||
GFXTOPModulate,
|
||||
GFXTOPModulate2X,
|
||||
GFXTOPModulate4X,
|
||||
GFXTOPAdd,
|
||||
GFXTOPAddSigned,
|
||||
GFXTOPAddSigned2X,
|
||||
GFXTOPSubtract,
|
||||
GFXTOPAddSmooth,
|
||||
GFXTOPBlendDiffuseAlpha,
|
||||
GFXTOPBlendTextureAlpha,
|
||||
GFXTOPBlendFactorAlpha,
|
||||
GFXTOPBlendTextureAlphaPM,
|
||||
GFXTOPBlendCURRENTALPHA,
|
||||
GFXTOPPreModulate,
|
||||
GFXTOPModulateAlphaAddColor,
|
||||
GFXTOPModulateColorAddAlpha,
|
||||
GFXTOPModulateInvAlphaAddColor,
|
||||
GFXTOPModulateInvColorAddAlpha,
|
||||
GFXTOPBumpEnvMap,
|
||||
GFXTOPBumpEnvMapLuminance,
|
||||
GFXTOPDotProduct3,
|
||||
GFXTOPLERP,
|
||||
GFXTOP_COUNT
|
||||
};
|
||||
|
||||
enum GFXTextureAddressMode
|
||||
{
|
||||
GFXAddress_FIRST = 0,
|
||||
GFXAddressWrap = 0,
|
||||
GFXAddressMirror,
|
||||
GFXAddressClamp,
|
||||
GFXAddressBorder,
|
||||
GFXAddressMirrorOnce,
|
||||
GFXAddress_COUNT
|
||||
};
|
||||
|
||||
enum GFXTextureFilterType
|
||||
{
|
||||
GFXTextureFilter_FIRST = 0,
|
||||
GFXTextureFilterNone = 0,
|
||||
GFXTextureFilterPoint,
|
||||
GFXTextureFilterLinear,
|
||||
GFXTextureFilterAnisotropic,
|
||||
GFXTextureFilterPyramidalQuad,
|
||||
GFXTextureFilterGaussianQuad,
|
||||
GFXTextureFilter_COUNT
|
||||
};
|
||||
|
||||
enum GFXFillMode
|
||||
{
|
||||
GFXFill_FIRST = 1,
|
||||
GFXFillPoint = 1,
|
||||
GFXFillWireframe,
|
||||
GFXFillSolid,
|
||||
GFXFill_COUNT
|
||||
};
|
||||
|
||||
enum GFXFormat
|
||||
{
|
||||
// when adding formats make sure to place
|
||||
// them in the correct group!
|
||||
//
|
||||
// if displacing the first entry in the group
|
||||
// make sure to update the GFXFormat_xBIT entries!
|
||||
//
|
||||
GFXFormat_FIRST = 0,
|
||||
|
||||
// 8 bit texture formats...
|
||||
GFXFormatA8 = 0,// first in group...
|
||||
GFXFormatL8,
|
||||
GFXFormatA4L4,
|
||||
|
||||
// 16 bit texture formats...
|
||||
GFXFormatR5G6B5,// first in group...
|
||||
GFXFormatR5G5B5A1,
|
||||
GFXFormatR5G5B5X1,
|
||||
GFXFormatA8L8,
|
||||
GFXFormatL16,
|
||||
GFXFormatR16F,
|
||||
GFXFormatD16,
|
||||
|
||||
// 24 bit texture formats...
|
||||
GFXFormatR8G8B8,// first in group...
|
||||
|
||||
// 32 bit texture formats...
|
||||
GFXFormatR8G8B8A8,// first in group...
|
||||
GFXFormatR8G8B8X8,
|
||||
GFXFormatR32F,
|
||||
GFXFormatR16G16,
|
||||
GFXFormatR16G16F,
|
||||
GFXFormatR10G10B10A2,
|
||||
GFXFormatD32,
|
||||
GFXFormatD24X8,
|
||||
GFXFormatD24S8,
|
||||
GFXFormatD24FS8,
|
||||
|
||||
// 64 bit texture formats...
|
||||
GFXFormatR16G16B16A16,// first in group...
|
||||
GFXFormatR16G16B16A16F,
|
||||
|
||||
// 128 bit texture formats...
|
||||
GFXFormatR32G32B32A32F,// first in group...
|
||||
|
||||
// unknown size...
|
||||
GFXFormatDXT1,// first in group...
|
||||
GFXFormatDXT2,
|
||||
GFXFormatDXT3,
|
||||
GFXFormatDXT4,
|
||||
GFXFormatDXT5,
|
||||
|
||||
GFXFormat_COUNT,
|
||||
|
||||
GFXFormat_8BIT = GFXFormatA8,
|
||||
GFXFormat_16BIT = GFXFormatR5G6B5,
|
||||
GFXFormat_24BIT = GFXFormatR8G8B8,
|
||||
GFXFormat_32BIT = GFXFormatR8G8B8A8,
|
||||
GFXFormat_64BIT = GFXFormatR16G16B16A16,
|
||||
GFXFormat_128BIT = GFXFormatR32G32B32A32F,
|
||||
GFXFormat_UNKNOWNSIZE = GFXFormatDXT1,
|
||||
};
|
||||
|
||||
/// Returns the byte size of the pixel for non-compressed formats.
|
||||
inline U32 GFXFormat_getByteSize( GFXFormat format )
|
||||
{
|
||||
AssertFatal( format < GFXFormat_UNKNOWNSIZE,
|
||||
"GFXDevice::formatByteSize - Cannot size a compressed format!" );
|
||||
|
||||
if ( format < GFXFormat_16BIT )
|
||||
return 1;// 8 bit...
|
||||
else if ( format < GFXFormat_24BIT )
|
||||
return 2;// 16 bit...
|
||||
else if ( format < GFXFormat_32BIT )
|
||||
return 3;// 24 bit...
|
||||
else if ( format < GFXFormat_64BIT )
|
||||
return 4;// 32 bit...
|
||||
else if ( format < GFXFormat_128BIT )
|
||||
return 8;// 64 bit...
|
||||
|
||||
// This should be 128bits... else its a DDS and
|
||||
// the assert should have gone off above.
|
||||
return 16;
|
||||
}
|
||||
|
||||
enum GFXShadeMode
|
||||
{
|
||||
GFXShadeFlat = 1,
|
||||
GFXShadeGouraud,
|
||||
GFXShadePhong,
|
||||
};
|
||||
|
||||
enum GFXClearFlags
|
||||
{
|
||||
GFXClearTarget = 1 << 0,
|
||||
GFXClearZBuffer = 1 << 1,
|
||||
GFXClearStencil = 1 << 2,
|
||||
};
|
||||
|
||||
/// The supported blend modes.
|
||||
enum GFXBlend
|
||||
{
|
||||
GFXBlend_FIRST = 0,
|
||||
GFXBlendZero = 0, /// (0, 0, 0, 0)
|
||||
GFXBlendOne, /// (1, 1, 1, 1)
|
||||
GFXBlendSrcColor, /// (Rs, Gs, Bs, As)
|
||||
GFXBlendInvSrcColor, /// (1 - Rs, 1 - Gs, 1 - Bs, 1 - As)
|
||||
GFXBlendSrcAlpha, /// (As, As, As, As)
|
||||
GFXBlendInvSrcAlpha, /// ( 1 - As, 1 - As, 1 - As, 1 - As)
|
||||
GFXBlendDestAlpha, /// (Ad Ad Ad Ad)
|
||||
GFXBlendInvDestAlpha, /// (1 - Ad 1 - Ad 1 - Ad 1 - Ad)
|
||||
GFXBlendDestColor, /// (Rd, Gd, Bd, Ad)
|
||||
GFXBlendInvDestColor, /// (1 - Rd, 1 - Gd, 1 - Bd, 1 - Ad)
|
||||
GFXBlendSrcAlphaSat, /// (f, f, f, 1) where f = min(As, 1 - Ad)
|
||||
GFXBlend_COUNT
|
||||
};
|
||||
|
||||
/// Constants that name each GFXDevice type. Any new GFXDevice subclass must be
|
||||
/// added to this enum. A string representing its name must also be added to
|
||||
/// GFXInit::getAdapterNameFromType().
|
||||
enum GFXAdapterType
|
||||
{
|
||||
OpenGL = 0,
|
||||
Direct3D9,
|
||||
Direct3D8,
|
||||
NullDevice,
|
||||
Direct3D9_360,
|
||||
GFXAdapterType_Count
|
||||
};
|
||||
|
||||
enum GFXCullMode
|
||||
{
|
||||
GFXCull_FIRST = 0,
|
||||
GFXCullNone = 0,
|
||||
GFXCullCW,
|
||||
GFXCullCCW,
|
||||
GFXCull_COUNT
|
||||
};
|
||||
|
||||
enum GFXCmpFunc
|
||||
{
|
||||
GFXCmp_FIRST = 0,
|
||||
GFXCmpNever = 0,
|
||||
GFXCmpLess,
|
||||
GFXCmpEqual,
|
||||
GFXCmpLessEqual,
|
||||
GFXCmpGreater,
|
||||
GFXCmpNotEqual,
|
||||
GFXCmpGreaterEqual,
|
||||
GFXCmpAlways,
|
||||
GFXCmp_COUNT
|
||||
};
|
||||
|
||||
enum GFXStencilOp
|
||||
{
|
||||
GFXStencilOp_FIRST = 0,
|
||||
GFXStencilOpKeep = 0,
|
||||
GFXStencilOpZero,
|
||||
GFXStencilOpReplace,
|
||||
GFXStencilOpIncrSat,
|
||||
GFXStencilOpDecrSat,
|
||||
GFXStencilOpInvert,
|
||||
GFXStencilOpIncr,
|
||||
GFXStencilOpDecr,
|
||||
GFXStencilOp_COUNT
|
||||
};
|
||||
|
||||
enum GFXMaterialColorSource
|
||||
{
|
||||
GFXMCSMaterial = 0,
|
||||
GFXMCSColor1,
|
||||
GFXMCSColor2,
|
||||
};
|
||||
|
||||
enum GFXBlendOp
|
||||
{
|
||||
GFXBlendOp_FIRST = 0,
|
||||
GFXBlendOpAdd = 0,
|
||||
GFXBlendOpSubtract,
|
||||
GFXBlendOpRevSubtract,
|
||||
GFXBlendOpMin,
|
||||
GFXBlendOpMax,
|
||||
GFXBlendOp_COUNT
|
||||
};
|
||||
|
||||
enum GFXRenderState
|
||||
{
|
||||
GFXRenderState_FIRST = 0,
|
||||
GFXRSZEnable = 0,
|
||||
GFXRSFillMode,
|
||||
GFXRSShadeMode,
|
||||
GFXRSZWriteEnable,
|
||||
GFXRSAlphaTestEnable,
|
||||
GFXRSLastPixel,
|
||||
GFXRSSrcBlend,
|
||||
GFXRSDestBlend,
|
||||
GFXRSCullMode,
|
||||
GFXRSZFunc,
|
||||
GFXRSAlphaRef,
|
||||
GFXRSAlphaFunc,
|
||||
GFXRSDitherEnable,
|
||||
GFXRSAlphaBlendEnable,
|
||||
GFXRSFogEnable,
|
||||
GFXRSSpecularEnable,
|
||||
GFXRSFogColor,
|
||||
GFXRSFogTableMode,
|
||||
GFXRSFogStart,
|
||||
GFXRSFogEnd,
|
||||
GFXRSFogDensity,
|
||||
GFXRSRangeFogEnable,
|
||||
GFXRSStencilEnable,
|
||||
GFXRSStencilFail,
|
||||
GFXRSStencilZFail,
|
||||
GFXRSStencilPass,
|
||||
GFXRSStencilFunc,
|
||||
GFXRSStencilRef,
|
||||
GFXRSStencilMask,
|
||||
GFXRSStencilWriteMask,
|
||||
GFXRSTextureFactor,
|
||||
GFXRSWrap0,
|
||||
GFXRSWrap1,
|
||||
GFXRSWrap2,
|
||||
GFXRSWrap3,
|
||||
GFXRSWrap4,
|
||||
GFXRSWrap5,
|
||||
GFXRSWrap6,
|
||||
GFXRSWrap7,
|
||||
GFXRSClipping,
|
||||
GFXRSLighting,
|
||||
GFXRSAmbient,
|
||||
GFXRSFogVertexMode,
|
||||
GFXRSColorVertex,
|
||||
GFXRSLocalViewer,
|
||||
GFXRSNormalizeNormals,
|
||||
GFXRSDiffuseMaterialSource,
|
||||
GFXRSSpecularMaterialSource,
|
||||
GFXRSAmbientMaterialSource,
|
||||
GFXRSEmissiveMaterialSource,
|
||||
GFXRSVertexBlend,
|
||||
GFXRSClipPlaneEnable,
|
||||
GFXRSPointSize,
|
||||
GFXRSPointSizeMin,
|
||||
GFXRSPointSpriteEnable,
|
||||
GFXRSPointScaleEnable,
|
||||
GFXRSPointScale_A,
|
||||
GFXRSPointScale_B,
|
||||
GFXRSPointScale_C,
|
||||
GFXRSMultiSampleantiAlias,
|
||||
GFXRSMultiSampleMask,
|
||||
GFXRSPatchEdgeStyle,
|
||||
GFXRSDebugMonitorToken,
|
||||
GFXRSPointSize_Max,
|
||||
GFXRSIndexedVertexBlendEnable,
|
||||
GFXRSColorWriteEnable,
|
||||
GFXRSTweenFactor,
|
||||
GFXRSBlendOp,
|
||||
GFXRSPositionDegree,
|
||||
GFXRSNormalDegree,
|
||||
GFXRSScissorTestEnable,
|
||||
GFXRSSlopeScaleDepthBias,
|
||||
GFXRSAntiAliasedLineEnable,
|
||||
GFXRSMinTessellationLevel,
|
||||
GFXRSMaxTessellationLevel,
|
||||
GFXRSAdaptiveTess_X,
|
||||
GFXRSAdaptiveTess_Y,
|
||||
GFXRSdaptiveTess_Z,
|
||||
GFXRSAdaptiveTess_W,
|
||||
GFXRSEnableAdaptiveTesselation,
|
||||
GFXRSTwoSidedStencilMode,
|
||||
GFXRSCCWStencilFail,
|
||||
GFXRSCCWStencilZFail,
|
||||
GFXRSCCWStencilPass,
|
||||
GFXRSCCWStencilFunc,
|
||||
GFXRSColorWriteEnable1,
|
||||
GFXRSColorWriteEnable2,
|
||||
GFXRSolorWriteEnable3,
|
||||
GFXRSBlendFactor,
|
||||
GFXRSSRGBWriteEnable,
|
||||
GFXRSDepthBias,
|
||||
GFXRSWrap8,
|
||||
GFXRSWrap9,
|
||||
GFXRSWrap10,
|
||||
GFXRSWrap11,
|
||||
GFXRSWrap12,
|
||||
GFXRSWrap13,
|
||||
GFXRSWrap14,
|
||||
GFXRSWrap15,
|
||||
GFXRSSeparateAlphaBlendEnable,
|
||||
GFXRSSrcBlendAlpha,
|
||||
GFXRSDestBlendAlpha,
|
||||
GFXRSBlendOpAlpha,
|
||||
GFXRenderState_COUNT ///< Don't use this one, this is a counter
|
||||
};
|
||||
|
||||
#define GFXCOLORWRITEENABLE_RED 1
|
||||
#define GFXCOLORWRITEENABLE_GREEN 2
|
||||
#define GFXCOLORWRITEENABLE_BLUE 4
|
||||
#define GFXCOLORWRITEENABLE_ALPHA 8
|
||||
|
||||
enum GFXTextureStageState
|
||||
{
|
||||
GFXTSS_FIRST = 0,
|
||||
GFXTSSColorOp = 0,
|
||||
GFXTSSColorArg1,
|
||||
GFXTSSColorArg2,
|
||||
GFXTSSAlphaOp,
|
||||
GFXTSSAlphaArg1,
|
||||
GFXTSSAlphaArg2,
|
||||
GFXTSSBumpEnvMat00,
|
||||
GFXTSSBumpEnvMat01,
|
||||
GFXTSSBumpEnvMat10,
|
||||
GFXTSSBumpEnvMat11,
|
||||
GFXTSSTexCoordIndex,
|
||||
GFXTSSBumpEnvlScale,
|
||||
GFXTSSBumpEnvlOffset,
|
||||
GFXTSSTextureTransformFlags,
|
||||
GFXTSSColorArg0,
|
||||
GFXTSSAlphaArg0,
|
||||
GFXTSSResultArg,
|
||||
GFXTSSConstant,
|
||||
GFXTSS_COUNT ///< Don't use this one, this is a counter
|
||||
};
|
||||
|
||||
enum GFXTextureTransformFlags
|
||||
{
|
||||
GFXTTFFDisable = 0,
|
||||
GFXTTFFCoord1D = 1,
|
||||
GFXTTFFCoord2D = 2,
|
||||
GFXTTFFCoord3D = 3,
|
||||
GFXTTFFCoord4D = 4,
|
||||
GFXTTFFProjected = 256,
|
||||
};
|
||||
|
||||
// CodeReview: This number is used for the declaration of variables, but it
|
||||
// should *not* be used for any run-time purposes [7/2/2007 Pat]
|
||||
#define TEXTURE_STAGE_COUNT 16
|
||||
|
||||
enum GFXSamplerState
|
||||
{
|
||||
GFXSAMP_FIRST = 0,
|
||||
GFXSAMPAddressU = 0,
|
||||
GFXSAMPAddressV,
|
||||
GFXSAMPAddressW,
|
||||
GFXSAMPBorderColor,
|
||||
GFXSAMPMagFilter,
|
||||
GFXSAMPMinFilter,
|
||||
GFXSAMPMipFilter,
|
||||
GFXSAMPMipMapLODBias,
|
||||
GFXSAMPMaxMipLevel,
|
||||
GFXSAMPMaxAnisotropy,
|
||||
GFXSAMPSRGBTexture,
|
||||
GFXSAMPElementIndex,
|
||||
GFXSAMPDMapOffset,
|
||||
GFXSAMP_COUNT ///< Don't use this one, this is a counter
|
||||
};
|
||||
|
||||
enum GFXTextureArgument
|
||||
{
|
||||
GFXTA_FIRST = 0,
|
||||
GFXTADiffuse = 0,
|
||||
GFXTACurrent,
|
||||
GFXTATexture,
|
||||
GFXTATFactor,
|
||||
GFXTASpecular,
|
||||
GFXTATemp,
|
||||
GFXTAConstant,
|
||||
GFXTA_COUNT,
|
||||
GFXTAComplement = 0x00000010, // take 1.0 - x (read modifier)
|
||||
GFXTAAlphaReplicate = 0x00000020, // replicate alpha to color components (read modifier)
|
||||
};
|
||||
|
||||
// Matrix stuff
|
||||
#define WORLD_STACK_MAX 24
|
||||
|
||||
enum GFXMatrixType
|
||||
{
|
||||
GFXMatrixWorld = 256,
|
||||
GFXMatrixView = 2,
|
||||
GFXMatrixProjection = 3,
|
||||
GFXMatrixTexture = 16, // This value is texture matrix for sampler 0, can use this for offset
|
||||
GFXMatrixTexture0 = 16,
|
||||
GFXMatrixTexture1 = 17,
|
||||
GFXMatrixTexture2 = 18,
|
||||
GFXMatrixTexture3 = 19,
|
||||
GFXMatrixTexture4 = 20,
|
||||
GFXMatrixTexture5 = 21,
|
||||
GFXMatrixTexture6 = 22,
|
||||
GFXMatrixTexture7 = 23,
|
||||
};
|
||||
|
||||
// Light define
|
||||
#define LIGHT_STAGE_COUNT 8
|
||||
|
||||
#define GFXVERTEXFLAG_F32 3
|
||||
#define GFXVERTEXFLAG_POINT2F 0
|
||||
#define GFXVERTEXFLAG_POINT3F 1
|
||||
#define GFXVERTEXFLAG_POINT4F 2
|
||||
|
||||
#define GFXVERTEXFLAG_TEXCOORD_F32(CoordIndex) ( GFXVERTEXFLAG_F32 << ( CoordIndex * 2 + 16 ) )
|
||||
#define GFXVERTEXFLAG_TEXCOORD_POINT2F(CoordIndex) ( GFXVERTEXFLAG_POINT2F )
|
||||
#define GFXVERTEXFLAG_TEXCOORD_POINT3F(CoordIndex) ( GFXVERTEXFLAG_POINT3F << ( CoordIndex * 2 + 16 ) )
|
||||
#define GFXVERTEXFLAG_TEXCOORD_POINT4F(CoordIndex) ( GFXVERTEXFLAG_POINT4F << ( CoordIndex * 2 + 16 ) )
|
||||
|
||||
#define STATE_STACK_SIZE 32
|
||||
|
||||
// Index Formats
|
||||
enum GFXIndexFormat
|
||||
{
|
||||
GFXIndexFormat_FIRST = 0,
|
||||
GFXIndexFormat16 = 0,
|
||||
GFXIndexFormat32,
|
||||
GFXIndexFormat_COUNT
|
||||
};
|
||||
|
||||
enum GFXShaderConstType
|
||||
{
|
||||
/// GFX"S"hader"C"onstant"T"ype
|
||||
// Scalar
|
||||
GFXSCT_Float,
|
||||
// Vectors
|
||||
GFXSCT_Float2,
|
||||
GFXSCT_Float3,
|
||||
GFXSCT_Float4,
|
||||
// Matrices
|
||||
GFXSCT_Float2x2,
|
||||
GFXSCT_Float3x3,
|
||||
GFXSCT_Float4x4,
|
||||
// Scalar
|
||||
GFXSCT_Int,
|
||||
// Vectors
|
||||
GFXSCT_Int2,
|
||||
GFXSCT_Int3,
|
||||
GFXSCT_Int4,
|
||||
// Samplers
|
||||
GFXSCT_Sampler,
|
||||
GFXSCT_SamplerCube
|
||||
};
|
||||
|
||||
|
||||
/// Defines a vertex declaration type.
|
||||
/// @see GFXVertexElement
|
||||
/// @see GFXVertexFormat
|
||||
enum GFXDeclType
|
||||
{
|
||||
GFXDeclType_FIRST = 0,
|
||||
|
||||
/// A single component F32.
|
||||
GFXDeclType_Float = 0,
|
||||
|
||||
/// A two-component F32.
|
||||
/// @see Point2F
|
||||
GFXDeclType_Float2,
|
||||
|
||||
/// A three-component F32.
|
||||
/// @see Point3F
|
||||
GFXDeclType_Float3,
|
||||
|
||||
/// A four-component F32.
|
||||
/// @see Point4F
|
||||
GFXDeclType_Float4,
|
||||
|
||||
/// A four-component, packed, unsigned bytes mapped to 0 to 1 range.
|
||||
/// @see GFXVertexColor
|
||||
GFXDeclType_Color,
|
||||
|
||||
/// The count of total GFXDeclTypes.
|
||||
GFXDeclType_COUNT,
|
||||
};
|
||||
|
||||
#endif // _GFXENUMS_H_
|
||||
142
Engine/source/gfx/gfxFence.cpp
Normal file
142
Engine/source/gfx/gfxFence.cpp
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "gfx/gfxFence.h"
|
||||
|
||||
#include "gfx/primBuilder.h"
|
||||
#include "gfx/gfxTextureManager.h"
|
||||
|
||||
|
||||
GFXGeneralFence::~GFXGeneralFence()
|
||||
{
|
||||
// Release the ref pointers
|
||||
mRenderTarget = NULL;
|
||||
mRTTexHandle = NULL;
|
||||
|
||||
// Unregister texture callback
|
||||
GFXTextureManager::removeEventDelegate( this, &GFXGeneralFence::_onTextureEvent );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void GFXGeneralFence::_init()
|
||||
{
|
||||
// Register texture callback to re-create resources
|
||||
if ( !mInitialized )
|
||||
GFXTextureManager::addEventDelegate( this, &GFXGeneralFence::_onTextureEvent );
|
||||
|
||||
// Set this to true for error checking
|
||||
mInitialized = true;
|
||||
|
||||
// Allocate resources
|
||||
mInitialized &= mRTTexHandle.set( 2, 2, GFXFormatR8G8B8X8, &GFXDefaultRenderTargetProfile, avar("%s() - mInitialized (line %d)", __FUNCTION__, __LINE__) );
|
||||
mRenderTarget = GFX->allocRenderToTextureTarget();
|
||||
mInitialized &= ( mRenderTarget != NULL );
|
||||
|
||||
GFXStateBlockDesc d;
|
||||
mRenderSB = GFX->createStateBlock(d);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void GFXGeneralFence::issue()
|
||||
{
|
||||
PROFILE_SCOPE(GFXGeneralFence_Issue);
|
||||
|
||||
// Resource creation will be done on first call to issue()
|
||||
if( !mInitialized )
|
||||
_init();
|
||||
|
||||
// If we can't init, return.
|
||||
if(!mInitialized)
|
||||
return;
|
||||
|
||||
AssertFatal( mInitialized, "Error occured during GFXGeneralFence::_init, sorry I can't be more specific, break and debug." );
|
||||
|
||||
RectI viewport = GFX->getViewport();
|
||||
|
||||
GFX->pushActiveRenderTarget();
|
||||
mRenderTarget->attachTexture( GFXTextureTarget::Color0, mRTTexHandle );
|
||||
GFX->setActiveRenderTarget( mRenderTarget );
|
||||
|
||||
// Set-up states
|
||||
GFX->setStateBlock(mRenderSB);
|
||||
GFX->pushWorldMatrix();
|
||||
GFX->setWorldMatrix( MatrixF::Identity );
|
||||
|
||||
// CodeReview: We can re-do this with a static vertex buffer at some point. [5/9/2007 Pat]
|
||||
PrimBuild::begin( GFXTriangleList, 3 );
|
||||
PrimBuild::vertex2f( 0.f, 0.f );
|
||||
PrimBuild::vertex2f( 0.f, 1.f );
|
||||
PrimBuild::vertex2f( 1.f, 0.f );
|
||||
PrimBuild::end();
|
||||
|
||||
GFX->popWorldMatrix();
|
||||
GFX->popActiveRenderTarget();
|
||||
|
||||
GFX->setViewport(viewport);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void GFXGeneralFence::block()
|
||||
{
|
||||
PROFILE_SCOPE(GFXGeneralFence_block);
|
||||
if( !mInitialized )
|
||||
return;
|
||||
|
||||
// We have to deal with the case where the lock fails (usually due to
|
||||
// a device reset).
|
||||
if(mRTTexHandle.lock())
|
||||
mRTTexHandle.unlock();
|
||||
}
|
||||
|
||||
void GFXGeneralFence::_onTextureEvent( GFXTexCallbackCode code )
|
||||
{
|
||||
switch( code )
|
||||
{
|
||||
case GFXZombify:
|
||||
mRTTexHandle = NULL;
|
||||
break;
|
||||
|
||||
case GFXResurrect:
|
||||
mRTTexHandle.set( 2, 2, GFXFormatR8G8B8X8, &GFXDefaultRenderTargetProfile, avar("%s() - GFXGeneralFence->mRTTexHandle (line %d)", __FUNCTION__, __LINE__) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GFXGeneralFence::zombify()
|
||||
{
|
||||
mRTTexHandle = NULL;
|
||||
}
|
||||
|
||||
void GFXGeneralFence::resurrect()
|
||||
{
|
||||
mRTTexHandle.set( 2, 2, GFXFormatR8G8B8X8, &GFXDefaultRenderTargetProfile, avar("%s() - mRTTexHandle (line %d)", __FUNCTION__, __LINE__) );
|
||||
}
|
||||
|
||||
const String GFXGeneralFence::describeSelf() const
|
||||
{
|
||||
// We've got nothing
|
||||
return String();
|
||||
}
|
||||
105
Engine/source/gfx/gfxFence.h
Normal file
105
Engine/source/gfx/gfxFence.h
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GFXFENCE_H_
|
||||
#define _GFXFENCE_H_
|
||||
|
||||
#ifndef _GFXDEVICE_H_
|
||||
#include "gfx/gfxDevice.h"
|
||||
#endif
|
||||
|
||||
|
||||
///
|
||||
class GFXFence : public GFXResource
|
||||
{
|
||||
protected:
|
||||
|
||||
GFXDevice *mDevice;
|
||||
|
||||
public:
|
||||
|
||||
/// The states returned by getStatus()
|
||||
enum FenceStatus
|
||||
{
|
||||
Unset, ///< The fence has not been set
|
||||
Pending, ///< The fence has been set and has not been hit
|
||||
Processed, ///< The fence has been processed
|
||||
Unsupported ///< A non-blocking query of fence status is not supported by the implementation
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
GFXFence( GFXDevice *device ) : mDevice( device ) {};
|
||||
virtual ~GFXFence(){};
|
||||
|
||||
/// This method inserts the fence into the command buffer
|
||||
virtual void issue() = 0;
|
||||
|
||||
// CodeReview: Do we need a remove() [5/10/2007 Pat]
|
||||
|
||||
/// This is a non-blocking call to get the status of the fence
|
||||
/// @see GFXFence::FenceStatus
|
||||
virtual FenceStatus getStatus() const = 0;
|
||||
|
||||
/// This method will not return until the fence has been processed by the GPU
|
||||
virtual void block() = 0;
|
||||
};
|
||||
|
||||
|
||||
///
|
||||
class GFXGeneralFence : public GFXFence
|
||||
{
|
||||
protected:
|
||||
|
||||
bool mInitialized;
|
||||
GFXTextureTargetRef mRenderTarget;
|
||||
GFXTexHandle mRTTexHandle;
|
||||
GFXStateBlockRef mRenderSB;
|
||||
|
||||
void _init();
|
||||
|
||||
/// The callback used to get texture events.
|
||||
/// @see GFXTextureManager::addEventDelegate
|
||||
void _onTextureEvent( GFXTexCallbackCode code );
|
||||
|
||||
public:
|
||||
|
||||
GFXGeneralFence( GFXDevice *device )
|
||||
: GFXFence( device ),
|
||||
mInitialized( false )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~GFXGeneralFence();
|
||||
|
||||
virtual void issue();
|
||||
virtual FenceStatus getStatus() const { return GFXFence::Unsupported; };
|
||||
virtual void block();
|
||||
|
||||
// GFXResource interface
|
||||
virtual void zombify();
|
||||
virtual void resurrect();
|
||||
/// The resource should put a description of itself (number of vertices, size/width of texture, etc.) in buffer
|
||||
virtual const String describeSelf() const;
|
||||
};
|
||||
|
||||
#endif // _GFXFENCE_H_
|
||||
242
Engine/source/gfx/gfxFontRenderBatcher.cpp
Normal file
242
Engine/source/gfx/gfxFontRenderBatcher.cpp
Normal file
|
|
@ -0,0 +1,242 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "gfx/gfxFontRenderBatcher.h"
|
||||
#include "gfx/gFont.h"
|
||||
|
||||
FontRenderBatcher::FontRenderBatcher() : mStorage(8096)
|
||||
{
|
||||
if (!mFontSB)
|
||||
{
|
||||
GFXStateBlockDesc f;
|
||||
f.zDefined = true;
|
||||
f.zEnable = false;
|
||||
f.zWriteEnable = false;
|
||||
f.cullDefined = true;
|
||||
f.cullMode = GFXCullNone;
|
||||
f.blendDefined = true;
|
||||
f.blendEnable = true;
|
||||
f.blendSrc = GFXBlendSrcAlpha;
|
||||
f.blendDest = GFXBlendInvSrcAlpha;
|
||||
f.samplersDefined = true;
|
||||
f.samplers[0].alphaOp = GFXTOPModulate;
|
||||
f.samplers[0].magFilter = GFXTextureFilterPoint;
|
||||
f.samplers[0].minFilter = GFXTextureFilterPoint;
|
||||
f.samplers[0].addressModeU = GFXAddressClamp;
|
||||
f.samplers[0].addressModeV = GFXAddressClamp;
|
||||
f.samplers[0].alphaArg1 = GFXTATexture;
|
||||
f.samplers[0].alphaArg2 = GFXTADiffuse;
|
||||
// This is an add operation because in D3D, when a texture of format D3DFMT_A8
|
||||
// is used, the RGB channels are all set to 0. Therefore a modulate would
|
||||
// result in the text always being black. This may not be the case in OpenGL
|
||||
// so it may have to change. -bramage
|
||||
f.samplers[0].textureColorOp = GFXTOPAdd;
|
||||
mFontSB = GFX->createStateBlock(f);
|
||||
}
|
||||
}
|
||||
|
||||
void FontRenderBatcher::render( F32 rot, const Point2F &offset )
|
||||
{
|
||||
if( mLength == 0 )
|
||||
return;
|
||||
|
||||
GFX->setStateBlock(mFontSB);
|
||||
GFX->disableShaders();
|
||||
for(U32 i = 0; i < GFX->getNumSamplers(); i++)
|
||||
GFX->setTexture(i, NULL);
|
||||
|
||||
MatrixF rotMatrix;
|
||||
|
||||
bool doRotation = rot != 0.f;
|
||||
if(doRotation)
|
||||
rotMatrix.set( EulerF( 0.0, 0.0, mDegToRad( rot ) ) );
|
||||
|
||||
// Write verts out.
|
||||
U32 currentPt = 0;
|
||||
GFXVertexBufferHandle<GFXVertexPCT> verts(GFX, mLength * 6, GFXBufferTypeVolatile);
|
||||
verts.lock();
|
||||
|
||||
for( S32 i = 0; i < mSheets.size(); i++ )
|
||||
{
|
||||
// Do some early outs...
|
||||
if(!mSheets[i])
|
||||
continue;
|
||||
|
||||
if(!mSheets[i]->numChars)
|
||||
continue;
|
||||
|
||||
mSheets[i]->startVertex = currentPt;
|
||||
const GFXTextureObject *tex = mFont->getTextureHandle(i);
|
||||
|
||||
for( S32 j = 0; j < mSheets[i]->numChars; j++ )
|
||||
{
|
||||
// Get some general info to proceed with...
|
||||
const CharMarker &m = mSheets[i]->charIndex[j];
|
||||
const PlatformFont::CharInfo &ci = mFont->getCharInfo( m.c );
|
||||
|
||||
// Where are we drawing it?
|
||||
F32 drawY = offset.y + mFont->getBaseline() - ci.yOrigin * TEXT_MAG;
|
||||
F32 drawX = offset.x + m.x + ci.xOrigin;
|
||||
|
||||
// Figure some values.
|
||||
const F32 texWidth = (F32)tex->getWidth();
|
||||
const F32 texHeight = (F32)tex->getHeight();
|
||||
const F32 texLeft = (F32)(ci.xOffset) / texWidth;
|
||||
const F32 texRight = (F32)(ci.xOffset + ci.width) / texWidth;
|
||||
const F32 texTop = (F32)(ci.yOffset) / texHeight;
|
||||
const F32 texBottom = (F32)(ci.yOffset + ci.height) / texHeight;
|
||||
|
||||
const F32 fillConventionOffset = GFX->getFillConventionOffset();
|
||||
const F32 screenLeft = drawX - fillConventionOffset;
|
||||
const F32 screenRight = drawX - fillConventionOffset + ci.width * TEXT_MAG;
|
||||
const F32 screenTop = drawY - fillConventionOffset;
|
||||
const F32 screenBottom = drawY - fillConventionOffset + ci.height * TEXT_MAG;
|
||||
|
||||
// Build our vertices. We NEVER read back from the buffer, that's
|
||||
// incredibly slow, so for rotation do it into tmp. This code is
|
||||
// ugly as sin.
|
||||
Point3F tmp;
|
||||
|
||||
tmp.set( screenLeft, screenTop, 0.f );
|
||||
if(doRotation)
|
||||
rotMatrix.mulP( tmp, &verts[currentPt].point);
|
||||
else
|
||||
verts[currentPt].point = tmp;
|
||||
verts[currentPt].color = m.color;
|
||||
verts[currentPt].texCoord.set( texLeft, texTop );
|
||||
currentPt++;
|
||||
|
||||
tmp.set( screenLeft, screenBottom, 0.f );
|
||||
if(doRotation)
|
||||
rotMatrix.mulP( tmp, &verts[currentPt].point);
|
||||
else
|
||||
verts[currentPt].point = tmp;
|
||||
verts[currentPt].color = m.color;
|
||||
verts[currentPt].texCoord.set( texLeft, texBottom );
|
||||
currentPt++;
|
||||
|
||||
tmp.set( screenRight, screenBottom, 0.f );
|
||||
if(doRotation)
|
||||
rotMatrix.mulP( tmp, &verts[currentPt].point);
|
||||
else
|
||||
verts[currentPt].point = tmp;
|
||||
verts[currentPt].color = m.color;
|
||||
verts[currentPt].texCoord.set( texRight, texBottom );
|
||||
currentPt++;
|
||||
|
||||
tmp.set( screenRight, screenBottom, 0.f );
|
||||
if(doRotation)
|
||||
rotMatrix.mulP( tmp, &verts[currentPt].point);
|
||||
else
|
||||
verts[currentPt].point = tmp;
|
||||
verts[currentPt].color = m.color;
|
||||
verts[currentPt].texCoord.set( texRight, texBottom );
|
||||
currentPt++;
|
||||
|
||||
tmp.set( screenRight, screenTop, 0.f );
|
||||
if(doRotation)
|
||||
rotMatrix.mulP( tmp, &verts[currentPt].point);
|
||||
else
|
||||
verts[currentPt].point = tmp;
|
||||
verts[currentPt].color = m.color;
|
||||
verts[currentPt].texCoord.set( texRight, texTop );
|
||||
currentPt++;
|
||||
|
||||
tmp.set( screenLeft, screenTop, 0.f );
|
||||
if(doRotation)
|
||||
rotMatrix.mulP( tmp, &verts[currentPt].point);
|
||||
else
|
||||
verts[currentPt].point = tmp;
|
||||
verts[currentPt].color = m.color;
|
||||
verts[currentPt].texCoord.set( texLeft, texTop );
|
||||
currentPt++;
|
||||
}
|
||||
}
|
||||
|
||||
verts->unlock();
|
||||
|
||||
AssertFatal(currentPt <= mLength * 6, "FontRenderBatcher::render - too many verts for length of string!");
|
||||
|
||||
GFX->setVertexBuffer(verts);
|
||||
|
||||
// Now do an optimal render!
|
||||
for( S32 i = 0; i < mSheets.size(); i++ )
|
||||
{
|
||||
if(!mSheets[i])
|
||||
continue;
|
||||
|
||||
if(!mSheets[i]->numChars )
|
||||
continue;
|
||||
|
||||
GFX->setupGenericShaders( GFXDevice::GSAddColorTexture );
|
||||
GFX->setTexture( 0, mFont->getTextureHandle(i) );
|
||||
GFX->drawPrimitive(GFXTriangleList, mSheets[i]->startVertex, mSheets[i]->numChars * 2);
|
||||
}
|
||||
}
|
||||
|
||||
void FontRenderBatcher::queueChar( UTF16 c, S32 ¤tX, GFXVertexColor ¤tColor )
|
||||
{
|
||||
const PlatformFont::CharInfo &ci = mFont->getCharInfo( c );
|
||||
U32 sidx = ci.bitmapIndex;
|
||||
|
||||
if( ci.width != 0 && ci.height != 0 )
|
||||
{
|
||||
SheetMarker &sm = getSheetMarker(sidx);
|
||||
|
||||
CharMarker &m = sm.charIndex[sm.numChars];
|
||||
sm.numChars++;
|
||||
|
||||
m.c = c;
|
||||
m.x = (F32)currentX;
|
||||
m.color = currentColor;
|
||||
}
|
||||
|
||||
currentX += ci.xIncrement;
|
||||
}
|
||||
|
||||
FontRenderBatcher::SheetMarker & FontRenderBatcher::getSheetMarker( U32 sheetID )
|
||||
{
|
||||
// Allocate if it doesn't exist...
|
||||
if(mSheets.size() <= sheetID || !mSheets[sheetID])
|
||||
{
|
||||
if(sheetID >= mSheets.size())
|
||||
mSheets.setSize(sheetID+1);
|
||||
|
||||
S32 size = sizeof( SheetMarker) + mLength * sizeof( CharMarker );
|
||||
mSheets[sheetID] = (SheetMarker *)mStorage.alloc(size);
|
||||
mSheets[sheetID]->numChars = 0;
|
||||
mSheets[sheetID]->startVertex = 0; // cosmetic initialization
|
||||
}
|
||||
|
||||
return *mSheets[sheetID];
|
||||
}
|
||||
|
||||
void FontRenderBatcher::init( GFont *font, U32 n )
|
||||
{
|
||||
// Clear out batched results
|
||||
dMemset(mSheets.address(), 0, mSheets.memSize());
|
||||
mSheets.clear();
|
||||
mStorage.freeBlocks(true);
|
||||
|
||||
mFont = font;
|
||||
mLength = n;
|
||||
}
|
||||
67
Engine/source/gfx/gfxFontRenderBatcher.h
Normal file
67
Engine/source/gfx/gfxFontRenderBatcher.h
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GFXFONTBATCHER_H_
|
||||
#define _GFXFONTBATCHER_H_
|
||||
|
||||
#include "core/dataChunker.h"
|
||||
#include "gfx/gfxDevice.h"
|
||||
#include "gfx/gFont.h"
|
||||
|
||||
#define TEXT_MAG 1
|
||||
|
||||
class FontRenderBatcher
|
||||
{
|
||||
struct CharMarker
|
||||
{
|
||||
S32 c;
|
||||
F32 x;
|
||||
GFXVertexColor color;
|
||||
PlatformFont::CharInfo *ci;
|
||||
};
|
||||
|
||||
struct SheetMarker
|
||||
{
|
||||
S32 numChars;
|
||||
S32 startVertex;
|
||||
CharMarker charIndex[1];
|
||||
};
|
||||
|
||||
DataChunker mStorage;
|
||||
Vector<SheetMarker *> mSheets;
|
||||
GFont *mFont;
|
||||
U32 mLength;
|
||||
GFXStateBlockRef mFontSB;
|
||||
|
||||
SheetMarker &getSheetMarker(U32 sheetID);
|
||||
|
||||
public:
|
||||
FontRenderBatcher();
|
||||
|
||||
void init(GFont *font, U32 n);
|
||||
|
||||
void queueChar(UTF16 c, S32 ¤tX, GFXVertexColor ¤tColor);
|
||||
|
||||
void render(F32 rot, const Point2F &offset );
|
||||
};
|
||||
|
||||
#endif
|
||||
90
Engine/source/gfx/gfxFormatUtils.cpp
Normal file
90
Engine/source/gfx/gfxFormatUtils.cpp
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "gfx/gfxFormatUtils.h"
|
||||
#include "gfx/gfxDevice.h"
|
||||
|
||||
|
||||
//RDTODO: complete format infos
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
GFXFormatInfo::Data GFXFormatInfo::smFormatInfos[ GFXFormat_COUNT ] =
|
||||
{
|
||||
// 8 bit texture formats...
|
||||
GFXFormatInfo::Data( 1, false, false, false ), // GFXFormatA8
|
||||
GFXFormatInfo::Data( 1, false, false, false ), // GFXFormatL8
|
||||
GFXFormatInfo::Data( 1, true, false, false ), // GFXFormatA4L4
|
||||
|
||||
// 16 bit texture formats...
|
||||
GFXFormatInfo::Data( 2, false, false, false ), // GFXFormatR5G6B5
|
||||
GFXFormatInfo::Data( 2, true, false, false ), // GFXFormatR5G5B5A1
|
||||
GFXFormatInfo::Data( 2, true, false, false ), // GFXFormatA8L8
|
||||
GFXFormatInfo::Data( 2, false, false, false ), // GFXFormatL16
|
||||
GFXFormatInfo::Data( 2, false, false, false ), // GFXFormatR16F
|
||||
GFXFormatInfo::Data( 2, false, false, false ), // GFXFormatD16
|
||||
|
||||
// 24 bit texture formats...
|
||||
GFXFormatInfo::Data( 3, false, false, false ), // GFXFormatR8G8B8
|
||||
|
||||
// 32 bit texture formats...
|
||||
GFXFormatInfo::Data( 4, true, false, false ), // GFXFormatR8G8B8A8
|
||||
GFXFormatInfo::Data( 4, false, false, false ), // GFXFormatR8G8B8X8
|
||||
GFXFormatInfo::Data( 4, false, false, false ), // GFXFormatR32F
|
||||
GFXFormatInfo::Data( 4, false, false, false ), // GFXFormatR16G16
|
||||
GFXFormatInfo::Data( 4, false, false, true ), // GFXFormatR16G16F
|
||||
GFXFormatInfo::Data( 4, true, false, false ), // GFXFormatR10G10B10A2
|
||||
GFXFormatInfo::Data( 4, false, false, false ), // GFXFormatD32
|
||||
GFXFormatInfo::Data( 4, false, false, false ), // GFXFormatD24X8
|
||||
GFXFormatInfo::Data( 4, false, false, false ), // GFXFormatD24S8
|
||||
GFXFormatInfo::Data( 4, false, false, false ), // GFXFormatD24FS8
|
||||
|
||||
// 64 bit texture formats...
|
||||
GFXFormatInfo::Data( 8, true, false, false ), // GFXFormatR16G16B16A16
|
||||
GFXFormatInfo::Data( 8, true, false, true ), // GFXFormatR16G16B16A16F
|
||||
|
||||
// 128 bit texture formats...
|
||||
GFXFormatInfo::Data( 16, true, false, true ), // GFXFormatR32G32B32A32F
|
||||
|
||||
// Compressed formats...
|
||||
GFXFormatInfo::Data( 0, false, true, false ), // GFXFormatDXT1
|
||||
GFXFormatInfo::Data( 0, true, true, false ), // GFXFormatDXT2
|
||||
GFXFormatInfo::Data( 0, true, true, false ), // GFXFormatDXT3
|
||||
GFXFormatInfo::Data( 0, true, true, false ), // GFXFormatDXT4
|
||||
GFXFormatInfo::Data( 0, true, true, false ), // GFXFormatDXT5
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void GFXCopyPixels( GFXFormat fromFormat, U32 fromWidth, U32 fromHeight, U8* fromData,
|
||||
GFXFormat toFormat, U32 toWidth, U32 toHeight, U8* toData )
|
||||
{
|
||||
if( fromFormat == toFormat
|
||||
&& fromWidth == toWidth
|
||||
&& fromHeight == fromHeight )
|
||||
dMemcpy( toData, fromData, fromWidth * fromHeight * GFXFormatInfo( fromFormat ).getBytesPerPixel() );
|
||||
else
|
||||
{
|
||||
AssertFatal( false, "Not implemented" );
|
||||
}
|
||||
}
|
||||
143
Engine/source/gfx/gfxFormatUtils.h
Normal file
143
Engine/source/gfx/gfxFormatUtils.h
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GFXFORMATUTILS_H_
|
||||
#define _GFXFORMATUTILS_H_
|
||||
|
||||
#ifndef _PLATFORM_H_
|
||||
#include "platform/platform.h"
|
||||
#endif
|
||||
#ifndef _GFXENUMS_H_
|
||||
#include "gfx/gfxEnums.h"
|
||||
#endif
|
||||
#ifndef _COLOR_H_
|
||||
#include "core/color.h"
|
||||
#endif
|
||||
|
||||
|
||||
//WIP: still in early stages
|
||||
|
||||
|
||||
|
||||
/// Some information about a GFXFormat.
|
||||
struct GFXFormatInfo
|
||||
{
|
||||
protected:
|
||||
|
||||
struct Data
|
||||
{
|
||||
/// Bytes per single pixel.
|
||||
U32 mBytesPerPixel;
|
||||
|
||||
/// If true, format has alpha channel.
|
||||
bool mHasAlpha;
|
||||
|
||||
/// If true, format uses compression.
|
||||
bool mIsCompressed;
|
||||
|
||||
/// If true, channels are in floating-point.
|
||||
bool mIsFloatingPoint;
|
||||
|
||||
Data() {}
|
||||
Data( U32 bpp, bool hasAlpha = false, bool isCompressed = false, bool isFP = false )
|
||||
: mBytesPerPixel( bpp ),
|
||||
mHasAlpha( hasAlpha ),
|
||||
mIsCompressed( isCompressed ),
|
||||
mIsFloatingPoint( isFP ) {}
|
||||
};
|
||||
|
||||
GFXFormat mFormat;
|
||||
|
||||
static Data smFormatInfos[ GFXFormat_COUNT ];
|
||||
|
||||
public:
|
||||
|
||||
GFXFormatInfo( GFXFormat format )
|
||||
: mFormat( format ) {}
|
||||
|
||||
/// @return the number of bytes per pixel in this format.
|
||||
/// @note For compressed formats that can't give a fixed value per pixel,
|
||||
/// this will be zero.
|
||||
U32 getBytesPerPixel() const { return smFormatInfos[ mFormat ].mBytesPerPixel; }
|
||||
|
||||
/// @return true if the format has an alpha channel.
|
||||
bool hasAlpha() const { return smFormatInfos[ mFormat ].mHasAlpha; }
|
||||
|
||||
/// @return true if format uses compression.
|
||||
bool isCompressed() const { return smFormatInfos[ mFormat ].mIsCompressed; }
|
||||
|
||||
/// @return true if channels are stored in floating-point format.
|
||||
bool isFloatingPoint() const { return smFormatInfos[ mFormat ].mIsFloatingPoint; }
|
||||
};
|
||||
|
||||
|
||||
#if 0
|
||||
///
|
||||
extern void GFXCopyPixels( GFXFormat fromFormat, U32 fromWidth, U32 fromHeight, U8* fromData,
|
||||
GFXFormat toFormat, U32 toWidth, U32 toHeight, U8* toData );
|
||||
#endif
|
||||
|
||||
|
||||
inline void GFXPackPixel( GFXFormat format, U8*& ptr, U8 red, U8 green, U8 blue, U8 alpha, bool leastSignficantFirst = true )
|
||||
{
|
||||
switch( format )
|
||||
{
|
||||
case GFXFormatR8G8B8A8:
|
||||
if( leastSignficantFirst )
|
||||
{
|
||||
ptr[ 0 ] = blue;
|
||||
ptr[ 1 ] = green;
|
||||
ptr[ 2 ] = red;
|
||||
ptr[ 3 ] = alpha;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr[ 0 ] = red;
|
||||
ptr[ 1 ] = green;
|
||||
ptr[ 2 ] = blue;
|
||||
ptr[ 3 ] = alpha;
|
||||
}
|
||||
ptr += 4;
|
||||
break;
|
||||
|
||||
case GFXFormatR8G8B8:
|
||||
if( leastSignficantFirst )
|
||||
{
|
||||
ptr[ 0 ] = blue;
|
||||
ptr[ 1 ] = green;
|
||||
ptr[ 2 ] = red;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr[ 0 ] = red;
|
||||
ptr[ 1 ] = green;
|
||||
ptr[ 2 ] = blue;
|
||||
}
|
||||
ptr += 3;
|
||||
break;
|
||||
|
||||
default:
|
||||
AssertISV( false, "GFXPackPixel() - pixel format not implemented." );
|
||||
}
|
||||
}
|
||||
|
||||
#endif // _GFXFORMATUTILS_H_
|
||||
499
Engine/source/gfx/gfxInit.cpp
Normal file
499
Engine/source/gfx/gfxInit.cpp
Normal file
|
|
@ -0,0 +1,499 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "gfx/gfxInit.h"
|
||||
|
||||
#include "gfx/gfxTextureManager.h"
|
||||
#include "gfx/gfxAPI.h"
|
||||
#include "console/console.h"
|
||||
#include "windowManager/platformWindowMgr.h"
|
||||
#include "core/module.h"
|
||||
|
||||
|
||||
Vector<GFXAdapter*> GFXInit::smAdapters( __FILE__, __LINE__ );
|
||||
GFXInit::RegisterDeviceSignal* GFXInit::smRegisterDeviceSignal;
|
||||
|
||||
|
||||
MODULE_BEGIN( GFX )
|
||||
|
||||
MODULE_INIT
|
||||
{
|
||||
GFXInit::init();
|
||||
if( engineAPI::gUseConsoleInterop )
|
||||
GFXDevice::initConsole();
|
||||
GFXTextureManager::init();
|
||||
}
|
||||
|
||||
MODULE_SHUTDOWN
|
||||
{
|
||||
GFXDevice::destroy();
|
||||
GFXInit::cleanup();
|
||||
}
|
||||
|
||||
MODULE_END;
|
||||
|
||||
IMPLEMENT_STATIC_CLASS( GFXInit, GFXAPI,
|
||||
"Functions for tracking GFX adapters and initializing them into devices."
|
||||
);
|
||||
|
||||
ConsoleDoc(
|
||||
"@class GFXInit\n"
|
||||
"@ingroup GFX\n"
|
||||
"@brief Functions for tracking GFX adapters and initializing them into devices.\n"
|
||||
);
|
||||
|
||||
inline static void _GFXInitReportAdapters(Vector<GFXAdapter*> &adapters)
|
||||
{
|
||||
for (U32 i = 0; i < adapters.size(); i++)
|
||||
{
|
||||
switch (adapters[i]->mType)
|
||||
{
|
||||
case Direct3D9:
|
||||
Con::printf(" Direct 3D (version 9.x) device found");
|
||||
break;
|
||||
case OpenGL:
|
||||
Con::printf(" OpenGL device found");
|
||||
break;
|
||||
case NullDevice:
|
||||
Con::printf(" Null device found");
|
||||
break;
|
||||
case Direct3D8:
|
||||
Con::printf(" Direct 3D (version 8.1) device found");
|
||||
break;
|
||||
default :
|
||||
Con::printf(" Unknown device found");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline static void _GFXInitGetInitialRes(GFXVideoMode &vm, const Point2I &initialSize)
|
||||
{
|
||||
const U32 kDefaultWindowSizeX = 800;
|
||||
const U32 kDefaultWindowSizeY = 600;
|
||||
const bool kDefaultFullscreen = false;
|
||||
const U32 kDefaultBitDepth = 32;
|
||||
const U32 kDefaultRefreshRate = 60;
|
||||
|
||||
// cache the desktop size of the main screen
|
||||
GFXVideoMode desktopVm = GFXInit::getDesktopResolution();
|
||||
|
||||
// load pref variables, properly choose windowed / fullscreen
|
||||
const String resString = Con::getVariable("$pref::Video::mode");
|
||||
|
||||
// Set defaults into the video mode, then have it parse the user string.
|
||||
vm.resolution.x = kDefaultWindowSizeX;
|
||||
vm.resolution.y = kDefaultWindowSizeY;
|
||||
vm.fullScreen = kDefaultFullscreen;
|
||||
vm.bitDepth = kDefaultBitDepth;
|
||||
vm.refreshRate = kDefaultRefreshRate;
|
||||
vm.wideScreen = false;
|
||||
|
||||
vm.parseFromString(resString);
|
||||
}
|
||||
|
||||
GFXInit::RegisterDeviceSignal& GFXInit::getRegisterDeviceSignal()
|
||||
{
|
||||
if (smRegisterDeviceSignal)
|
||||
return *smRegisterDeviceSignal;
|
||||
smRegisterDeviceSignal = new RegisterDeviceSignal();
|
||||
return *smRegisterDeviceSignal;
|
||||
}
|
||||
|
||||
void GFXInit::init()
|
||||
{
|
||||
// init only once.
|
||||
static bool doneOnce = false;
|
||||
if(doneOnce)
|
||||
return;
|
||||
doneOnce = true;
|
||||
|
||||
Con::printf( "GFX Init:" );
|
||||
|
||||
//find our adapters
|
||||
Vector<GFXAdapter*> adapters( __FILE__, __LINE__ );
|
||||
GFXInit::enumerateAdapters();
|
||||
GFXInit::getAdapters(&adapters);
|
||||
|
||||
if(!adapters.size())
|
||||
Con::errorf("Could not find a display adapter");
|
||||
|
||||
//loop through and tell the user what kind of adapters we found
|
||||
_GFXInitReportAdapters(adapters);
|
||||
Con::printf( "" );
|
||||
}
|
||||
|
||||
void GFXInit::cleanup()
|
||||
{
|
||||
while( smAdapters.size() )
|
||||
{
|
||||
GFXAdapter* adapter = smAdapters.last();
|
||||
smAdapters.decrement();
|
||||
delete adapter;
|
||||
}
|
||||
|
||||
if( smRegisterDeviceSignal )
|
||||
SAFE_DELETE( smRegisterDeviceSignal );
|
||||
}
|
||||
|
||||
GFXAdapter* GFXInit::getAdapterOfType( GFXAdapterType type )
|
||||
{
|
||||
GFXAdapter* adapter = NULL;
|
||||
for( U32 i = 0; i < smAdapters.size(); i++ )
|
||||
{
|
||||
if( smAdapters[i]->mType == type )
|
||||
{
|
||||
adapter = smAdapters[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return adapter;
|
||||
}
|
||||
|
||||
GFXAdapter* GFXInit::chooseAdapter( GFXAdapterType type)
|
||||
{
|
||||
GFXAdapter* adapter = GFXInit::getAdapterOfType(type);
|
||||
|
||||
if(!adapter && type != OpenGL)
|
||||
{
|
||||
Con::errorf("The requested renderer, %s, doesn't seem to be available."
|
||||
" Trying the default, OpenGL.", getAdapterNameFromType(type));
|
||||
adapter = GFXInit::getAdapterOfType(OpenGL);
|
||||
}
|
||||
|
||||
if(!adapter)
|
||||
{
|
||||
Con::errorf("The OpenGL renderer doesn't seem to be available. Trying the GFXNulDevice.");
|
||||
adapter = GFXInit::getAdapterOfType(NullDevice);
|
||||
}
|
||||
|
||||
AssertFatal( adapter, "There is no rendering device available whatsoever.");
|
||||
return adapter;
|
||||
}
|
||||
|
||||
const char* GFXInit::getAdapterNameFromType(GFXAdapterType type)
|
||||
{
|
||||
static const char* _names[] = { "OpenGL", "D3D9", "D3D8", "NullDevice", "Xenon" };
|
||||
|
||||
if( type < 0 || type >= GFXAdapterType_Count )
|
||||
{
|
||||
Con::errorf( "GFXInit::getAdapterNameFromType - Invalid renderer type, defaulting to OpenGL" );
|
||||
return _names[OpenGL];
|
||||
}
|
||||
|
||||
return _names[type];
|
||||
}
|
||||
|
||||
GFXAdapterType GFXInit::getAdapterTypeFromName(const char* name)
|
||||
{
|
||||
S32 ret = -1;
|
||||
for(S32 i = 0; i < GFXAdapterType_Count; i++)
|
||||
{
|
||||
if( !dStricmp( getAdapterNameFromType((GFXAdapterType)i), name ) )
|
||||
ret = i;
|
||||
}
|
||||
|
||||
if( ret == -1 )
|
||||
{
|
||||
Con::errorf( "GFXInit::getAdapterTypeFromName - Invalid renderer name, defaulting to D3D9" );
|
||||
ret = Direct3D9;
|
||||
}
|
||||
|
||||
return (GFXAdapterType)ret;
|
||||
}
|
||||
|
||||
GFXAdapter *GFXInit::getBestAdapterChoice()
|
||||
{
|
||||
// Get the user's preference for device...
|
||||
const String renderer = Con::getVariable("$pref::Video::displayDevice");
|
||||
GFXAdapterType adapterType = getAdapterTypeFromName(renderer);
|
||||
GFXAdapter *adapter = chooseAdapter(adapterType);
|
||||
|
||||
// Did they have one? Return it.
|
||||
if(adapter)
|
||||
return adapter;
|
||||
|
||||
// Didn't have one. So make it up. Find the highest SM available. Prefer
|
||||
// D3D to GL because if we have a D3D device at all we're on windows,
|
||||
// and in an unknown situation on Windows D3D is probably the safest bet.
|
||||
//
|
||||
// If D3D is unavailable, we're not on windows, so GL is de facto the
|
||||
// best choice!
|
||||
F32 highestSM9 = 0.f, highestSMGL = 0.f;
|
||||
GFXAdapter *foundAdapter8 = NULL, *foundAdapter9 = NULL,
|
||||
*foundAdapterGL = NULL;
|
||||
|
||||
for(S32 i=0; i<smAdapters.size(); i++)
|
||||
{
|
||||
GFXAdapter *currAdapter = smAdapters[i];
|
||||
switch(currAdapter->mType)
|
||||
{
|
||||
case Direct3D9:
|
||||
if(currAdapter->mShaderModel > highestSM9)
|
||||
{
|
||||
highestSM9 = currAdapter->mShaderModel;
|
||||
foundAdapter9 = currAdapter;
|
||||
}
|
||||
break;
|
||||
|
||||
case OpenGL:
|
||||
if(currAdapter->mShaderModel > highestSMGL)
|
||||
{
|
||||
highestSMGL = currAdapter->mShaderModel;
|
||||
foundAdapterGL = currAdapter;
|
||||
}
|
||||
break;
|
||||
|
||||
case Direct3D8:
|
||||
if(!foundAdapter8)
|
||||
foundAdapter8 = currAdapter;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Return best found in order DX9, GL, DX8.
|
||||
if(foundAdapter9)
|
||||
return foundAdapter9;
|
||||
|
||||
if(foundAdapterGL)
|
||||
return foundAdapterGL;
|
||||
|
||||
if(foundAdapter8)
|
||||
return foundAdapter8;
|
||||
|
||||
// Uh oh - we didn't find anything. Grab whatever we can that's not Null...
|
||||
for(S32 i=0; i<smAdapters.size(); i++)
|
||||
if(smAdapters[i]->mType != NullDevice)
|
||||
return smAdapters[i];
|
||||
|
||||
// Dare we return a null device? No. Just return NULL.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GFXVideoMode GFXInit::getInitialVideoMode()
|
||||
{
|
||||
GFXVideoMode vm;
|
||||
_GFXInitGetInitialRes(vm, Point2I(800,600));
|
||||
return vm;
|
||||
}
|
||||
|
||||
S32 GFXInit::getAdapterCount()
|
||||
{
|
||||
return smAdapters.size();
|
||||
}
|
||||
|
||||
void GFXInit::getAdapters(Vector<GFXAdapter*> *adapters)
|
||||
{
|
||||
adapters->clear();
|
||||
for (U32 k = 0; k < smAdapters.size(); k++)
|
||||
adapters->push_back(smAdapters[k]);
|
||||
}
|
||||
|
||||
GFXVideoMode GFXInit::getDesktopResolution()
|
||||
{
|
||||
GFXVideoMode resVm;
|
||||
|
||||
// Retrieve Resolution Information.
|
||||
resVm.bitDepth = WindowManager->getDesktopBitDepth();
|
||||
resVm.resolution = WindowManager->getDesktopResolution();
|
||||
resVm.fullScreen = false;
|
||||
resVm.refreshRate = 60;
|
||||
|
||||
// Return results
|
||||
return resVm;
|
||||
}
|
||||
|
||||
void GFXInit::enumerateAdapters()
|
||||
{
|
||||
// Call each device class and have it report any adapters it supports.
|
||||
if(smAdapters.size())
|
||||
{
|
||||
// CodeReview Seems like this is ok to just ignore? [bjg, 5/19/07]
|
||||
//Con::warnf("GFXInit::enumerateAdapters - already have a populated adapter list, aborting re-analysis.");
|
||||
return;
|
||||
}
|
||||
|
||||
getRegisterDeviceSignal().trigger(GFXInit::smAdapters);
|
||||
}
|
||||
|
||||
GFXDevice *GFXInit::createDevice( GFXAdapter *adapter )
|
||||
{
|
||||
Con::printf("Attempting to create GFX device: %s", adapter->getName());
|
||||
|
||||
GFXDevice* temp = adapter->mCreateDeviceInstanceDelegate(adapter->mIndex);
|
||||
if (temp)
|
||||
{
|
||||
Con::printf("Device created, setting adapter and enumerating modes");
|
||||
temp->setAdapter(*adapter);
|
||||
temp->enumerateVideoModes();
|
||||
temp->getVideoModeList();
|
||||
}
|
||||
else
|
||||
Con::errorf("Failed to create GFX device");
|
||||
|
||||
GFXDevice::getDeviceEventSignal().trigger(GFXDevice::deCreate);
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
||||
DefineEngineFunction( getDesktopResolution, Point3F, (),,
|
||||
"Returns the width, height, and bitdepth of the screen/desktop.\n\n@ingroup GFX" )
|
||||
{
|
||||
GFXVideoMode res = GFXInit::getDesktopResolution();
|
||||
return Point3F( res.resolution.x, res.resolution.y, res.bitDepth );
|
||||
}
|
||||
|
||||
DefineEngineStaticMethod( GFXInit, getAdapterCount, S32, (),,
|
||||
"Return the number of graphics adapters available. @ingroup GFX")
|
||||
{
|
||||
return GFXInit::getAdapterCount();
|
||||
}
|
||||
|
||||
DefineEngineStaticMethod( GFXInit, getAdapterName, String, ( S32 index ),,
|
||||
"Returns the name of the graphics adapter.\n"
|
||||
"@param index The index of the adapter." )
|
||||
{
|
||||
Vector<GFXAdapter*> adapters( __FILE__, __LINE__ );
|
||||
GFXInit::getAdapters(&adapters);
|
||||
|
||||
if(index >= 0 && index < adapters.size())
|
||||
return adapters[index]->mName;
|
||||
|
||||
Con::errorf( "GFXInit::getAdapterName - Out of range adapter index." );
|
||||
return String::EmptyString;
|
||||
}
|
||||
|
||||
DefineEngineStaticMethod( GFXInit, getAdapterType, GFXAdapterType, ( S32 index ),,
|
||||
"Returns the type (D3D9, D3D8, GL, Null) of a graphics adapter.\n"
|
||||
"@param index The index of the adapter." )
|
||||
{
|
||||
Vector<GFXAdapter*> adapters( __FILE__, __LINE__ );
|
||||
GFXInit::getAdapters(&adapters);
|
||||
|
||||
if( index >= 0 && index < adapters.size())
|
||||
return adapters[index]->mType;
|
||||
|
||||
Con::errorf( "GFXInit::getAdapterType - Out of range adapter index." );
|
||||
return GFXAdapterType_Count;
|
||||
}
|
||||
|
||||
DefineEngineStaticMethod( GFXInit, getAdapterShaderModel, F32, ( S32 index ),,
|
||||
"Returns the supported shader model of the graphics adapter or -1 if the index is bad.\n"
|
||||
"@param index The index of the adapter." )
|
||||
{
|
||||
Vector<GFXAdapter*> adapters( __FILE__, __LINE__ );
|
||||
GFXInit::getAdapters(&adapters);
|
||||
|
||||
if(index < 0 || index >= adapters.size())
|
||||
{
|
||||
Con::errorf("GFXInit::getAdapterShaderModel - Out of range adapter index.");
|
||||
return -1.0f;
|
||||
}
|
||||
|
||||
return adapters[index]->mShaderModel;
|
||||
}
|
||||
|
||||
DefineEngineStaticMethod( GFXInit, getDefaultAdapterIndex, S32, (),,
|
||||
"Returns the index of the default graphics adapter. This is the graphics device "
|
||||
"which will be used to initialize the engine." )
|
||||
{
|
||||
GFXAdapter *a = GFXInit::getBestAdapterChoice();
|
||||
|
||||
// We have to find the index of the adapter in the list to
|
||||
// return an index that makes sense to the script.
|
||||
Vector<GFXAdapter*> adapters( __FILE__, __LINE__ );
|
||||
GFXInit::getAdapters(&adapters);
|
||||
for(S32 i=0; i<adapters.size(); i++)
|
||||
if ( adapters[i]->mIndex == a->mIndex &&
|
||||
adapters[i]->mType == a->mType )
|
||||
return i;
|
||||
|
||||
Con::warnf( "GFXInit::getDefaultAdapterIndex - Didn't find the adapter in the list!" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
DefineEngineStaticMethod( GFXInit, getAdapterModeCount, S32, ( S32 index ),,
|
||||
"Gets the number of modes available on the specified adapter.\n\n"
|
||||
"@param index Index of the adapter to get modes from.\n"
|
||||
"@return The number of video modes supported by the adapter or -1 if the given adapter was not found." )
|
||||
{
|
||||
Vector<GFXAdapter*> adapters( __FILE__, __LINE__ );
|
||||
GFXInit::getAdapters(&adapters);
|
||||
|
||||
if( index < 0 || index >= adapters.size())
|
||||
{
|
||||
Con::warnf( "GFXInit::getAdapterModeCount - The index was out of range." );
|
||||
return -1;
|
||||
}
|
||||
|
||||
return adapters[index]->mAvailableModes.size();
|
||||
}
|
||||
|
||||
DefineConsoleStaticMethod( GFXInit, getAdapterMode, String, ( S32 index, S32 modeIndex ),,
|
||||
"Gets the details of the specified adapter mode.\n\n"
|
||||
"@param index Index of the adapter to query.\n"
|
||||
"@param modeIndex Index of the mode to get data from.\n"
|
||||
"@return A video mode string in the format 'width height fullscreen bitDepth refreshRate aaLevel'.\n"
|
||||
"@see GuiCanvas::getVideoMode()" )
|
||||
{
|
||||
Vector<GFXAdapter*> adapters( __FILE__, __LINE__ );
|
||||
GFXInit::getAdapters(&adapters);
|
||||
|
||||
if ( index < 0 || index >= adapters.size() )
|
||||
{
|
||||
Con::warnf( "GFXInit::getAdapterMode - The adapter index was out of range." );
|
||||
return String::EmptyString;
|
||||
}
|
||||
|
||||
if ( modeIndex < 0 || modeIndex >= adapters[index]->mAvailableModes.size() )
|
||||
{
|
||||
Con::warnf( "GFXInit::getAdapterMode - The mode index was out of range." );
|
||||
return String::EmptyString;
|
||||
}
|
||||
|
||||
const GFXVideoMode &vm = adapters[index]->mAvailableModes[modeIndex];
|
||||
return vm.toString();
|
||||
}
|
||||
|
||||
DefineEngineStaticMethod( GFXInit, createNullDevice, void, (),,
|
||||
"Create the NULL graphics device used for testing or headless operation." )
|
||||
{
|
||||
// Enumerate things for GFX before we have an active device.
|
||||
GFXInit::enumerateAdapters();
|
||||
|
||||
// Create a device.
|
||||
GFXAdapter *a = GFXInit::chooseAdapter(NullDevice);
|
||||
|
||||
GFXDevice *newDevice = GFX;
|
||||
|
||||
// Do we have a global device already? (This is the site if you want
|
||||
// to start rendering to multiple devices simultaneously)
|
||||
if(newDevice == NULL)
|
||||
newDevice = GFXInit::createDevice(a);
|
||||
|
||||
newDevice->setAllowRender( false );
|
||||
}
|
||||
101
Engine/source/gfx/gfxInit.h
Normal file
101
Engine/source/gfx/gfxInit.h
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GFXINIT_H_
|
||||
#define _GFXINIT_H_
|
||||
|
||||
#ifndef _GFXDEVICE_H_
|
||||
#include "gfx/gfxDevice.h"
|
||||
#endif
|
||||
#ifndef _ENGINEOBJECT_H_
|
||||
#include "console/engineObject.h"
|
||||
#endif
|
||||
|
||||
|
||||
/// Interface for tracking GFX adapters and initializing them into devices.
|
||||
/// @note Implement this class per platform.
|
||||
/// @note This is just a class so it can be friends with GFXDevice)
|
||||
class GFXInit
|
||||
{
|
||||
DECLARE_STATIC_CLASS( GFXInit );
|
||||
|
||||
public:
|
||||
/// Allows device to register themselves as available
|
||||
typedef Signal<void (Vector<GFXAdapter*>&)> RegisterDeviceSignal;
|
||||
static RegisterDeviceSignal& getRegisterDeviceSignal();
|
||||
|
||||
/// Prepares the adapter list.
|
||||
static void init();
|
||||
|
||||
/// Cleans out the adapter list.
|
||||
static void cleanup();
|
||||
|
||||
/// Creates a GFXDevice based on an adapter from the
|
||||
/// enumerateAdapters method.
|
||||
///
|
||||
/// @param adapter Graphics adapter to create device
|
||||
static GFXDevice *createDevice( GFXAdapter *adapter );
|
||||
|
||||
/// Enumerate all the graphics adapters on the system
|
||||
static void enumerateAdapters();
|
||||
|
||||
/// Get the enumerated adapters. Should only call this after
|
||||
/// a call to enumerateAdapters.
|
||||
static void getAdapters( Vector<GFXAdapter*> *adapters );
|
||||
|
||||
/// Get the number of available adapters.
|
||||
static S32 getAdapterCount();
|
||||
|
||||
/// Chooses a suitable GFXAdapter, based on type, preferences, and fallbacks.
|
||||
/// If the requested type is omitted, we use the prefs value.
|
||||
/// If the requested type isn't found, we use fallbacks: OpenGL, NullDevice
|
||||
/// This method never returns NULL.
|
||||
static GFXAdapter *chooseAdapter( GFXAdapterType type);
|
||||
|
||||
/// Gets the first adapter of the requested type from the list of enumerated
|
||||
/// adapters. Should only call this after a call to enumerateAdapters.
|
||||
static GFXAdapter *getAdapterOfType( GFXAdapterType type );
|
||||
|
||||
/// Converts a GFXAdapterType to a string name. Useful for writing out prefs
|
||||
static const char *getAdapterNameFromType( GFXAdapterType type );
|
||||
|
||||
/// Converts a string to a GFXAdapterType. Useful for reading in prefs.
|
||||
static GFXAdapterType getAdapterTypeFromName( const char* name );
|
||||
|
||||
/// Returns a GFXVideoMode that describes the current state of the main monitor.
|
||||
/// This should probably move to the abstract window manager
|
||||
static GFXVideoMode getDesktopResolution();
|
||||
|
||||
/// Based on user preferences (or in the absence of a valid user selection,
|
||||
/// a heuristic), return a "best" adapter.
|
||||
static GFXAdapter *getBestAdapterChoice();
|
||||
|
||||
/// Get the initial video mode based on user preferences (or a heuristic).
|
||||
static GFXVideoMode getInitialVideoMode();
|
||||
private:
|
||||
/// List of known adapters.
|
||||
static Vector<GFXAdapter*> smAdapters;
|
||||
|
||||
static RegisterDeviceSignal* smRegisterDeviceSignal;
|
||||
};
|
||||
|
||||
#endif
|
||||
43
Engine/source/gfx/gfxOcclusionQuery.cpp
Normal file
43
Engine/source/gfx/gfxOcclusionQuery.cpp
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "gfx/gfxOcclusionQuery.h"
|
||||
|
||||
String GFXOcclusionQuery::statusToString( OcclusionQueryStatus status )
|
||||
{
|
||||
String outStr;
|
||||
if ( status == GFXOcclusionQuery::Unset )
|
||||
outStr = "Unset";
|
||||
else if ( status == GFXOcclusionQuery::Waiting )
|
||||
outStr = "Waiting";
|
||||
else if ( status == GFXOcclusionQuery::Occluded )
|
||||
outStr = "Occluded";
|
||||
else if ( status == GFXOcclusionQuery::NotOccluded )
|
||||
outStr = "Visible";
|
||||
else if ( status == GFXOcclusionQuery::Error )
|
||||
outStr = "Error";
|
||||
else
|
||||
outStr = "Unknown";
|
||||
|
||||
return outStr;
|
||||
}
|
||||
85
Engine/source/gfx/gfxOcclusionQuery.h
Normal file
85
Engine/source/gfx/gfxOcclusionQuery.h
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GFXOCCLUSIONQUERY_H_
|
||||
#define _GFXOCCLUSIONQUERY_H_
|
||||
|
||||
#ifndef _GFXDEVICE_H_
|
||||
#include "gfx/gfxDevice.h"
|
||||
#endif
|
||||
|
||||
|
||||
/// A geometry visibility query object.
|
||||
/// @see GFXDevice::createOcclusionQuery
|
||||
class GFXOcclusionQuery : public GFXResource
|
||||
{
|
||||
protected:
|
||||
|
||||
GFXDevice *mDevice;
|
||||
|
||||
GFXOcclusionQuery( GFXDevice *device )
|
||||
: mDevice( device )
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/// The states returned by getStatus()
|
||||
/// If you modify this enum you should also modify statusToString()
|
||||
enum OcclusionQueryStatus
|
||||
{
|
||||
Unset, ///<
|
||||
Waiting, ///<
|
||||
Error, ///<
|
||||
Occluded,
|
||||
NotOccluded
|
||||
};
|
||||
|
||||
virtual ~GFXOcclusionQuery() {}
|
||||
|
||||
/// Prepares the query returning true if the last query
|
||||
/// has been processed and more geometry can be issued.
|
||||
/// @see getStatus
|
||||
virtual bool begin() = 0;
|
||||
|
||||
/// Called after your geometry is drawn to submit
|
||||
/// the query for processing.
|
||||
virtual void end() = 0;
|
||||
|
||||
/// Returns the status of the last submitted query. In general
|
||||
/// you should avoid blocking for the result until the frame
|
||||
/// following your query to keep from stalling the CPU.
|
||||
/// @return Status
|
||||
/// @param block If true CPU will block until the query finishes.
|
||||
/// @param data Number of pixels rendered, valid only if status returned is NotOccluded.
|
||||
virtual OcclusionQueryStatus getStatus( bool block, U32 *data = NULL ) = 0;
|
||||
|
||||
/// Returns a status string.
|
||||
static String statusToString( OcclusionQueryStatus status );
|
||||
|
||||
// GFXResource
|
||||
virtual void zombify() = 0;
|
||||
virtual void resurrect() = 0;
|
||||
virtual const String describeSelf() const = 0;
|
||||
};
|
||||
|
||||
#endif // _GFXOCCLUSIONQUERY_H_
|
||||
82
Engine/source/gfx/gfxPrimitiveBuffer.cpp
Normal file
82
Engine/source/gfx/gfxPrimitiveBuffer.cpp
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "core/strings/stringFunctions.h"
|
||||
#include "console/console.h"
|
||||
|
||||
#include "gfx/gfxDevice.h"
|
||||
#include "gfx/gfxPrimitiveBuffer.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifdef TORQUE_DEBUG
|
||||
GFXPrimitiveBuffer *GFXPrimitiveBuffer::smHead = NULL;
|
||||
U32 GFXPrimitiveBuffer::smActivePBCount = 0;
|
||||
|
||||
void GFXPrimitiveBuffer::dumpActivePBs()
|
||||
{
|
||||
if(!smActivePBCount)
|
||||
{
|
||||
Con::printf("GFXPrimitiveBuffer::dumpActivePBs - no currently active PBs to dump. You are A-OK!");
|
||||
return;
|
||||
}
|
||||
|
||||
Con::printf("GFXPrimitiveBuffer Usage Report - %d active PBs", smActivePBCount);
|
||||
Con::printf("---------------------------------------------------------------");
|
||||
Con::printf(" Addr #idx #prims Profiler Path RefCount");
|
||||
for(GFXPrimitiveBuffer *walk = smHead; walk; walk=walk->mDebugNext)
|
||||
{
|
||||
#if defined(TORQUE_ENABLE_PROFILER)
|
||||
Con::printf(" %x %6d %6d %s %d", walk, walk->mIndexCount, walk->mPrimitiveCount, walk->mDebugCreationPath.c_str(), walk->getRefCount());
|
||||
#else
|
||||
Con::printf(" %x %6d %6d %s %d", walk, walk->mIndexCount, walk->mPrimitiveCount, "", walk->getRefCount());
|
||||
#endif
|
||||
}
|
||||
Con::printf("----- dump complete -------------------------------------------");
|
||||
AssertFatal(false, "There is a primitive buffer leak, check the log for more details.");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/// The resource should put a description of itself (number of vertices, size/width of texture, etc.) in buffer
|
||||
const String GFXPrimitiveBuffer::describeSelf() const
|
||||
{
|
||||
#if defined(TORQUE_DEBUG) && defined(TORQUE_ENABLE_PROFILER)
|
||||
return String::ToString("indexCount: %6d primCount: %6d refCount: %d path: %s",
|
||||
mIndexCount, mPrimitiveCount, getRefCount(), mDebugCreationPath.c_str());
|
||||
#else
|
||||
return String::ToString("indexCount: %6d primCount: %6d refCount: %d path: %s",
|
||||
mIndexCount, mPrimitiveCount, getRefCount(), "");
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Set
|
||||
//-----------------------------------------------------------------------------
|
||||
void GFXPrimitiveBufferHandle::set(GFXDevice *theDevice, U32 indexCount, U32 primitiveCount, GFXBufferType bufferType, String desc)
|
||||
{
|
||||
StrongRefPtr<GFXPrimitiveBuffer>::operator=( theDevice->allocPrimitiveBuffer(indexCount, primitiveCount, bufferType) );
|
||||
|
||||
#ifdef TORQUE_DEBUG
|
||||
if( desc.isNotEmpty() )
|
||||
getPointer()->mDebugCreationPath = desc;
|
||||
#endif
|
||||
}
|
||||
175
Engine/source/gfx/gfxPrimitiveBuffer.h
Normal file
175
Engine/source/gfx/gfxPrimitiveBuffer.h
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GFXPRIMITIVEBUFFER_H_
|
||||
#define _GFXPRIMITIVEBUFFER_H_
|
||||
|
||||
#ifndef _GFXSTRUCTS_H_
|
||||
#include "gfx/gfxStructs.h"
|
||||
#endif
|
||||
|
||||
#ifdef TORQUE_ENABLE_PROFILER
|
||||
#include "platform/profiler.h"
|
||||
#endif
|
||||
|
||||
|
||||
class GFXPrimitiveBuffer : public StrongRefBase, public GFXResource
|
||||
{
|
||||
friend class GFXPrimitiveBufferHandle;
|
||||
friend class GFXDevice;
|
||||
|
||||
public: //protected:
|
||||
|
||||
U32 mIndexCount;
|
||||
U32 mPrimitiveCount;
|
||||
GFXBufferType mBufferType;
|
||||
GFXPrimitive *mPrimitiveArray;
|
||||
GFXDevice *mDevice;
|
||||
|
||||
#ifdef TORQUE_DEBUG
|
||||
// In debug builds we provide a TOC leak tracking system.
|
||||
static U32 smActivePBCount;
|
||||
static GFXPrimitiveBuffer *smHead;
|
||||
static void dumpActivePBs();
|
||||
|
||||
String mDebugCreationPath;
|
||||
GFXPrimitiveBuffer *mDebugNext;
|
||||
GFXPrimitiveBuffer *mDebugPrev;
|
||||
#endif
|
||||
|
||||
GFXPrimitiveBuffer( GFXDevice *device,
|
||||
U32 indexCount,
|
||||
U32 primitiveCount,
|
||||
GFXBufferType bufferType )
|
||||
{
|
||||
mDevice = device;
|
||||
mIndexCount = indexCount;
|
||||
mPrimitiveCount = primitiveCount;
|
||||
mBufferType = bufferType;
|
||||
if(primitiveCount)
|
||||
{
|
||||
mPrimitiveArray = new GFXPrimitive[primitiveCount];
|
||||
dMemset((void *) mPrimitiveArray, 0, primitiveCount * sizeof(GFXPrimitive));
|
||||
}
|
||||
else
|
||||
mPrimitiveArray = NULL;
|
||||
|
||||
#if defined(TORQUE_DEBUG)
|
||||
// Active copy tracking.
|
||||
smActivePBCount++;
|
||||
#if defined(TORQUE_ENABLE_PROFILE_PATH)
|
||||
mDebugCreationPath = gProfiler->getProfilePath();
|
||||
#endif
|
||||
mDebugNext = smHead;
|
||||
mDebugPrev = NULL;
|
||||
|
||||
if(smHead)
|
||||
{
|
||||
AssertFatal(smHead->mDebugPrev == NULL, "GFXPrimitiveBuffer::GFXPrimitiveBuffer - found unexpected previous in current head!");
|
||||
smHead->mDebugPrev = this;
|
||||
}
|
||||
|
||||
smHead = this;
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual ~GFXPrimitiveBuffer()
|
||||
{
|
||||
if( mPrimitiveArray != NULL )
|
||||
{
|
||||
delete [] mPrimitiveArray;
|
||||
mPrimitiveArray = NULL;
|
||||
}
|
||||
|
||||
#ifdef TORQUE_DEBUG
|
||||
if(smHead == this)
|
||||
smHead = this->mDebugNext;
|
||||
|
||||
if(mDebugNext)
|
||||
mDebugNext->mDebugPrev = mDebugPrev;
|
||||
|
||||
if(mDebugPrev)
|
||||
mDebugPrev->mDebugNext = mDebugNext;
|
||||
|
||||
mDebugPrev = mDebugNext = NULL;
|
||||
|
||||
smActivePBCount--;
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual void lock(U32 indexStart, U32 indexEnd, void **indexPtr)=0; ///< locks this primitive buffer for writing into
|
||||
virtual void unlock()=0; ///< unlocks this primitive buffer.
|
||||
virtual void prepare()=0; ///< prepares this primitive buffer for use on the device it was allocated on
|
||||
|
||||
// GFXResource interface
|
||||
/// The resource should put a description of itself (number of vertices, size/width of texture, etc.) in buffer
|
||||
virtual const String describeSelf() const;
|
||||
};
|
||||
|
||||
class GFXPrimitiveBufferHandle : public StrongRefPtr<GFXPrimitiveBuffer>
|
||||
{
|
||||
typedef StrongRefPtr<GFXPrimitiveBuffer> Parent;
|
||||
public:
|
||||
enum Constants {
|
||||
MaxIndexCount = 65535,
|
||||
};
|
||||
GFXPrimitiveBufferHandle() {};
|
||||
|
||||
GFXPrimitiveBufferHandle(GFXDevice *theDevice, U32 indexCount, U32 primitiveCount, GFXBufferType bufferType, String desc = String::EmptyString )
|
||||
{
|
||||
set(theDevice, indexCount, primitiveCount, bufferType, desc);
|
||||
}
|
||||
|
||||
void set(GFXDevice *theDevice, U32 indexCount, U32 primitiveCount, GFXBufferType bufferType, String desc = String::EmptyString );
|
||||
|
||||
void lock(U16 **indexBuffer, GFXPrimitive **primitiveBuffer = NULL, U32 indexStart = 0, U32 indexEnd = 0)
|
||||
{
|
||||
if(indexEnd == 0)
|
||||
indexEnd = getPointer()->mIndexCount;
|
||||
AssertFatal(indexStart < indexEnd && indexEnd <= getPointer()->mIndexCount, "Out of range index lock!");
|
||||
getPointer()->lock(indexStart, indexEnd, (void**)indexBuffer);
|
||||
if(primitiveBuffer)
|
||||
*primitiveBuffer = getPointer()->mPrimitiveArray;
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
getPointer()->unlock();
|
||||
}
|
||||
|
||||
void prepare()
|
||||
{
|
||||
getPointer()->prepare();
|
||||
}
|
||||
|
||||
bool operator==(const GFXPrimitiveBufferHandle &buffer) const {
|
||||
return getPointer() == buffer.getPointer();
|
||||
}
|
||||
|
||||
GFXPrimitiveBufferHandle& operator=(GFXPrimitiveBuffer *ptr)
|
||||
{
|
||||
StrongObjectRef::set(ptr);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // _GFXPRIMITIVEBUFFER_H_
|
||||
60
Engine/source/gfx/gfxResource.cpp
Normal file
60
Engine/source/gfx/gfxResource.cpp
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "gfx/gfxResource.h"
|
||||
#include "gfx/gfxDevice.h"
|
||||
|
||||
GFXResource::GFXResource()
|
||||
{
|
||||
mPrevResource = mNextResource = NULL;
|
||||
mOwningDevice = NULL;
|
||||
mFlagged = false;
|
||||
}
|
||||
|
||||
GFXResource::~GFXResource()
|
||||
{
|
||||
// Make sure we're not the head of the list and referencd on the device.
|
||||
if(mOwningDevice && mOwningDevice->mResourceListHead == this)
|
||||
{
|
||||
AssertFatal(mPrevResource == NULL,
|
||||
"GFXResource::~GFXResource - head of list but have a previous item!");
|
||||
mOwningDevice->mResourceListHead = mNextResource;
|
||||
}
|
||||
|
||||
// Unlink ourselves from the list.
|
||||
if(mPrevResource)
|
||||
mPrevResource->mNextResource = mNextResource;
|
||||
if(mNextResource)
|
||||
mNextResource->mPrevResource = mPrevResource;
|
||||
|
||||
mPrevResource = mNextResource = NULL;
|
||||
}
|
||||
|
||||
void GFXResource::registerResourceWithDevice( GFXDevice *device )
|
||||
{
|
||||
mOwningDevice = device;
|
||||
mNextResource = device->mResourceListHead;
|
||||
device->mResourceListHead = this;
|
||||
|
||||
if(mNextResource)
|
||||
mNextResource->mPrevResource = this;
|
||||
}
|
||||
106
Engine/source/gfx/gfxResource.h
Normal file
106
Engine/source/gfx/gfxResource.h
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GFXRESOURCE_H_
|
||||
#define _GFXRESOURCE_H_
|
||||
|
||||
#ifndef _TORQUE_TYPES_H_
|
||||
#include "platform/types.h"
|
||||
#endif
|
||||
|
||||
#ifndef _TORQUE_STRING_H_
|
||||
#include "core/util/str.h"
|
||||
#endif
|
||||
|
||||
class GFXDevice;
|
||||
|
||||
/// Mixin for the purpose of tracking GFX resources owned by a GFXDevice.
|
||||
///
|
||||
/// There are many types of resource that are allocated from a GFXDevice that
|
||||
/// must be participatory in device resets. For instance, all default pool
|
||||
/// DirectX resources have to be involved when the device resets. Render
|
||||
/// targets in all APIs need to unbind themselves when resets happen.
|
||||
///
|
||||
/// This system is also handy for accounting purposes. For instance, we may
|
||||
/// want to traverse all registered VBs, IBs, Textures, or RTs in order to
|
||||
/// determine what, if any, items are still allocated. This can be used in
|
||||
/// leak reports, memory usage reports, etc.
|
||||
class GFXResource
|
||||
{
|
||||
private:
|
||||
friend class GFXDevice;
|
||||
|
||||
GFXResource *mPrevResource;
|
||||
GFXResource *mNextResource;
|
||||
GFXDevice *mOwningDevice;
|
||||
|
||||
/// Helper flag to check new resource allocations
|
||||
bool mFlagged;
|
||||
|
||||
public:
|
||||
GFXResource();
|
||||
virtual ~GFXResource();
|
||||
|
||||
/// Registers this resource with the given device
|
||||
void registerResourceWithDevice(GFXDevice *device);
|
||||
|
||||
/// When called the resource should destroy all device sensitive information (e.g. D3D resources in D3DPOOL_DEFAULT
|
||||
virtual void zombify()=0;
|
||||
|
||||
/// When called the resource should restore all device sensitive information destroyed by zombify()
|
||||
virtual void resurrect()=0;
|
||||
|
||||
/// The resource should put a description of itself (number of vertices, size/width of texture, etc.) in buffer
|
||||
virtual const String describeSelf() const = 0;
|
||||
|
||||
inline GFXResource *getNextResource() const
|
||||
{
|
||||
return mNextResource;
|
||||
}
|
||||
|
||||
inline GFXResource *getPrevResource() const
|
||||
{
|
||||
return mPrevResource;
|
||||
}
|
||||
|
||||
inline GFXDevice *getOwningDevice() const
|
||||
{
|
||||
return mOwningDevice;
|
||||
}
|
||||
|
||||
inline bool isFlagged()
|
||||
{
|
||||
return mFlagged;
|
||||
}
|
||||
|
||||
inline void setFlag()
|
||||
{
|
||||
mFlagged = true;
|
||||
}
|
||||
|
||||
inline void clearFlag()
|
||||
{
|
||||
mFlagged = false;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
174
Engine/source/gfx/gfxShader.cpp
Normal file
174
Engine/source/gfx/gfxShader.cpp
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "gfx/gfxShader.h"
|
||||
|
||||
#include "shaderGen/conditionerFeature.h"
|
||||
#include "core/volume.h"
|
||||
#include "console/engineAPI.h"
|
||||
|
||||
|
||||
Vector<GFXShaderMacro> GFXShader::smGlobalMacros;
|
||||
bool GFXShader::smLogErrors = true;
|
||||
bool GFXShader::smLogWarnings = true;
|
||||
|
||||
|
||||
GFXShader::GFXShader()
|
||||
: mPixVersion( 0.0f ),
|
||||
mReloadKey( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
GFXShader::~GFXShader()
|
||||
{
|
||||
Torque::FS::RemoveChangeNotification( mVertexFile, this, &GFXShader::_onFileChanged );
|
||||
Torque::FS::RemoveChangeNotification( mPixelFile, this, &GFXShader::_onFileChanged );
|
||||
}
|
||||
|
||||
bool GFXShader::init( const Torque::Path &vertFile,
|
||||
const Torque::Path &pixFile,
|
||||
F32 pixVersion,
|
||||
const Vector<GFXShaderMacro> ¯os )
|
||||
{
|
||||
// Store the inputs for use in reloading.
|
||||
mVertexFile = vertFile;
|
||||
mPixelFile = pixFile;
|
||||
mPixVersion = pixVersion;
|
||||
mMacros = macros;
|
||||
|
||||
// Before we compile the shader make sure the
|
||||
// conditioner features have been updated.
|
||||
ConditionerFeature::updateConditioners();
|
||||
|
||||
// Now do the real initialization.
|
||||
if ( !_init() )
|
||||
return false;
|
||||
|
||||
_updateDesc();
|
||||
|
||||
// Add file change notifications for reloads.
|
||||
Torque::FS::AddChangeNotification( mVertexFile, this, &GFXShader::_onFileChanged );
|
||||
Torque::FS::AddChangeNotification( mPixelFile, this, &GFXShader::_onFileChanged );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GFXShader::reload()
|
||||
{
|
||||
// Before we compile the shader make sure the
|
||||
// conditioner features have been updated.
|
||||
ConditionerFeature::updateConditioners();
|
||||
|
||||
mReloadKey++;
|
||||
|
||||
// Init does the work.
|
||||
bool success = _init();
|
||||
if ( success )
|
||||
_updateDesc();
|
||||
|
||||
// Let anything that cares know that
|
||||
// this shader has reloaded
|
||||
mReloadSignal.trigger();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
void GFXShader::_updateDesc()
|
||||
{
|
||||
mDescription = String::ToString( "Files: %s, %s Pix Version: %0.2f\nMacros: ",
|
||||
mVertexFile.getFullPath().c_str(), mPixelFile.getFullPath().c_str(), mPixVersion );
|
||||
|
||||
GFXShaderMacro::stringize( smGlobalMacros, &mDescription );
|
||||
GFXShaderMacro::stringize( mMacros, &mDescription );
|
||||
}
|
||||
|
||||
void GFXShader::addGlobalMacro( const String &name, const String &value )
|
||||
{
|
||||
// Check to see if we already have this macro.
|
||||
Vector<GFXShaderMacro>::iterator iter = smGlobalMacros.begin();
|
||||
for ( ; iter != smGlobalMacros.end(); iter++ )
|
||||
{
|
||||
if ( iter->name == name )
|
||||
{
|
||||
if ( iter->value != value )
|
||||
iter->value = value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Add a new macro.
|
||||
smGlobalMacros.increment();
|
||||
smGlobalMacros.last().name = name;
|
||||
smGlobalMacros.last().value = value;
|
||||
}
|
||||
|
||||
bool GFXShader::removeGlobalMacro( const String &name )
|
||||
{
|
||||
Vector<GFXShaderMacro>::iterator iter = smGlobalMacros.begin();
|
||||
for ( ; iter != smGlobalMacros.end(); iter++ )
|
||||
{
|
||||
if ( iter->name == name )
|
||||
{
|
||||
smGlobalMacros.erase( iter );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void GFXShader::_unlinkBuffer( GFXShaderConstBuffer *buf )
|
||||
{
|
||||
Vector<GFXShaderConstBuffer*>::iterator iter = mActiveBuffers.begin();
|
||||
for ( ; iter != mActiveBuffers.end(); iter++ )
|
||||
{
|
||||
if ( *iter == buf )
|
||||
{
|
||||
mActiveBuffers.erase_fast( iter );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
AssertFatal( false, "GFXShader::_unlinkBuffer - buffer was not found?" );
|
||||
}
|
||||
|
||||
|
||||
DefineEngineFunction( addGlobalShaderMacro, void,
|
||||
( const char *name, const char *value ), ( NULL ),
|
||||
"Adds a global shader macro which will be merged with the script defined "
|
||||
"macros on every shader. The macro will replace the value of an existing "
|
||||
"macro of the same name. For the new macro to take effect all the shaders "
|
||||
"in the system need to be reloaded.\n"
|
||||
"@see resetLightManager, removeGlobalShaderMacro\n"
|
||||
"@ingroup Rendering\n" )
|
||||
{
|
||||
GFXShader::addGlobalMacro( name, value );
|
||||
}
|
||||
|
||||
DefineEngineFunction( removeGlobalShaderMacro, void, ( const char *name ),,
|
||||
"Removes an existing global macro by name.\n"
|
||||
"@see addGlobalShaderMacro\n"
|
||||
"@ingroup Rendering\n" )
|
||||
{
|
||||
GFXShader::removeGlobalMacro( name );
|
||||
}
|
||||
365
Engine/source/gfx/gfxShader.h
Normal file
365
Engine/source/gfx/gfxShader.h
Normal file
|
|
@ -0,0 +1,365 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GFXSHADER_H_
|
||||
#define _GFXSHADER_H_
|
||||
|
||||
#ifndef _GFXRESOURCE_H_
|
||||
#include "gfx/gfxResource.h"
|
||||
#endif
|
||||
#ifndef _TORQUE_STRING_H_
|
||||
#include "core/util/str.h"
|
||||
#endif
|
||||
#ifndef _TVECTOR_H_
|
||||
#include "core/util/tVector.h"
|
||||
#endif
|
||||
#ifndef _ALIGNEDARRAY_H_
|
||||
#include "core/util/tAlignedArray.h"
|
||||
#endif
|
||||
#ifndef _MMATRIX_H_
|
||||
#include "math/mMatrix.h"
|
||||
#endif
|
||||
#ifndef _GFXENUMS_H_
|
||||
#include "gfx/gfxEnums.h"
|
||||
#endif
|
||||
#ifndef _GFXSTRUCTS_H_
|
||||
#include "gfx/gfxStructs.h"
|
||||
#endif
|
||||
#ifndef _COLOR_H_
|
||||
#include "core/color.h"
|
||||
#endif
|
||||
#ifndef _REFBASE_H_
|
||||
#include "core/util/refBase.h"
|
||||
#endif
|
||||
#ifndef _PATH_H_
|
||||
#include "core/util/path.h"
|
||||
#endif
|
||||
#ifndef _TSIGNAL_H_
|
||||
#include "core/util/tSignal.h"
|
||||
#endif
|
||||
|
||||
class Point2I;
|
||||
class Point2F;
|
||||
class ColorF;
|
||||
class MatrixF;
|
||||
class GFXShader;
|
||||
class GFXVertexFormat;
|
||||
|
||||
|
||||
/// Instances of this struct are returned GFXShaderConstBuffer
|
||||
struct GFXShaderConstDesc
|
||||
{
|
||||
public:
|
||||
String name;
|
||||
GFXShaderConstType constType;
|
||||
U32 arraySize; // > 1 means it is an array!
|
||||
};
|
||||
|
||||
/// This is an opaque handle used by GFXShaderConstBuffer clients to set individual shader constants.
|
||||
/// Derived classes can put whatever info they need into here, these handles are owned by the shader constant buffer
|
||||
/// (or shader). Client code should not free these.
|
||||
class GFXShaderConstHandle
|
||||
{
|
||||
public:
|
||||
|
||||
GFXShaderConstHandle() { mValid = false; }
|
||||
virtual ~GFXShaderConstHandle() {}
|
||||
|
||||
/// Returns true if this constant is valid and can
|
||||
/// be set on the shader.
|
||||
bool isValid() const { return mValid; }
|
||||
|
||||
/// Returns the name of the constant handle.
|
||||
virtual const String& getName() const = 0;
|
||||
|
||||
/// Returns the type of the constant handle.
|
||||
virtual GFXShaderConstType getType() const = 0;
|
||||
|
||||
virtual U32 getArraySize() const = 0;
|
||||
|
||||
/// Returns -1 if this handle does not point to a Sampler.
|
||||
virtual S32 getSamplerRegister() const = 0;
|
||||
|
||||
protected:
|
||||
|
||||
/// The state of the constant which is
|
||||
/// set from the derived class.
|
||||
bool mValid;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/// GFXShaderConstBuffer is a collection of shader data which
|
||||
/// are sent to the device in one call in most cases.
|
||||
///
|
||||
/// The content of the buffer is persistant and if a value
|
||||
/// does not change frequently there is a savings in not setting
|
||||
/// the value every frame.
|
||||
///
|
||||
class GFXShaderConstBuffer : public GFXResource, public StrongRefBase
|
||||
{
|
||||
protected:
|
||||
|
||||
/// The lost state of the buffer content.
|
||||
///
|
||||
/// Derived classes need to set the lost state
|
||||
/// on first creation of the buffer and shader
|
||||
/// reloads.
|
||||
///
|
||||
/// @see wasLost
|
||||
bool mWasLost;
|
||||
|
||||
GFXShaderConstBuffer()
|
||||
: mWasLost( true ),
|
||||
mInstPtr( NULL )
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/// Return the shader that created this buffer
|
||||
virtual GFXShader* getShader() = 0;
|
||||
|
||||
/// The content of the buffer is in the lost state when
|
||||
/// first created or when the shader is reloaded. When
|
||||
/// the content is lost you must refill the buffer
|
||||
/// with all the constants used by your shader.
|
||||
///
|
||||
/// Use this property to avoid setting constants which do
|
||||
/// not changefrom one frame to the next.
|
||||
///
|
||||
bool wasLost() const { return mWasLost; }
|
||||
|
||||
/// An inline helper which ensures the handle is valid
|
||||
/// before the virtual set method is called.
|
||||
///
|
||||
/// You should prefer using this method unless your sure the
|
||||
/// handle is always valid or if your doing your own test.
|
||||
///
|
||||
template< typename VALUE >
|
||||
inline void setSafe( GFXShaderConstHandle *handle, const VALUE& v )
|
||||
{
|
||||
if ( handle->isValid() )
|
||||
set( handle, v );
|
||||
}
|
||||
|
||||
/// Set a shader constant.
|
||||
///
|
||||
/// The constant handle is assumed to be valid.
|
||||
///
|
||||
/// Perfer using setSafe unless you can check the handle
|
||||
/// validity yourself and skip a significat amount of work.
|
||||
///
|
||||
/// @see GFXShaderConstHandle::isValid()
|
||||
///
|
||||
virtual void set(GFXShaderConstHandle* handle, const F32 f) = 0;
|
||||
virtual void set(GFXShaderConstHandle* handle, const Point2F& fv) = 0;
|
||||
virtual void set(GFXShaderConstHandle* handle, const Point3F& fv) = 0;
|
||||
virtual void set(GFXShaderConstHandle* handle, const Point4F& fv) = 0;
|
||||
virtual void set(GFXShaderConstHandle* handle, const PlaneF& fv) = 0;
|
||||
virtual void set(GFXShaderConstHandle* handle, const ColorF& fv) = 0;
|
||||
virtual void set(GFXShaderConstHandle* handle, const S32 f) = 0;
|
||||
virtual void set(GFXShaderConstHandle* handle, const Point2I& fv) = 0;
|
||||
virtual void set(GFXShaderConstHandle* handle, const Point3I& fv) = 0;
|
||||
virtual void set(GFXShaderConstHandle* handle, const Point4I& fv) = 0;
|
||||
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<F32>& fv) = 0;
|
||||
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point2F>& fv) = 0;
|
||||
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point3F>& fv) = 0;
|
||||
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point4F>& fv) = 0;
|
||||
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<S32>& fv) = 0;
|
||||
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point2I>& fv) = 0;
|
||||
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point3I>& fv) = 0;
|
||||
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point4I>& fv) = 0;
|
||||
|
||||
/// Set a variable sized matrix shader constant.
|
||||
virtual void set( GFXShaderConstHandle* handle,
|
||||
const MatrixF& mat,
|
||||
const GFXShaderConstType matrixType = GFXSCT_Float4x4 ) = 0;
|
||||
|
||||
/// Set a variable sized matrix shader constant from
|
||||
/// an array of matricies.
|
||||
virtual void set( GFXShaderConstHandle* handle,
|
||||
const MatrixF* mat,
|
||||
const U32 arraySize,
|
||||
const GFXShaderConstType matrixType = GFXSCT_Float4x4 ) = 0;
|
||||
|
||||
// TODO: Make this protected and put a real API around it.
|
||||
U8 *mInstPtr;
|
||||
};
|
||||
|
||||
typedef StrongRefPtr<GFXShaderConstBuffer> GFXShaderConstBufferRef;
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// Shader
|
||||
//**************************************************************************
|
||||
class GFXShader : public StrongRefBase, public GFXResource
|
||||
{
|
||||
friend class GFXShaderConstBuffer;
|
||||
|
||||
protected:
|
||||
|
||||
/// These are system wide shader macros which are
|
||||
/// merged with shader specific macros at creation.
|
||||
static Vector<GFXShaderMacro> smGlobalMacros;
|
||||
|
||||
/// If true the shader errors are spewed to the console.
|
||||
static bool smLogErrors;
|
||||
|
||||
/// If true the shader warnings are spewed to the console.
|
||||
static bool smLogWarnings;
|
||||
|
||||
/// The vertex shader file.
|
||||
Torque::Path mVertexFile;
|
||||
|
||||
/// The pixel shader file.
|
||||
Torque::Path mPixelFile;
|
||||
|
||||
/// The macros to be passed to the shader.
|
||||
Vector<GFXShaderMacro> mMacros;
|
||||
|
||||
/// The pixel version this is compiled for.
|
||||
F32 mPixVersion;
|
||||
|
||||
///
|
||||
String mDescription;
|
||||
|
||||
/// Counter that is incremented each time this shader is reloaded.
|
||||
U32 mReloadKey;
|
||||
|
||||
Signal<void()> mReloadSignal;
|
||||
|
||||
/// Vector of buffers that reference this shader.
|
||||
/// It is the responsibility of the derived shader class to populate this
|
||||
/// vector and to notify them when this shader is reloaded. Classes
|
||||
/// derived from GFXShaderConstBuffer should call _unlinkBuffer from
|
||||
/// their destructor.
|
||||
Vector<GFXShaderConstBuffer*> mActiveBuffers;
|
||||
|
||||
/// A protected constructor so it cannot be instantiated.
|
||||
GFXShader();
|
||||
|
||||
public:
|
||||
|
||||
// TODO: Add this into init().
|
||||
GFXVertexFormat mInstancingFormat;
|
||||
|
||||
/// Adds a global shader macro which will be merged with
|
||||
/// the script defined macros on every shader reload.
|
||||
///
|
||||
/// The macro will replace the value of an existing macro
|
||||
/// of the same name.
|
||||
///
|
||||
/// For the new macro to take effect all the shaders/materials
|
||||
/// in the system need to be reloaded.
|
||||
///
|
||||
/// @see MaterialManager::flushAndReInitInstances
|
||||
/// @see ShaderData::reloadAll
|
||||
static void addGlobalMacro( const String &name, const String &value = String::EmptyString );
|
||||
|
||||
/// Removes an existing global macro by name.
|
||||
/// @see addGlobalMacro
|
||||
static bool removeGlobalMacro( const String &name );
|
||||
|
||||
/// Toggle logging for shader errors.
|
||||
static void setLogging( bool logErrors,
|
||||
bool logWarning )
|
||||
{
|
||||
smLogErrors = logErrors;
|
||||
smLogWarnings = logWarning;
|
||||
}
|
||||
|
||||
/// The destructor.
|
||||
virtual ~GFXShader();
|
||||
|
||||
///
|
||||
bool init( const Torque::Path &vertFile,
|
||||
const Torque::Path &pixFile,
|
||||
F32 pixVersion,
|
||||
const Vector<GFXShaderMacro> ¯os );
|
||||
|
||||
/// Reloads the shader from disk.
|
||||
bool reload();
|
||||
|
||||
Signal<void()> getReloadSignal() { return mReloadSignal; }
|
||||
|
||||
/// Allocate a constant buffer
|
||||
virtual GFXShaderConstBufferRef allocConstBuffer() = 0;
|
||||
|
||||
/// Returns our list of shader constants, the material can get this and just set the constants it knows about
|
||||
virtual const Vector<GFXShaderConstDesc>& getShaderConstDesc() const = 0;
|
||||
|
||||
/// Returns a shader constant handle for the name constant.
|
||||
///
|
||||
/// Since shaders can reload and later have handles that didn't
|
||||
/// exist originally this will return a handle in an invalid state
|
||||
/// if the constant doesn't exist at this time.
|
||||
virtual GFXShaderConstHandle* getShaderConstHandle( const String& name ) = 0;
|
||||
|
||||
/// Returns the alignment value for constType
|
||||
virtual U32 getAlignmentValue(const GFXShaderConstType constType) const = 0;
|
||||
|
||||
/// Returns the required vertex format for this shader.
|
||||
/// Returns the pixel shader version.
|
||||
F32 getPixVersion() const { return mPixVersion; }
|
||||
|
||||
/// Returns a counter which is incremented each time this shader is reloaded.
|
||||
U32 getReloadKey() const { return mReloadKey; }
|
||||
|
||||
/// Device specific shaders can override this method to return
|
||||
/// the shader disassembly.
|
||||
virtual bool getDisassembly( String &outStr ) const { return false; }
|
||||
|
||||
/// Returns the vertex shader file path.
|
||||
const String& getVertexShaderFile() const { return mVertexFile.getFullPath(); }
|
||||
|
||||
/// Returns the pixel shader file path.
|
||||
const String& getPixelShaderFile() const { return mPixelFile.getFullPath(); }
|
||||
|
||||
// GFXResource
|
||||
const String describeSelf() const { return mDescription; }
|
||||
|
||||
protected:
|
||||
|
||||
/// Called when the shader files change on disk.
|
||||
void _onFileChanged( const Torque::Path &path ) { reload(); }
|
||||
|
||||
/// Internal initialization function overloaded for
|
||||
/// each GFX device type.
|
||||
virtual bool _init() = 0;
|
||||
|
||||
/// Buffers call this from their destructor (so we don't have to ref count them).
|
||||
void _unlinkBuffer( GFXShaderConstBuffer *buf );
|
||||
|
||||
/// Called to update the description string after init.
|
||||
void _updateDesc();
|
||||
};
|
||||
|
||||
/// A strong pointer to a reference counted GFXShader.
|
||||
typedef StrongRefPtr<GFXShader> GFXShaderRef;
|
||||
|
||||
|
||||
/// A weak pointer to a reference counted GFXShader.
|
||||
typedef WeakRefPtr<GFXShader> GFXShaderWeakRef;
|
||||
|
||||
|
||||
#endif // GFXSHADER
|
||||
336
Engine/source/gfx/gfxStateBlock.cpp
Normal file
336
Engine/source/gfx/gfxStateBlock.cpp
Normal file
|
|
@ -0,0 +1,336 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "gfx/gfxStateBlock.h"
|
||||
#include "core/crc.h"
|
||||
#include "gfx/gfxDevice.h"
|
||||
#include "core/strings/stringFunctions.h"
|
||||
#include "gfx/gfxStringEnumTranslate.h"
|
||||
|
||||
///
|
||||
/// GFXStateBlock
|
||||
///
|
||||
const String GFXStateBlock::describeSelf() const
|
||||
{
|
||||
return String::ToString("hashvalue: 0x%x", getDesc().getHashValue());
|
||||
}
|
||||
|
||||
///
|
||||
/// GFXStateBlockDesc
|
||||
///
|
||||
GFXStateBlockDesc::GFXStateBlockDesc()
|
||||
{
|
||||
// Alpha blending
|
||||
blendDefined = false;
|
||||
blendEnable = false;
|
||||
blendSrc = GFXBlendOne;
|
||||
blendDest = GFXBlendZero;
|
||||
blendOp = GFXBlendOpAdd;
|
||||
|
||||
// Separate alpha blending
|
||||
separateAlphaBlendDefined = false;
|
||||
separateAlphaBlendEnable = false;
|
||||
separateAlphaBlendSrc = GFXBlendOne;
|
||||
separateAlphaBlendDest = GFXBlendZero;
|
||||
separateAlphaBlendOp = GFXBlendOpAdd;
|
||||
|
||||
// Alpha test
|
||||
alphaDefined = false;
|
||||
alphaTestEnable = false;
|
||||
alphaTestRef = 0;
|
||||
alphaTestFunc = GFXCmpGreaterEqual;
|
||||
|
||||
// Color Writes
|
||||
colorWriteDefined = false;
|
||||
colorWriteRed = true;
|
||||
colorWriteBlue = true;
|
||||
colorWriteGreen = true;
|
||||
colorWriteAlpha = true;
|
||||
|
||||
// Rasterizer
|
||||
cullDefined = false;
|
||||
cullMode = GFXCullCCW;
|
||||
|
||||
// Depth
|
||||
zDefined = false;
|
||||
zEnable = true;
|
||||
zWriteEnable = true;
|
||||
zFunc = GFXCmpLessEqual;
|
||||
zBias = 0;
|
||||
zSlopeBias = 0;
|
||||
|
||||
// Stencil
|
||||
stencilDefined = false;
|
||||
stencilEnable = false;
|
||||
stencilFailOp = GFXStencilOpKeep;
|
||||
stencilZFailOp = GFXStencilOpKeep;
|
||||
stencilPassOp = GFXStencilOpKeep;
|
||||
stencilFunc = GFXCmpNever;
|
||||
stencilRef = 0;
|
||||
stencilMask = 0xFFFFFFFF;
|
||||
stencilWriteMask = 0xFFFFFFFF;
|
||||
|
||||
// FF lighting
|
||||
ffLighting = false;
|
||||
|
||||
vertexColorEnable = false;
|
||||
|
||||
fillMode = GFXFillSolid;
|
||||
|
||||
samplersDefined = false;
|
||||
textureFactor.set( 255, 255, 255, 255 );
|
||||
}
|
||||
|
||||
// This method just needs to return a unique value based on its contents.
|
||||
U32 GFXStateBlockDesc::getHashValue() const
|
||||
{
|
||||
return CRC::calculateCRC(this, sizeof(GFXStateBlockDesc));
|
||||
}
|
||||
|
||||
/// Adds data from desc to this description, uses *defined parameters in desc to figure out
|
||||
/// what blocks of state to actually copy from desc.
|
||||
void GFXStateBlockDesc::addDesc(const GFXStateBlockDesc& desc)
|
||||
{
|
||||
// Alpha blending
|
||||
if (desc.blendDefined)
|
||||
{
|
||||
blendDefined = true;
|
||||
blendEnable = desc.blendEnable;
|
||||
blendSrc = desc.blendSrc;
|
||||
blendDest = desc.blendDest;
|
||||
blendOp = desc.blendOp;
|
||||
}
|
||||
|
||||
// Separate alpha blending
|
||||
if ( desc.separateAlphaBlendDefined )
|
||||
{
|
||||
separateAlphaBlendDefined = true;
|
||||
separateAlphaBlendEnable = desc.separateAlphaBlendEnable;
|
||||
separateAlphaBlendSrc = desc.separateAlphaBlendSrc;
|
||||
separateAlphaBlendDest = desc.separateAlphaBlendDest;
|
||||
separateAlphaBlendOp = desc.separateAlphaBlendOp;
|
||||
}
|
||||
|
||||
// Alpha test
|
||||
if (desc.alphaDefined)
|
||||
{
|
||||
alphaDefined = true;
|
||||
alphaTestEnable = desc.alphaTestEnable;
|
||||
alphaTestRef = desc.alphaTestRef;
|
||||
alphaTestFunc = desc.alphaTestFunc;
|
||||
}
|
||||
|
||||
// Color Writes
|
||||
if (desc.colorWriteDefined)
|
||||
{
|
||||
colorWriteDefined = true;
|
||||
colorWriteRed = desc.colorWriteRed;
|
||||
colorWriteBlue = desc.colorWriteBlue;
|
||||
colorWriteGreen = desc.colorWriteGreen;
|
||||
colorWriteAlpha = desc.colorWriteAlpha;
|
||||
}
|
||||
|
||||
// Rasterizer
|
||||
if (desc.cullDefined)
|
||||
{
|
||||
cullDefined = true;
|
||||
cullMode = desc.cullMode;
|
||||
}
|
||||
|
||||
// Depth
|
||||
if (desc.zDefined)
|
||||
{
|
||||
zDefined = true;
|
||||
zEnable = desc.zEnable;
|
||||
zWriteEnable = desc.zWriteEnable;
|
||||
zFunc = desc.zFunc;
|
||||
zBias = desc.zBias;
|
||||
zSlopeBias = desc.zSlopeBias;
|
||||
}
|
||||
|
||||
// Stencil
|
||||
if (desc.stencilDefined)
|
||||
{
|
||||
stencilDefined = true;
|
||||
stencilEnable = desc.stencilEnable;
|
||||
stencilFailOp = desc.stencilFailOp;
|
||||
stencilZFailOp = desc.stencilZFailOp;
|
||||
stencilPassOp = desc.stencilPassOp;
|
||||
stencilFunc = desc.stencilFunc;
|
||||
stencilRef = desc.stencilRef;
|
||||
stencilMask = desc.stencilMask;
|
||||
stencilWriteMask = desc.stencilWriteMask;
|
||||
}
|
||||
|
||||
if (desc.samplersDefined)
|
||||
{
|
||||
samplersDefined = true;
|
||||
for (U32 i = 0; i < TEXTURE_STAGE_COUNT; i++)
|
||||
{
|
||||
samplers[i] = desc.samplers[i];
|
||||
}
|
||||
textureFactor = desc.textureFactor;
|
||||
}
|
||||
|
||||
vertexColorEnable = desc.vertexColorEnable;
|
||||
fillMode = desc.fillMode;
|
||||
}
|
||||
|
||||
/// Returns a string that describes the options set (used by GFXStateBlock::describeSelf)
|
||||
const String GFXStateBlockDesc::describeSelf() const
|
||||
{
|
||||
GFXStringEnumTranslate::init();
|
||||
|
||||
String ret;
|
||||
ret = String::ToString(" AlphaBlend: %d, BlendSrc: %s, BlendDest: %s, BlendOp: %s\n",
|
||||
blendEnable, GFXStringBlend[blendSrc], GFXStringBlend[blendDest], GFXStringBlendOp[blendOp]);
|
||||
ret += String::ToString(" SeparateAlphaBlend: %d, SeparateAlphaBlendSrc: %s, SeparateAlphaBlendDest: %s, SeparateAlphaBlendOp: %s\n",
|
||||
separateAlphaBlendEnable, GFXStringBlend[separateAlphaBlendSrc], GFXStringBlend[separateAlphaBlendDest], GFXStringBlendOp[separateAlphaBlendOp]);
|
||||
ret += String::ToString(" AlphaTest: %d, AlphaTestFunc: %s, AlphaTestRef: %d\n",
|
||||
alphaTestEnable, GFXStringCmpFunc[alphaTestFunc], alphaTestRef);
|
||||
ret += String::ToString(" ColorWrites: r: %d g: %d b: %d a: %d",
|
||||
colorWriteRed, colorWriteGreen, colorWriteBlue, colorWriteAlpha);
|
||||
ret += String::ToString(" CullMode: %s\n", GFXStringCullMode[cullMode]);
|
||||
ret += String::ToString(" ZEnable: %d, ZWriteEnable: %d, ZFunc: %s, ZBias: %f, ZSlopeBias: %f\n",
|
||||
zEnable, zWriteEnable, GFXStringCmpFunc[zFunc], zBias, zSlopeBias);
|
||||
ret += String::ToString(" Stencil: %d, StencilFailOp: %s, StencilZFailOp: %s, StencilPassOp: %s, \n stencilFunc: %s, stencilRef: %d, stencilMask: 0x%x, stencilWriteMask: 0x%x\n",
|
||||
stencilEnable, GFXStringCmpFunc[stencilFailOp], GFXStringCmpFunc[stencilZFailOp], GFXStringCmpFunc[stencilPassOp],
|
||||
GFXStringCmpFunc[stencilFunc], stencilRef, stencilMask, stencilWriteMask);
|
||||
ret += String::ToString(" FF Lighting: %d, VertexColors: %d, fillMode: %s",
|
||||
ffLighting, vertexColorEnable, GFXStringFillMode[fillMode]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//
|
||||
// Utility functions
|
||||
//
|
||||
|
||||
void GFXStateBlockDesc::setCullMode( GFXCullMode m )
|
||||
{
|
||||
cullDefined = true;
|
||||
cullMode = m;
|
||||
}
|
||||
|
||||
void GFXStateBlockDesc::setZReadWrite( bool read, bool write )
|
||||
{
|
||||
zDefined = true;
|
||||
zEnable = read;
|
||||
zWriteEnable = write;
|
||||
}
|
||||
|
||||
void GFXStateBlockDesc::setAlphaTest( bool enable, GFXCmpFunc func, S32 alphaRef )
|
||||
{
|
||||
alphaDefined = true;
|
||||
alphaTestEnable = enable;
|
||||
alphaTestFunc = func;
|
||||
alphaTestRef = alphaRef;
|
||||
}
|
||||
|
||||
void GFXStateBlockDesc::setBlend( bool enable, GFXBlend src, GFXBlend dest, GFXBlendOp op )
|
||||
{
|
||||
blendDefined = true;
|
||||
blendEnable = enable;
|
||||
blendSrc = src;
|
||||
blendDest = dest;
|
||||
blendOp = op;
|
||||
}
|
||||
|
||||
void GFXStateBlockDesc::setSeparateAlphaBlend( bool enable, GFXBlend src, GFXBlend dest, GFXBlendOp op )
|
||||
{
|
||||
separateAlphaBlendDefined = true;
|
||||
separateAlphaBlendEnable = enable;
|
||||
separateAlphaBlendSrc = src;
|
||||
separateAlphaBlendDest = dest;
|
||||
separateAlphaBlendOp = op;
|
||||
}
|
||||
|
||||
void GFXStateBlockDesc::setColorWrites( bool red, bool green, bool blue, bool alpha )
|
||||
{
|
||||
colorWriteDefined = true;
|
||||
colorWriteRed = red;
|
||||
colorWriteGreen = green;
|
||||
colorWriteBlue = blue;
|
||||
colorWriteAlpha = alpha;
|
||||
}
|
||||
|
||||
GFXSamplerStateDesc::GFXSamplerStateDesc()
|
||||
{
|
||||
textureColorOp = GFXTOPDisable;
|
||||
addressModeU = GFXAddressWrap;
|
||||
addressModeV = GFXAddressWrap;
|
||||
addressModeW = GFXAddressWrap;
|
||||
magFilter = GFXTextureFilterLinear;
|
||||
minFilter = GFXTextureFilterLinear;
|
||||
mipFilter = GFXTextureFilterLinear;
|
||||
maxAnisotropy = 1;
|
||||
alphaArg1 = GFXTATexture;
|
||||
alphaArg2 = GFXTADiffuse;
|
||||
alphaArg3 = GFXTACurrent;
|
||||
colorArg1 = GFXTACurrent;
|
||||
colorArg2 = GFXTATexture;
|
||||
colorArg3 = GFXTACurrent;
|
||||
alphaOp = GFXTOPModulate;
|
||||
textureTransform = GFXTTFFDisable;
|
||||
resultArg = GFXTACurrent;
|
||||
mipLODBias = 0.0f;
|
||||
}
|
||||
|
||||
GFXSamplerStateDesc GFXSamplerStateDesc::getWrapLinear()
|
||||
{
|
||||
// Linear with wrapping is already the default
|
||||
GFXSamplerStateDesc ssd;
|
||||
ssd.textureColorOp = GFXTOPModulate;
|
||||
return ssd;
|
||||
}
|
||||
|
||||
GFXSamplerStateDesc GFXSamplerStateDesc::getWrapPoint()
|
||||
{
|
||||
GFXSamplerStateDesc ssd;
|
||||
ssd.textureColorOp = GFXTOPModulate;
|
||||
ssd.magFilter = GFXTextureFilterPoint;
|
||||
ssd.minFilter = GFXTextureFilterPoint;
|
||||
ssd.mipFilter = GFXTextureFilterPoint;
|
||||
return ssd;
|
||||
}
|
||||
|
||||
GFXSamplerStateDesc GFXSamplerStateDesc::getClampLinear()
|
||||
{
|
||||
GFXSamplerStateDesc ssd;
|
||||
ssd.textureColorOp = GFXTOPModulate;
|
||||
ssd.addressModeU = GFXAddressClamp;
|
||||
ssd.addressModeV = GFXAddressClamp;
|
||||
ssd.addressModeW = GFXAddressClamp;
|
||||
return ssd;
|
||||
}
|
||||
|
||||
GFXSamplerStateDesc GFXSamplerStateDesc::getClampPoint()
|
||||
{
|
||||
GFXSamplerStateDesc ssd;
|
||||
ssd.textureColorOp = GFXTOPModulate;
|
||||
ssd.addressModeU = GFXAddressClamp;
|
||||
ssd.addressModeV = GFXAddressClamp;
|
||||
ssd.addressModeW = GFXAddressClamp;
|
||||
ssd.magFilter = GFXTextureFilterPoint;
|
||||
ssd.minFilter = GFXTextureFilterPoint;
|
||||
ssd.mipFilter = GFXTextureFilterPoint;
|
||||
return ssd;
|
||||
}
|
||||
219
Engine/source/gfx/gfxStateBlock.h
Normal file
219
Engine/source/gfx/gfxStateBlock.h
Normal file
|
|
@ -0,0 +1,219 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GFXSTATEBLOCK_H_
|
||||
#define _GFXSTATEBLOCK_H_
|
||||
|
||||
#ifndef _REFBASE_H_
|
||||
#include "core/util/refBase.h"
|
||||
#endif
|
||||
#ifndef _GFXENUMS_H_
|
||||
#include "gfx/gfxEnums.h"
|
||||
#endif
|
||||
#ifndef _GFXRESOURCE_H_
|
||||
#include "gfx/gfxResource.h"
|
||||
#endif
|
||||
#ifndef _COLOR_H_
|
||||
#include "core/color.h"
|
||||
#endif
|
||||
|
||||
|
||||
struct GFXSamplerStateDesc
|
||||
{
|
||||
GFXTextureAddressMode addressModeU;
|
||||
GFXTextureAddressMode addressModeV;
|
||||
GFXTextureAddressMode addressModeW;
|
||||
|
||||
GFXTextureFilterType magFilter;
|
||||
GFXTextureFilterType minFilter;
|
||||
GFXTextureFilterType mipFilter;
|
||||
|
||||
/// The maximum anisotropy used when one of the filter types
|
||||
/// is set to anisotropic.
|
||||
///
|
||||
/// Defaults to 1.
|
||||
///
|
||||
/// @see GFXTextureFilterType
|
||||
U32 maxAnisotropy;
|
||||
|
||||
/// Used to offset the mipmap selection by whole or
|
||||
/// fractional amounts either postively or negatively.
|
||||
///
|
||||
/// Defaults to zero.
|
||||
F32 mipLODBias;
|
||||
|
||||
GFXTextureOp textureColorOp;
|
||||
|
||||
GFXTextureOp alphaOp;
|
||||
GFXTextureArgument alphaArg1;
|
||||
GFXTextureArgument alphaArg2;
|
||||
GFXTextureArgument alphaArg3;
|
||||
|
||||
GFXTextureArgument colorArg1;
|
||||
GFXTextureArgument colorArg2;
|
||||
GFXTextureArgument colorArg3;
|
||||
|
||||
GFXTextureArgument resultArg;
|
||||
|
||||
GFXTextureTransformFlags textureTransform;
|
||||
|
||||
GFXSamplerStateDesc();
|
||||
|
||||
/// Returns an modulate, wrap, and linear sampled state.
|
||||
static GFXSamplerStateDesc getWrapLinear();
|
||||
|
||||
/// Returns an modulate, wrap, and point sampled state.
|
||||
static GFXSamplerStateDesc getWrapPoint();
|
||||
|
||||
/// Returns an modulate, clamp, and linear sampled state.
|
||||
static GFXSamplerStateDesc getClampLinear();
|
||||
|
||||
/// Returns an modulate, clamp, and point sampled state.
|
||||
static GFXSamplerStateDesc getClampPoint();
|
||||
};
|
||||
|
||||
/// GFXStateBlockDesc defines a render state, which is then used to create a GFXStateBlock instance.
|
||||
struct GFXStateBlockDesc
|
||||
{
|
||||
// Blending
|
||||
bool blendDefined;
|
||||
bool blendEnable;
|
||||
GFXBlend blendSrc;
|
||||
GFXBlend blendDest;
|
||||
GFXBlendOp blendOp;
|
||||
|
||||
/// @name Separate Alpha Blending
|
||||
/// @{
|
||||
bool separateAlphaBlendDefined;
|
||||
bool separateAlphaBlendEnable;
|
||||
GFXBlend separateAlphaBlendSrc;
|
||||
GFXBlend separateAlphaBlendDest;
|
||||
GFXBlendOp separateAlphaBlendOp;
|
||||
/// @}
|
||||
|
||||
// Alpha test
|
||||
bool alphaDefined;
|
||||
bool alphaTestEnable;
|
||||
S32 alphaTestRef;
|
||||
GFXCmpFunc alphaTestFunc;
|
||||
|
||||
// Color Writes
|
||||
bool colorWriteDefined;
|
||||
bool colorWriteRed;
|
||||
bool colorWriteBlue;
|
||||
bool colorWriteGreen;
|
||||
bool colorWriteAlpha;
|
||||
|
||||
// Rasterizer
|
||||
bool cullDefined;
|
||||
GFXCullMode cullMode;
|
||||
|
||||
// Depth
|
||||
bool zDefined;
|
||||
bool zEnable;
|
||||
bool zWriteEnable;
|
||||
GFXCmpFunc zFunc;
|
||||
F32 zBias;
|
||||
F32 zSlopeBias;
|
||||
|
||||
// Stencil
|
||||
bool stencilDefined;
|
||||
bool stencilEnable;
|
||||
GFXStencilOp stencilFailOp;
|
||||
GFXStencilOp stencilZFailOp;
|
||||
GFXStencilOp stencilPassOp;
|
||||
GFXCmpFunc stencilFunc;
|
||||
U32 stencilRef;
|
||||
U32 stencilMask;
|
||||
U32 stencilWriteMask;
|
||||
|
||||
// FF lighting
|
||||
bool ffLighting;
|
||||
|
||||
bool vertexColorEnable;
|
||||
|
||||
GFXFillMode fillMode;
|
||||
|
||||
// Sampler states
|
||||
bool samplersDefined;
|
||||
GFXSamplerStateDesc samplers[TEXTURE_STAGE_COUNT];
|
||||
ColorI textureFactor;
|
||||
|
||||
GFXStateBlockDesc();
|
||||
|
||||
/// Returns the hash value of this state description
|
||||
U32 getHashValue() const;
|
||||
|
||||
/// Adds data from desc to this description, uses *defined parameters in desc to figure out
|
||||
/// what blocks of state to actually copy from desc.
|
||||
void addDesc( const GFXStateBlockDesc& desc );
|
||||
|
||||
/// Returns a string that describes the options set (used by GFXStateBlock::describeSelf)
|
||||
const String describeSelf() const;
|
||||
|
||||
/// Utility functions to make setting up stateblock descriptions less wordy.
|
||||
void setCullMode( GFXCullMode m );
|
||||
|
||||
/// Helpers for setting the fill modes.
|
||||
void setFillModePoint() { fillMode = GFXFillPoint; }
|
||||
void setFillModeWireframe() { fillMode = GFXFillWireframe; }
|
||||
void setFillModeSolid() { fillMode = GFXFillSolid; }
|
||||
|
||||
void setZReadWrite( bool read, bool write = true );
|
||||
|
||||
void setAlphaTest( bool enable,
|
||||
GFXCmpFunc func = GFXCmpGreaterEqual,
|
||||
S32 alphaRef = 0 );
|
||||
|
||||
void setBlend( bool enable,
|
||||
GFXBlend src = GFXBlendSrcAlpha,
|
||||
GFXBlend dest = GFXBlendInvSrcAlpha,
|
||||
GFXBlendOp op = GFXBlendOpAdd );
|
||||
|
||||
void setSeparateAlphaBlend( bool enable,
|
||||
GFXBlend src = GFXBlendOne,
|
||||
GFXBlend dest = GFXBlendZero,
|
||||
GFXBlendOp op = GFXBlendOpAdd );
|
||||
|
||||
|
||||
///
|
||||
void setColorWrites( bool red, bool green, bool blue, bool alpha );
|
||||
};
|
||||
|
||||
class GFXStateBlock : public StrongRefBase, public GFXResource
|
||||
{
|
||||
public:
|
||||
virtual ~GFXStateBlock() { }
|
||||
|
||||
/// Returns the hash value of the desc that created this block
|
||||
virtual U32 getHashValue() const = 0;
|
||||
|
||||
/// Returns a GFXStateBlockDesc that this block represents
|
||||
virtual const GFXStateBlockDesc& getDesc() const = 0;
|
||||
|
||||
/// Default implementation for GFXResource::describeSelf
|
||||
virtual const String describeSelf() const;
|
||||
};
|
||||
|
||||
typedef StrongRefPtr<GFXStateBlock> GFXStateBlockRef;
|
||||
|
||||
#endif
|
||||
418
Engine/source/gfx/gfxStringEnumTranslate.cpp
Normal file
418
Engine/source/gfx/gfxStringEnumTranslate.cpp
Normal file
|
|
@ -0,0 +1,418 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "core/strings/stringFunctions.h"
|
||||
|
||||
#include "gfx/gfxStringEnumTranslate.h"
|
||||
#include "gfx/gfxAPI.h"
|
||||
#include "console/console.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const char *GFXStringIndexFormat[GFXIndexFormat_COUNT];
|
||||
const char *GFXStringSamplerState[GFXSAMP_COUNT];
|
||||
const char *GFXStringTextureFormat[GFXFormat_COUNT];
|
||||
const char *GFXStringTiledTextureFormat[GFXFormat_COUNT];
|
||||
const char *GFXStringRenderTargetFormat[GFXFormat_COUNT];
|
||||
const char *GFXStringRenderState[GFXRenderState_COUNT];
|
||||
const char *GFXStringTextureFilter[GFXTextureFilter_COUNT];
|
||||
const char *GFXStringBlend[GFXBlend_COUNT];
|
||||
const char *GFXStringBlendOp[GFXBlendOp_COUNT];
|
||||
const char *GFXStringStencilOp[GFXStencilOp_COUNT];
|
||||
const char *GFXStringCmpFunc[GFXCmp_COUNT];
|
||||
const char *GFXStringCullMode[GFXCull_COUNT];
|
||||
const char *GFXStringPrimType[GFXPT_COUNT];
|
||||
const char *GFXStringTextureStageState[GFXTSS_COUNT];
|
||||
const char *GFXStringTextureAddress[GFXAddress_COUNT];
|
||||
const char *GFXStringTextureOp[GFXTOP_COUNT];
|
||||
const char *GFXStringFillMode[GFXFill_COUNT];
|
||||
|
||||
StringValueLookupFn GFXStringRenderStateValueLookup[GFXRenderState_COUNT];
|
||||
StringValueLookupFn GFXStringSamplerStateValueLookup[GFXSAMP_COUNT];
|
||||
StringValueLookupFn GFXStringTextureStageStateValueLookup[GFXTSS_COUNT];
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const char *defaultStringValueLookup( const U32 &value )
|
||||
{
|
||||
static char retbuffer[256];
|
||||
|
||||
dSprintf( retbuffer, sizeof( retbuffer ), "%d", value );
|
||||
|
||||
return retbuffer;
|
||||
}
|
||||
|
||||
#define _STRING_VALUE_LOOKUP_FXN( table ) \
|
||||
const char * table##_lookup( const U32 &value ) { return table[value]; }
|
||||
|
||||
_STRING_VALUE_LOOKUP_FXN(GFXStringTextureAddress);
|
||||
_STRING_VALUE_LOOKUP_FXN(GFXStringTextureFilter);
|
||||
_STRING_VALUE_LOOKUP_FXN(GFXStringBlend);
|
||||
_STRING_VALUE_LOOKUP_FXN(GFXStringTextureOp);
|
||||
_STRING_VALUE_LOOKUP_FXN(GFXStringCmpFunc);
|
||||
_STRING_VALUE_LOOKUP_FXN(GFXStringStencilOp);
|
||||
_STRING_VALUE_LOOKUP_FXN(GFXStringCullMode);
|
||||
_STRING_VALUE_LOOKUP_FXN(GFXStringBlendOp);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#define INIT_LOOKUPTABLE( tablearray, enumprefix, type ) \
|
||||
for( int i = enumprefix##_FIRST; i < enumprefix##_COUNT; i++ ) \
|
||||
tablearray[i] = (type)GFX_UNINIT_VAL;
|
||||
#define INIT_LOOKUPTABLE_EX( tablearray, enumprefix, type, typeTable ) \
|
||||
for( int i = enumprefix##_FIRST; i < enumprefix##_COUNT; i++ ) \
|
||||
{\
|
||||
tablearray[i] = (type)GFX_UNINIT_VAL;\
|
||||
typeTable[i] = &defaultStringValueLookup;\
|
||||
}
|
||||
|
||||
#define VALIDATE_LOOKUPTABLE( tablearray, enumprefix ) \
|
||||
for( int i = enumprefix##_FIRST; i < enumprefix##_COUNT; i++ ) \
|
||||
if( (int)tablearray[i] == GFX_UNINIT_VAL ) \
|
||||
Con::warnf( "GFXStringEnumTranslate: Unassigned value in " #tablearray ": %i", i ); \
|
||||
else if( (int)tablearray[i] == GFX_UNSUPPORTED_VAL ) \
|
||||
Con::warnf( "GFXStringEnumTranslate: Unsupported value in " #tablearray ": %i", i );
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#define GFX_STRING_ASSIGN_MACRO( table, indexEnum ) table[indexEnum] = #indexEnum;
|
||||
#define GFX_STRING_ASSIGN_MACRO_EX( table, indexEnum, typeTable ) table[indexEnum] = #indexEnum; table##ValueLookup[indexEnum] = &typeTable##_lookup;
|
||||
|
||||
void GFXStringEnumTranslate::init()
|
||||
{
|
||||
static bool sInitCalled = false;
|
||||
|
||||
if( sInitCalled )
|
||||
return;
|
||||
|
||||
sInitCalled = true;
|
||||
|
||||
INIT_LOOKUPTABLE( GFXStringIndexFormat, GFXIndexFormat, const char * );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringIndexFormat, GFXIndexFormat16 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringIndexFormat, GFXIndexFormat32 );
|
||||
VALIDATE_LOOKUPTABLE( GFXStringIndexFormat, GFXIndexFormat );
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
INIT_LOOKUPTABLE_EX( GFXStringSamplerState, GFXSAMP, const char *, GFXStringSamplerStateValueLookup );
|
||||
GFX_STRING_ASSIGN_MACRO_EX( GFXStringSamplerState, GFXSAMPAddressU, GFXStringTextureAddress );
|
||||
GFX_STRING_ASSIGN_MACRO_EX( GFXStringSamplerState, GFXSAMPAddressV, GFXStringTextureAddress );
|
||||
GFX_STRING_ASSIGN_MACRO_EX( GFXStringSamplerState, GFXSAMPAddressW, GFXStringTextureAddress );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringSamplerState, GFXSAMPBorderColor );
|
||||
GFX_STRING_ASSIGN_MACRO_EX( GFXStringSamplerState, GFXSAMPMagFilter, GFXStringTextureFilter );
|
||||
GFX_STRING_ASSIGN_MACRO_EX( GFXStringSamplerState, GFXSAMPMinFilter, GFXStringTextureFilter );
|
||||
GFX_STRING_ASSIGN_MACRO_EX( GFXStringSamplerState, GFXSAMPMipFilter, GFXStringTextureFilter );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringSamplerState, GFXSAMPMipMapLODBias );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringSamplerState, GFXSAMPMaxMipLevel );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringSamplerState, GFXSAMPMaxAnisotropy );
|
||||
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringSamplerState, GFXSAMPSRGBTexture );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringSamplerState, GFXSAMPElementIndex );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringSamplerState, GFXSAMPDMapOffset );
|
||||
|
||||
VALIDATE_LOOKUPTABLE( GFXStringSamplerState, GFXSAMP );
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
INIT_LOOKUPTABLE( GFXStringTextureFormat, GFXFormat, const char * );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatR8G8B8 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatR8G8B8A8 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatR8G8B8X8 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatR32F );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatR5G6B5 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatR5G5B5A1 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatR5G5B5X1 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatA4L4 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatA8L8 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatA8 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatL8 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatDXT1 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatDXT2 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatDXT3 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatDXT4 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatDXT5 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatD32 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatD24X8 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatD24S8 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatD24FS8 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatD16 );
|
||||
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatR32G32B32A32F );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatR16G16B16A16F );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatL16 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatR16G16B16A16 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatR16G16 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatR16F );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatR16G16F );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatR10G10B10A2 );
|
||||
VALIDATE_LOOKUPTABLE( GFXStringTextureFormat, GFXFormat);
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
INIT_LOOKUPTABLE_EX( GFXStringRenderState, GFXRenderState, const char *, GFXStringRenderStateValueLookup );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSZEnable );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSFillMode );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSZWriteEnable );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSAlphaTestEnable );
|
||||
GFX_STRING_ASSIGN_MACRO_EX( GFXStringRenderState, GFXRSSrcBlend, GFXStringBlend );
|
||||
GFX_STRING_ASSIGN_MACRO_EX( GFXStringRenderState, GFXRSDestBlend, GFXStringBlend );
|
||||
GFX_STRING_ASSIGN_MACRO_EX( GFXStringRenderState, GFXRSCullMode, GFXStringCullMode );
|
||||
GFX_STRING_ASSIGN_MACRO_EX( GFXStringRenderState, GFXRSZFunc, GFXStringCmpFunc );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSAlphaRef );
|
||||
GFX_STRING_ASSIGN_MACRO_EX( GFXStringRenderState, GFXRSAlphaFunc, GFXStringCmpFunc );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSAlphaBlendEnable );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSStencilEnable );
|
||||
GFX_STRING_ASSIGN_MACRO_EX( GFXStringRenderState, GFXRSStencilFail, GFXStringStencilOp );
|
||||
GFX_STRING_ASSIGN_MACRO_EX( GFXStringRenderState, GFXRSStencilZFail, GFXStringStencilOp );
|
||||
GFX_STRING_ASSIGN_MACRO_EX( GFXStringRenderState, GFXRSStencilPass, GFXStringStencilOp );
|
||||
GFX_STRING_ASSIGN_MACRO_EX( GFXStringRenderState, GFXRSStencilFunc, GFXStringCmpFunc );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSStencilRef );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSStencilMask );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSStencilWriteMask );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSWrap0 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSWrap1 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSWrap2 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSWrap3 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSWrap4 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSWrap5 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSWrap6 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSWrap7 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSClipPlaneEnable );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSPointSize );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSPointSizeMin );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSPointSize_Max );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSPointSpriteEnable );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSMultiSampleantiAlias );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSMultiSampleMask );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSShadeMode );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSLastPixel );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSClipping );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSPointScaleEnable );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSPointScale_A );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSPointScale_B );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSPointScale_C );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSLighting );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSAmbient );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSFogVertexMode );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSColorVertex );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSLocalViewer );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSNormalizeNormals );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSDiffuseMaterialSource );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSSpecularMaterialSource );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSAmbientMaterialSource );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSEmissiveMaterialSource );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSVertexBlend );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSFogEnable );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSSpecularEnable );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSFogColor );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSFogTableMode );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSFogStart );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSFogEnd );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSFogDensity );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSRangeFogEnable );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSDebugMonitorToken );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSIndexedVertexBlendEnable );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSTweenFactor );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSTextureFactor );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSPatchEdgeStyle );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSDitherEnable );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSColorWriteEnable );
|
||||
GFX_STRING_ASSIGN_MACRO_EX( GFXStringRenderState, GFXRSBlendOp, GFXStringBlendOp );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSPositionDegree );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSNormalDegree );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSAntiAliasedLineEnable );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSAdaptiveTess_X );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSAdaptiveTess_Y );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSdaptiveTess_Z );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSAdaptiveTess_W );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSEnableAdaptiveTesselation );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSScissorTestEnable );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSSlopeScaleDepthBias );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSMinTessellationLevel );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSMaxTessellationLevel );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSTwoSidedStencilMode );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSCCWStencilFail );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSCCWStencilZFail );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSCCWStencilPass );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSCCWStencilFunc );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSColorWriteEnable1 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSColorWriteEnable2 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSolorWriteEnable3 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSBlendFactor );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSSRGBWriteEnable );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSDepthBias );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSWrap8 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSWrap9 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSWrap10 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSWrap11 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSWrap12 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSWrap13 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSWrap14 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSWrap15 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringRenderState, GFXRSSeparateAlphaBlendEnable );
|
||||
GFX_STRING_ASSIGN_MACRO_EX( GFXStringRenderState, GFXRSSrcBlendAlpha, GFXStringBlend );
|
||||
GFX_STRING_ASSIGN_MACRO_EX( GFXStringRenderState, GFXRSDestBlendAlpha, GFXStringBlend );
|
||||
GFX_STRING_ASSIGN_MACRO_EX( GFXStringRenderState, GFXRSBlendOpAlpha, GFXStringBlendOp );
|
||||
|
||||
VALIDATE_LOOKUPTABLE( GFXStringRenderState, GFXRenderState );
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
INIT_LOOKUPTABLE( GFXStringTextureFilter, GFXTextureFilter, const char * );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFilter, GFXTextureFilterNone );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFilter, GFXTextureFilterPoint );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFilter, GFXTextureFilterLinear );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFilter, GFXTextureFilterAnisotropic );
|
||||
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFilter, GFXTextureFilterPyramidalQuad );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFilter, GFXTextureFilterGaussianQuad );
|
||||
|
||||
VALIDATE_LOOKUPTABLE( GFXStringTextureFilter, GFXTextureFilter );
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
INIT_LOOKUPTABLE( GFXStringBlend, GFXBlend, const char * );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringBlend, GFXBlendZero );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringBlend, GFXBlendOne );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringBlend, GFXBlendSrcColor );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringBlend, GFXBlendInvSrcColor );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringBlend, GFXBlendSrcAlpha );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringBlend, GFXBlendInvSrcAlpha );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringBlend, GFXBlendDestAlpha );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringBlend, GFXBlendInvDestAlpha );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringBlend, GFXBlendDestColor );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringBlend, GFXBlendInvDestColor );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringBlend, GFXBlendSrcAlphaSat );
|
||||
VALIDATE_LOOKUPTABLE( GFXStringBlend, GFXBlend );
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
INIT_LOOKUPTABLE( GFXStringBlendOp, GFXBlendOp, const char * );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringBlendOp, GFXBlendOpAdd );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringBlendOp, GFXBlendOpSubtract );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringBlendOp, GFXBlendOpRevSubtract );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringBlendOp, GFXBlendOpMin );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringBlendOp, GFXBlendOpMax );
|
||||
VALIDATE_LOOKUPTABLE( GFXStringBlendOp, GFXBlendOp );
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
INIT_LOOKUPTABLE( GFXStringStencilOp, GFXStencilOp, const char * );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringStencilOp, GFXStencilOpKeep );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringStencilOp, GFXStencilOpZero );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringStencilOp, GFXStencilOpReplace );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringStencilOp, GFXStencilOpIncrSat );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringStencilOp, GFXStencilOpDecrSat );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringStencilOp, GFXStencilOpInvert );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringStencilOp, GFXStencilOpIncr );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringStencilOp, GFXStencilOpDecr );
|
||||
VALIDATE_LOOKUPTABLE( GFXStringStencilOp, GFXStencilOp );
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
INIT_LOOKUPTABLE( GFXStringCmpFunc, GFXCmp, const char * );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringCmpFunc, GFXCmpNever );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringCmpFunc, GFXCmpLess );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringCmpFunc, GFXCmpEqual );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringCmpFunc, GFXCmpLessEqual );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringCmpFunc, GFXCmpGreater );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringCmpFunc, GFXCmpNotEqual );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringCmpFunc, GFXCmpGreaterEqual );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringCmpFunc, GFXCmpAlways );
|
||||
VALIDATE_LOOKUPTABLE( GFXStringCmpFunc, GFXCmp );
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
INIT_LOOKUPTABLE( GFXStringCullMode, GFXCull, const char * );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringCullMode, GFXCullNone );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringCullMode, GFXCullCW );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringCullMode, GFXCullCCW );
|
||||
VALIDATE_LOOKUPTABLE( GFXStringCullMode, GFXCull );
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
INIT_LOOKUPTABLE( GFXStringPrimType, GFXPT, const char * );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringPrimType, GFXPointList );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringPrimType, GFXLineList );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringPrimType, GFXLineStrip );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringPrimType, GFXTriangleList );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringPrimType, GFXTriangleStrip );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringPrimType, GFXTriangleFan );
|
||||
VALIDATE_LOOKUPTABLE( GFXStringPrimType, GFXPT );
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
INIT_LOOKUPTABLE_EX( GFXStringTextureStageState, GFXTSS, const char *, GFXStringTextureStageStateValueLookup );
|
||||
GFX_STRING_ASSIGN_MACRO_EX( GFXStringTextureStageState, GFXTSSColorOp, GFXStringTextureOp );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureStageState, GFXTSSColorArg1 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureStageState, GFXTSSColorArg2 );
|
||||
GFX_STRING_ASSIGN_MACRO_EX( GFXStringTextureStageState, GFXTSSAlphaOp, GFXStringTextureOp );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureStageState, GFXTSSAlphaArg1 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureStageState, GFXTSSAlphaArg2 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureStageState, GFXTSSBumpEnvMat00 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureStageState, GFXTSSBumpEnvMat01 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureStageState, GFXTSSBumpEnvMat10 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureStageState, GFXTSSBumpEnvMat11 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureStageState, GFXTSSTexCoordIndex );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureStageState, GFXTSSBumpEnvlScale );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureStageState, GFXTSSBumpEnvlOffset );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureStageState, GFXTSSTextureTransformFlags );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureStageState, GFXTSSColorArg0 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureStageState, GFXTSSAlphaArg0 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureStageState, GFXTSSResultArg );
|
||||
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureStageState, GFXTSSConstant );
|
||||
VALIDATE_LOOKUPTABLE( GFXStringTextureStageState, GFXTSS );
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
INIT_LOOKUPTABLE( GFXStringTextureAddress, GFXAddress, const char * );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureAddress, GFXAddressWrap );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureAddress, GFXAddressMirror );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureAddress, GFXAddressClamp );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureAddress, GFXAddressBorder );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureAddress, GFXAddressMirrorOnce );
|
||||
VALIDATE_LOOKUPTABLE(GFXStringTextureAddress, GFXAddress );
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
INIT_LOOKUPTABLE( GFXStringTextureOp, GFXTOP, const char * );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureOp, GFXTOPDisable );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureOp, GFXTOPSelectARG1 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureOp, GFXTOPSelectARG2 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureOp, GFXTOPModulate );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureOp, GFXTOPModulate2X );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureOp, GFXTOPModulate4X );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureOp, GFXTOPAdd );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureOp, GFXTOPAddSigned );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureOp, GFXTOPAddSigned2X );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureOp, GFXTOPSubtract );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureOp, GFXTOPAddSmooth );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureOp, GFXTOPBlendDiffuseAlpha );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureOp, GFXTOPBlendTextureAlpha );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureOp, GFXTOPBlendFactorAlpha );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureOp, GFXTOPBlendTextureAlphaPM );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureOp, GFXTOPBlendCURRENTALPHA );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureOp, GFXTOPPreModulate );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureOp, GFXTOPModulateAlphaAddColor );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureOp, GFXTOPModulateColorAddAlpha );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureOp, GFXTOPModulateInvAlphaAddColor );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureOp, GFXTOPModulateInvColorAddAlpha );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureOp, GFXTOPBumpEnvMap );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureOp, GFXTOPBumpEnvMapLuminance );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureOp, GFXTOPDotProduct3 );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringTextureOp, GFXTOPLERP );
|
||||
VALIDATE_LOOKUPTABLE( GFXStringTextureOp, GFXTOP );
|
||||
|
||||
INIT_LOOKUPTABLE( GFXStringFillMode, GFXFill, const char * );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringFillMode, GFXFillPoint );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringFillMode, GFXFillWireframe );
|
||||
GFX_STRING_ASSIGN_MACRO( GFXStringFillMode, GFXFillSolid );
|
||||
VALIDATE_LOOKUPTABLE( GFXStringFillMode, GFXFill );
|
||||
}
|
||||
89
Engine/source/gfx/gfxStringEnumTranslate.h
Normal file
89
Engine/source/gfx/gfxStringEnumTranslate.h
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef _GFXSTRINGENUMTRANSLATE_H_
|
||||
#define _GFXSTRINGENUMTRANSLATE_H_
|
||||
|
||||
#ifndef _PLATFORM_H_
|
||||
#include "platform/platform.h"
|
||||
#endif
|
||||
#ifndef _GFXENUMS_H_
|
||||
#include "gfx/gfxEnums.h"
|
||||
#endif
|
||||
#ifndef _CONSOLE_H_
|
||||
#include "console/console.h"
|
||||
#endif
|
||||
#ifndef _DYNAMIC_CONSOLETYPES_H_
|
||||
#include "console/dynamicTypes.h"
|
||||
#endif
|
||||
#ifndef _GFXAPI_H_
|
||||
#include "gfx/gfxAPI.h"
|
||||
#endif
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace GFXStringEnumTranslate
|
||||
{
|
||||
void init();
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
extern const char *GFXStringIndexFormat[GFXIndexFormat_COUNT];
|
||||
extern const char *GFXStringSamplerState[GFXSAMP_COUNT];
|
||||
extern const char *GFXStringTextureFormat[GFXFormat_COUNT];
|
||||
extern const char *GFXStringRenderState[GFXRenderState_COUNT];
|
||||
extern const char *GFXStringTextureFilter[GFXTextureFilter_COUNT];
|
||||
extern const char *GFXStringBlend[GFXBlend_COUNT];
|
||||
extern const char *GFXStringBlendOp[GFXBlendOp_COUNT];
|
||||
extern const char *GFXStringStencilOp[GFXStencilOp_COUNT];
|
||||
extern const char *GFXStringCmpFunc[GFXCmp_COUNT];
|
||||
extern const char *GFXStringCullMode[GFXCull_COUNT];
|
||||
extern const char *GFXStringPrimType[GFXPT_COUNT];
|
||||
extern const char *GFXStringTextureStageState[GFXTSS_COUNT];
|
||||
extern const char *GFXStringTextureAddress[GFXAddress_COUNT];
|
||||
extern const char *GFXStringTextureOp[GFXTOP_COUNT];
|
||||
extern const char *GFXStringFillMode[GFXFill_COUNT];
|
||||
|
||||
typedef const char *(*StringValueLookupFn)( const U32 &value );
|
||||
|
||||
extern StringValueLookupFn GFXStringRenderStateValueLookup[GFXRenderState_COUNT];
|
||||
extern StringValueLookupFn GFXStringSamplerStateValueLookup[GFXSAMP_COUNT];
|
||||
extern StringValueLookupFn GFXStringTextureStageStateValueLookup[GFXTSS_COUNT];
|
||||
|
||||
#define GFXREVERSE_LOOKUP( tablearray, enumprefix, val ) \
|
||||
for( int i = enumprefix##_FIRST; i < enumprefix##_COUNT; i++ ) \
|
||||
if( (int)tablearray##[i] == val ) \
|
||||
{ \
|
||||
val = i; \
|
||||
break; \
|
||||
} \
|
||||
|
||||
|
||||
// TODOS!
|
||||
extern EnumTable gTextureArgumentEnumTable_M;
|
||||
//extern EnumTable srcBlendFactorTable;
|
||||
//extern EnumTable dstBlendFactorTable;
|
||||
//extern EnumTable::Enums srcBlendFactorLookup[9];
|
||||
//extern EnumTable::Enums dstBlendFactorLookup[9];
|
||||
|
||||
#endif
|
||||
79
Engine/source/gfx/gfxStructs.cpp
Normal file
79
Engine/source/gfx/gfxStructs.cpp
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "gfx/gfxDevice.h"
|
||||
|
||||
|
||||
GFXVideoMode::GFXVideoMode()
|
||||
{
|
||||
bitDepth = 32;
|
||||
fullScreen = false;
|
||||
refreshRate = 60;
|
||||
wideScreen = false;
|
||||
resolution.set(800,600);
|
||||
antialiasLevel = 0;
|
||||
}
|
||||
|
||||
void GFXVideoMode::parseFromString( const char *str )
|
||||
{
|
||||
if(!str)
|
||||
return;
|
||||
|
||||
// Copy the string, as dStrtok is destructive
|
||||
char *tempBuf = new char[dStrlen( str ) + 1];
|
||||
dStrcpy( tempBuf, str );
|
||||
|
||||
#define PARSE_ELEM(type, var, func, tokParam, sep) \
|
||||
if(const char *ptr = dStrtok( tokParam, sep)) \
|
||||
{ type tmp = func(ptr); if(tmp > 0) var = tmp; }
|
||||
|
||||
PARSE_ELEM(S32, resolution.x, dAtoi, tempBuf, " x\0")
|
||||
PARSE_ELEM(S32, resolution.y, dAtoi, NULL, " x\0")
|
||||
PARSE_ELEM(S32, fullScreen, dAtob, NULL, " \0")
|
||||
PARSE_ELEM(S32, bitDepth, dAtoi, NULL, " \0")
|
||||
PARSE_ELEM(S32, refreshRate, dAtoi, NULL, " \0")
|
||||
PARSE_ELEM(S32, antialiasLevel, dAtoi, NULL, " \0")
|
||||
|
||||
#undef PARSE_ELEM
|
||||
|
||||
delete [] tempBuf;
|
||||
}
|
||||
|
||||
const String GFXVideoMode::toString() const
|
||||
{
|
||||
return String::ToString("%d %d %s %d %d %d", resolution.x, resolution.y, (fullScreen ? "true" : "false"), bitDepth, refreshRate, antialiasLevel);
|
||||
}
|
||||
|
||||
void GFXShaderMacro::stringize( const Vector<GFXShaderMacro> ¯os, String *outString )
|
||||
{
|
||||
Vector<GFXShaderMacro>::const_iterator itr = macros.begin();
|
||||
for ( ; itr != macros.end(); itr++ )
|
||||
{
|
||||
(*outString) += itr->name;
|
||||
if ( itr->value.isNotEmpty() )
|
||||
{
|
||||
(*outString) += "=";
|
||||
(*outString) += itr->value;
|
||||
}
|
||||
(*outString) += ";";
|
||||
}
|
||||
}
|
||||
194
Engine/source/gfx/gfxStructs.h
Normal file
194
Engine/source/gfx/gfxStructs.h
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GFXSTRUCTS_H_
|
||||
#define _GFXSTRUCTS_H_
|
||||
|
||||
#ifndef _COLOR_H_
|
||||
#include "core/color.h"
|
||||
#endif
|
||||
#ifndef _GFXVERTEXCOLOR_H_
|
||||
#include "gfx/gfxVertexColor.h"
|
||||
#endif
|
||||
#ifndef _GFXENUMS_H_
|
||||
#include "gfx/gfxEnums.h"
|
||||
#endif
|
||||
#ifndef _MMATH_H_
|
||||
#include "math/mMath.h"
|
||||
#endif
|
||||
#ifndef _PROFILER_H_
|
||||
#include "platform/profiler.h"
|
||||
#endif
|
||||
#ifndef _GFXRESOURCE_H_
|
||||
#include "gfx/gfxResource.h"
|
||||
#endif
|
||||
#ifndef _REFBASE_H_
|
||||
#include "core/util/refBase.h"
|
||||
#endif
|
||||
#ifndef _GFXVERTEXTYPES_H_
|
||||
#include "gfx/gfxVertexTypes.h"
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This class is used to interact with an API's fixed function lights. See GFX->setLight
|
||||
class GFXLightInfo
|
||||
{
|
||||
public:
|
||||
enum Type {
|
||||
Point = 0,
|
||||
Spot = 1,
|
||||
Vector = 2,
|
||||
Ambient = 3,
|
||||
};
|
||||
Type mType;
|
||||
|
||||
Point3F mPos;
|
||||
VectorF mDirection;
|
||||
ColorF mColor;
|
||||
ColorF mAmbient;
|
||||
F32 mRadius;
|
||||
F32 mInnerConeAngle;
|
||||
F32 mOuterConeAngle;
|
||||
|
||||
/// @todo Revisit below (currently unused by fixed function lights)
|
||||
Point3F position;
|
||||
ColorF ambient;
|
||||
ColorF diffuse;
|
||||
ColorF specular;
|
||||
VectorF spotDirection;
|
||||
F32 spotExponent;
|
||||
F32 spotCutoff;
|
||||
F32 constantAttenuation;
|
||||
F32 linearAttenuation;
|
||||
F32 quadraticAttenuation;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Material definition for FF lighting
|
||||
struct GFXLightMaterial
|
||||
{
|
||||
ColorF ambient;
|
||||
ColorF diffuse;
|
||||
ColorF specular;
|
||||
ColorF emissive;
|
||||
F32 shininess;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
struct GFXVideoMode
|
||||
{
|
||||
GFXVideoMode();
|
||||
|
||||
Point2I resolution;
|
||||
U32 bitDepth;
|
||||
U32 refreshRate;
|
||||
bool fullScreen;
|
||||
bool wideScreen;
|
||||
// When this is returned from GFX, it's the max, otherwise it's the desired AA level.
|
||||
U32 antialiasLevel;
|
||||
|
||||
inline bool operator == ( const GFXVideoMode &otherMode ) const
|
||||
{
|
||||
if( otherMode.fullScreen != fullScreen )
|
||||
return false;
|
||||
if( otherMode.resolution != resolution )
|
||||
return false;
|
||||
if( otherMode.bitDepth != bitDepth )
|
||||
return false;
|
||||
if( otherMode.refreshRate != refreshRate )
|
||||
return false;
|
||||
if( otherMode.wideScreen != wideScreen )
|
||||
return false;
|
||||
if( otherMode.antialiasLevel != antialiasLevel)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool operator !=( const GFXVideoMode& otherMode ) const
|
||||
{
|
||||
return !( *this == otherMode );
|
||||
}
|
||||
|
||||
/// Fill whatever fields we can from the passed string, which should be
|
||||
/// of form "width height [bitDepth [refreshRate] [antialiasLevel]]" Unspecified fields
|
||||
/// aren't modified, so you may want to set defaults before parsing.
|
||||
void parseFromString( const char *str );
|
||||
|
||||
/// Gets a string representation of the object as
|
||||
/// "resolution.x resolution.y fullScreen bitDepth refreshRate antialiasLevel"
|
||||
///
|
||||
/// \return (string) A string representation of the object.
|
||||
const String toString() const;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
struct GFXPrimitive
|
||||
{
|
||||
GFXPrimitiveType type;
|
||||
|
||||
U32 startVertex; /// offset into vertex buffer to change where vertex[0] is
|
||||
U32 minIndex; /// minimal value we will see in the indices
|
||||
U32 startIndex; /// start of indices in buffer
|
||||
U32 numPrimitives; /// how many prims to render
|
||||
U32 numVertices; /// how many vertices... (used for locking, we lock from minIndex to minIndex + numVertices)
|
||||
|
||||
GFXPrimitive()
|
||||
{
|
||||
dMemset( this, 0, sizeof( GFXPrimitive ) );
|
||||
}
|
||||
};
|
||||
|
||||
/// Passed to GFX for shader defines.
|
||||
struct GFXShaderMacro
|
||||
{
|
||||
GFXShaderMacro() {}
|
||||
|
||||
GFXShaderMacro( const GFXShaderMacro ¯o )
|
||||
: name( macro.name ),
|
||||
value( macro.value )
|
||||
{}
|
||||
|
||||
GFXShaderMacro( const String &name_,
|
||||
const String &value_ = String::EmptyString )
|
||||
: name( name_ ),
|
||||
value( value_ )
|
||||
{}
|
||||
|
||||
~GFXShaderMacro() {}
|
||||
|
||||
/// The macro name.
|
||||
String name;
|
||||
|
||||
/// The optional macro value.
|
||||
String value;
|
||||
|
||||
static void stringize( const Vector<GFXShaderMacro> ¯os, String *outString );
|
||||
};
|
||||
|
||||
|
||||
#endif // _GFXSTRUCTS_H_
|
||||
31
Engine/source/gfx/gfxTarget.cpp
Normal file
31
Engine/source/gfx/gfxTarget.cpp
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "gfx/gfxTarget.h"
|
||||
#include "console/console.h"
|
||||
|
||||
GFXTextureObject *GFXTextureTarget::sDefaultDepthStencil = reinterpret_cast<GFXTextureObject *>( 0x1 );
|
||||
|
||||
const String GFXTarget::describeSelf() const
|
||||
{
|
||||
return String();
|
||||
}
|
||||
207
Engine/source/gfx/gfxTarget.h
Normal file
207
Engine/source/gfx/gfxTarget.h
Normal file
|
|
@ -0,0 +1,207 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GFXTARGET_H_
|
||||
#define _GFXTARGET_H_
|
||||
|
||||
#ifndef _REFBASE_H_
|
||||
#include "core/util/refBase.h"
|
||||
#endif
|
||||
#ifndef _GFXENUMS_H_
|
||||
#include "gfx/gfxEnums.h"
|
||||
#endif
|
||||
#ifndef _GFXRESOURCE_H_
|
||||
#include "gfx/gfxResource.h"
|
||||
#endif
|
||||
#ifndef _MPOINT3_H_
|
||||
#include "math/mPoint3.h"
|
||||
#endif
|
||||
|
||||
|
||||
class Point2I;
|
||||
class PlatformWindow;
|
||||
class GFXCubemap;
|
||||
class GFXTextureObject;
|
||||
|
||||
/// Base class for a target to which GFX can render.
|
||||
///
|
||||
/// Most modern graphics hardware supports selecting render targets. However,
|
||||
/// there may be multiple types of render target, with wildly varying
|
||||
/// device-level implementations, resource requirements, and so forth.
|
||||
///
|
||||
/// This base class is used to represent a render target; it might be a context
|
||||
/// tied to a window, or a set of surfaces or textures.
|
||||
class GFXTarget : public StrongRefBase, public GFXResource
|
||||
{
|
||||
friend class GFXD3D9Device;
|
||||
friend class GFX360Device;
|
||||
|
||||
private:
|
||||
S32 mChangeToken;
|
||||
S32 mLastAppliedChange;
|
||||
|
||||
protected:
|
||||
|
||||
/// Called whenever a change is made to this target.
|
||||
inline void invalidateState()
|
||||
{
|
||||
mChangeToken++;
|
||||
}
|
||||
|
||||
/// Called when the device has applied pending state.
|
||||
inline void stateApplied()
|
||||
{
|
||||
mLastAppliedChange = mChangeToken;
|
||||
}
|
||||
public:
|
||||
|
||||
/// Constructor to initialize the state tracking logic.
|
||||
GFXTarget() : mChangeToken( 0 ),
|
||||
mLastAppliedChange( 0 )
|
||||
{
|
||||
}
|
||||
virtual ~GFXTarget() {}
|
||||
|
||||
/// Called to check if we have pending state for the device to apply.
|
||||
inline const bool isPendingState() const
|
||||
{
|
||||
return (mChangeToken != mLastAppliedChange);
|
||||
}
|
||||
|
||||
/// Returns the size in pixels of the render target.
|
||||
virtual const Point2I getSize()=0;
|
||||
|
||||
/// Returns the texture format of the render target.
|
||||
virtual GFXFormat getFormat()=0;
|
||||
|
||||
// GFXResourceInterface
|
||||
/// The resource should put a description of itself (number of vertices, size/width of texture, etc.) in buffer
|
||||
virtual const String describeSelf() const;
|
||||
|
||||
/// This is called to set the render target.
|
||||
virtual void activate() { }
|
||||
|
||||
/// This is called when the target is not being used anymore.
|
||||
virtual void deactivate() { }
|
||||
|
||||
/// This tells the target that the contents of this target should be restored
|
||||
/// when activate() is next called.
|
||||
virtual void preserve() { }
|
||||
|
||||
/// Copy this surface to the passed GFXTextureObject.
|
||||
/// @param tex The GFXTextureObject to copy to.
|
||||
virtual void resolveTo( GFXTextureObject *tex ) { }
|
||||
};
|
||||
|
||||
/// A render target associated with an OS window.
|
||||
///
|
||||
/// Various API/OS combinations will implement their own GFXTargets for
|
||||
/// rendering to a window. However, they are all subclasses of GFXWindowTarget.
|
||||
///
|
||||
/// This allows platform-neutral code to safely distinguish between various
|
||||
/// types of render targets (using dynamic_cast<>), as well as letting it
|
||||
/// gain access to useful things like the corresponding PlatformWindow.
|
||||
class GFXWindowTarget : public GFXTarget
|
||||
{
|
||||
protected:
|
||||
PlatformWindow *mWindow;
|
||||
public:
|
||||
GFXWindowTarget() : mWindow(NULL){};
|
||||
GFXWindowTarget( PlatformWindow *windowObject )
|
||||
{
|
||||
mWindow = windowObject;
|
||||
}
|
||||
virtual ~GFXWindowTarget() {}
|
||||
|
||||
/// Returns a pointer to the window this target is bound to.
|
||||
inline PlatformWindow *getWindow() { return mWindow; };
|
||||
|
||||
/// Present latest buffer, if buffer swapping is in effect.
|
||||
virtual bool present()=0;
|
||||
|
||||
/// Notify the target that the video mode on the window has changed.
|
||||
virtual void resetMode()=0;
|
||||
};
|
||||
|
||||
/// A render target associated with one or more textures.
|
||||
///
|
||||
/// Although some APIs allow directly selecting any texture or surfaces, in
|
||||
/// some cases it is necessary to allocate helper resources to enable RTT
|
||||
/// operations.
|
||||
///
|
||||
/// @note A GFXTextureTarget will retain references to textures that are
|
||||
/// attached to it, so be sure to clear them out when you're done!
|
||||
///
|
||||
/// @note Different APIs have different restrictions on what they can support
|
||||
/// here. Be aware when mixing cubemaps vs. non-cubemaps, or targets of
|
||||
/// different resolutions. The devices will attempt to limit behavior
|
||||
/// to things that are safely portable, but they cannot catch every
|
||||
/// possible situation for all drivers and API - so make sure to
|
||||
/// actually test things!
|
||||
class GFXTextureTarget : public GFXTarget
|
||||
{
|
||||
public:
|
||||
enum RenderSlot
|
||||
{
|
||||
DepthStencil,
|
||||
Color0, Color1, Color2, Color3, Color4,
|
||||
MaxRenderSlotId,
|
||||
};
|
||||
|
||||
static GFXTextureObject *sDefaultDepthStencil;
|
||||
|
||||
virtual ~GFXTextureTarget() {}
|
||||
|
||||
/// Attach a surface to a given slot as part of this render target.
|
||||
///
|
||||
/// @param slot What slot is used for multiple render target (MRT) effects.
|
||||
/// Most of the time you'll use Color0.
|
||||
/// @param tex A texture and miplevel to bind for rendering, or else NULL/0
|
||||
/// to clear a slot.
|
||||
/// @param mipLevel What level of this texture are we rendering to?
|
||||
/// @param zOffset If this is a depth texture, what z level are we
|
||||
/// rendering to?
|
||||
virtual void attachTexture(RenderSlot slot, GFXTextureObject *tex, U32 mipLevel=0, U32 zOffset = 0) = 0;
|
||||
|
||||
/// Support binding to cubemaps.
|
||||
///
|
||||
/// @param slot What slot is used for multiple render target (MRT) effects.
|
||||
/// Most of the time you'll use Color0.
|
||||
/// @param tex What cubemap will we be rendering to?
|
||||
/// @param face A face identifier.
|
||||
/// @param mipLevel What level of this texture are we rendering to?
|
||||
virtual void attachTexture(RenderSlot slot, GFXCubemap *tex, U32 face, U32 mipLevel=0) = 0;
|
||||
|
||||
/// Resolve the current render target data to the associated textures. This method
|
||||
/// will get called automatically when a rendertarget is changed, before new geometry
|
||||
/// is drawn to a different rendertarget. This method can also be called to
|
||||
/// gather render target data without switching targets.
|
||||
///
|
||||
/// By default, this method will resolve all color targets.
|
||||
virtual void resolve()=0;
|
||||
};
|
||||
|
||||
typedef StrongRefPtr<GFXTarget> GFXTargetRef;
|
||||
typedef StrongRefPtr<GFXWindowTarget> GFXWindowTargetRef;
|
||||
typedef StrongRefPtr<GFXTextureTarget> GFXTextureTargetRef;
|
||||
|
||||
#endif // _GFXTARGET_H_
|
||||
161
Engine/source/gfx/gfxTextureHandle.cpp
Normal file
161
Engine/source/gfx/gfxTextureHandle.cpp
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "gfx/gfxTextureHandle.h"
|
||||
|
||||
#include "gfx/gfxDevice.h"
|
||||
#include "gfx/gfxTextureManager.h"
|
||||
|
||||
|
||||
GFXTexHandle GFXTexHandle::ZERO;
|
||||
GFXTexHandle GFXTexHandle::ONE;
|
||||
GFXTexHandle GFXTexHandle::ZUP;
|
||||
|
||||
|
||||
GFXTexHandle::GFXTexHandle( GFXTextureObject *obj )
|
||||
{
|
||||
StrongObjectRef::set( obj );
|
||||
}
|
||||
|
||||
GFXTexHandle::GFXTexHandle( const GFXTexHandle &handle, const String &desc )
|
||||
{
|
||||
StrongObjectRef::set( handle.getPointer() );
|
||||
|
||||
#ifdef TORQUE_DEBUG
|
||||
if ( getPointer() )
|
||||
getPointer()->mDebugDescription = desc;
|
||||
#endif
|
||||
}
|
||||
|
||||
GFXTexHandle::GFXTexHandle( const String &texName, GFXTextureProfile *profile, const String &desc )
|
||||
{
|
||||
set( texName, profile, desc );
|
||||
}
|
||||
|
||||
bool GFXTexHandle::set( const String &texName, GFXTextureProfile *profile, const String &desc )
|
||||
{
|
||||
// Clear the existing texture first, so that
|
||||
// its memory is free for the new allocation.
|
||||
free();
|
||||
|
||||
// Create and set the new texture.
|
||||
AssertFatal( texName.isNotEmpty(), "Texture name is empty" );
|
||||
StrongObjectRef::set( TEXMGR->createTexture( texName, profile ) );
|
||||
|
||||
#ifdef TORQUE_DEBUG
|
||||
if ( getPointer() )
|
||||
getPointer()->mDebugDescription = desc;
|
||||
#endif
|
||||
|
||||
return isValid();
|
||||
}
|
||||
|
||||
GFXTexHandle::GFXTexHandle( GBitmap *bmp, GFXTextureProfile *profile, bool deleteBmp, const String &desc )
|
||||
{
|
||||
set( bmp, profile, deleteBmp, desc );
|
||||
}
|
||||
|
||||
bool GFXTexHandle::set( GBitmap *bmp, GFXTextureProfile *profile, bool deleteBmp, const String &desc )
|
||||
{
|
||||
// Clear the existing texture first, so that
|
||||
// its memory is free for the new allocation.
|
||||
free();
|
||||
|
||||
// Create and set the new texture.
|
||||
AssertFatal( bmp, "Bitmap is NULL" );
|
||||
StrongObjectRef::set( TEXMGR->createTexture( bmp, String(), profile, deleteBmp ) );
|
||||
|
||||
#ifdef TORQUE_DEBUG
|
||||
if ( getPointer() )
|
||||
getPointer()->mDebugDescription = desc;
|
||||
#endif
|
||||
|
||||
return isValid();
|
||||
}
|
||||
|
||||
GFXTexHandle::GFXTexHandle( DDSFile *dds, GFXTextureProfile *profile, bool deleteDDS, const String &desc )
|
||||
{
|
||||
set( dds, profile, deleteDDS, desc );
|
||||
}
|
||||
|
||||
bool GFXTexHandle::set( DDSFile *dds, GFXTextureProfile *profile, bool deleteDDS, const String &desc )
|
||||
{
|
||||
// Clear the existing texture first, so that
|
||||
// its memory is free for the new allocation.
|
||||
free();
|
||||
|
||||
// Create and set the new texture.
|
||||
AssertFatal( dds, "Bitmap is NULL" );
|
||||
StrongObjectRef::set( TEXMGR->createTexture( dds, profile, deleteDDS ) );
|
||||
|
||||
#ifdef TORQUE_DEBUG
|
||||
if ( getPointer() )
|
||||
getPointer()->mDebugDescription = desc;
|
||||
#endif
|
||||
|
||||
return isValid();
|
||||
}
|
||||
|
||||
GFXTexHandle::GFXTexHandle( U32 width, U32 height, GFXFormat format, GFXTextureProfile *profile, const String &desc, U32 numMipLevels, S32 antialiasLevel)
|
||||
{
|
||||
set( width, height, format, profile, desc, numMipLevels, antialiasLevel );
|
||||
}
|
||||
|
||||
bool GFXTexHandle::set( U32 width, U32 height, GFXFormat format, GFXTextureProfile *profile, const String &desc, U32 numMipLevels, S32 antialiasLevel)
|
||||
{
|
||||
// Clear the existing texture first, so that
|
||||
// its memory is free for the new allocation.
|
||||
free();
|
||||
|
||||
// Create and set the new texture.
|
||||
StrongObjectRef::set( TEXMGR->createTexture( width, height, format, profile, numMipLevels, antialiasLevel ) );
|
||||
|
||||
#ifdef TORQUE_DEBUG
|
||||
if ( getPointer() )
|
||||
getPointer()->mDebugDescription = desc;
|
||||
#endif
|
||||
|
||||
return isValid();
|
||||
}
|
||||
|
||||
bool GFXTexHandle::set( U32 width, U32 height, U32 depth, void *pixels, GFXFormat format, GFXTextureProfile *profile, const String &desc, U32 numMipLevels )
|
||||
{
|
||||
// Clear the existing texture first, so that
|
||||
// its memory is free for the new allocation.
|
||||
free();
|
||||
|
||||
// Create and set the new texture.
|
||||
StrongObjectRef::set( TEXMGR->createTexture( width, height, depth, pixels, format, profile ) );
|
||||
|
||||
#ifdef TORQUE_DEBUG
|
||||
if ( getPointer() )
|
||||
getPointer()->mDebugDescription = desc;
|
||||
#endif
|
||||
|
||||
return isValid();
|
||||
}
|
||||
|
||||
void GFXTexHandle::refresh()
|
||||
{
|
||||
TEXMGR->reloadTexture( getPointer() );
|
||||
}
|
||||
129
Engine/source/gfx/gfxTextureHandle.h
Normal file
129
Engine/source/gfx/gfxTextureHandle.h
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GFXTEXTUREHANDLE_H_
|
||||
#define _GFXTEXTUREHANDLE_H_
|
||||
|
||||
#ifndef _GFXTEXTUREOBJECT_H_
|
||||
#include "gfx/gfxTextureObject.h"
|
||||
#endif
|
||||
#ifndef _MPOINT2_H_
|
||||
#include "math/mPoint2.h"
|
||||
#endif
|
||||
|
||||
|
||||
class GFXTextureProfile;
|
||||
|
||||
|
||||
/// A reference counted handle to a texture resource.
|
||||
class GFXTexHandle : public StrongRefPtr<GFXTextureObject>
|
||||
{
|
||||
public:
|
||||
GFXTexHandle() {}
|
||||
GFXTexHandle( GFXTextureObject* obj );
|
||||
GFXTexHandle( const GFXTexHandle &handle, const String &desc );
|
||||
|
||||
// load texture
|
||||
GFXTexHandle( const String &texName, GFXTextureProfile *profile, const String &desc );
|
||||
bool set( const String &texName, GFXTextureProfile *profile, const String &desc );
|
||||
|
||||
// register texture
|
||||
GFXTexHandle( GBitmap *bmp, GFXTextureProfile *profile, bool deleteBmp, const String &desc );
|
||||
bool set( GBitmap *bmp, GFXTextureProfile *profile, bool deleteBmp, const String &desc );
|
||||
|
||||
GFXTexHandle( DDSFile *bmp, GFXTextureProfile *profile, bool deleteDDS, const String &desc );
|
||||
bool set( DDSFile *bmp, GFXTextureProfile *profile, bool deleteDDS, const String &desc );
|
||||
|
||||
// Sized bitmap
|
||||
GFXTexHandle( U32 width, U32 height, GFXFormat format, GFXTextureProfile *profile, const String &desc, U32 numMipLevels = 1, S32 antialiasLevel = 0);
|
||||
bool set( U32 width, U32 height, GFXFormat format, GFXTextureProfile *profile, const String &desc, U32 numMipLevels = 1, S32 antialiasLevel = 0);
|
||||
bool set( U32 width, U32 height, U32 depth, void *pixels, GFXFormat format, GFXTextureProfile *profile, const String &desc, U32 numMipLevels = 1 );
|
||||
|
||||
/// Returns the width and height as a point.
|
||||
Point2I getWidthHeight() const { return getPointer() ? Point2I( getPointer()->getWidth(), getPointer()->getHeight() ) : Point2I::Zero; }
|
||||
|
||||
U32 getWidth() const { return getPointer() ? getPointer()->getWidth() : 0; }
|
||||
U32 getHeight() const { return getPointer() ? getPointer()->getHeight() : 0; }
|
||||
U32 getDepth() const { return getPointer() ? getPointer()->getDepth() : 0; }
|
||||
GFXFormat getFormat() const { return getPointer() ? getPointer()->getFormat() : GFXFormat_COUNT; }
|
||||
|
||||
/// Reloads the texture.
|
||||
/// @see GFXTextureManager::reloadTexture
|
||||
void refresh();
|
||||
|
||||
/// Releases the texture handle.
|
||||
void free() { StrongObjectRef::set( NULL ); }
|
||||
|
||||
GFXLockedRect *lock( U32 mipLevel = 0, RectI *inRect = NULL )
|
||||
{
|
||||
return getPointer()->lock(mipLevel, inRect);
|
||||
}
|
||||
|
||||
void unlock( U32 mipLevel = 0)
|
||||
{
|
||||
getPointer()->unlock(mipLevel);
|
||||
}
|
||||
|
||||
// copy to bitmap. see gfxTetureObject.h for description of what types of textures
|
||||
// can be copied into bitmaps. returns true if successful, false otherwise
|
||||
bool copyToBmp(GBitmap* bmp) { return getPointer() ? getPointer()->copyToBmp(bmp) : false; }
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Operator overloads
|
||||
//---------------------------------------------------------------------------
|
||||
GFXTexHandle& operator=(const GFXTexHandle &t)
|
||||
{
|
||||
StrongObjectRef::set(t.getPointer());
|
||||
return *this;
|
||||
}
|
||||
|
||||
GFXTexHandle& operator=( GFXTextureObject *to)
|
||||
{
|
||||
StrongObjectRef::set(to);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const GFXTexHandle &t) const { return t.getPointer() == getPointer(); }
|
||||
bool operator!=(const GFXTexHandle &t) const { return t.getPointer() != getPointer(); }
|
||||
|
||||
/// Returns the texture object.
|
||||
operator GFXTextureObject*() const { return getPointer(); }
|
||||
|
||||
/// Returns the backing bitmap for this texture.
|
||||
GBitmap* getBitmap() { return getPointer() ? getPointer()->getBitmap() : NULL; }
|
||||
const GBitmap* getBitmap() const { return getPointer() ? getPointer()->getBitmap() : NULL; }
|
||||
|
||||
|
||||
/// Helper 2x2 R8G8B8A8 texture filled with 0.
|
||||
static GFXTexHandle ZERO;
|
||||
|
||||
/// Helper 2x2 R8G8B8A8 texture filled with 255.
|
||||
static GFXTexHandle ONE;
|
||||
|
||||
/// Helper 2x2 R8G8B8A8 normal map texture filled
|
||||
/// with 128, 128, 255.
|
||||
static GFXTexHandle ZUP;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // _GFXTEXTUREHANDLE_H_
|
||||
1229
Engine/source/gfx/gfxTextureManager.cpp
Normal file
1229
Engine/source/gfx/gfxTextureManager.cpp
Normal file
File diff suppressed because it is too large
Load diff
348
Engine/source/gfx/gfxTextureManager.h
Normal file
348
Engine/source/gfx/gfxTextureManager.h
Normal file
|
|
@ -0,0 +1,348 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GFXTEXTUREMANAGER_H_
|
||||
#define _GFXTEXTUREMANAGER_H_
|
||||
|
||||
#ifndef _GFXTEXTUREOBJECT_H_
|
||||
#include "gfx/gfxTextureObject.h"
|
||||
#endif
|
||||
#ifndef _GBITMAP_H_
|
||||
#include "gfx/bitmap/gBitmap.h"
|
||||
#endif
|
||||
#ifndef _DDSFILE_H_
|
||||
#include "gfx/bitmap/ddsFile.h"
|
||||
#endif
|
||||
#ifndef _RESOURCEMANAGER_H_
|
||||
#include "core/resourceManager.h"
|
||||
#endif
|
||||
#ifndef _TDICTIONARY_H_
|
||||
#include "core/util/tDictionary.h"
|
||||
#endif
|
||||
#ifndef _TSIGNAL_H_
|
||||
#include "core/util/tSignal.h"
|
||||
#endif
|
||||
|
||||
|
||||
namespace Torque
|
||||
{
|
||||
class Path;
|
||||
}
|
||||
|
||||
class GFXCubemap;
|
||||
|
||||
|
||||
class GFXTextureManager
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
AA_MATCH_BACKBUFFER = -1
|
||||
};
|
||||
|
||||
GFXTextureManager();
|
||||
virtual ~GFXTextureManager();
|
||||
|
||||
/// Set up some global script interface stuff.
|
||||
static void init();
|
||||
|
||||
/// Update width and height based on available resources.
|
||||
///
|
||||
/// We provide a simple interface for managing texture memory usage. Specifically,
|
||||
/// if the total video memory is below a certain threshold, we scale all texture
|
||||
/// resolutions down by a specific factor (you can specify different scale factors
|
||||
/// for different types of textures).
|
||||
///
|
||||
/// @note The base GFXTextureManager class provides all the logic to do this scaling.
|
||||
/// Subclasses need only implement getTotalVideoMemory().
|
||||
///
|
||||
/// @param type Type of the requested texture. This is used to determine scaling factors.
|
||||
/// @param width Requested width - is changed to the actual width that should be used.
|
||||
/// @param height Requested height - is changed to the actual height that should be used.
|
||||
/// @return True if the texture request should be granted, false otherwise.
|
||||
virtual bool validateTextureQuality(GFXTextureProfile *profile, U32 &width, U32 &height);
|
||||
|
||||
///
|
||||
static U32 getTextureDownscalePower( GFXTextureProfile *profile );
|
||||
|
||||
virtual GFXTextureObject *createTexture( GBitmap *bmp,
|
||||
const String &resourceName,
|
||||
GFXTextureProfile *profile,
|
||||
bool deleteBmp);
|
||||
|
||||
virtual GFXTextureObject *createTexture( DDSFile *dds,
|
||||
GFXTextureProfile *profile,
|
||||
bool deleteDDS);
|
||||
|
||||
virtual GFXTextureObject *createTexture( const Torque::Path &path,
|
||||
GFXTextureProfile *profile );
|
||||
|
||||
virtual GFXTextureObject *createTexture( U32 width,
|
||||
U32 height,
|
||||
void *pixels,
|
||||
GFXFormat format,
|
||||
GFXTextureProfile *profile);
|
||||
|
||||
virtual GFXTextureObject *createTexture( U32 width,
|
||||
U32 height,
|
||||
U32 depth,
|
||||
void *pixels,
|
||||
GFXFormat format,
|
||||
GFXTextureProfile *profile );
|
||||
|
||||
virtual GFXTextureObject *createTexture( U32 width,
|
||||
U32 height,
|
||||
GFXFormat format,
|
||||
GFXTextureProfile *profile,
|
||||
U32 numMipLevels,
|
||||
S32 antialiasLevel);
|
||||
|
||||
void deleteTexture( GFXTextureObject *texture );
|
||||
void reloadTexture( GFXTextureObject *texture );
|
||||
|
||||
/// Request that the texture be deleted which will
|
||||
/// either occur immediately or delayed if its cached.
|
||||
void requestDeleteTexture( GFXTextureObject *texture );
|
||||
|
||||
/// @name Texture Necromancy
|
||||
///
|
||||
/// Texture necromancy in three easy steps:
|
||||
/// - If you want to destroy the texture manager, call kill().
|
||||
/// - If you want to switch resolutions, or otherwise reset the device, call zombify().
|
||||
/// - When you want to bring the manager back from zombie state, call resurrect().
|
||||
/// @{
|
||||
|
||||
///
|
||||
void kill();
|
||||
void zombify();
|
||||
void resurrect();
|
||||
|
||||
/// This releases any pooled textures which are
|
||||
/// currently unused freeing up video memory.
|
||||
void cleanupPool();
|
||||
|
||||
///
|
||||
void reloadTextures();
|
||||
|
||||
/// This releases cached textures that have not
|
||||
/// been referenced for a period of time.
|
||||
void cleanupCache( U32 secondsToLive = 0 );
|
||||
|
||||
/// Registers a callback for texture zombify and resurrect events.
|
||||
/// @see GFXTexCallbackCode
|
||||
/// @see removeEventDelegate
|
||||
template <class T,class U>
|
||||
static void addEventDelegate( T obj, U func );
|
||||
|
||||
/// Unregisteres a texture event callback.
|
||||
/// @see addEventDelegate
|
||||
template <class T,class U>
|
||||
static void removeEventDelegate( T obj, U func ) { smEventSignal.remove( obj, func ); }
|
||||
|
||||
/// @}
|
||||
|
||||
/// Load a cubemap from a texture file.
|
||||
GFXCubemap* createCubemap( const Torque::Path &path );
|
||||
|
||||
/// Used to remove a cubemap from the cache.
|
||||
void releaseCubemap( GFXCubemap *cubemap );
|
||||
|
||||
protected:
|
||||
|
||||
/// The amount of texture mipmaps to skip when loading a
|
||||
/// texture that allows downscaling.
|
||||
///
|
||||
/// Exposed to script via $pref::Video::textureReductionLevel.
|
||||
///
|
||||
/// @see GFXTextureProfile::PreserveSize
|
||||
///
|
||||
static S32 smTextureReductionLevel;
|
||||
|
||||
GFXTextureObject *mListHead;
|
||||
GFXTextureObject *mListTail;
|
||||
|
||||
// We have a hash table for fast texture lookups
|
||||
GFXTextureObject **mHashTable;
|
||||
U32 mHashCount;
|
||||
GFXTextureObject *hashFind( const String &name );
|
||||
void hashInsert(GFXTextureObject *object);
|
||||
void hashRemove(GFXTextureObject *object);
|
||||
|
||||
// The cache of loaded cubemap textures.
|
||||
typedef HashTable<String,GFXCubemap*> CubemapTable;
|
||||
CubemapTable mCubemapTable;
|
||||
|
||||
/// The textures waiting to be deleted.
|
||||
Vector<GFXTextureObject*> mToDelete;
|
||||
|
||||
enum TextureManagerState
|
||||
{
|
||||
Living,
|
||||
Zombie,
|
||||
Dead
|
||||
|
||||
} mTextureManagerState;
|
||||
|
||||
/// The texture pool collection type.
|
||||
typedef HashTable<GFXTextureProfile*,StrongRefPtr<GFXTextureObject> > TexturePoolMap;
|
||||
|
||||
/// All the allocated texture pool textures.
|
||||
TexturePoolMap mTexturePool;
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Protected methods
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
/// Returns a free texture of the requested attributes from
|
||||
/// from the shared texture pool. It returns NULL if no match
|
||||
/// is found.
|
||||
GFXTextureObject* _findPooledTexure( U32 width,
|
||||
U32 height,
|
||||
GFXFormat format,
|
||||
GFXTextureProfile *profile,
|
||||
U32 numMipLevels,
|
||||
S32 antialiasLevel );
|
||||
|
||||
GFXTextureObject *_createTexture( GBitmap *bmp,
|
||||
const String &resourceName,
|
||||
GFXTextureProfile *profile,
|
||||
bool deleteBmp,
|
||||
GFXTextureObject *inObj );
|
||||
|
||||
GFXTextureObject *_createTexture( DDSFile *dds,
|
||||
GFXTextureProfile *profile,
|
||||
bool deleteDDS,
|
||||
GFXTextureObject *inObj );
|
||||
|
||||
/// Frees the API handles to the texture, for D3D this is a release call
|
||||
///
|
||||
/// @note freeTexture MUST NOT DELETE THE TEXTURE OBJECT
|
||||
virtual void freeTexture( GFXTextureObject *texture, bool zombify = false );
|
||||
|
||||
virtual void refreshTexture( GFXTextureObject *texture );
|
||||
|
||||
/// @group Internal Texture Manager Interface
|
||||
///
|
||||
/// These pure virtual functions are overloaded by each API-specific
|
||||
/// subclass.
|
||||
///
|
||||
/// The order of calls is:
|
||||
/// @code
|
||||
/// _createTexture()
|
||||
/// _loadTexture
|
||||
/// _refreshTexture()
|
||||
/// _refreshTexture()
|
||||
/// _refreshTexture()
|
||||
/// ...
|
||||
/// _freeTexture()
|
||||
/// @endcode
|
||||
///
|
||||
/// @{
|
||||
|
||||
/// Allocate a texture with the internal API.
|
||||
///
|
||||
/// @param height Height of the texture.
|
||||
/// @param width Width of the texture.
|
||||
/// @param depth Depth of the texture. (Will normally be 1 unless
|
||||
/// we are doing a cubemap or volumetexture.)
|
||||
/// @param format Pixel format of the texture.
|
||||
/// @param profile Profile for the texture.
|
||||
/// @param numMipLevels If not-NULL, then use that many mips.
|
||||
/// If NULL create the full mip chain
|
||||
/// @param antialiasLevel, Use GFXTextureManager::AA_MATCH_BACKBUFFER to match the backbuffer settings (for render targets that want to share
|
||||
/// the backbuffer z buffer. 0 for no antialiasing, > 0 for levels that match the GFXVideoMode struct.
|
||||
virtual GFXTextureObject *_createTextureObject( U32 height,
|
||||
U32 width,
|
||||
U32 depth,
|
||||
GFXFormat format,
|
||||
GFXTextureProfile *profile,
|
||||
U32 numMipLevels,
|
||||
bool forceMips = false,
|
||||
S32 antialiasLevel = 0,
|
||||
GFXTextureObject *inTex = NULL ) = 0;
|
||||
|
||||
/// Load a texture from a proper DDSFile instance.
|
||||
virtual bool _loadTexture(GFXTextureObject *texture, DDSFile *dds)=0;
|
||||
|
||||
/// Load data into a texture from a GBitmap using the internal API.
|
||||
virtual bool _loadTexture(GFXTextureObject *texture, GBitmap *bmp)=0;
|
||||
|
||||
/// Load data into a texture from a raw buffer using the internal API.
|
||||
///
|
||||
/// Note that the size of the buffer is assumed from the parameters used
|
||||
/// for this GFXTextureObject's _createTexture call.
|
||||
virtual bool _loadTexture(GFXTextureObject *texture, void *raw)=0;
|
||||
|
||||
/// Refresh a texture using the internal API.
|
||||
virtual bool _refreshTexture(GFXTextureObject *texture)=0;
|
||||
|
||||
/// Free a texture (but do not delete the GFXTextureObject) using the internal
|
||||
/// API.
|
||||
///
|
||||
/// This is only called during zombification for textures which need it, so you
|
||||
/// don't need to do any internal safety checks.
|
||||
virtual bool _freeTexture(GFXTextureObject *texture, bool zombify=false)=0;
|
||||
|
||||
/// @}
|
||||
|
||||
/// Store texture into the hash table cache and linked list.
|
||||
void _linkTexture( GFXTextureObject *obj );
|
||||
|
||||
/// Validate the parameters for creating a texture.
|
||||
void _validateTexParams( const U32 width, const U32 height, const GFXTextureProfile *profile,
|
||||
U32 &inOutNumMips, GFXFormat &inOutFormat );
|
||||
|
||||
// New texture manager methods for the cleanup work:
|
||||
GFXTextureObject *_lookupTexture( const char *filename, const GFXTextureProfile *profile );
|
||||
GFXTextureObject *_lookupTexture( const DDSFile *ddsFile, const GFXTextureProfile *profile );
|
||||
|
||||
void _onFileChanged( const Torque::Path &path );
|
||||
|
||||
/// The texture event signal type.
|
||||
typedef Signal<void(GFXTexCallbackCode code)> EventSignal;
|
||||
|
||||
/// The texture event signal.
|
||||
static EventSignal smEventSignal;
|
||||
};
|
||||
|
||||
|
||||
template <class T,class U>
|
||||
inline void GFXTextureManager::addEventDelegate( T obj, U func )
|
||||
{
|
||||
EventSignal::DelegateSig d( obj, func );
|
||||
|
||||
AssertFatal( !smEventSignal.contains( d ),
|
||||
"GFXTextureManager::addEventDelegate() - This is already registered!" );
|
||||
|
||||
smEventSignal.notify( d );
|
||||
}
|
||||
|
||||
inline void GFXTextureManager::reloadTexture( GFXTextureObject *texture )
|
||||
{
|
||||
refreshTexture( texture );
|
||||
}
|
||||
|
||||
/// Returns the GFXTextureManager singleton. Should only be
|
||||
/// called after the GFX device has been initialized.
|
||||
#define TEXMGR GFXDevice::get()->getTextureManager()
|
||||
|
||||
#endif // _GFXTEXTUREMANAGER_H_
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue