Implementation of sRGB image support. Overhauls the linearization setup to utilize the sRGB image types, as well as refactors the use of ColorF and ColorI to be properly internally consistent. ColorIs are used only for front-facing/editing/UI settings, and ColorFs, now renamed to LinearColorF to reduce confusion of purpose, are used for color info in the engine itself. This avoids confusing and expensive conversions back and forth between types and avoids botches with linearity. Majority work done by @rextimmy

This commit is contained in:
Areloch 2017-06-23 11:36:20 -05:00
parent 8780f83262
commit 25686ed4be
294 changed files with 3894 additions and 2813 deletions

View file

@ -24,6 +24,7 @@
#include "gfx/gfxCardProfile.h"
#include "gfx/gfxTextureManager.h"
#include "gfx/D3D11/gfxD3D11EnumTranslate.h"
#include "gfx/bitmap/imageUtils.h"
GFXD3D11Cubemap::GFXD3D11Cubemap() : mTexture(NULL), mSRView(NULL), mDSView(NULL)
{
@ -65,14 +66,6 @@ void GFXD3D11Cubemap::_onTextureEvent(GFXTexCallbackCode code)
initDynamic(mTexSize);
}
bool GFXD3D11Cubemap::isCompressed(GFXFormat format)
{
if (format >= GFXFormatDXT1 && format <= GFXFormatDXT5)
return true;
return false;
}
void GFXD3D11Cubemap::initStatic(GFXTexHandle *faces)
{
AssertFatal( faces, "GFXD3D11Cubemap::initStatic - Got null GFXTexHandle!" );
@ -81,7 +74,7 @@ void GFXD3D11Cubemap::initStatic(GFXTexHandle *faces)
// NOTE - check tex sizes on all faces - they MUST be all same size
mTexSize = faces->getWidth();
mFaceFormat = faces->getFormat();
bool compressed = isCompressed(mFaceFormat);
bool compressed = ImageUtil::isCompressedFormat(mFaceFormat);
UINT bindFlags = D3D11_BIND_SHADER_RESOURCE;
UINT miscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
@ -91,15 +84,15 @@ void GFXD3D11Cubemap::initStatic(GFXTexHandle *faces)
miscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS;
}
U32 mipLevels = faces->getPointer()->getMipLevels();
if (mipLevels > 1 && !compressed)
mMipMapLevels = faces->getPointer()->getMipLevels();
if (mMipMapLevels < 1 && !compressed)
mAutoGenMips = true;
D3D11_TEXTURE2D_DESC desc;
ZeroMemory(&desc, sizeof(D3D11_TEXTURE2D_DESC));
desc.Width = mTexSize;
desc.Height = mTexSize;
desc.MipLevels = mAutoGenMips ? 0 : mipLevels;
desc.MipLevels = mAutoGenMips ? 0 : mMipMapLevels;
desc.ArraySize = 6;
desc.Format = GFXD3D11TextureFormat[mFaceFormat];
desc.SampleDesc.Count = 1;
@ -113,15 +106,15 @@ void GFXD3D11Cubemap::initStatic(GFXTexHandle *faces)
if (FAILED(hr))
{
AssertFatal(false, "GFXD3D11Cubemap:initStatic(GFXTexhandle *faces) - failed to create texcube texture");
AssertFatal(false, "GFXD3D11Cubemap:initStatic(GFXTexhandle *faces) - CreateTexture2D failure");
}
for (U32 i = 0; i < CubeFaces; i++)
{
GFXD3D11TextureObject *texObj = static_cast<GFXD3D11TextureObject*>((GFXTextureObject*)faces[i]);
for (U32 currentMip = 0; currentMip < mipLevels; currentMip++)
for (U32 currentMip = 0; currentMip < mMipMapLevels; currentMip++)
{
U32 subResource = D3D11CalcSubresource(currentMip, i, mipLevels);
U32 subResource = D3D11CalcSubresource(currentMip, i, mMipMapLevels);
D3D11DEVICECONTEXT->CopySubresourceRegion(mTexture, subResource, 0, 0, 0, texObj->get2DTex(), currentMip, NULL);
}
}
@ -129,7 +122,7 @@ void GFXD3D11Cubemap::initStatic(GFXTexHandle *faces)
D3D11_SHADER_RESOURCE_VIEW_DESC SMViewDesc;
SMViewDesc.Format = GFXD3D11TextureFormat[mFaceFormat];
SMViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
SMViewDesc.TextureCube.MipLevels = mAutoGenMips ? -1 : mipLevels;
SMViewDesc.TextureCube.MipLevels = mAutoGenMips ? -1 : mMipMapLevels;
SMViewDesc.TextureCube.MostDetailedMip = 0;
hr = D3D11DEVICE->CreateShaderResourceView(mTexture, &SMViewDesc, &mSRView);
@ -138,8 +131,16 @@ void GFXD3D11Cubemap::initStatic(GFXTexHandle *faces)
AssertFatal(false, "GFXD3D11Cubemap::initStatic(GFXTexHandle *faces) - texcube shader resource view creation failure");
}
//Generate mips
if (mAutoGenMips && !compressed)
{
D3D11DEVICECONTEXT->GenerateMips(mSRView);
//get mip level count
D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc;
mSRView->GetDesc(&viewDesc);
mMipMapLevels = viewDesc.TextureCube.MipLevels;
}
}
void GFXD3D11Cubemap::initStatic(DDSFile *dds)
@ -151,45 +152,53 @@ void GFXD3D11Cubemap::initStatic(DDSFile *dds)
// NOTE - check tex sizes on all faces - they MUST be all same size
mTexSize = dds->getWidth();
mFaceFormat = dds->getFormat();
U32 levels = dds->getMipLevels();
mMipMapLevels = dds->getMipLevels();
D3D11_TEXTURE2D_DESC desc;
desc.Width = mTexSize;
desc.Height = mTexSize;
desc.MipLevels = levels;
desc.ArraySize = 6;
desc.MipLevels = mMipMapLevels;
desc.ArraySize = CubeFaces;
desc.Format = GFXD3D11TextureFormat[mFaceFormat];
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_IMMUTABLE;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE | D3D11_RESOURCE_MISC_GENERATE_MIPS;
desc.CPUAccessFlags = 0;
desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
D3D11_SUBRESOURCE_DATA* pData = new D3D11_SUBRESOURCE_DATA[6 + levels];
for (U32 i = 0; i<CubeFaces; i++)
D3D11_SUBRESOURCE_DATA* pData = new D3D11_SUBRESOURCE_DATA[CubeFaces * mMipMapLevels];
for (U32 currentFace = 0; currentFace < CubeFaces; currentFace++)
{
if (!dds->mSurfaces[i])
if (!dds->mSurfaces[currentFace])
continue;
for(U32 j = 0; j < levels; j++)
// convert to Z up
const U32 faceIndex = _zUpFaceIndex(currentFace);
for(U32 currentMip = 0; currentMip < mMipMapLevels; currentMip++)
{
pData[i + j].pSysMem = dds->mSurfaces[i]->mMips[j];
pData[i + j].SysMemPitch = dds->getSurfacePitch(j);
pData[i + j].SysMemSlicePitch = dds->getSurfaceSize(j);
const U32 dataIndex = faceIndex * mMipMapLevels + currentMip;
pData[dataIndex].pSysMem = dds->mSurfaces[currentFace]->mMips[currentMip];
pData[dataIndex].SysMemPitch = dds->getSurfacePitch(currentMip);
pData[dataIndex].SysMemSlicePitch = 0;
}
}
HRESULT hr = D3D11DEVICE->CreateTexture2D(&desc, pData, &mTexture);
HRESULT hr = D3D11DEVICE->CreateTexture2D(&desc, pData, &mTexture);
if (FAILED(hr))
{
AssertFatal(false, "GFXD3D11Cubemap::initStatic(DDSFile *dds) - CreateTexture2D failure");
}
delete [] pData;
D3D11_SHADER_RESOURCE_VIEW_DESC SMViewDesc;
SMViewDesc.Format = GFXD3D11TextureFormat[mFaceFormat];
SMViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
SMViewDesc.TextureCube.MipLevels = levels;
SMViewDesc.TextureCube.MipLevels = mMipMapLevels;
SMViewDesc.TextureCube.MostDetailedMip = 0;
hr = D3D11DEVICE->CreateShaderResourceView(mTexture, &SMViewDesc, &mSRView);
@ -209,7 +218,8 @@ void GFXD3D11Cubemap::initDynamic(U32 texSize, GFXFormat faceFormat)
mAutoGenMips = true;
mTexSize = texSize;
mFaceFormat = faceFormat;
bool compressed = isCompressed(mFaceFormat);
mMipMapLevels = 0;
bool compressed = ImageUtil::isCompressedFormat(mFaceFormat);
UINT bindFlags = D3D11_BIND_SHADER_RESOURCE;
UINT miscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
@ -250,6 +260,16 @@ void GFXD3D11Cubemap::initDynamic(U32 texSize, GFXFormat faceFormat)
AssertFatal(false, "GFXD3D11Cubemap::initDynamic - CreateTexture2D call failure");
}
//Generate mips
if (mAutoGenMips && !compressed)
{
D3D11DEVICECONTEXT->GenerateMips(mSRView);
//get mip level count
D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc;
mSRView->GetDesc(&viewDesc);
mMipMapLevels = viewDesc.TextureCube.MipLevels;
}
D3D11_RENDER_TARGET_VIEW_DESC viewDesc;
viewDesc.Format = desc.Format;
viewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;

View file

@ -71,7 +71,6 @@ private:
void releaseSurfaces();
bool isCompressed(GFXFormat format);
/// The callback used to get texture events.
/// @see GFXTextureManager::addEventDelegate
void _onTextureEvent(GFXTexCallbackCode code);

View file

@ -45,14 +45,6 @@
#pragma comment(lib, "dxgi.lib")
#pragma comment(lib, "d3d11.lib")
GFXAdapter::CreateDeviceInstanceDelegate GFXD3D11Device::mCreateDeviceInstance(GFXD3D11Device::createInstance);
GFXDevice *GFXD3D11Device::createInstance(U32 adapterIndex)
{
GFXD3D11Device* dev = new GFXD3D11Device(adapterIndex);
return dev;
}
class GFXPCD3D11RegisterDevice
{
public:
@ -79,6 +71,14 @@ static void sgPCD3D11DeviceHandleCommandLine(S32 argc, const char **argv)
// Register the command line parsing hook
static ProcessRegisterCommandLine sgCommandLine(sgPCD3D11DeviceHandleCommandLine);
GFXAdapter::CreateDeviceInstanceDelegate GFXD3D11Device::mCreateDeviceInstance(GFXD3D11Device::createInstance);
GFXDevice *GFXD3D11Device::createInstance(U32 adapterIndex)
{
GFXD3D11Device* dev = new GFXD3D11Device(adapterIndex);
return dev;
}
GFXD3D11Device::GFXD3D11Device(U32 index)
{
mDeviceSwizzle32 = &Swizzles::bgra;
@ -88,6 +88,9 @@ GFXD3D11Device::GFXD3D11Device(U32 index)
mAdapterIndex = index;
mD3DDevice = NULL;
mD3DDeviceContext = NULL;
mD3DDevice1 = NULL;
mD3DDeviceContext1 = NULL;
mUserAnnotation = NULL;
mVolatileVB = NULL;
@ -104,10 +107,6 @@ GFXD3D11Device::GFXD3D11Device(U32 index)
mPixVersion = 0.0;
mVertexShaderTarget = String::EmptyString;
mPixelShaderTarget = String::EmptyString;
mShaderModel = String::EmptyString;
mDrawInstancesCount = 0;
mCardProfiler = NULL;
@ -122,6 +121,7 @@ GFXD3D11Device::GFXD3D11Device(U32 index)
mCurrentConstBuffer = NULL;
mOcclusionQuerySupported = false;
mCbufferPartialSupported = false;
mDebugLayers = false;
@ -149,7 +149,7 @@ GFXD3D11Device::~GFXD3D11Device()
// Free the vertex declarations.
VertexDeclMap::Iterator iter = mVertexDecls.begin();
for (; iter != mVertexDecls.end(); iter++)
for (; iter != mVertexDecls.end(); ++iter)
delete iter->value;
// Forcibly clean up the pools
@ -162,6 +162,7 @@ GFXD3D11Device::~GFXD3D11Device()
SAFE_RELEASE(mDeviceDepthStencil);
SAFE_RELEASE(mDeviceBackbuffer);
SAFE_RELEASE(mUserAnnotation);
SAFE_RELEASE(mD3DDeviceContext1);
SAFE_RELEASE(mD3DDeviceContext);
SAFE_DELETE(mCardProfiler);
@ -179,6 +180,7 @@ GFXD3D11Device::~GFXD3D11Device()
#endif
SAFE_RELEASE(mSwapChain);
SAFE_RELEASE(mD3DDevice1);
SAFE_RELEASE(mD3DDevice);
}
@ -220,7 +222,7 @@ DXGI_SWAP_CHAIN_DESC GFXD3D11Device::setupPresentParams(const GFXVideoMode &mode
d3dpp.BufferCount = !smDisableVSync ? 2 : 1; // triple buffering when vsync is on.
d3dpp.BufferDesc.Width = mode.resolution.x;
d3dpp.BufferDesc.Height = mode.resolution.y;
d3dpp.BufferDesc.Format = GFXD3D11TextureFormat[GFXFormatR8G8B8A8];
d3dpp.BufferDesc.Format = GFXD3D11TextureFormat[GFXFormatR8G8B8A8_SRGB];
d3dpp.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
d3dpp.OutputWindow = hwnd;
d3dpp.SampleDesc = sampleDesc;
@ -287,7 +289,7 @@ void GFXD3D11Device::enumerateAdapters(Vector<GFXAdapter*> &adapterList)
UINT numModes = 0;
DXGI_MODE_DESC* displayModes = NULL;
DXGI_FORMAT format = DXGI_FORMAT_B8G8R8A8_UNORM;
DXGI_FORMAT format = GFXD3D11TextureFormat[GFXFormatR8G8B8A8_SRGB];
// Get the number of elements
hr = pOutput->GetDisplayModeList(format, 0, &numModes, NULL);
@ -315,47 +317,10 @@ void GFXD3D11Device::enumerateAdapters(Vector<GFXAdapter*> &adapterList)
toAdd->mAvailableModes.push_back(vmAdd);
}
//Check adapater can handle feature level 10
D3D_FEATURE_LEVEL deviceFeature;
ID3D11Device *pTmpDevice = nullptr;
// Create temp Direct3D11 device.
bool suitable = true;
UINT createDeviceFlags = D3D11_CREATE_DEVICE_SINGLETHREADED | D3D11_CREATE_DEVICE_BGRA_SUPPORT;
hr = D3D11CreateDevice(EnumAdapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, createDeviceFlags, NULL, 0, D3D11_SDK_VERSION, &pTmpDevice, &deviceFeature, NULL);
if (FAILED(hr))
suitable = false;
if (deviceFeature < D3D_FEATURE_LEVEL_10_0)
suitable = false;
//double check we support required bgra format for LEVEL_10_0 & LEVEL_10_1
if (deviceFeature == D3D_FEATURE_LEVEL_10_0 || deviceFeature == D3D_FEATURE_LEVEL_10_1)
{
U32 formatSupported = 0;
pTmpDevice->CheckFormatSupport(DXGI_FORMAT_B8G8R8A8_UNORM, &formatSupported);
U32 flagsRequired = D3D11_FORMAT_SUPPORT_RENDER_TARGET | D3D11_FORMAT_SUPPORT_DISPLAY;
if (!(formatSupported && flagsRequired))
{
Con::printf("DXGI adapter: %s does not support BGRA", Description.c_str());
suitable = false;
}
}
delete[] displayModes;
SAFE_RELEASE(pTmpDevice);
SAFE_RELEASE(pOutput);
SAFE_RELEASE(EnumAdapter);
if (suitable)
{
adapterList.push_back(toAdd);
}
else
{
Con::printf("DXGI adapter: %s does not support D3D11 feature level 10 or better", Description.c_str());
delete toAdd;
}
adapterList.push_back(toAdd);
}
SAFE_RELEASE(DXGIFactory);
@ -391,7 +356,7 @@ void GFXD3D11Device::enumerateVideoModes()
UINT numModes = 0;
DXGI_MODE_DESC* displayModes = NULL;
DXGI_FORMAT format = GFXD3D11TextureFormat[GFXFormatR8G8B8A8];
DXGI_FORMAT format = GFXD3D11TextureFormat[GFXFormatR8G8B8A8_SRGB];
// Get the number of elements
hr = pOutput->GetDisplayModeList(format, 0, &numModes, NULL);
@ -430,8 +395,8 @@ void GFXD3D11Device::enumerateVideoModes()
void GFXD3D11Device::init(const GFXVideoMode &mode, PlatformWindow *window)
{
AssertFatal(window, "GFXD3D11Device::init - must specify a window!");
HWND hwnd = (HWND)window->getSystemWindow(PlatformWindow::WindowSystem_Windows);
SetFocus(hwnd);//ensure window has focus
HWND winHwnd = (HWND)window->getSystemWindow( PlatformWindow::WindowSystem_Windows );
UINT createDeviceFlags = D3D11_CREATE_DEVICE_SINGLETHREADED | D3D11_CREATE_DEVICE_BGRA_SUPPORT;
#ifdef TORQUE_DEBUG
@ -439,77 +404,88 @@ void GFXD3D11Device::init(const GFXVideoMode &mode, PlatformWindow *window)
mDebugLayers = true;
#endif
DXGI_SWAP_CHAIN_DESC d3dpp = setupPresentParams(mode, winHwnd);
D3D_FEATURE_LEVEL deviceFeature;
// TODO support at least feature level 10 to match GL
D3D_FEATURE_LEVEL pFeatureLevels[] = { D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0 };
U32 nFeatureCount = ARRAYSIZE(pFeatureLevels);
D3D_DRIVER_TYPE driverType = D3D_DRIVER_TYPE_HARDWARE;// use D3D_DRIVER_TYPE_REFERENCE for reference device
// create a device & device context
HRESULT hres = D3D11CreateDevice(NULL,
driverType,
NULL,
createDeviceFlags,
NULL,
0,
D3D11_SDK_VERSION,
&mD3DDevice,
&mFeatureLevel,
&mD3DDeviceContext);
// create a device, device context and swap chain using the information in the d3dpp struct
HRESULT hres = D3D11CreateDeviceAndSwapChain(NULL,
driverType,
NULL,
createDeviceFlags,
pFeatureLevels,
nFeatureCount,
D3D11_SDK_VERSION,
&d3dpp,
&mSwapChain,
&mD3DDevice,
&deviceFeature,
&mD3DDeviceContext);
if(FAILED(hres))
{
#ifdef TORQUE_DEBUG
//try again without debug device layer enabled
createDeviceFlags &= ~D3D11_CREATE_DEVICE_DEBUG;
hres = D3D11CreateDevice(NULL,
driverType,
NULL,
createDeviceFlags,
NULL,
0,
D3D11_SDK_VERSION,
&mD3DDevice,
&mFeatureLevel,
&mD3DDeviceContext);
//if we failed again than we definitely have a problem
if (FAILED(hres))
AssertFatal(false, "GFXD3D11Device::init - D3D11CreateDeviceAndSwapChain failed!");
Con::warnf("GFXD3D11Device::init - Debug layers not detected!");
mDebugLayers = false;
#else
//try again without debug device layer enabled
createDeviceFlags &= ~D3D11_CREATE_DEVICE_DEBUG;
hres = D3D11CreateDeviceAndSwapChain(NULL, driverType,NULL,createDeviceFlags,NULL, 0,
D3D11_SDK_VERSION,
&d3dpp,
&mSwapChain,
&mD3DDevice,
&deviceFeature,
&mD3DDeviceContext);
//if we failed again than we definitely have a problem
if (FAILED(hres))
AssertFatal(false, "GFXD3D11Device::init - D3D11CreateDeviceAndSwapChain failed!");
Con::warnf("GFXD3D11Device::init - Debug layers not detected!");
mDebugLayers = false;
#else
AssertFatal(false, "GFXD3D11Device::init - D3D11CreateDeviceAndSwapChain failed!");
#endif
}
#ifdef TORQUE_DEBUG
_suppressDebugMessages();
#endif
// Grab DX 11.1 device and context if available and also ID3DUserDefinedAnnotation
hres = mD3DDevice->QueryInterface(__uuidof(ID3D11Device1), reinterpret_cast<void**>(&mD3DDevice1));
if (SUCCEEDED(hres))
{
//11.1 context
mD3DDeviceContext->QueryInterface(__uuidof(ID3D11DeviceContext1), reinterpret_cast<void**>(&mD3DDeviceContext1));
// ID3DUserDefinedAnnotation
mD3DDeviceContext->QueryInterface(IID_PPV_ARGS(&mUserAnnotation));
//Check what is supported, windows 7 supports very little from 11.1
D3D11_FEATURE_DATA_D3D11_OPTIONS options;
mD3DDevice1->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS, &options,
sizeof(D3D11_FEATURE_DATA_D3D11_OPTIONS));
//Cbuffer partial updates
if (options.ConstantBufferOffsetting && options.ConstantBufferPartialUpdate)
mCbufferPartialSupported = true;
}
//set the fullscreen state here if we need to
if(mode.fullScreen)
{
hres = mSwapChain->SetFullscreenState(TRUE, NULL);
if(FAILED(hres))
{
AssertFatal(false, "GFXD3D11Device::init- Failed to set fullscreen state!");
}
}
mTextureManager = new GFXD3D11TextureManager();
// Now reacquire all the resources we trashed earlier
reacquireDefaultPoolResources();
//set vert/pixel shader targets
switch (mFeatureLevel)
{
case D3D_FEATURE_LEVEL_11_0:
mVertexShaderTarget = "vs_5_0";
mPixelShaderTarget = "ps_5_0";
if (deviceFeature >= D3D_FEATURE_LEVEL_11_0)
mPixVersion = 5.0f;
mShaderModel = "50";
break;
case D3D_FEATURE_LEVEL_10_1:
mVertexShaderTarget = "vs_4_1";
mPixelShaderTarget = "ps_4_1";
mPixVersion = 4.1f;
mShaderModel = "41";
break;
case D3D_FEATURE_LEVEL_10_0:
mVertexShaderTarget = "vs_4_0";
mPixelShaderTarget = "ps_4_0";
mPixVersion = 4.0f;
mShaderModel = "40";
break;
default:
AssertFatal(false, "GFXD3D11Device::init - We don't support this feature level");
}
else
AssertFatal(false, "GFXD3D11Device::init - We don't support anything below feature level 11.");
D3D11_QUERY_DESC queryDesc;
queryDesc.Query = D3D11_QUERY_OCCLUSION;
@ -527,6 +503,68 @@ void GFXD3D11Device::init(const GFXVideoMode &mode, PlatformWindow *window)
mCardProfiler = new GFXD3D11CardProfiler();
mCardProfiler->init();
D3D11_TEXTURE2D_DESC desc;
desc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
desc.CPUAccessFlags = 0;
desc.Format = GFXD3D11TextureFormat[GFXFormatD24S8];
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.Width = mode.resolution.x;
desc.Height = mode.resolution.y;
desc.SampleDesc.Count =1;
desc.SampleDesc.Quality =0;
desc.MiscFlags = 0;
HRESULT hr = mD3DDevice->CreateTexture2D(&desc, NULL, &mDeviceDepthStencil);
if(FAILED(hr))
{
AssertFatal(false, "GFXD3D11Device::init - couldn't create device's depth-stencil surface.");
}
D3D11_DEPTH_STENCIL_VIEW_DESC depthDesc;
depthDesc.Format = GFXD3D11TextureFormat[GFXFormatD24S8];
depthDesc.Flags =0 ;
depthDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
depthDesc.Texture2D.MipSlice = 0;
hr = mD3DDevice->CreateDepthStencilView(mDeviceDepthStencil, &depthDesc, &mDeviceDepthStencilView);
if(FAILED(hr))
{
AssertFatal(false, "GFXD3D11Device::init - couldn't create depth stencil view");
}
hr = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mDeviceBackbuffer);
if(FAILED(hr))
AssertFatal(false, "GFXD3D11Device::init - coudln't retrieve backbuffer ref");
//create back buffer view
D3D11_RENDER_TARGET_VIEW_DESC RTDesc;
RTDesc.Format = GFXD3D11TextureFormat[GFXFormatR8G8B8A8_SRGB];
RTDesc.Texture2D.MipSlice = 0;
RTDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
hr = mD3DDevice->CreateRenderTargetView(mDeviceBackbuffer, &RTDesc, &mDeviceBackBufferView);
if(FAILED(hr))
AssertFatal(false, "GFXD3D11Device::init - couldn't create back buffer target view");
#ifdef TORQUE_DEBUG
String backBufferName = "MainBackBuffer";
String depthSteniclName = "MainDepthStencil";
String backBuffViewName = "MainBackBuffView";
String depthStencViewName = "MainDepthView";
mDeviceBackbuffer->SetPrivateData(WKPDID_D3DDebugObjectName, backBufferName.size(), backBufferName.c_str());
mDeviceDepthStencil->SetPrivateData(WKPDID_D3DDebugObjectName, depthSteniclName.size(), depthSteniclName.c_str());
mDeviceDepthStencilView->SetPrivateData(WKPDID_D3DDebugObjectName, depthStencViewName.size(), depthStencViewName.c_str());
mDeviceBackBufferView->SetPrivateData(WKPDID_D3DDebugObjectName, backBuffViewName.size(), backBuffViewName.c_str());
_suppressDebugMessages();
#endif
gScreenShot = new ScreenShotD3D11;
mInitialized = true;
@ -576,35 +614,14 @@ GFXWindowTarget * GFXD3D11Device::allocWindowTarget(PlatformWindow *window)
{
AssertFatal(window,"GFXD3D11Device::allocWindowTarget - no window provided!");
// Allocate the device.
init(window->getVideoMode(), window);
// Set up a new window target...
GFXD3D11WindowTarget *gdwt = new GFXD3D11WindowTarget();
gdwt->mWindow = window;
gdwt->mSize = window->getClientExtent();
if (!mInitialized)
{
gdwt->mSecondaryWindow = false;
// Allocate the device.
init(window->getVideoMode(), window);
gdwt->initPresentationParams();
gdwt->createSwapChain();
gdwt->createBuffersAndViews();
mSwapChain = gdwt->getSwapChain();
mDeviceBackbuffer = gdwt->getBackBuffer();
mDeviceDepthStencil = gdwt->getDepthStencil();
mDeviceBackBufferView = gdwt->getBackBufferView();
mDeviceDepthStencilView = gdwt->getDepthStencilView();
}
else //additional window/s
{
gdwt->mSecondaryWindow = true;
gdwt->initPresentationParams();
gdwt->createSwapChain();
gdwt->createBuffersAndViews();
}
gdwt->initPresentationParams();
gdwt->registerResourceWithDevice(this);
return gdwt;
@ -618,15 +635,13 @@ GFXTextureTarget* GFXD3D11Device::allocRenderToTextureTarget()
return targ;
}
void GFXD3D11Device::beginReset()
void GFXD3D11Device::reset(DXGI_SWAP_CHAIN_DESC &d3dpp)
{
if (!mD3DDevice)
return;
mInitialized = false;
releaseDefaultPoolResources();
// Clean up some commonly dangling state. This helps prevents issues with
// items that are destroyed by the texture manager callbacks and recreated
// later, but still left bound.
@ -637,26 +652,117 @@ void GFXD3D11Device::beginReset()
mD3DDeviceContext->ClearState();
//release old buffers and views
SAFE_RELEASE(mDeviceDepthStencilView);
SAFE_RELEASE(mDeviceBackBufferView);
SAFE_RELEASE(mDeviceDepthStencil);
SAFE_RELEASE(mDeviceBackbuffer);
}
DXGI_MODE_DESC displayModes;
displayModes.Format = d3dpp.BufferDesc.Format;
displayModes.Height = d3dpp.BufferDesc.Height;
displayModes.Width = d3dpp.BufferDesc.Width;
displayModes.RefreshRate = d3dpp.BufferDesc.RefreshRate;
displayModes.Scaling = d3dpp.BufferDesc.Scaling;
displayModes.ScanlineOrdering = d3dpp.BufferDesc.ScanlineOrdering;
void GFXD3D11Device::endReset(GFXD3D11WindowTarget *windowTarget)
{
//grab new references
mDeviceBackbuffer = windowTarget->getBackBuffer();
mDeviceDepthStencil = windowTarget->getDepthStencil();
mDeviceBackBufferView = windowTarget->getBackBufferView();
mDeviceDepthStencilView = windowTarget->getDepthStencilView();
HRESULT hr;
if (!d3dpp.Windowed)
{
hr = mSwapChain->ResizeTarget(&displayModes);
if (FAILED(hr))
{
AssertFatal(false, "D3D11Device::reset - failed to resize target!");
}
}
// First release all the stuff we allocated from D3DPOOL_DEFAULT
releaseDefaultPoolResources();
//release the backbuffer, depthstencil, and their views
SAFE_RELEASE(mDeviceBackBufferView);
SAFE_RELEASE(mDeviceBackbuffer);
SAFE_RELEASE(mDeviceDepthStencilView);
SAFE_RELEASE(mDeviceDepthStencil);
hr = mSwapChain->ResizeBuffers(d3dpp.BufferCount, d3dpp.BufferDesc.Width, d3dpp.BufferDesc.Height, d3dpp.BufferDesc.Format, d3dpp.Windowed ? 0 : DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH);
if (FAILED(hr))
{
AssertFatal(false, "D3D11Device::reset - failed to resize back buffer!");
}
//recreate backbuffer view. depth stencil view and texture
D3D11_TEXTURE2D_DESC desc;
desc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
desc.CPUAccessFlags = 0;
desc.Format = GFXD3D11TextureFormat[GFXFormatD24S8];
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.Width = d3dpp.BufferDesc.Width;
desc.Height = d3dpp.BufferDesc.Height;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.MiscFlags = 0;
hr = mD3DDevice->CreateTexture2D(&desc, NULL, &mDeviceDepthStencil);
if (FAILED(hr))
{
AssertFatal(false, "GFXD3D11Device::reset - couldn't create device's depth-stencil surface.");
}
D3D11_DEPTH_STENCIL_VIEW_DESC depthDesc;
depthDesc.Format = GFXD3D11TextureFormat[GFXFormatD24S8];
depthDesc.Flags = 0;
depthDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
depthDesc.Texture2D.MipSlice = 0;
hr = mD3DDevice->CreateDepthStencilView(mDeviceDepthStencil, &depthDesc, &mDeviceDepthStencilView);
if (FAILED(hr))
{
AssertFatal(false, "GFXD3D11Device::reset - couldn't create depth stencil view");
}
hr = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mDeviceBackbuffer);
if (FAILED(hr))
AssertFatal(false, "GFXD3D11Device::reset - coudln't retrieve backbuffer ref");
//create back buffer view
D3D11_RENDER_TARGET_VIEW_DESC RTDesc;
RTDesc.Format = GFXD3D11TextureFormat[GFXFormatR8G8B8A8_SRGB];
RTDesc.Texture2D.MipSlice = 0;
RTDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
hr = mD3DDevice->CreateRenderTargetView(mDeviceBackbuffer, &RTDesc, &mDeviceBackBufferView);
if (FAILED(hr))
AssertFatal(false, "GFXD3D11Device::reset - couldn't create back buffer target view");
mD3DDeviceContext->OMSetRenderTargets(1, &mDeviceBackBufferView, mDeviceDepthStencilView);
// Now reacquire all the resources we trashed earlier
reacquireDefaultPoolResources();
hr = mSwapChain->SetFullscreenState(!d3dpp.Windowed, NULL);
if (FAILED(hr))
{
AssertFatal(false, "D3D11Device::reset - failed to change screen states!");
}
//Microsoft recommend this, see DXGI documentation
if (!d3dpp.Windowed)
{
displayModes.RefreshRate.Numerator = 0;
displayModes.RefreshRate.Denominator = 0;
hr = mSwapChain->ResizeTarget(&displayModes);
if (FAILED(hr))
{
AssertFatal(false, "D3D11Device::reset - failed to resize target!");
}
}
mInitialized = true;
// Now re aquire all the resources we trashed earlier
reacquireDefaultPoolResources();
// Mark everything dirty and flush to card, for sanity.
updateStates(true);
}
@ -668,12 +774,11 @@ void GFXD3D11Device::setupGenericShaders(GenericShaderType type)
if(mGenericShader[GSColor] == NULL)
{
ShaderData *shaderData;
//shader model 4.0 is enough for the generic shaders
const char* shaderModel = "4.0";
shaderData = new ShaderData();
shaderData->setField("DXVertexShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/colorV.hlsl"));
shaderData->setField("DXPixelShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/colorP.hlsl"));
shaderData->setField("pixVersion", shaderModel);
shaderData->setField("pixVersion", "5.0");
shaderData->registerObject();
mGenericShader[GSColor] = shaderData->getShader();
mGenericShaderBuffer[GSColor] = mGenericShader[GSColor]->allocConstBuffer();
@ -683,7 +788,7 @@ void GFXD3D11Device::setupGenericShaders(GenericShaderType type)
shaderData = new ShaderData();
shaderData->setField("DXVertexShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/modColorTextureV.hlsl"));
shaderData->setField("DXPixelShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/modColorTextureP.hlsl"));
shaderData->setField("pixVersion", shaderModel);
shaderData->setField("pixVersion", "5.0");
shaderData->registerObject();
mGenericShader[GSModColorTexture] = shaderData->getShader();
mGenericShaderBuffer[GSModColorTexture] = mGenericShader[GSModColorTexture]->allocConstBuffer();
@ -693,7 +798,7 @@ void GFXD3D11Device::setupGenericShaders(GenericShaderType type)
shaderData = new ShaderData();
shaderData->setField("DXVertexShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/addColorTextureV.hlsl"));
shaderData->setField("DXPixelShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/addColorTextureP.hlsl"));
shaderData->setField("pixVersion", shaderModel);
shaderData->setField("pixVersion", "5.0");
shaderData->registerObject();
mGenericShader[GSAddColorTexture] = shaderData->getShader();
mGenericShaderBuffer[GSAddColorTexture] = mGenericShader[GSAddColorTexture]->allocConstBuffer();
@ -703,7 +808,7 @@ void GFXD3D11Device::setupGenericShaders(GenericShaderType type)
shaderData = new ShaderData();
shaderData->setField("DXVertexShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/textureV.hlsl"));
shaderData->setField("DXPixelShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/textureP.hlsl"));
shaderData->setField("pixVersion", shaderModel);
shaderData->setField("pixVersion", "5.0");
shaderData->registerObject();
mGenericShader[GSTexture] = shaderData->getShader();
mGenericShaderBuffer[GSTexture] = mGenericShader[GSTexture]->allocConstBuffer();
@ -763,7 +868,7 @@ void GFXD3D11Device::setShaderConstBufferInternal(GFXShaderConstBuffer* buffer)
//-----------------------------------------------------------------------------
void GFXD3D11Device::clear(U32 flags, ColorI color, F32 z, U32 stencil)
void GFXD3D11Device::clear(U32 flags, const LinearColorF& color, F32 z, U32 stencil)
{
// Make sure we have flushed our render target state.
_updateRenderTargets();
@ -775,12 +880,7 @@ void GFXD3D11Device::clear(U32 flags, ColorI color, F32 z, U32 stencil)
mD3DDeviceContext->OMGetRenderTargets(1, &rtView, &dsView);
const FLOAT clearColor[4] = {
static_cast<F32>(color.red) * (1.0f / 255.0f),
static_cast<F32>(color.green) * (1.0f / 255.0f),
static_cast<F32>(color.blue) * (1.0f / 255.0f),
static_cast<F32>(color.alpha) * (1.0f / 255.0f)
};
const FLOAT clearColor[4] = { color.red, color.green, color.blue, color.alpha };
if (flags & GFXClearTarget && rtView)
mD3DDeviceContext->ClearRenderTargetView(rtView, clearColor);
@ -1355,7 +1455,6 @@ String GFXD3D11Device::_createTempShaderInternal(const GFXVertexFormat *vertexFo
//make shader
mainBodyData.append("VertOut main(VertIn IN){VertOut OUT;");
bool addedPadding = false;
for (U32 i = 0; i < elemCount; i++)
{
const GFXVertexElement &element = vertexFormat->getElement(i);
@ -1363,8 +1462,6 @@ String GFXD3D11Device::_createTempShaderInternal(const GFXVertexFormat *vertexFo
String semanticOut = semantic;
String type;
AssertFatal(!(addedPadding && !element.isSemantic(GFXSemantic::PADDING)), "Padding added before data");
if (element.isSemantic(GFXSemantic::POSITION))
{
semantic = "POSITION";
@ -1400,11 +1497,6 @@ String GFXD3D11Device::_createTempShaderInternal(const GFXVertexFormat *vertexFo
semantic = String::ToString("BLENDWEIGHT%d", element.getSemanticIndex());
semanticOut = semantic;
}
else if (element.isSemantic(GFXSemantic::PADDING))
{
addedPadding = true;
continue;
}
else
{
//Anything that falls thru to here will be a texture coord.
@ -1566,12 +1658,6 @@ GFXVertexDecl* GFXD3D11Device::allocVertexDecl( const GFXVertexFormat *vertexFor
vd[i].SemanticName = "BLENDINDICES";
vd[i].SemanticIndex = element.getSemanticIndex();
}
else if (element.isSemantic(GFXSemantic::PADDING))
{
i--;
elemCount--;
continue;
}
else
{
//Anything that falls thru to here will be a texture coord.

View file

@ -39,6 +39,9 @@
#define D3D11 static_cast<GFXD3D11Device*>(GFX)
#define D3D11DEVICE D3D11->getDevice()
#define D3D11DEVICECONTEXT D3D11->getDeviceContext()
// DX 11.1 - always check these are not NULL, dodgy support with win 7
#define D3D11DEVICE1 D3D11->getDevice1()
#define D3D11DEVICECONTEXT1 D3D11->getDeviceContext1()
class PlatformWindow;
class GFXD3D11ShaderConstBuffer;
@ -126,6 +129,9 @@ protected:
IDXGISwapChain *mSwapChain;
ID3D11Device* mD3DDevice;
ID3D11DeviceContext* mD3DDeviceContext;
// DX 11.1
ID3D11Device1* mD3DDevice1;
ID3D11DeviceContext1* mD3DDeviceContext1;
ID3DUserDefinedAnnotation* mUserAnnotation;
GFXShader* mCurrentShader;
@ -137,18 +143,12 @@ protected:
F32 mPixVersion;
D3D_FEATURE_LEVEL mFeatureLevel;
// Shader Model targers
String mVertexShaderTarget;
String mPixelShaderTarget;
// String for use with shader macros in the form of shader model version * 10
String mShaderModel;
bool mDebugLayers;
DXGI_SAMPLE_DESC mMultisampleDesc;
bool mOcclusionQuerySupported;
bool mCbufferPartialSupported;
U32 mDrawInstancesCount;
@ -181,7 +181,7 @@ protected:
virtual void setMatrix( GFXMatrixType /*mtype*/, const MatrixF &/*mat*/ ) { };
virtual void setLightInternal(U32 /*lightStage*/, const GFXLightInfo /*light*/, bool /*lightEnable*/) { };
virtual void setLightMaterialInternal(const GFXLightMaterial /*mat*/) { };
virtual void setGlobalAmbientInternal(ColorF /*color*/) { };
virtual void setGlobalAmbientInternal(LinearColorF /*color*/) { };
// }
@ -243,7 +243,7 @@ public:
// Misc rendering control
// {
virtual void clear( U32 flags, ColorI color, F32 z, U32 stencil );
virtual void clear( U32 flags, const LinearColorF& color, F32 z, U32 stencil );
virtual bool beginSceneInternal();
virtual void endSceneInternal();
@ -291,10 +291,13 @@ public:
ID3D11DeviceContext* getDeviceContext(){ return mD3DDeviceContext; }
ID3D11Device* getDevice(){ return mD3DDevice; }
IDXGISwapChain* getSwapChain() { return mSwapChain; }
//DX 11.1
ID3D11DeviceContext1* getDeviceContext1() { return mD3DDeviceContext1; }
ID3D11Device1* getDevice1() { return mD3DDevice1; }
/// Reset
void beginReset();
void endReset(GFXD3D11WindowTarget *windowTarget);
void reset( DXGI_SWAP_CHAIN_DESC &d3dpp );
virtual void setupGenericShaders( GenericShaderType type = GSColor );
@ -308,13 +311,6 @@ public:
// Default multisample parameters
DXGI_SAMPLE_DESC getMultisampleType() const { return mMultisampleDesc; }
// Get feature level this gfx device supports
D3D_FEATURE_LEVEL getFeatureLevel() const { return mFeatureLevel; }
// Shader Model targers
const String &getVertexShaderTarget() const { return mVertexShaderTarget; }
const String &getPixelShaderTarget() const { return mPixelShaderTarget; }
const String &getShaderModel() const { return mShaderModel; }
// grab the sampler map
const SamplerMap &getSamplersMap() const { return mSamplersMap; }
SamplerMap &getSamplersMap() { return mSamplersMap; }

View file

@ -54,11 +54,11 @@ void GFXD3D11EnumTranslate::init()
GFXD3D11TextureFormat[GFXFormatA8L8] = DXGI_FORMAT_R8G8_UNORM;
GFXD3D11TextureFormat[GFXFormatA8] = DXGI_FORMAT_A8_UNORM;
GFXD3D11TextureFormat[GFXFormatL8] = DXGI_FORMAT_R8_UNORM;
GFXD3D11TextureFormat[GFXFormatDXT1] = DXGI_FORMAT_BC1_UNORM;
GFXD3D11TextureFormat[GFXFormatDXT2] = DXGI_FORMAT_BC1_UNORM;
GFXD3D11TextureFormat[GFXFormatDXT3] = DXGI_FORMAT_BC2_UNORM;
GFXD3D11TextureFormat[GFXFormatDXT4] = DXGI_FORMAT_BC2_UNORM;
GFXD3D11TextureFormat[GFXFormatDXT5] = DXGI_FORMAT_BC3_UNORM;
GFXD3D11TextureFormat[GFXFormatBC1] = DXGI_FORMAT_BC1_UNORM;
GFXD3D11TextureFormat[GFXFormatBC2] = DXGI_FORMAT_BC2_UNORM;
GFXD3D11TextureFormat[GFXFormatBC3] = DXGI_FORMAT_BC3_UNORM;
GFXD3D11TextureFormat[GFXFormatBC4] = DXGI_FORMAT_BC4_UNORM;
GFXD3D11TextureFormat[GFXFormatBC5] = DXGI_FORMAT_BC5_UNORM;
GFXD3D11TextureFormat[GFXFormatR32G32B32A32F] = DXGI_FORMAT_R32G32B32A32_FLOAT;
GFXD3D11TextureFormat[GFXFormatR16G16B16A16F] = DXGI_FORMAT_R16G16B16A16_FLOAT;
GFXD3D11TextureFormat[GFXFormatL16] = DXGI_FORMAT_R16_UNORM;
@ -72,8 +72,14 @@ void GFXD3D11EnumTranslate::init()
GFXD3D11TextureFormat[GFXFormatD24S8] = DXGI_FORMAT_D24_UNORM_S8_UINT;
GFXD3D11TextureFormat[GFXFormatD24FS8] = DXGI_FORMAT_UNKNOWN;
GFXD3D11TextureFormat[GFXFormatD16] = DXGI_FORMAT_D16_UNORM;
//sRGB
GFXD3D11TextureFormat[GFXFormatR8G8B8A8_SRGB] = DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
GFXD3D11TextureFormat[GFXFormatR8G8B8A8_LINEAR_FORCE] = DXGI_FORMAT_R8G8B8A8_UNORM;
GFXD3D11TextureFormat[GFXFormatR8G8B8_SRGB] = DXGI_FORMAT_B8G8R8X8_UNORM_SRGB;
GFXD3D11TextureFormat[GFXFormatBC1_SRGB] = DXGI_FORMAT_BC1_UNORM_SRGB;
GFXD3D11TextureFormat[GFXFormatBC2_SRGB] = DXGI_FORMAT_BC2_UNORM_SRGB;
GFXD3D11TextureFormat[GFXFormatBC3_SRGB] = DXGI_FORMAT_BC3_UNORM_SRGB;
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
GFXD3D11TextureFilter[GFXTextureFilterNone] = D3D11_FILTER_MIN_MAG_MIP_POINT;

View file

@ -204,39 +204,6 @@ bool GFXD3D11ConstBufferLayout::setMatrix(const ParamDesc& pd, const GFXShaderCo
return false;
}
else if (pd.constType == GFXSCT_Float4x3)
{
const U32 csize = 48;
// Loop through and copy
bool ret = false;
U8* currDestPointer = basePointer + pd.offset;
const U8* currSourcePointer = static_cast<const U8*>(data);
const U8* endData = currSourcePointer + size;
while (currSourcePointer < endData)
{
#ifdef TORQUE_DOUBLE_CHECK_43MATS
Point4F col;
((MatrixF*)currSourcePointer)->getRow(3, &col);
AssertFatal(col.x == 0.0f && col.y == 0.0f && col.z == 0.0f && col.w == 1.0f, "3rd row used");
#endif
if (dMemcmp(currDestPointer, currSourcePointer, csize) != 0)
{
dMemcpy(currDestPointer, currSourcePointer, csize);
ret = true;
}
else if (pd.constType == GFXSCT_Float4x3)
{
ret = true;
}
currDestPointer += csize;
currSourcePointer += sizeof(MatrixF);
}
return ret;
}
else
{
PROFILE_SCOPE(GFXD3D11ConstBufferLayout_setMatrix_not4x4);
@ -251,6 +218,9 @@ bool GFXD3D11ConstBufferLayout::setMatrix(const ParamDesc& pd, const GFXShaderCo
case GFXSCT_Float3x3 :
csize = 44; //This takes up 16+16+12
break;
case GFXSCT_Float4x3:
csize = 48;
break;
default:
AssertFatal(false, "Unhandled case!");
return false;
@ -269,6 +239,10 @@ bool GFXD3D11ConstBufferLayout::setMatrix(const ParamDesc& pd, const GFXShaderCo
dMemcpy(currDestPointer, currSourcePointer, csize);
ret = true;
}
else if (pd.constType == GFXSCT_Float4x3)
{
ret = true;
}
currDestPointer += csize;
currSourcePointer += sizeof(MatrixF);
@ -303,6 +277,8 @@ GFXD3D11ShaderConstBuffer::GFXD3D11ShaderConstBuffer( GFXD3D11Shader* shader,
mPixelConstBufferLayout = pixelLayout;
mPixelConstBuffer = new GenericConstBuffer(pixelLayout);
mDeviceContext = D3D11DEVICECONTEXT;
_createBuffers();
}
@ -431,7 +407,7 @@ void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const PlaneF&
SET_CONSTANT(handle, fv, mVertexConstBuffer, mPixelConstBuffer);
}
void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const ColorF& fv)
void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const LinearColorF& fv)
{
SET_CONSTANT(handle, fv, mVertexConstBuffer, mPixelConstBuffer);
}
@ -654,8 +630,6 @@ void GFXD3D11ShaderConstBuffer::activate( GFXD3D11ShaderConstBuffer *prevShaderB
}
}
ID3D11DeviceContext* devCtx = D3D11DEVICECONTEXT;
D3D11_MAPPED_SUBRESOURCE pConstData;
ZeroMemory(&pConstData, sizeof(D3D11_MAPPED_SUBRESOURCE));
@ -670,11 +644,11 @@ void GFXD3D11ShaderConstBuffer::activate( GFXD3D11ShaderConstBuffer *prevShaderB
for (U32 i = 0; i < subBuffers.size(); ++i)
{
const ConstSubBufferDesc &desc = subBuffers[i];
devCtx->UpdateSubresource(mConstantBuffersV[i], 0, NULL, buf + desc.start, desc.size, 0);
mDeviceContext->UpdateSubresource(mConstantBuffersV[i], 0, NULL, buf + desc.start, desc.size, 0);
nbBuffers++;
}
devCtx->VSSetConstantBuffers(0, nbBuffers, mConstantBuffersV);
mDeviceContext->VSSetConstantBuffers(0, nbBuffers, mConstantBuffersV);
}
nbBuffers = 0;
@ -688,11 +662,11 @@ void GFXD3D11ShaderConstBuffer::activate( GFXD3D11ShaderConstBuffer *prevShaderB
for (U32 i = 0; i < subBuffers.size(); ++i)
{
const ConstSubBufferDesc &desc = subBuffers[i];
devCtx->UpdateSubresource(mConstantBuffersP[i], 0, NULL, buf + desc.start, desc.size, 0);
mDeviceContext->UpdateSubresource(mConstantBuffersP[i], 0, NULL, buf + desc.start, desc.size, 0);
nbBuffers++;
}
devCtx->PSSetConstantBuffers(0, nbBuffers, mConstantBuffersP);
mDeviceContext->PSSetConstantBuffers(0, nbBuffers, mConstantBuffersP);
}
#ifdef TORQUE_DEBUG
@ -790,8 +764,9 @@ bool GFXD3D11Shader::_init()
d3dMacros[i+smGlobalMacros.size()].Definition = mMacros[i].value.c_str();
}
//TODO support D3D_FEATURE_LEVEL properly with shaders instead of hard coding at hlsl 5
d3dMacros[macroCount - 2].Name = "TORQUE_SM";
d3dMacros[macroCount - 2].Definition = D3D11->getShaderModel().c_str();
d3dMacros[macroCount - 2].Definition = "50";
memset(&d3dMacros[macroCount - 1], 0, sizeof(D3D_SHADER_MACRO));
@ -809,21 +784,18 @@ bool GFXD3D11Shader::_init()
mSamplerDescriptions.clear();
mShaderConsts.clear();
String vertTarget = D3D11->getVertexShaderTarget();
String pixTarget = D3D11->getPixelShaderTarget();
if ( !Con::getBoolVariable( "$shaders::forceLoadCSF", false ) )
{
if (!mVertexFile.isEmpty() && !_compileShader( mVertexFile, vertTarget, d3dMacros, mVertexConstBufferLayout, mSamplerDescriptions ) )
if (!mVertexFile.isEmpty() && !_compileShader( mVertexFile, "vs_5_0", d3dMacros, mVertexConstBufferLayout, mSamplerDescriptions ) )
return false;
if (!mPixelFile.isEmpty() && !_compileShader( mPixelFile, pixTarget, d3dMacros, mPixelConstBufferLayout, mSamplerDescriptions ) )
if (!mPixelFile.isEmpty() && !_compileShader( mPixelFile, "ps_5_0", d3dMacros, mPixelConstBufferLayout, mSamplerDescriptions ) )
return false;
}
else
{
if ( !_loadCompiledOutput( mVertexFile, vertTarget, mVertexConstBufferLayout, mSamplerDescriptions ) )
if ( !_loadCompiledOutput( mVertexFile, "vs_5_0", mVertexConstBufferLayout, mSamplerDescriptions ) )
{
if ( smLogErrors )
Con::errorf( "GFXD3D11Shader::init - Unable to load precompiled vertex shader for '%s'.", mVertexFile.getFullPath().c_str() );
@ -831,7 +803,7 @@ bool GFXD3D11Shader::_init()
return false;
}
if ( !_loadCompiledOutput( mPixelFile, pixTarget, mPixelConstBufferLayout, mSamplerDescriptions ) )
if ( !_loadCompiledOutput( mPixelFile, "ps_5_0", mPixelConstBufferLayout, mSamplerDescriptions ) )
{
if ( smLogErrors )
Con::errorf( "GFXD3D11Shader::init - Unable to load precompiled pixel shader for '%s'.", mPixelFile.getFullPath().c_str() );
@ -877,12 +849,12 @@ bool GFXD3D11Shader::_compileShader( const Torque::Path &filePath,
ID3DBlob* errorBuff = NULL;
ID3D11ShaderReflection* reflectionTable = NULL;
#ifdef TORQUE_DEBUG
U32 flags = D3DCOMPILE_DEBUG | D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_WARNINGS_ARE_ERRORS;
#else
U32 flags = D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_OPTIMIZATION_LEVEL3; //TODO double check load times with D3DCOMPILE_OPTIMIZATION_LEVEL3
//recommended flags for NSight, uncomment to use. NSight should be used in release mode only. *Still works with above flags however
//flags = D3DCOMPILE_DEBUG | D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_PREFER_FLOW_CONTROL | D3DCOMPILE_SKIP_OPTIMIZATION;
#ifdef TORQUE_GFX_VISUAL_DEBUG //for use with NSight, GPU Perf studio, VS graphics debugger
U32 flags = D3DCOMPILE_DEBUG | D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_PREFER_FLOW_CONTROL | D3DCOMPILE_SKIP_OPTIMIZATION;
#elif defined(TORQUE_DEBUG) //debug build
U32 flags = D3DCOMPILE_DEBUG | D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_WARNINGS_ARE_ERRORS;
#else //release build
U32 flags = D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_OPTIMIZATION_LEVEL3;
#endif
#ifdef D3D11_DEBUG_SPEW
@ -1054,20 +1026,20 @@ bool GFXD3D11Shader::_compileShader( const Torque::Path &filePath,
return result;
}
void GFXD3D11Shader::_getShaderConstants( ID3D11ShaderReflection *pTable,
void GFXD3D11Shader::_getShaderConstants( ID3D11ShaderReflection *refTable,
GenericConstBufferLayout *bufferLayoutIn,
Vector<GFXShaderConstDesc> &samplerDescriptions )
{
PROFILE_SCOPE( GFXD3D11Shader_GetShaderConstants );
AssertFatal(pTable, "NULL constant table not allowed, is this an assembly shader?");
AssertFatal(refTable, "NULL constant table not allowed, is this an assembly shader?");
GFXD3D11ConstBufferLayout *bufferLayout = (GFXD3D11ConstBufferLayout*)bufferLayoutIn;
Vector<ConstSubBufferDesc> &subBuffers = bufferLayout->getSubBufferDesc();
subBuffers.clear();
D3D11_SHADER_DESC tableDesc;
HRESULT hr = pTable->GetDesc(&tableDesc);
HRESULT hr = refTable->GetDesc(&tableDesc);
if (FAILED(hr))
{
AssertFatal(false, "Shader Reflection table unable to be created");
@ -1077,7 +1049,7 @@ void GFXD3D11Shader::_getShaderConstants( ID3D11ShaderReflection *pTable,
U32 bufferOffset = 0;
for (U32 i = 0; i < tableDesc.ConstantBuffers; i++)
{
ID3D11ShaderReflectionConstantBuffer* constantBuffer = pTable->GetConstantBufferByIndex(i);
ID3D11ShaderReflectionConstantBuffer* constantBuffer = refTable->GetConstantBufferByIndex(i);
D3D11_SHADER_BUFFER_DESC constantBufferDesc;
if (constantBuffer->GetDesc(&constantBufferDesc) == S_OK)
@ -1162,7 +1134,7 @@ void GFXD3D11Shader::_getShaderConstants( ID3D11ShaderReflection *pTable,
{
GFXShaderConstDesc desc;
D3D11_SHADER_INPUT_BIND_DESC bindDesc;
pTable->GetResourceBindingDesc(i, &bindDesc);
refTable->GetResourceBindingDesc(i, &bindDesc);
switch (bindDesc.Type)
{

View file

@ -297,6 +297,8 @@ public:
class GFXD3D11ShaderConstBuffer : public GFXShaderConstBuffer
{
friend class GFXD3D11Shader;
// Cache device context
ID3D11DeviceContext* mDeviceContext;
public:
@ -324,7 +326,7 @@ public:
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 LinearColorF& 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);
@ -434,7 +436,7 @@ protected:
GenericConstBufferLayout *bufferLayout,
Vector<GFXShaderConstDesc> &samplerDescriptions );
void _getShaderConstants( ID3D11ShaderReflection* pTable,
void _getShaderConstants( ID3D11ShaderReflection* refTable,
GenericConstBufferLayout *bufferLayout,
Vector<GFXShaderConstDesc> &samplerDescriptions );

View file

@ -151,29 +151,32 @@ GFXD3D11StateBlock::GFXD3D11StateBlock(const GFXStateBlockDesc& desc)
mSamplerDesc[i].MinLOD = 0;
mSamplerDesc[i].MaxLOD = FLT_MAX;
const bool comparison = gfxSamplerState.samplerFunc != GFXCmpNever;
if (gfxSamplerState.magFilter == GFXTextureFilterPoint && gfxSamplerState.minFilter == GFXTextureFilterPoint && gfxSamplerState.mipFilter == GFXTextureFilterPoint)
mSamplerDesc[i].Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
mSamplerDesc[i].Filter = comparison ? D3D11_FILTER_COMPARISON_MIN_MAG_MIP_POINT : D3D11_FILTER_MIN_MAG_MIP_POINT;
else if (gfxSamplerState.magFilter == GFXTextureFilterPoint && gfxSamplerState.minFilter == GFXTextureFilterPoint && gfxSamplerState.mipFilter == GFXTextureFilterLinear)
mSamplerDesc[i].Filter = D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR;
mSamplerDesc[i].Filter = comparison ? D3D11_FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR : D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR;
else if (gfxSamplerState.magFilter == GFXTextureFilterLinear && gfxSamplerState.minFilter == GFXTextureFilterPoint && gfxSamplerState.mipFilter == GFXTextureFilterPoint)
mSamplerDesc[i].Filter = D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT;
mSamplerDesc[i].Filter = comparison ? D3D11_FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT : D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT;
else if (gfxSamplerState.magFilter == GFXTextureFilterLinear && gfxSamplerState.minFilter == GFXTextureFilterPoint && gfxSamplerState.mipFilter == GFXTextureFilterLinear)
mSamplerDesc[i].Filter = D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR;
mSamplerDesc[i].Filter = comparison ? D3D11_FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR : D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR;
else if (gfxSamplerState.magFilter == GFXTextureFilterPoint && gfxSamplerState.minFilter == GFXTextureFilterLinear && gfxSamplerState.mipFilter == GFXTextureFilterPoint)
mSamplerDesc[i].Filter = D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT;
mSamplerDesc[i].Filter = comparison ? D3D11_FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT : D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT;
else if (gfxSamplerState.magFilter == GFXTextureFilterPoint && gfxSamplerState.minFilter == GFXTextureFilterLinear && gfxSamplerState.mipFilter == GFXTextureFilterLinear)
mSamplerDesc[i].Filter = D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR;
mSamplerDesc[i].Filter = comparison ? D3D11_FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR : D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR;
else if (gfxSamplerState.magFilter == GFXTextureFilterLinear && gfxSamplerState.minFilter == GFXTextureFilterLinear && gfxSamplerState.mipFilter == GFXTextureFilterPoint)
mSamplerDesc[i].Filter = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT;
mSamplerDesc[i].Filter = comparison ? D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT : D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT;
else if (gfxSamplerState.magFilter == GFXTextureFilterLinear && gfxSamplerState.minFilter == GFXTextureFilterLinear && mDesc.samplers[i].mipFilter == GFXTextureFilterLinear)
mSamplerDesc[i].Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
mSamplerDesc[i].Filter = comparison ? D3D11_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR : D3D11_FILTER_MIN_MAG_MIP_LINEAR;
else
mSamplerDesc[i].Filter = D3D11_FILTER_ANISOTROPIC;
mSamplerDesc[i].Filter = comparison ? D3D11_FILTER_COMPARISON_ANISOTROPIC : D3D11_FILTER_ANISOTROPIC;
mSamplerDesc[i].BorderColor[0] = 1.0f;
mSamplerDesc[i].BorderColor[1] = 1.0f;
mSamplerDesc[i].BorderColor[2] = 1.0f;
mSamplerDesc[i].BorderColor[3] = 1.0f;
mSamplerDesc[i].ComparisonFunc = GFXD3D11CmpFunc[gfxSamplerState.samplerFunc];
hr = D3D11DEVICE->CreateSamplerState(&mSamplerDesc[i], &mSamplerStates[i]);
if (FAILED(hr))

View file

@ -248,10 +248,10 @@ void GFXD3D11TextureTarget::activate()
stateApplied();
// Now set all the new surfaces into the appropriate slots.
ID3D11RenderTargetView* rtViews[MaxRenderSlotId] = { NULL, NULL, NULL, NULL, NULL, NULL};
ID3D11RenderTargetView* rtViews[MaxRenderSlotId] = { NULL, NULL, NULL, NULL, NULL, NULL };
ID3D11DepthStencilView* dsView = (ID3D11DepthStencilView*)(mTargetViews[GFXTextureTarget::DepthStencil]);
for (U32 i = 0; i < 4; i++)
for (U32 i = 0; i < 6; i++)
{
rtViews[i] = (ID3D11RenderTargetView*)mTargetViews[GFXTextureTarget::Color0 + i];
}
@ -263,7 +263,7 @@ void GFXD3D11TextureTarget::activate()
void GFXD3D11TextureTarget::deactivate()
{
//re-gen mip maps
for (U32 i = 0; i < 4; i++)
for (U32 i = 0; i < 6; i++)
{
ID3D11ShaderResourceView* pSRView = mTargetSRViews[GFXTextureTarget::Color0 + i];
if (pSRView)
@ -314,34 +314,21 @@ void GFXD3D11TextureTarget::resurrect()
GFXD3D11WindowTarget::GFXD3D11WindowTarget()
{
mWindow = NULL;
mBackBuffer = NULL;
mDepthStencilView = NULL;
mDepthStencil = NULL;
mBackBufferView = NULL;
mSecondaryWindow = false;
mWindow = NULL;
mBackbuffer = NULL;
}
GFXD3D11WindowTarget::~GFXD3D11WindowTarget()
{
SAFE_RELEASE(mDepthStencilView)
SAFE_RELEASE(mDepthStencil);
SAFE_RELEASE(mBackBufferView);
SAFE_RELEASE(mBackBuffer);
SAFE_RELEASE(mSwapChain);
SAFE_RELEASE(mBackbuffer);
}
void GFXD3D11WindowTarget::initPresentationParams()
{
// Get some video mode related info.
const GFXVideoMode &vm = mWindow->getVideoMode();
HWND hwnd = (HWND)mWindow->getSystemWindow(PlatformWindow::WindowSystem_Windows);
// Do some validation...
if (vm.fullScreen && mSecondaryWindow)
{
AssertFatal(false, "GFXD3D11WindowTarget::initPresentationParams - Cannot go fullscreen with secondary window!");
}
GFXVideoMode vm = mWindow->getVideoMode();
Win32Window* win = static_cast<Win32Window*>(mWindow);
HWND hwnd = win->getHWND();
mPresentationParams = D3D11->setupPresentParams(vm, hwnd);
}
@ -360,178 +347,40 @@ GFXFormat GFXD3D11WindowTarget::getFormat()
bool GFXD3D11WindowTarget::present()
{
return (mSwapChain->Present(!D3D11->smDisableVSync, 0) == S_OK);
return (D3D11->getSwapChain()->Present(!D3D11->smDisableVSync, 0) == S_OK);
}
void GFXD3D11WindowTarget::createSwapChain()
void GFXD3D11WindowTarget::setImplicitSwapChain()
{
//create dxgi factory & swapchain
IDXGIFactory1* DXGIFactory;
HRESULT hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), reinterpret_cast<void**>(&DXGIFactory));
if (FAILED(hr))
AssertFatal(false, "GFXD3D11WindowTarget::createSwapChain - couldn't create dxgi factory.");
hr = DXGIFactory->CreateSwapChain(D3D11DEVICE, &mPresentationParams, &mSwapChain);
if (FAILED(hr))
AssertFatal(false, "GFXD3D11WindowTarget::createSwapChain - couldn't create swap chain.");
SAFE_RELEASE(DXGIFactory);
}
void GFXD3D11WindowTarget::createBuffersAndViews()
{
//release old if they exist
SAFE_RELEASE(mDepthStencilView);
SAFE_RELEASE(mDepthStencil);
SAFE_RELEASE(mBackBufferView);
SAFE_RELEASE(mBackBuffer);
//grab video mode
const GFXVideoMode &vm = mWindow->getVideoMode();
//create depth/stencil
D3D11_TEXTURE2D_DESC desc;
desc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
desc.CPUAccessFlags = 0;
desc.Format = GFXD3D11TextureFormat[GFXFormatD24S8];
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.Width = vm.resolution.x;
desc.Height = vm.resolution.y;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.MiscFlags = 0;
HRESULT hr = D3D11DEVICE->CreateTexture2D(&desc, NULL, &mDepthStencil);
if (FAILED(hr))
AssertFatal(false, "GFXD3D11WindowTarget::createBuffersAndViews - couldn't create device's depth-stencil surface.");
D3D11_DEPTH_STENCIL_VIEW_DESC depthDesc;
depthDesc.Format = GFXD3D11TextureFormat[GFXFormatD24S8];
depthDesc.Flags = 0;
depthDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
depthDesc.Texture2D.MipSlice = 0;
hr = D3D11DEVICE->CreateDepthStencilView(mDepthStencil, &depthDesc, &mDepthStencilView);
if (FAILED(hr))
AssertFatal(false, "GFXD3D11WindowTarget::createBuffersAndViews - couldn't create depth stencil view");
setBackBuffer();
//create back buffer view
D3D11_RENDER_TARGET_VIEW_DESC RTDesc;
RTDesc.Format = GFXD3D11TextureFormat[GFXFormatR8G8B8A8];
RTDesc.Texture2D.MipSlice = 0;
RTDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
hr = D3D11DEVICE->CreateRenderTargetView(mBackBuffer, &RTDesc, &mBackBufferView);
if (FAILED(hr))
AssertFatal(false, "GFXD3D11WindowTarget::createBuffersAndViews - couldn't create back buffer target view");
//debug names
#ifdef TORQUE_DEBUG
if (!mSecondaryWindow)
{
String backBufferName = "MainBackBuffer";
String depthSteniclName = "MainDepthStencil";
String backBuffViewName = "MainBackBuffView";
String depthStencViewName = "MainDepthView";
mBackBuffer->SetPrivateData(WKPDID_D3DDebugObjectName, backBufferName.size(), backBufferName.c_str());
mDepthStencil->SetPrivateData(WKPDID_D3DDebugObjectName, depthSteniclName.size(), depthSteniclName.c_str());
mDepthStencilView->SetPrivateData(WKPDID_D3DDebugObjectName, depthStencViewName.size(), depthStencViewName.c_str());
mBackBufferView->SetPrivateData(WKPDID_D3DDebugObjectName, backBuffViewName.size(), backBuffViewName.c_str());
}
#endif
if (!mBackbuffer)
D3D11->mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mBackbuffer);
}
void GFXD3D11WindowTarget::resetMode()
{
HRESULT hr;
if (mSwapChain)
{
// The current video settings.
DXGI_SWAP_CHAIN_DESC desc;
hr = mSwapChain->GetDesc(&desc);
if (FAILED(hr))
AssertFatal(false, "GFXD3D11WindowTarget::resetMode - failed to get swap chain description!");
bool fullscreen = !desc.Windowed;
Point2I backbufferSize(desc.BufferDesc.Width, desc.BufferDesc.Height);
// The settings we are now applying.
const GFXVideoMode &vm = mWindow->getVideoMode();
// Early out if none of the settings which require a device reset
// have changed.
if (backbufferSize == vm.resolution &&
fullscreen == vm.fullScreen)
return;
}
//release old buffers and views
SAFE_RELEASE(mDepthStencilView)
SAFE_RELEASE(mDepthStencil);
SAFE_RELEASE(mBackBufferView);
SAFE_RELEASE(mBackBuffer);
if(!mSecondaryWindow)
D3D11->beginReset();
mWindow->setSuppressReset(true);
// Setup our presentation params.
initPresentationParams();
if (!mPresentationParams.Windowed)
{
mPresentationParams.BufferDesc.RefreshRate.Numerator = 0;
mPresentationParams.BufferDesc.RefreshRate.Denominator = 0;
hr = mSwapChain->ResizeTarget(&mPresentationParams.BufferDesc);
if (FAILED(hr))
AssertFatal(false, "GFXD3D11WindowTarget::resetMode - failed to resize target!");
}
hr = mSwapChain->ResizeBuffers(mPresentationParams.BufferCount, mPresentationParams.BufferDesc.Width, mPresentationParams.BufferDesc.Height,
mPresentationParams.BufferDesc.Format, mPresentationParams.Windowed ? 0 : DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH);
if (FAILED(hr))
AssertFatal(false, "GFXD3D11WindowTarget::resetMode - failed to resize back buffer!");
hr = mSwapChain->SetFullscreenState(!mPresentationParams.Windowed, NULL);
if (FAILED(hr))
AssertFatal(false, "GFXD3D11WindowTarget::resetMode - failed to change screen states!");
// Otherwise, we have to reset the device, if we're the implicit swapchain.
D3D11->reset(mPresentationParams);
// Update our size, too.
mSize = Point2I(mPresentationParams.BufferDesc.Width, mPresentationParams.BufferDesc.Height);
mWindow->setSuppressReset(false);
//re-create buffers and views
createBuffersAndViews();
if (!mSecondaryWindow)
D3D11->endReset(this);
GFX->beginReset();
}
void GFXD3D11WindowTarget::zombify()
{
SAFE_RELEASE(mBackBuffer);
SAFE_RELEASE(mBackbuffer);
}
void GFXD3D11WindowTarget::resurrect()
{
setBackBuffer();
}
void GFXD3D11WindowTarget::setBackBuffer()
{
if (!mBackBuffer)
mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mBackBuffer);
setImplicitSwapChain();
}
void GFXD3D11WindowTarget::activate()
@ -542,10 +391,10 @@ void GFXD3D11WindowTarget::activate()
ID3D11RenderTargetView* rtViews[8] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
D3D11DEVICECONTEXT->OMSetRenderTargets(8, rtViews, NULL);
D3D11DEVICECONTEXT->OMSetRenderTargets(1, &mBackBufferView, mDepthStencilView);
D3D11DEVICECONTEXT->OMSetRenderTargets(1, &D3D11->mDeviceBackBufferView, D3D11->mDeviceDepthStencilView);
DXGI_SWAP_CHAIN_DESC pp;
mSwapChain->GetDesc(&pp);
D3D11->mSwapChain->GetDesc(&pp);
// Update our video mode here, too.
GFXVideoMode vm;
@ -563,35 +412,5 @@ void GFXD3D11WindowTarget::resolveTo(GFXTextureObject *tex)
D3D11_TEXTURE2D_DESC desc;
ID3D11Texture2D* surf = ((GFXD3D11TextureObject*)(tex))->get2DTex();
surf->GetDesc(&desc);
D3D11DEVICECONTEXT->ResolveSubresource(surf, 0, mBackBuffer, 0, desc.Format);
}
IDXGISwapChain *GFXD3D11WindowTarget::getSwapChain()
{
mSwapChain->AddRef();
return mSwapChain;
}
ID3D11Texture2D *GFXD3D11WindowTarget::getBackBuffer()
{
mBackBuffer->AddRef();
return mBackBuffer;
}
ID3D11Texture2D *GFXD3D11WindowTarget::getDepthStencil()
{
mDepthStencil->AddRef();
return mDepthStencil;
}
ID3D11RenderTargetView* GFXD3D11WindowTarget::getBackBufferView()
{
mBackBufferView->AddRef();
return mBackBufferView;
}
ID3D11DepthStencilView* GFXD3D11WindowTarget::getDepthStencilView()
{
mDepthStencilView->AddRef();
return mDepthStencilView;
D3D11DEVICECONTEXT->ResolveSubresource(surf, 0, D3D11->mDeviceBackbuffer, 0, desc.Format);
}

View file

@ -76,11 +76,7 @@ class GFXD3D11WindowTarget : public GFXWindowTarget
friend class GFXD3D11Device;
/// Our backbuffer
ID3D11Texture2D *mBackBuffer;
ID3D11Texture2D *mDepthStencil;
ID3D11RenderTargetView* mBackBufferView;
ID3D11DepthStencilView* mDepthStencilView;
IDXGISwapChain *mSwapChain;
ID3D11Texture2D *mBackbuffer;
/// Maximum size we can render to.
Point2I mSize;
@ -89,9 +85,6 @@ class GFXD3D11WindowTarget : public GFXWindowTarget
/// Internal interface that notifies us we need to reset our video mode.
void resetMode();
/// Is this a secondary window
bool mSecondaryWindow;
public:
GFXD3D11WindowTarget();
@ -102,9 +95,7 @@ public:
virtual bool present();
void initPresentationParams();
void createSwapChain();
void createBuffersAndViews();
void setBackBuffer();
void setImplicitSwapChain();
virtual void activate();
@ -112,13 +103,6 @@ public:
void resurrect();
virtual void resolveTo( GFXTextureObject *tex );
// These are all reference counted and must be released by whomever uses the get* function
IDXGISwapChain *getSwapChain();
ID3D11Texture2D *getBackBuffer();
ID3D11Texture2D *getDepthStencil();
ID3D11RenderTargetView* getBackBufferView();
ID3D11DepthStencilView* getDepthStencilView();
};
#endif

View file

@ -23,6 +23,7 @@
#include "gfx/D3D11/gfxD3D11Device.h"
#include "gfx/D3D11/gfxD3D11EnumTranslate.h"
#include "gfx/bitmap/bitmapUtils.h"
#include "gfx/bitmap/imageUtils.h"
#include "gfx/gfxCardProfile.h"
#include "gfx/gfxStringEnumTranslate.h"
#include "core/strings/unicode.h"
@ -139,7 +140,7 @@ void GFXD3D11TextureManager::_innerCreateTexture( GFXD3D11TextureObject *retTex,
}
else
{
UINT numQualityLevels = 0;
U32 numQualityLevels = 0;
switch (antialiasLevel)
{
@ -151,7 +152,6 @@ void GFXD3D11TextureManager::_innerCreateTexture( GFXD3D11TextureObject *retTex,
default:
{
antialiasLevel = 0;
UINT numQualityLevels;
D3D11DEVICE->CheckMultisampleQualityLevels(d3dTextureFormat, antialiasLevel, &numQualityLevels);
AssertFatal(numQualityLevels, "Invalid AA level!");
break;
@ -287,7 +287,7 @@ bool GFXD3D11TextureManager::_loadTexture(GFXTextureObject *aTexture, GBitmap *p
const bool supportsAutoMips = GFX->getCardProfiler()->queryProfile("autoMipMapLevel", true);
// Helper bool
const bool isCompressedTexFmt = aTexture->mFormat >= GFXFormatDXT1 && aTexture->mFormat <= GFXFormatDXT5;
const bool isCompressedTexFmt = ImageUtil::isCompressedFormat(aTexture->mFormat);
// Settings for mipmap generation
U32 maxDownloadMip = pDL->getNumMipLevels();
@ -312,10 +312,10 @@ bool GFXD3D11TextureManager::_loadTexture(GFXTextureObject *aTexture, GBitmap *p
switch(texture->mFormat)
{
case GFXFormatR8G8B8:
case GFXFormatR8G8B8:
case GFXFormatR8G8B8_SRGB:
{
PROFILE_SCOPE(Swizzle24_Upload);
AssertFatal(pDL->getFormat() == GFXFormatR8G8B8, "Assumption failed");
U8* Bits = new U8[pDL->getWidth(i) * pDL->getHeight(i) * 4];
dMemcpy(Bits, pDL->getBits(i), pDL->getWidth(i) * pDL->getHeight(i) * 3);
@ -330,6 +330,7 @@ bool GFXD3D11TextureManager::_loadTexture(GFXTextureObject *aTexture, GBitmap *p
case GFXFormatR8G8B8A8:
case GFXFormatR8G8B8X8:
case GFXFormatR8G8B8A8_SRGB:
{
PROFILE_SCOPE(Swizzle32_Upload);
copyBuffer = new U8[pDL->getWidth(i) * pDL->getHeight(i) * pDL->getBytesPerPixel()];
@ -360,9 +361,9 @@ bool GFXD3D11TextureManager::_loadTexture(GFXTextureObject *aTexture, GBitmap *p
switch( texture->mFormat )
{
case GFXFormatR8G8B8:
case GFXFormatR8G8B8_SRGB:
{
PROFILE_SCOPE(Swizzle24_Upload);
AssertFatal(pDL->getFormat() == GFXFormatR8G8B8, "Assumption failed");
U8* Bits = new U8[pDL->getWidth(i) * pDL->getHeight(i) * 4];
dMemcpy(Bits, pDL->getBits(i), pDL->getWidth(i) * pDL->getHeight(i) * 3);
@ -375,6 +376,7 @@ bool GFXD3D11TextureManager::_loadTexture(GFXTextureObject *aTexture, GBitmap *p
case GFXFormatR8G8B8A8:
case GFXFormatR8G8B8X8:
case GFXFormatR8G8B8A8_SRGB:
{
PROFILE_SCOPE(Swizzle32_Upload);
dev->getDeviceSwizzle32()->ToBuffer(mapping.pData, pDL->getBits(i), pDL->getWidth(i) * pDL->getHeight(i) * pDL->getBytesPerPixel());
@ -417,7 +419,7 @@ bool GFXD3D11TextureManager::_loadTexture(GFXTextureObject *inTex, void *raw)
U8* Bits = NULL;
if(texture->mFormat == GFXFormatR8G8B8)
if(texture->mFormat == GFXFormatR8G8B8 || texture->mFormat == GFXFormatR8G8B8_SRGB)
{
// convert 24 bit to 32 bit
Bits = new U8[texture->getWidth() * texture->getHeight() * texture->getDepth() * 4];
@ -430,8 +432,10 @@ bool GFXD3D11TextureManager::_loadTexture(GFXTextureObject *inTex, void *raw)
switch(texture->mFormat)
{
case GFXFormatR8G8B8:
case GFXFormatR8G8B8_SRGB:
case GFXFormatR8G8B8A8:
case GFXFormatR8G8B8X8:
case GFXFormatR8G8B8A8_SRGB:
bytesPerPix = 4;
break;
}
@ -444,7 +448,7 @@ bool GFXD3D11TextureManager::_loadTexture(GFXTextureObject *inTex, void *raw)
box.top = 0;
box.bottom = texture->getHeight();
if(texture->mFormat == GFXFormatR8G8B8) // converted format also for volume textures
if(texture->mFormat == GFXFormatR8G8B8 || texture->mFormat == GFXFormatR8G8B8_SRGB) // converted format also for volume textures
dev->getDeviceContext()->UpdateSubresource(texture->get3DTex(), 0, &box, Bits, texture->getWidth() * bytesPerPix, texture->getHeight() * bytesPerPix);
else
dev->getDeviceContext()->UpdateSubresource(texture->get3DTex(), 0, &box, raw, texture->getWidth() * bytesPerPix, texture->getHeight() * bytesPerPix);

View file

@ -74,7 +74,7 @@ GFXLockedRect *GFXD3D11TextureObject::lock(U32 mipLevel /*= 0*/, RectI *inRect /
mLockTex->getWidth() != getWidth() ||
mLockTex->getHeight() != getHeight() )
{
mLockTex.set( getWidth(), getHeight(), mFormat, &GFXSystemMemProfile, avar("%s() - mLockTex (line %d)", __FUNCTION__, __LINE__) );
mLockTex.set( getWidth(), getHeight(), mFormat, &GFXSystemMemTextureProfile, avar("%s() - mLockTex (line %d)", __FUNCTION__, __LINE__) );
}
PROFILE_START(GFXD3D11TextureObject_lockRT);
@ -180,8 +180,8 @@ bool GFXD3D11TextureObject::copyToBmp(GBitmap* bmp)
// 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 || mFormat == GFXFormatR8G8B8A8_LINEAR_FORCE, "copyToBmp: invalid format");
if (mFormat != GFXFormatR8G8B8A8 && mFormat != GFXFormatR8G8B8A8_LINEAR_FORCE)
AssertFatal(mFormat == GFXFormatR8G8B8A8 || mFormat == GFXFormatR8G8B8A8_LINEAR_FORCE || mFormat == GFXFormatR8G8B8A8_SRGB, "copyToBmp: invalid format");
if (mFormat != GFXFormatR8G8B8A8 && mFormat != GFXFormatR8G8B8A8_LINEAR_FORCE && mFormat != GFXFormatR8G8B8A8_SRGB)
return false;
PROFILE_START(GFXD3D11TextureObject_copyToBmp);
@ -197,7 +197,8 @@ bool GFXD3D11TextureObject::copyToBmp(GBitmap* bmp)
const U32 sourceBytesPerPixel = 4;
U32 destBytesPerPixel = 0;
if (bmp->getFormat() == GFXFormatR8G8B8A8 || bmp->getFormat() == GFXFormatR8G8B8A8_LINEAR_FORCE)
const GFXFormat fmt = bmp->getFormat();
if (fmt == GFXFormatR8G8B8A8 || fmt == GFXFormatR8G8B8A8_LINEAR_FORCE || fmt == GFXFormatR8G8B8A8_SRGB)
destBytesPerPixel = 4;
else if(bmp->getFormat() == GFXFormatR8G8B8)
destBytesPerPixel = 3;

View file

@ -101,7 +101,7 @@ protected:
virtual void setLightInternal(U32 lightStage, const GFXLightInfo light, bool lightEnable);
virtual void setLightMaterialInternal(const GFXLightMaterial mat) { };
virtual void setGlobalAmbientInternal(ColorF color) { };
virtual void setGlobalAmbientInternal(LinearColorF color) { };
/// @name State Initalization.
/// @{
@ -150,7 +150,7 @@ public:
virtual GFXShader* createShader() { return NULL; };
virtual void clear( U32 flags, ColorI color, F32 z, U32 stencil ) { };
virtual void clear( U32 flags, const LinearColorF& color, F32 z, U32 stencil ) { };
virtual bool beginSceneInternal() { return true; };
virtual void endSceneInternal() { };

View file

@ -0,0 +1,779 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2016 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.
//-----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
// Portions Copyright (c) Microsoft Corporation. All rights reserved.
// https://github.com/Microsoft/DirectXTex
////////////////////////////////////////////////////////////////////////////////
#ifndef _DDSDATA_H_
#define _DDSDATA_H_
#ifndef _TORQUE_TYPES_H_
#include "platform/types.h"
#endif
#include "core/util/fourcc.h"
#ifdef TORQUE_OS_WIN
#include <dxgiformat.h>
#endif
namespace dds
{
///////////////////////////////////////////////////////////////////////////////////
// DXGI Formats //
///////////////////////////////////////////////////////////////////////////////////
#ifndef TORQUE_OS_WIN
//From directx SDK
typedef enum DXGI_FORMAT
{
DXGI_FORMAT_UNKNOWN = 0,
DXGI_FORMAT_R32G32B32A32_TYPELESS = 1,
DXGI_FORMAT_R32G32B32A32_FLOAT = 2,
DXGI_FORMAT_R32G32B32A32_UINT = 3,
DXGI_FORMAT_R32G32B32A32_SINT = 4,
DXGI_FORMAT_R32G32B32_TYPELESS = 5,
DXGI_FORMAT_R32G32B32_FLOAT = 6,
DXGI_FORMAT_R32G32B32_UINT = 7,
DXGI_FORMAT_R32G32B32_SINT = 8,
DXGI_FORMAT_R16G16B16A16_TYPELESS = 9,
DXGI_FORMAT_R16G16B16A16_FLOAT = 10,
DXGI_FORMAT_R16G16B16A16_UNORM = 11,
DXGI_FORMAT_R16G16B16A16_UINT = 12,
DXGI_FORMAT_R16G16B16A16_SNORM = 13,
DXGI_FORMAT_R16G16B16A16_SINT = 14,
DXGI_FORMAT_R32G32_TYPELESS = 15,
DXGI_FORMAT_R32G32_FLOAT = 16,
DXGI_FORMAT_R32G32_UINT = 17,
DXGI_FORMAT_R32G32_SINT = 18,
DXGI_FORMAT_R32G8X24_TYPELESS = 19,
DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 20,
DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 21,
DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 22,
DXGI_FORMAT_R10G10B10A2_TYPELESS = 23,
DXGI_FORMAT_R10G10B10A2_UNORM = 24,
DXGI_FORMAT_R10G10B10A2_UINT = 25,
DXGI_FORMAT_R11G11B10_FLOAT = 26,
DXGI_FORMAT_R8G8B8A8_TYPELESS = 27,
DXGI_FORMAT_R8G8B8A8_UNORM = 28,
DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29,
DXGI_FORMAT_R8G8B8A8_UINT = 30,
DXGI_FORMAT_R8G8B8A8_SNORM = 31,
DXGI_FORMAT_R8G8B8A8_SINT = 32,
DXGI_FORMAT_R16G16_TYPELESS = 33,
DXGI_FORMAT_R16G16_FLOAT = 34,
DXGI_FORMAT_R16G16_UNORM = 35,
DXGI_FORMAT_R16G16_UINT = 36,
DXGI_FORMAT_R16G16_SNORM = 37,
DXGI_FORMAT_R16G16_SINT = 38,
DXGI_FORMAT_R32_TYPELESS = 39,
DXGI_FORMAT_D32_FLOAT = 40,
DXGI_FORMAT_R32_FLOAT = 41,
DXGI_FORMAT_R32_UINT = 42,
DXGI_FORMAT_R32_SINT = 43,
DXGI_FORMAT_R24G8_TYPELESS = 44,
DXGI_FORMAT_D24_UNORM_S8_UINT = 45,
DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 46,
DXGI_FORMAT_X24_TYPELESS_G8_UINT = 47,
DXGI_FORMAT_R8G8_TYPELESS = 48,
DXGI_FORMAT_R8G8_UNORM = 49,
DXGI_FORMAT_R8G8_UINT = 50,
DXGI_FORMAT_R8G8_SNORM = 51,
DXGI_FORMAT_R8G8_SINT = 52,
DXGI_FORMAT_R16_TYPELESS = 53,
DXGI_FORMAT_R16_FLOAT = 54,
DXGI_FORMAT_D16_UNORM = 55,
DXGI_FORMAT_R16_UNORM = 56,
DXGI_FORMAT_R16_UINT = 57,
DXGI_FORMAT_R16_SNORM = 58,
DXGI_FORMAT_R16_SINT = 59,
DXGI_FORMAT_R8_TYPELESS = 60,
DXGI_FORMAT_R8_UNORM = 61,
DXGI_FORMAT_R8_UINT = 62,
DXGI_FORMAT_R8_SNORM = 63,
DXGI_FORMAT_R8_SINT = 64,
DXGI_FORMAT_A8_UNORM = 65,
DXGI_FORMAT_R1_UNORM = 66,
DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 67,
DXGI_FORMAT_R8G8_B8G8_UNORM = 68,
DXGI_FORMAT_G8R8_G8B8_UNORM = 69,
DXGI_FORMAT_BC1_TYPELESS = 70,
DXGI_FORMAT_BC1_UNORM = 71,
DXGI_FORMAT_BC1_UNORM_SRGB = 72,
DXGI_FORMAT_BC2_TYPELESS = 73,
DXGI_FORMAT_BC2_UNORM = 74,
DXGI_FORMAT_BC2_UNORM_SRGB = 75,
DXGI_FORMAT_BC3_TYPELESS = 76,
DXGI_FORMAT_BC3_UNORM = 77,
DXGI_FORMAT_BC3_UNORM_SRGB = 78,
DXGI_FORMAT_BC4_TYPELESS = 79,
DXGI_FORMAT_BC4_UNORM = 80,
DXGI_FORMAT_BC4_SNORM = 81,
DXGI_FORMAT_BC5_TYPELESS = 82,
DXGI_FORMAT_BC5_UNORM = 83,
DXGI_FORMAT_BC5_SNORM = 84,
DXGI_FORMAT_B5G6R5_UNORM = 85,
DXGI_FORMAT_B5G5R5A1_UNORM = 86,
DXGI_FORMAT_B8G8R8A8_UNORM = 87,
DXGI_FORMAT_B8G8R8X8_UNORM = 88,
DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89,
DXGI_FORMAT_B8G8R8A8_TYPELESS = 90,
DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91,
DXGI_FORMAT_B8G8R8X8_TYPELESS = 92,
DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93,
DXGI_FORMAT_BC6H_TYPELESS = 94,
DXGI_FORMAT_BC6H_UF16 = 95,
DXGI_FORMAT_BC6H_SF16 = 96,
DXGI_FORMAT_BC7_TYPELESS = 97,
DXGI_FORMAT_BC7_UNORM = 98,
DXGI_FORMAT_BC7_UNORM_SRGB = 99,
DXGI_FORMAT_AYUV = 100,
DXGI_FORMAT_Y410 = 101,
DXGI_FORMAT_Y416 = 102,
DXGI_FORMAT_NV12 = 103,
DXGI_FORMAT_P010 = 104,
DXGI_FORMAT_P016 = 105,
DXGI_FORMAT_420_OPAQUE = 106,
DXGI_FORMAT_YUY2 = 107,
DXGI_FORMAT_Y210 = 108,
DXGI_FORMAT_Y216 = 109,
DXGI_FORMAT_NV11 = 110,
DXGI_FORMAT_AI44 = 111,
DXGI_FORMAT_IA44 = 112,
DXGI_FORMAT_P8 = 113,
DXGI_FORMAT_A8P8 = 114,
DXGI_FORMAT_B4G4R4A4_UNORM = 115,
DXGI_FORMAT_FORCE_UINT = 0xffffffff
} DXGI_FORMAT;
#endif
///////////////////////////////////////////////////////////////////////////////////
// D3DFMT Formats //
///////////////////////////////////////////////////////////////////////////////////
enum D3DFMT
{
D3DFMT_UNKNOWN = 0,
D3DFMT_R8G8B8 = 20,
D3DFMT_A8R8G8B8 = 21,
D3DFMT_X8R8G8B8 = 22,
D3DFMT_R5G6B5 = 23,
D3DFMT_X1R5G5B5 = 24,
D3DFMT_A1R5G5B5 = 25,
D3DFMT_A4R4G4B4 = 26,
D3DFMT_R3G3B2 = 27,
D3DFMT_A8 = 28,
D3DFMT_A8R3G3B2 = 29,
D3DFMT_X4R4G4B4 = 30,
D3DFMT_A2B10G10R10 = 31,
D3DFMT_A8B8G8R8 = 32,
D3DFMT_X8B8G8R8 = 33,
D3DFMT_G16R16 = 34,
D3DFMT_A2R10G10B10 = 35,
D3DFMT_A16B16G16R16 = 36,
D3DFMT_A8P8 = 40,
D3DFMT_P8 = 41,
D3DFMT_L8 = 50,
D3DFMT_A8L8 = 51,
D3DFMT_A4L4 = 52,
D3DFMT_V8U8 = 60,
D3DFMT_L6V5U5 = 61,
D3DFMT_X8L8V8U8 = 62,
D3DFMT_Q8W8V8U8 = 63,
D3DFMT_V16U16 = 64,
D3DFMT_A2W10V10U10 = 67,
D3DFMT_UYVY = MakeFourCC('U', 'Y', 'V', 'Y'),
D3DFMT_R8G8_B8G8 = MakeFourCC('R', 'G', 'B', 'G'),
D3DFMT_YUY2 = MakeFourCC('Y', 'U', 'Y', '2'),
D3DFMT_G8R8_G8B8 = MakeFourCC('G', 'R', 'G', 'B'),
D3DFMT_DXT1 = MakeFourCC('D', 'X', 'T', '1'),
D3DFMT_DXT2 = MakeFourCC('D', 'X', 'T', '2'),
D3DFMT_DXT3 = MakeFourCC('D', 'X', 'T', '3'),
D3DFMT_DXT4 = MakeFourCC('D', 'X', 'T', '4'),
D3DFMT_DXT5 = MakeFourCC('D', 'X', 'T', '5'),
D3DFMT_ATI1 = MakeFourCC('A', 'T', 'I', '1'),
D3DFMT_AT1N = MakeFourCC('A', 'T', '1', 'N'),
D3DFMT_ATI2 = MakeFourCC('A', 'T', 'I', '2'),
D3DFMT_AT2N = MakeFourCC('A', 'T', '2', 'N'),
D3DFMT_BC4U = MakeFourCC('B', 'C', '4', 'U'),
D3DFMT_BC4S = MakeFourCC('B', 'C', '4', 'S'),
D3DFMT_BC5U = MakeFourCC('B', 'C', '5', 'U'),
D3DFMT_BC5S = MakeFourCC('B', 'C', '5', 'S'),
D3DFMT_ETC = MakeFourCC('E', 'T', 'C', ' '),
D3DFMT_ETC1 = MakeFourCC('E', 'T', 'C', '1'),
D3DFMT_ATC = MakeFourCC('A', 'T', 'C', ' '),
D3DFMT_ATCA = MakeFourCC('A', 'T', 'C', 'A'),
D3DFMT_ATCI = MakeFourCC('A', 'T', 'C', 'I'),
D3DFMT_POWERVR_2BPP = MakeFourCC('P', 'T', 'C', '2'),
D3DFMT_POWERVR_4BPP = MakeFourCC('P', 'T', 'C', '4'),
D3DFMT_D16_LOCKABLE = 70,
D3DFMT_D32 = 71,
D3DFMT_D15S1 = 73,
D3DFMT_D24S8 = 75,
D3DFMT_D24X8 = 77,
D3DFMT_D24X4S4 = 79,
D3DFMT_D16 = 80,
D3DFMT_D32F_LOCKABLE = 82,
D3DFMT_D24FS8 = 83,
D3DFMT_L16 = 81,
D3DFMT_VERTEXDATA = 100,
D3DFMT_INDEX16 = 101,
D3DFMT_INDEX32 = 102,
D3DFMT_Q16W16V16U16 = 110,
D3DFMT_MULTI2_ARGB8 = MakeFourCC('M', 'E', 'T', '1'),
D3DFMT_R16F = 111,
D3DFMT_G16R16F = 112,
D3DFMT_A16B16G16R16F = 113,
D3DFMT_R32F = 114,
D3DFMT_G32R32F = 115,
D3DFMT_A32B32G32R32F = 116,
D3DFMT_CxV8U8 = 117,
D3DFMT_DX10 = MakeFourCC('D', 'X', '1', '0'),
D3DFMT_FORCE_DWORD = 0x7fffffff
};
///////////////////////////////////////////////////////////////////////////////////
// Defines //
///////////////////////////////////////////////////////////////////////////////////
#pragma pack(push,1)
#define DDS_HEADER_SIZE 124
#define DDS_HEADER_DX10_SIZE 20
#define DDS_MAGIC 0x20534444 // "DDS "
#define DDS_FOURCC 0x00000004 // DDPF_FOURCC
#define DDS_RGB 0x00000040 // DDPF_RGB
#define DDS_RGBA 0x00000041 // DDPF_RGB | DDPF_ALPHAPIXELS
#define DDS_LUMINANCE 0x00020000 // DDPF_LUMINANCE
#define DDS_LUMINANCEA 0x00020001 // DDPF_LUMINANCE | DDPF_ALPHAPIXELS
#define DDS_ALPHAPIXELS 0x00000001 // DDPF_ALPHAPIXELS
#define DDS_ALPHA 0x00000002 // DDPF_ALPHA
#define DDS_PAL8 0x00000020 // DDPF_PALETTEINDEXED8
#define DDS_BUMPDUDV 0x00080000 // DDPF_BUMPDUDV
#define DDS_YUV 0x00000200 //DDPF_YUV
#define DDS_HEADER_FLAGS_TEXTURE 0x00001007 // DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT
#define DDS_HEADER_FLAGS_MIPMAP 0x00020000 // DDSD_MIPMAPCOUNT
#define DDS_HEADER_FLAGS_VOLUME 0x00800000 // DDSD_DEPTH
#define DDS_HEADER_FLAGS_PITCH 0x00000008 // DDSD_PITCH
#define DDS_HEADER_FLAGS_LINEARSIZE 0x00080000 // DDSD_LINEARSIZE
#define DDS_HEIGHT 0x00000002 // DDSD_HEIGHT
#define DDS_WIDTH 0x00000004 // DDSD_WIDTH
#define DDS_SURFACE_FLAGS_TEXTURE 0x00001000 // DDSCAPS_TEXTURE
#define DDS_SURFACE_FLAGS_MIPMAP 0x00400008 // DDSCAPS_COMPLEX | DDSCAPS_MIPMAP
#define DDS_SURFACE_FLAGS_CUBEMAP 0x00000008 // DDSCAPS_COMPLEX
#define DDS_CUBEMAP 0x00000200 // DDSCAPS2_CUBEMAP
#define DDS_CUBEMAP_POSITIVEX 0x00000400 // DDSCAPS2_CUBEMAP_POSITIVEX
#define DDS_CUBEMAP_NEGATIVEX 0x00000800 // DDSCAPS2_CUBEMAP_NEGATIVEX
#define DDS_CUBEMAP_POSITIVEY 0x00001000 // DDSCAPS2_CUBEMAP_POSITIVEY
#define DDS_CUBEMAP_NEGATIVEY 0x00002000 // DDSCAPS2_CUBEMAP_NEGATIVEY
#define DDS_CUBEMAP_POSITIVEZ 0x00004000 // DDSCAPS2_CUBEMAP_POSITIVEZ
#define DDS_CUBEMAP_NEGATIVEZ 0x00008000 // DDSCAPS2_CUBEMAP_NEGATIVEZ
#define DDS_CUBEMAP_ALLFACES ( DDS_CUBEMAP | DDS_CUBEMAP_POSITIVEX | DDS_CUBEMAP_NEGATIVEX |\
DDS_CUBEMAP_POSITIVEY | DDS_CUBEMAP_NEGATIVEY |\
DDS_CUBEMAP_POSITIVEZ | DDS_CUBEMAP_NEGATIVEZ )
#define DDS_FLAGS_VOLUME 0x00200000 // DDSCAPS2_VOLUME
///////////////////////////////////////////////////////////////////////////////////
// Enums //
///////////////////////////////////////////////////////////////////////////////////
// Subset here matches D3D10_RESOURCE_DIMENSION and D3D11_RESOURCE_DIMENSION
enum DDS_RESOURCE_DIMENSION
{
DDS_DIMENSION_TEXTURE1D = 2,
DDS_DIMENSION_TEXTURE2D = 3,
DDS_DIMENSION_TEXTURE3D = 4,
};
// Subset here matches D3D10_RESOURCE_MISC_FLAG and D3D11_RESOURCE_MISC_FLAG
enum DDS_RESOURCE_MISC_FLAG
{
DDS_RESOURCE_MISC_TEXTURECUBE = 0x4L,
};
enum DDS_MISC_FLAGS2
{
DDS_MISC_FLAGS2_ALPHA_MODE_MASK = 0x7L,
};
enum DDS_ALPHA_MODE
{
DDS_ALPHA_MODE_UNKNOWN = 0,
DDS_ALPHA_MODE_STRAIGHT = 1,
DDS_ALPHA_MODE_PREMULTIPLIED = 2,
DDS_ALPHA_MODE_OPAQUE = 3,
DDS_ALPHA_MODE_CUSTOM = 4,
};
enum D3D10_RESOURCE_DIMENSION
{
D3D10_RESOURCE_DIMENSION_UNKNOWN = 0,
D3D10_RESOURCE_DIMENSION_BUFFER = 1,
D3D10_RESOURCE_DIMENSION_TEXTURE1D = 2,
D3D10_RESOURCE_DIMENSION_TEXTURE2D = 3,
D3D10_RESOURCE_DIMENSION_TEXTURE3D = 4
};
enum D3D10_RESOURCE_MISC_FLAG
{
D3D10_RESOURCE_MISC_GENERATE_MIPS = 0x1L,
D3D10_RESOURCE_MISC_SHARED = 0x2L,
D3D10_RESOURCE_MISC_TEXTURECUBE = 0x4L,
D3D10_RESOURCE_MISC_SHARED_KEYEDMUTEX = 0x10L,
D3D10_RESOURCE_MISC_GDI_COMPATIBLE = 0x20L,
};
///////////////////////////////////////////////////////////////////////////////////
// Structs //
///////////////////////////////////////////////////////////////////////////////////
struct DDS_PIXELFORMAT
{
U32 size;
U32 flags;
U32 fourCC;
U32 bpp;
U32 RBitMask;
U32 GBitMask;
U32 BBitMask;
U32 ABitMask;
bool operator==(const DDS_PIXELFORMAT& _test) const
{
return ( size == _test.size &&
flags == _test.flags &&
fourCC == _test.fourCC &&
bpp == _test.bpp &&
RBitMask == _test.RBitMask &&
GBitMask == _test.GBitMask &&
BBitMask == _test.BBitMask &&
ABitMask == _test.ABitMask);
}
};
struct DDS_HEADER
{
U32 size;
U32 flags;
U32 height;
U32 width;
U32 pitchOrLinearSize;
U32 depth; // only if DDS_HEADER_FLAGS_VOLUME is set in dwFlags
U32 mipMapCount;
U32 reserved1[11];
DDS_PIXELFORMAT ddspf;
U32 surfaceFlags;
U32 cubemapFlags;
U32 reserved2[3];
};
struct DDS_HEADER_DXT10
{
DXGI_FORMAT dxgiFormat;
U32 resourceDimension;
U32 miscFlag; // see DDS_RESOURCE_MISC_FLAG
U32 arraySize;
U32 miscFlags2; // see DDS_MISC_FLAGS2
};
///////////////////////////////////////////////////////////////////////////////////
// Pixel Formats //
///////////////////////////////////////////////////////////////////////////////////
const DDS_PIXELFORMAT DDSPF_DXT1 =
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 };
const DDS_PIXELFORMAT DDSPF_DXT2 =
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, D3DFMT_DXT2, 0, 0, 0, 0, 0 };
const DDS_PIXELFORMAT DDSPF_DXT3 =
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, D3DFMT_DXT3, 0, 0, 0, 0, 0 };
const DDS_PIXELFORMAT DDSPF_DXT4 =
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, D3DFMT_DXT4, 0, 0, 0, 0, 0 };
const DDS_PIXELFORMAT DDSPF_DXT5 =
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, D3DFMT_DXT5, 0, 0, 0, 0, 0 };
const DDS_PIXELFORMAT DDSPF_BC4_UNORM =
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, D3DFMT_BC4U, 0, 0, 0, 0, 0 };
const DDS_PIXELFORMAT DDSPF_BC4_SNORM =
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, D3DFMT_BC4S, 0, 0, 0, 0, 0 };
//todo check diff between this and ('B','C','5','U')
const DDS_PIXELFORMAT DDSPF_ATI2 =
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, D3DFMT_ATI2, 0, 0, 0, 0, 0 };
const DDS_PIXELFORMAT DDSPF_ATI1 =
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, D3DFMT_ATI1, 0, 0, 0, 0, 0 };
const DDS_PIXELFORMAT DDSPF_BC5_UNORM =
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, D3DFMT_BC5U, 0, 0, 0, 0, 0 };
const DDS_PIXELFORMAT DDSPF_BC5_SNORM =
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, D3DFMT_BC5S, 0, 0, 0, 0, 0 };
const DDS_PIXELFORMAT DDSPF_R8G8_B8G8 =
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, D3DFMT_R8G8_B8G8, 0, 0, 0, 0, 0 };
const DDS_PIXELFORMAT DDSPF_G8R8_G8B8 =
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, D3DFMT_G8R8_G8B8, 0, 0, 0, 0, 0 };
const DDS_PIXELFORMAT DDSPF_YUY2 =
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, D3DFMT_YUY2, 0, 0, 0, 0, 0 };
const DDS_PIXELFORMAT DDSPF_A8R8G8B8 =
{ sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 };
const DDS_PIXELFORMAT DDSPF_X8R8G8B8 =
{ sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000 };
const DDS_PIXELFORMAT DDSPF_A8B8G8R8 =
{ sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 };
const DDS_PIXELFORMAT DDSPF_X8B8G8R8 =
{ sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000 };
const DDS_PIXELFORMAT DDSPF_G16R16 =
{ sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 32, 0x0000ffff, 0xffff0000, 0x00000000, 0x00000000 };
const DDS_PIXELFORMAT DDSPF_R5G6B5 =
{ sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 16, 0x0000f800, 0x000007e0, 0x0000001f, 0x00000000 };
const DDS_PIXELFORMAT DDSPF_A1R5G5B5 =
{ sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 16, 0x00007c00, 0x000003e0, 0x0000001f, 0x00008000 };
const DDS_PIXELFORMAT DDSPF_A4R4G4B4 =
{ sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 16, 0x00000f00, 0x000000f0, 0x0000000f, 0x0000f000 };
const DDS_PIXELFORMAT DDSPF_R8G8B8 =
{ sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000 };
const DDS_PIXELFORMAT DDSPF_L8 =
{ sizeof(DDS_PIXELFORMAT), DDS_LUMINANCE, 0, 8, 0xff, 0x00, 0x00, 0x00 };
const DDS_PIXELFORMAT DDSPF_L16 =
{ sizeof(DDS_PIXELFORMAT), DDS_LUMINANCE, 0, 16, 0xffff, 0x0000, 0x0000, 0x0000 };
const DDS_PIXELFORMAT DDSPF_A8L8 =
{ sizeof(DDS_PIXELFORMAT), DDS_LUMINANCEA, 0, 16, 0x00ff, 0x0000, 0x0000, 0xff00 };
const DDS_PIXELFORMAT DDSPF_A4L4 =
{ sizeof(DDS_PIXELFORMAT), DDS_LUMINANCEA, 0, 8, 0x0000000f, 0x0000, 0x0000, 0x000000f0 };
const DDS_PIXELFORMAT DDSPF_A8 =
{ sizeof(DDS_PIXELFORMAT), DDS_ALPHA, 0, 8, 0x00, 0x00, 0x00, 0xff };
const DDS_PIXELFORMAT DDSPF_V8U8 =
{ sizeof(DDS_PIXELFORMAT), DDS_BUMPDUDV, 0, 16, 0x00ff, 0xff00, 0x0000, 0x0000 };
const DDS_PIXELFORMAT DDSPF_Q8W8V8U8 =
{ sizeof(DDS_PIXELFORMAT), DDS_BUMPDUDV, 0, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 };
const DDS_PIXELFORMAT DDSPF_V16U16 =
{ sizeof(DDS_PIXELFORMAT), DDS_BUMPDUDV, 0, 32, 0x0000ffff, 0xffff0000, 0x00000000, 0x00000000 };
// D3DFMT_A2R10G10B10/D3DFMT_A2B10G10R10 should be written using DX10 extension to avoid D3DX 10:10:10:2 reversal issue
// This indicates the DDS_HEADER_DXT10 extension is present (the format is in dxgiFormat)
const DDS_PIXELFORMAT DDSPF_DX10 =
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, D3DFMT_DX10, 0, 0, 0, 0, 0 };
#pragma pack(pop)
///////////////////////////////////////////////////////////////////////////////////
// Functions //
///////////////////////////////////////////////////////////////////////////////////
//get DDS_PIXELFORMAT struct from GFXFormat - todo more formats
const DDS_PIXELFORMAT getDDSFormat(const GFXFormat format)
{
switch (format)
{
case GFXFormatA4L4: return DDSPF_A4L4;
case GFXFormatL8: return DDSPF_L8;
case GFXFormatA8: return DDSPF_A8;
case GFXFormatA8L8: return DDSPF_A8L8;
case GFXFormatL16: return DDSPF_L16;
case GFXFormatR5G6B5: return DDSPF_R5G6B5;
case GFXFormatR5G5B5A1: return DDSPF_A1R5G5B5;
case GFXFormatR8G8B8: return DDSPF_R8G8B8;
case GFXFormatR8G8B8A8: return DDSPF_A8R8G8B8;
case GFXFormatR8G8B8X8: return DDSPF_X8R8G8B8;
case GFXFormatB8G8R8A8: return DDSPF_A8B8G8R8;
case GFXFormatR16G16B16A16F:
case GFXFormatR32G32B32A32F: return DDSPF_DX10;
//compressed
case GFXFormatBC1: return DDSPF_DXT1;
case GFXFormatBC2: return DDSPF_DXT3;
case GFXFormatBC3: return DDSPF_DXT5;
case GFXFormatBC4: return DDSPF_ATI1;
case GFXFormatBC5: return DDSPF_ATI2;
default:
{
Con::errorf("dds::getDDSFormat: unknown format");
return DDSPF_A8R8G8B8;
}
}
}
//get DXGI_FORMAT from GFXFormat - todo more formats
const DXGI_FORMAT getDXGIFormat(const GFXFormat format)
{
switch (format)
{
//byte
case GFXFormatR5G6B5: return DXGI_FORMAT_B5G6R5_UNORM;
case GFXFormatR5G5B5A1: return DXGI_FORMAT_B5G5R5A1_UNORM;
case GFXFormatB8G8R8A8: return DXGI_FORMAT_R8G8B8A8_UNORM;
case GFXFormatR8G8B8A8: return DXGI_FORMAT_B8G8R8A8_UNORM;
case GFXFormatR8G8B8X8: return DXGI_FORMAT_B8G8R8X8_UNORM;
case GFXFormatR10G10B10A2: return DXGI_FORMAT_R10G10B10A2_UNORM;
//uint
case GFXFormatR16G16: return DXGI_FORMAT_R16G16_UINT;
case GFXFormatR16G16B16A16: return DXGI_FORMAT_R16G16B16A16_UINT;
//float
case GFXFormatR16F: return DXGI_FORMAT_R16_FLOAT;
case GFXFormatR32F: return DXGI_FORMAT_R32_FLOAT;
case GFXFormatR16G16B16A16F: return DXGI_FORMAT_R16G16B16A16_FLOAT;
case GFXFormatR32G32B32A32F: return DXGI_FORMAT_R32G32B32A32_FLOAT;
//compressed
case GFXFormatBC1: return DXGI_FORMAT_BC1_UNORM;
case GFXFormatBC2: return DXGI_FORMAT_BC2_UNORM;
case GFXFormatBC3: return DXGI_FORMAT_BC3_UNORM;
case GFXFormatBC4: return DXGI_FORMAT_BC4_UNORM;
case GFXFormatBC5: return DXGI_FORMAT_BC5_UNORM;
default:
{
Con::errorf("dds::getDXGIFormat: unknown format");
return DXGI_FORMAT_UNKNOWN;
}
}
}
//get GFXFormat from D3DFMT - todo more formats
const GFXFormat getGFXFormat(const D3DFMT format)
{
switch (format)
{
//byte
case D3DFMT_A4L4: return GFXFormatA4L4;
case D3DFMT_L8: return GFXFormatL8;
case D3DFMT_A8: return GFXFormatA8;
case D3DFMT_A8L8: return GFXFormatA8L8;
case D3DFMT_L16: return GFXFormatL16;
case D3DFMT_R5G6B5: return GFXFormatR5G6B5;
case D3DFMT_A1R5G5B5: return GFXFormatR5G5B5A1;
case D3DFMT_R8G8B8: return GFXFormatR8G8B8;
case D3DFMT_A8R8G8B8: return GFXFormatR8G8B8A8;
case D3DFMT_X8R8G8B8: return GFXFormatR8G8B8A8;
case D3DFMT_A8B8G8R8: return GFXFormatB8G8R8A8;
case D3DFMT_X8B8G8R8: return GFXFormatB8G8R8A8;
//uint
case D3DFMT_G16R16: return GFXFormatR16G16;
case D3DFMT_A16B16G16R16: return GFXFormatR16G16B16A16;
//float
case D3DFMT_R16F: return GFXFormatR16F;
case D3DFMT_R32F: return GFXFormatR32F;
case D3DFMT_A16B16G16R16F: return GFXFormatR16G16B16A16F;
case D3DFMT_A32B32G32R32F: return GFXFormatR32G32B32A32F;
//compressed
case D3DFMT_DXT1: return GFXFormatBC1;
case D3DFMT_DXT2:
case D3DFMT_DXT3: return GFXFormatBC2;
case D3DFMT_DXT4:
case D3DFMT_DXT5: return GFXFormatBC3;
case D3DFMT_ATI1: return GFXFormatBC4;
case D3DFMT_ATI2: return GFXFormatBC5;
default:
{
Con::errorf("dds::getGFXFormat: unknown format");
return GFXFormat_FIRST;
}
}
}
//get GFXFormat from DXGI_FORMAT - todo more formats
const GFXFormat getGFXFormat(const DXGI_FORMAT format)
{
switch (format)
{
//byte
case DXGI_FORMAT_B5G6R5_UNORM: return GFXFormatR5G6B5;
case DXGI_FORMAT_B5G5R5A1_UNORM: return GFXFormatR5G5B5A1;
case DXGI_FORMAT_R8G8B8A8_UNORM: return GFXFormatB8G8R8A8;
case DXGI_FORMAT_B8G8R8A8_UNORM: return GFXFormatR8G8B8A8;
case DXGI_FORMAT_B8G8R8X8_UNORM: return GFXFormatR8G8B8X8;
case DXGI_FORMAT_R10G10B10A2_UNORM: return GFXFormatR10G10B10A2;
//uint
case DXGI_FORMAT_R16G16_UINT: return GFXFormatR16G16;
case DXGI_FORMAT_R16G16B16A16_UINT: return GFXFormatR16G16B16A16;
//float
case DXGI_FORMAT_R16_FLOAT: return GFXFormatR16F;
case DXGI_FORMAT_R32_FLOAT: return GFXFormatR32F;
case DXGI_FORMAT_R16G16B16A16_FLOAT: return GFXFormatR16G16B16A16F;
case DXGI_FORMAT_R32G32B32A32_FLOAT: return GFXFormatR32G32B32A32F;
//compressed
case DXGI_FORMAT_BC1_UNORM: return GFXFormatBC1;
case DXGI_FORMAT_BC2_UNORM: return GFXFormatBC2;
case DXGI_FORMAT_BC3_UNORM: return GFXFormatBC3;
case DXGI_FORMAT_BC4_UNORM: return GFXFormatBC4;
case DXGI_FORMAT_BC5_UNORM: return GFXFormatBC5;
default:
{
Con::errorf("dds::getGFXFormatDxgi: unknown format");
return GFXFormat_FIRST;
}
}
}
//get GFXFormat from DDS_PIXELFORMAT struct - todo more formats
const GFXFormat getGFXFormat(const DDS_PIXELFORMAT &format)
{
if (format == DDSPF_DXT1)
return GFXFormatBC1;
else if (format == DDSPF_DXT2)
return GFXFormatBC2;
else if (format == DDSPF_DXT3)
return GFXFormatBC2;
else if (format == DDSPF_DXT4)
return GFXFormatBC3;
else if (format == DDSPF_DXT5)
return GFXFormatBC3;
else if (format == DDSPF_ATI1)
return GFXFormatBC4;
else if (format == DDSPF_ATI2)
return GFXFormatBC5;
else if (format == DDSPF_A8R8G8B8)
return GFXFormatR8G8B8A8;
else if (format == DDSPF_X8R8G8B8)
return GFXFormatR8G8B8A8;
else if (format == DDSPF_A8B8G8R8)
return GFXFormatB8G8R8A8;
else if (format == DDSPF_X8B8G8R8)
return GFXFormatB8G8R8A8;
else if (format == DDSPF_R8G8B8)
return GFXFormatR8G8B8;
else if (format == DDSPF_A8L8)
return GFXFormatA8L8;
else if (format == DDSPF_A4L4)
return GFXFormatA4L4;
else if (format == DDSPF_A8)
return GFXFormatA8;
else if (format == DDSPF_L8)
return GFXFormatL8;
else if (format == DDSPF_R5G6B5)
return GFXFormatR5G6B5;
else if (format == DDSPF_A1R5G5B5)
return GFXFormatR5G5B5A1;
else
{
Con::errorf("dds::getGFXFormat: unknown format");
return GFXFormat_FIRST;
}
}
//get GFXFormat from fourcc value - todo more formats
const GFXFormat getGFXFormat(const U32 fourcc)
{
switch (fourcc)
{
case D3DFMT_DXT1: return GFXFormatBC1;
case D3DFMT_DXT2:
case D3DFMT_DXT3: return GFXFormatBC2;
case D3DFMT_DXT4:
case D3DFMT_DXT5: return GFXFormatBC3;
case D3DFMT_ATI1: return GFXFormatBC4;
case D3DFMT_ATI2: return GFXFormatBC5;
case D3DFMT_A16B16G16R16F: return GFXFormatR16G16B16A16F;
case D3DFMT_A32B32G32R32F: return GFXFormatR32G32B32A32F;
default:
{
Con::errorf("dds::getGFXFormatFourcc: unknown format");
return GFXFormat_FIRST;
}
}
}
const bool validateHeader(const DDS_HEADER &header)
{
if (header.size != DDS_HEADER_SIZE)
{
Con::errorf("DDS_HEADER - incorrect header size. Expected 124 bytes.");
return false;
}
if (!(header.flags & DDS_HEADER_FLAGS_TEXTURE))
{
Con::errorf("DDS_HEADER - incorrect surface description flags.");
return false;
}
if ((header.flags & (DDS_HEADER_FLAGS_LINEARSIZE | DDS_HEADER_FLAGS_PITCH)) == (DDS_HEADER_FLAGS_LINEARSIZE | DDS_HEADER_FLAGS_PITCH))
{
// Both are invalid!
Con::errorf("DDS_HEADER - encountered both DDSD_LINEARSIZE and DDSD_PITCH!");
return false;
}
return true;
}
const bool validateHeaderDx10(const DDS_HEADER_DXT10 &header)
{
if (sizeof(DDS_HEADER_DXT10) != DDS_HEADER_DX10_SIZE)
{
Con::errorf("DDS_HEADER_DXT10 - incorrect header size. Expected 20 bytes.");
return false;
}
return true;
}
}
#endif

View file

@ -22,7 +22,9 @@
#include "platform/platform.h"
#include "gfx/bitmap/ddsFile.h"
#include "gfx/bitmap/ddsData.h"
#include "gfx/bitmap/bitmapUtils.h"
#include "gfx/bitmap/imageUtils.h"
#include "gfx/gfxDevice.h"
#include "core/util/fourcc.h"
#include "console/console.h"
@ -31,56 +33,11 @@
#include "gfx/bitmap/gBitmap.h"
#include "console/engineAPI.h"
#include <squish.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 ),
@ -133,13 +90,13 @@ U32 DDSFile::getSurfacePitch( U32 mipLevel ) const
switch(mFormat)
{
case GFXFormatDXT1:
case GFXFormatBC1:
case GFXFormatBC4:
sizeMultiple = 8;
break;
case GFXFormatDXT2:
case GFXFormatDXT3:
case GFXFormatDXT4:
case GFXFormatDXT5:
case GFXFormatBC2:
case GFXFormatBC3:
case GFXFormatBC5:
sizeMultiple = 16;
break;
default:
@ -172,13 +129,13 @@ U32 DDSFile::getSurfaceSize( U32 height, U32 width, U32 mipLevel ) const
switch(mFormat)
{
case GFXFormatDXT1:
case GFXFormatBC1:
case GFXFormatBC4:
sizeMultiple = 8;
break;
case GFXFormatDXT2:
case GFXFormatDXT3:
case GFXFormatDXT4:
case GFXFormatDXT5:
case GFXFormatBC2:
case GFXFormatBC3:
case GFXFormatBC5:
sizeMultiple = 16;
break;
default:
@ -197,25 +154,34 @@ U32 DDSFile::getSurfaceSize( U32 height, U32 width, U32 mipLevel ) const
U32 DDSFile::getSizeInBytes() const
{
// TODO: This doesn't take mDepth into account, so
// it doesn't work right for volume or cubemap textures!
// it doesn't work right for volume textures!
U32 bytes = 0;
for ( U32 i=0; i < mMipMapCount; i++ )
bytes += getSurfaceSize( mHeight, mWidth, i );
if (mFlags.test(CubeMapFlag))
{
for(U32 cubeFace=0;cubeFace < Cubemap_Surface_Count;cubeFace++)
for (U32 i = 0; i < mMipMapCount; i++)
bytes += getSurfaceSize(mHeight, mWidth, i);
}
else
{
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!" );
AssertFatal( ImageUtil::isCompressedFormat(format),
"DDSFile::getSizeInBytes - Must be a Block Compression 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 )
if ( format == GFXFormatBC1 || format == GFXFormatBC1_SRGB || format == GFXFormatBC4)
sizeMultiple = 8;
else
sizeMultiple = 16;
@ -236,317 +202,146 @@ U32 DDSFile::getSizeInBytes( GFXFormat format, U32 height, U32 width, U32 mipLev
bool DDSFile::readHeader(Stream &s)
{
U32 tmp;
U32 fourcc;
// Read the FOURCC
s.read(&tmp);
s.read(&fourcc);
if(tmp != MakeFourCC('D', 'D', 'S', ' '))
if(fourcc != DDS_MAGIC)
{
Con::errorf("DDSFile::readHeader - unexpected magic number, wanted 'DDS '!");
return false;
}
// Read the size of the header.
s.read(&tmp);
//dds headers
dds::DDS_HEADER header = {};
dds::DDS_HEADER_DXT10 dx10header = {};
//todo DX10 formats
bool hasDx10Header = false;
if(tmp != 124)
//read in header
s.read(DDS_HEADER_SIZE, &header);
//check for dx10 header support
if ((header.ddspf.flags & DDS_FOURCC) && (header.ddspf.fourCC == dds::D3DFMT_DX10))
{
Con::errorf("DDSFile::readHeader - incorrect header size. Expected 124 bytes.");
//read in dx10 header
s.read(DDS_HEADER_DX10_SIZE, &dx10header);
if (!dds::validateHeaderDx10(dx10header))
return false;
hasDx10Header = true;
}
//make sure our dds header is valid
if (!dds::validateHeader(header))
return false;
// store details
mPitchOrLinearSize = header.pitchOrLinearSize;
mMipMapCount = header.mipMapCount ? header.mipMapCount : 1;
mHeight = header.height;
mWidth = header.width;
mDepth = header.depth;
mFourCC = header.ddspf.fourCC;
//process dx10 header
if (hasDx10Header)
{
if (dx10header.arraySize > 1)
{
Con::errorf("DDSFile::readHeader - DX10 arrays not supported");
return false;
}
mFormat = dds::getGFXFormat(dx10header.dxgiFormat);
//make sure getGFXFormat gave us a valid format
if (mFormat == GFXFormat_FIRST)
return false;
//cubemap
if (dx10header.miscFlag & dds::D3D10_RESOURCE_MISC_TEXTURECUBE)
{
mFlags.set(CubeMap_All_Flags | ComplexFlag);
}
mHasTransparency = ImageUtil::isAlphaFormat(mFormat);
//mip map flag
if (mMipMapCount > 1)
mFlags.set(MipMapsFlag | ComplexFlag);
if (ImageUtil::isCompressedFormat(mFormat))
mFlags.set(CompressedData);
else
{
mBytesPerPixel = header.ddspf.bpp / 8;
mFlags.set(RGBData);
}
// we finished now
return true;
}
// Read some flags...
U32 ddsdFlags;
s.read(&ddsdFlags);
//process regular header
// "Always include DDSD_CAPS, DDSD_PIXELFORMAT, DDSD_WIDTH, DDSD_HEIGHT."
if(!(ddsdFlags & (DDSDCaps | DDSDPixelFormat | DDSDWidth | DDSDHeight)))
//D3DFMT_DX10 is caught above, no need to check now
if (header.ddspf.flags & DDS_FOURCC)
{
Con::errorf("DDSFile::readHeader - incorrect surface description flags.");
return false;
}
mFormat = dds::getGFXFormat(mFourCC);
//make sure getGFXFormat gave us a valid format
if (mFormat == GFXFormat_FIRST)
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 ???
if (ImageUtil::isCompressedFormat(mFormat))
mFlags.set(CompressedData);
else
{
mBytesPerPixel = header.ddspf.bpp / 8;
mFlags.set(RGBData);
}
}
else
{
// Neither set! This appears to be depressingly common.
// Con::warnf("DDSFile::readHeader - encountered neither DDSD_LINEARSIZE nor DDSD_PITCH!");
}
mFormat = dds::getGFXFormat(header.ddspf);
//make sure getGFXFormat gave us a valid format
if (mFormat == GFXFormat_FIRST)
return false;
// 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)
{
mBytesPerPixel = header.ddspf.bpp / 8;
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?
//mip map flag
if (mMipMapCount > 1)
mFlags.set(MipMapsFlag | ComplexFlag);
U32 caps1, caps2;
s.read(&caps1);
s.read(&caps2);
s.read(&tmp);
s.read(&tmp); // More icky reserved space.
//set transparency flag
mHasTransparency = (header.ddspf.flags & DDS_ALPHAPIXELS);
// Screw caps1.
// if(!(caps1 & DDSCAPS_TEXTURE)))
// {
// }
if (header.flags & DDS_HEADER_FLAGS_LINEARSIZE)
mFlags.set(LinearSizeFlag);
else if (header.flags & DDS_HEADER_FLAGS_PITCH)
mFlags.set(PitchSizeFlag);
// Caps2 has cubemap/volume info. Care about that.
if(caps2 & DDSCAPS2Cubemap)
//set cubemap flags
if (header.cubemapFlags & DDS_CUBEMAP)
{
mFlags.set(CubeMapFlag);
mFlags.set(CubeMapFlag | ComplexFlag);
// 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 );
if (header.cubemapFlags & DDS_CUBEMAP_POSITIVEX) mFlags.set(CubeMap_PosX_Flag);
if (header.cubemapFlags & DDS_CUBEMAP_NEGATIVEX) mFlags.set(CubeMap_NegX_Flag);
if (header.cubemapFlags & DDS_CUBEMAP_POSITIVEY) mFlags.set(CubeMap_PosY_Flag);
if (header.cubemapFlags & DDS_CUBEMAP_NEGATIVEY) mFlags.set(CubeMap_NegY_Flag);
if (header.cubemapFlags & DDS_CUBEMAP_POSITIVEZ) mFlags.set(CubeMap_PosZ_Flag);
if (header.cubemapFlags & DDS_CUBEMAP_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 )
if( !readHeader(s) )
{
Con::errorf("DDSFile::read - error reading header!");
return false;
@ -618,96 +413,82 @@ bool DDSFile::read(Stream &s, U32 dropMipCount)
bool DDSFile::writeHeader( Stream &s )
{
// Read the FOURCC
s.write( 4, "DDS " );
// write DDS magic
U32 magic = DDS_MAGIC;
s.write(magic);
U32 tmp = 0;
dds::DDS_HEADER header = {};
dds::DDS_HEADER_DXT10 dx10header = {};
// Read the size of the header.
s.write( 124 );
bool hasDx10Header = false;
//flags
U32 surfaceFlags = DDS_SURFACE_FLAGS_TEXTURE;
U32 cubemapFlags = 0;
U32 headerFlags = DDS_HEADER_FLAGS_TEXTURE;
// Read some flags...
U32 ddsdFlags = DDSDCaps | DDSDPixelFormat | DDSDWidth | DDSDHeight;
if ( mFlags.test( CompressedData ) )
ddsdFlags |= DDSDLinearSize;
else
ddsdFlags |= DDSDPitch;
//pixel format
const dds::DDS_PIXELFORMAT &format = dds::getDDSFormat(mFormat);
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 ) )
// todo better dx10 support
if (format.fourCC == dds::D3DFMT_DX10)
{
ddpfFlags = DDPFFourCC;
if (mFormat == GFXFormatDXT1)
fourCC = FOURCC_DXT1;
if (mFormat == GFXFormatDXT3)
fourCC = FOURCC_DXT3;
if (mFormat == GFXFormatDXT5)
fourCC = FOURCC_DXT5;
dx10header.dxgiFormat = dds::getDXGIFormat(mFormat);
dx10header.arraySize = 1;
dx10header.resourceDimension = dds::D3D10_RESOURCE_DIMENSION_TEXTURE2D;
dx10header.miscFlag = 0;
dx10header.miscFlags2 = 0;
hasDx10Header = true;
}
if (mFlags.test(CompressedData))
headerFlags |= DDS_HEADER_FLAGS_LINEARSIZE;
else
ddpfFlags = mBytesPerPixel == 4 ? DDPFRGB | DDPFAlphaPixels : DDPFRGB;
headerFlags |= DDS_HEADER_FLAGS_PITCH;
s.write( ddpfFlags );
if (mMipMapCount > 1)
{
surfaceFlags |= DDS_SURFACE_FLAGS_MIPMAP;
headerFlags |= DDS_HEADER_FLAGS_MIPMAP;
}
// Read the next few values so we can deal with them all in one go.
//U32 pfFourCC, pfBitCount, pfRMask, pfGMask, pfBMask, pfAlphaMask;
//cubemap flags
if (mFlags.test(CubeMapFlag))
{
surfaceFlags |= DDS_SURFACE_FLAGS_CUBEMAP;
cubemapFlags |= DDS_CUBEMAP_ALLFACES;
}
s.write( fourCC );
s.write( mBytesPerPixel * 8 );
s.write( 0x000000FF );
s.write( 0x00FF0000 );
s.write( 0x0000FF00 );
s.write( 0xFF000000 );
//volume texture
if (mDepth > 0)
{
headerFlags |= DDS_HEADER_FLAGS_VOLUME;
dx10header.resourceDimension = dds::D3D10_RESOURCE_DIMENSION_TEXTURE3D;
}
// Deal with final caps bits... Is this really necessary?
U32 caps1 = DDSCAPSTexture;
if ( mMipMapCount > 0 )
caps1 |= DDSCAPSComplex | DDSCAPSMipMap;
//main dds header
header.size = sizeof(dds::DDS_HEADER);
header.flags = headerFlags;
header.height = mHeight;
header.width = mWidth;
header.pitchOrLinearSize = mPitchOrLinearSize;
header.depth = mDepth;
header.ddspf = format;
header.mipMapCount = mMipMapCount;
header.surfaceFlags = surfaceFlags;
header.cubemapFlags = cubemapFlags;
memset(header.reserved1, 0, sizeof(header.reserved1));
memset(header.reserved2, 0, sizeof(header.reserved2));
tmp = 0;
//check our header is ok
if (!dds::validateHeader(header))
return false;
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 );
//Write out the header
s.write(DDS_HEADER_SIZE, &header);
//Write out dx10 header
if (hasDx10Header)
s.write(DDS_HEADER_DX10_SIZE, &dx10header);
return true;
}
@ -720,13 +501,16 @@ bool DDSFile::write( Stream &s )
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.
for (U32 cubeFace = 0; cubeFace < Cubemap_Surface_Count; cubeFace++)
{
// write the mips
for (S32 i = 0; i < mMipMapCount; i++)
mSurfaces[cubeFace]->writeNextMip(this, s, mHeight, mWidth, i);
}
}
else if (mFlags.test(VolumeFlag))
{
@ -912,6 +696,82 @@ DDSFile *DDSFile::createDDSFileFromGBitmap( const GBitmap *gbmp )
return ret;
}
DDSFile *DDSFile::createDDSCubemapFileFromGBitmaps(GBitmap **gbmps)
{
if (gbmps == NULL)
return NULL;
AssertFatal(gbmps[0], "createDDSCubemapFileFromGBitmaps bitmap 0 is null");
AssertFatal(gbmps[1], "createDDSCubemapFileFromGBitmaps bitmap 1 is null");
AssertFatal(gbmps[2], "createDDSCubemapFileFromGBitmaps bitmap 2 is null");
AssertFatal(gbmps[3], "createDDSCubemapFileFromGBitmaps bitmap 3 is null");
AssertFatal(gbmps[4], "createDDSCubemapFileFromGBitmaps bitmap 4 is null");
AssertFatal(gbmps[5], "createDDSCubemapFileFromGBitmaps bitmap 5 is null");
DDSFile *ret = new DDSFile;
//all cubemaps have the same dimensions and formats
GBitmap *pBitmap = gbmps[0];
if (pBitmap->getFormat() != GFXFormatR8G8B8A8)
{
Con::errorf("createDDSCubemapFileFromGBitmaps: Only GFXFormatR8G8B8A8 supported for now");
return NULL;
}
// Set up the DDSFile properties that matter. Since this is a GBitmap, there
// are assumptions that can be made
ret->mHeight = pBitmap->getHeight();
ret->mWidth = pBitmap->getWidth();
ret->mDepth = 0;
ret->mFormat = pBitmap->getFormat();
ret->mFlags.set( RGBData | CubeMapFlag | CubeMap_PosX_Flag | CubeMap_NegX_Flag | CubeMap_PosY_Flag |
CubeMap_NegY_Flag | CubeMap_PosZ_Flag | CubeMap_NegZ_Flag);
ret->mBytesPerPixel = pBitmap->getBytesPerPixel();
//todo implement mip mapping
ret->mMipMapCount = pBitmap->getNumMipLevels();
ret->mHasTransparency = pBitmap->getHasTransparency();
for (U32 cubeFace = 0; cubeFace < Cubemap_Surface_Count; cubeFace++)
{
ret->mSurfaces.push_back(new SurfaceData());
// Load the mips
for (S32 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();
//straight copy
dMemcpy(mipMem, gbmps[cubeFace]->getBits(i), mipSz);
}
}
return ret;
}
bool DDSFile::decompressToGBitmap(GBitmap *dest)
{
// TBD: do we support other formats?
if (mFormat != GFXFormatBC1 && mFormat != GFXFormatBC2 && mFormat != GFXFormatBC3)
return false;
dest->allocateBitmapWithMips(getWidth(), getHeight(), getMipLevels(), GFXFormatR8G8B8A8);
// Decompress and copy mips...
U32 numMips = getMipLevels();
for (U32 i = 0; i < numMips; i++)
{
U8 *addr = dest->getAddress(0, 0, i);
const U8 *mipBuffer = mSurfaces[0]->mMips[i];
ImageUtil::decompress(mipBuffer, addr, getWidth(i), getHeight(i), mFormat);
}
return true;
}
DefineEngineFunction( getActiveDDSFiles, S32, (),,
"Returns the count of active DDSs files in memory.\n"
"@ingroup Rendering\n" )

View file

@ -65,6 +65,7 @@ struct DDSFile
CubeMap_NegY_Flag = BIT(11),
CubeMap_PosZ_Flag = BIT(12),
CubeMap_NegZ_Flag = BIT(13),
CubeMap_All_Flags = CubeMapFlag|CubeMap_PosX_Flag | CubeMap_NegX_Flag | CubeMap_PosY_Flag | CubeMap_NegY_Flag | CubeMap_PosZ_Flag | CubeMap_NegZ_Flag,
};
/// The index into mSurfaces for each
@ -115,9 +116,6 @@ struct DDSFile
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.
@ -200,6 +198,9 @@ struct DDSFile
}
static DDSFile *createDDSFileFromGBitmap( const GBitmap *gbmp );
//Create a single cubemap texture from 6 GBitmap
static DDSFile *createDDSCubemapFileFromGBitmaps(GBitmap **gbmps);
bool decompressToGBitmap(GBitmap *dest);
};
#endif // _DDSFILE_H_

View file

@ -1,113 +0,0 @@
//-----------------------------------------------------------------------------
// 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( S32 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::CompressImage( 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( S32 i = 0; i < srcDDS->mMipMapCount; i++ )
{
swizzle.InPlace( srcDDS->mSurfaces.last()->mMips[i], srcDDS->getSurfaceSize( i ) );
}
}

View file

@ -347,6 +347,77 @@ void GBitmap::allocateBitmap(const U32 in_width, const U32 in_height, const bool
}
}
//--------------------------------------------------------------------------
void GBitmap::allocateBitmapWithMips(const U32 in_width, const U32 in_height, const U32 in_numMips, const GFXFormat in_format)
{
//-------------------------------------- Some debug checks...
U32 svByteSize = mByteSize;
U8 *svBits = mBits;
AssertFatal(in_width != 0 && in_height != 0, "GBitmap::allocateBitmap: width or height is 0");
mInternalFormat = in_format;
mWidth = in_width;
mHeight = in_height;
mBytesPerPixel = 1;
switch (mInternalFormat)
{
case GFXFormatA8:
case GFXFormatL8: mBytesPerPixel = 1;
break;
case GFXFormatR8G8B8: mBytesPerPixel = 3;
break;
case GFXFormatR8G8B8X8:
case GFXFormatR8G8B8A8: mBytesPerPixel = 4;
break;
case GFXFormatR5G6B5:
case GFXFormatR5G5B5A1: mBytesPerPixel = 2;
break;
default:
AssertFatal(false, "GBitmap::GBitmap: misunderstood format specifier");
break;
}
// Set up the mip levels, if necessary...
mNumMipLevels = 1;
U32 allocPixels = in_width * in_height * mBytesPerPixel;
mMipLevelOffsets[0] = 0;
if (in_numMips != 0)
{
U32 currWidth = in_width;
U32 currHeight = in_height;
do
{
mMipLevelOffsets[mNumMipLevels] = mMipLevelOffsets[mNumMipLevels - 1] +
(currWidth * currHeight * mBytesPerPixel);
currWidth >>= 1;
currHeight >>= 1;
if (currWidth == 0) currWidth = 1;
if (currHeight == 0) currHeight = 1;
mNumMipLevels++;
allocPixels += currWidth * currHeight * mBytesPerPixel;
} while (currWidth != 1 || currHeight != 1 && mNumMipLevels != in_numMips);
}
AssertFatal(mNumMipLevels <= c_maxMipLevels, "GBitmap::allocateBitmap: too many miplevels");
// Set up the memory...
mByteSize = allocPixels;
mBits = new U8[mByteSize];
dMemset(mBits, 0xFF, mByteSize);
if (svBits != NULL)
{
dMemcpy(mBits, svBits, getMin(mByteSize, svByteSize));
delete[] svBits;
}
}
//--------------------------------------------------------------------------
void GBitmap::extrudeMipLevels(bool clearBorders)
{
@ -410,6 +481,38 @@ void GBitmap::extrudeMipLevels(bool clearBorders)
}
}
//--------------------------------------------------------------------------
void GBitmap::chopTopMips(U32 mipsToChop)
{
U32 scalePower = getMin(mipsToChop, getNumMipLevels() - 1);
U32 newMipCount = getNumMipLevels() - scalePower;
U32 realWidth = getMax((U32)1, getWidth() >> scalePower);
U32 realHeight = getMax((U32)1, getHeight() >> scalePower);
U8 *destBits = mBits;
U32 destOffsets[c_maxMipLevels];
for (U32 i = scalePower; i<mNumMipLevels; i++)
{
// Copy to the new bitmap...
dMemcpy(destBits,
getWritableBits(i),
getSurfaceSize(i));
destOffsets[i - scalePower] = destBits - mBits;
destBits += getSurfaceSize(i);
}
dMemcpy(mMipLevelOffsets, destOffsets, sizeof(destOffsets));
mWidth = realWidth;
mHeight = realHeight;
mByteSize = destBits - mBits;
mNumMipLevels = newMipCount;
}
//--------------------------------------------------------------------------
void GBitmap::extrudeMipLevelsDetail()
{
@ -609,9 +712,9 @@ bool GBitmap::checkForTransparency()
}
//------------------------------------------------------------------------------
ColorF GBitmap::sampleTexel(F32 u, F32 v) const
LinearColorF GBitmap::sampleTexel(F32 u, F32 v) const
{
ColorF col(0.5f, 0.5f, 0.5f);
LinearColorF col(0.5f, 0.5f, 0.5f);
// normally sampling wraps all the way around at 1.0,
// but locking doesn't support this, and we seem to calc
// the uv based on a clamped 0 - 1...
@ -733,6 +836,20 @@ bool GBitmap::setColor(const U32 x, const U32 y, const ColorI& rColor)
return true;
}
//--------------------------------------------------------------------------
U8 GBitmap::getChanelValueAt(U32 x, U32 y, U32 chan)
{
ColorI pixelColor = ColorI(255,255,255,255);
getColor(x, y, pixelColor);
switch (chan) {
case 0: return pixelColor.red;
case 1: return pixelColor.green;
case 2: return pixelColor.blue;
default: return pixelColor.alpha;
}
}
//-----------------------------------------------------------------------------
bool GBitmap::combine( const GBitmap *bitmapA, const GBitmap *bitmapB, const GFXTextureOp combineOp )
@ -1175,6 +1292,41 @@ Resource<GBitmap> GBitmap::_search(const Torque::Path &path)
return Resource< GBitmap >( NULL );
}
U32 GBitmap::getSurfaceSize(const U32 mipLevel) const
{
// Bump by the mip level.
U32 height = getMax(U32(1), mHeight >> mipLevel);
U32 width = getMax(U32(1), mWidth >> mipLevel);
if (mInternalFormat >= GFXFormatBC1 && mInternalFormat <= GFXFormatBC3)
{
// From the directX docs:
// max(1, width ÷ 4) x max(1, height ÷ 4) x 8(DXT1) or 16(DXT2-5)
U32 sizeMultiple = 0;
switch (mInternalFormat)
{
case GFXFormatBC1:
sizeMultiple = 8;
break;
case GFXFormatBC2:
case GFXFormatBC3:
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;
}
}
DefineEngineFunction( getBitmapInfo, String, ( const char *filename ),,
"Returns image info in the following format: width TAB height TAB bytesPerPixel. "
"It will return an empty string if the file is not found.\n"

View file

@ -47,7 +47,7 @@ class Stream;
class RectI;
class Point2I;
class ColorI;
class ColorF;
class LinearColorF;
//------------------------------------------------------------------------------
//-------------------------------------- GBitmap
@ -151,7 +151,13 @@ public:
const bool in_extrudeMipLevels = false,
const GFXFormat in_format = GFXFormatR8G8B8 );
void allocateBitmapWithMips(const U32 in_width,
const U32 in_height,
const U32 in_numMips,
const GFXFormat in_format = GFXFormatR8G8B8);
void extrudeMipLevels(bool clearBorders = false);
void chopTopMips(U32 mipsToChop);
void extrudeMipLevelsDetail();
U32 getNumMipLevels() const { return mNumMipLevels; }
@ -182,6 +188,8 @@ public:
U32 getByteSize() const { return mByteSize; }
U32 getBytesPerPixel() const { return mBytesPerPixel; }
U32 getSurfaceSize(const U32 mipLevel) const;
/// 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)
@ -194,9 +202,10 @@ public:
/// the bitmap bits and to check for alpha values less than 255
bool checkForTransparency();
ColorF sampleTexel(F32 u, F32 v) const;
LinearColorF 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);
U8 getChanelValueAt(U32 x, U32 y, U32 chan);
/// 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

View file

@ -0,0 +1,304 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2016 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/imageUtils.h"
#include "gfx/bitmap/ddsFile.h"
#include "platform/threads/threadPool.h"
#include "squish/squish.h"
namespace ImageUtil
{
// get squish quality flag
S32 _getSquishQuality(const CompressQuality quality)
{
switch (quality)
{
case LowQuality:
return squish::kColourRangeFit;
case MediumQuality:
return squish::kColourClusterFit;
case HighQuality:
return squish::kColourIterativeClusterFit;
default:
return squish::kColourRangeFit;//default is low quality
}
}
// get squish compression flag
S32 _getSquishFormat(const GFXFormat compressFormat)
{
switch (compressFormat)
{
case GFXFormatBC1:
return squish::kDxt1;
case GFXFormatBC2:
return squish::kDxt3;
case GFXFormatBC3:
return squish::kDxt5;
case GFXFormatBC4:
return squish::kBc4;
case GFXFormatBC5:
return squish::kBc5;
default:
return squish::kDxt1;
}
}
//Thread work job for compression
struct CompressJob : public ThreadPool::WorkItem
{
S32 width;
S32 height;
S32 flags;
const U8 *pSrc;
U8 *pDst;
GFXFormat format;
CompressQuality quality;
CompressJob(const U8 *srcRGBA, U8 *dst, const S32 w, const S32 h, const GFXFormat compressFormat, const CompressQuality compressQuality)
: pSrc(srcRGBA),pDst(dst), width(w), height(h), format(compressFormat),quality(compressQuality) {}
protected:
virtual void execute()
{
rawCompress(pSrc,pDst, width, height, format,quality);
}
};
// compress raw pixel data, expects rgba format
bool rawCompress(const U8 *srcRGBA, U8 *dst, const S32 width, const S32 height, const GFXFormat compressFormat, const CompressQuality compressQuality)
{
if (!isCompressedFormat(compressFormat))
return false;
S32 squishFlags = _getSquishQuality(compressQuality);
S32 squishFormat = _getSquishFormat(compressFormat);
squishFlags |= squishFormat;
squish::CompressImage(srcRGBA, width,height,dst,squishFlags);
return true;
}
// compress DDSFile
bool ddsCompress(DDSFile *srcDDS, const GFXFormat compressFormat,const CompressQuality compressQuality)
{
if (srcDDS->mBytesPerPixel != 4)
{
Con::errorf("ImageCompress::ddsCompress: data must be 32bit");
return false;
}
//can't compress DDSFile if it is already compressed
if (ImageUtil::isCompressedFormat(srcDDS->mFormat))
{
Con::errorf("ImageCompress::ddsCompress: file is already compressed");
return false;
}
const bool cubemap = srcDDS->mFlags.test(DDSFile::CubeMapFlag);
const U32 mipCount = srcDDS->mMipMapCount;
// We got this far, so assume we can finish (gosh I hope so)
srcDDS->mFormat = compressFormat;
srcDDS->mFlags.set(DDSFile::CompressedData);
//grab global thread pool
ThreadPool* pThreadPool = &ThreadPool::GLOBAL();
if (cubemap)
{
static U32 nCubeFaces = 6;
Vector<U8*> dstDataStore;
dstDataStore.setSize(nCubeFaces * mipCount);
for (S32 cubeFace = 0; cubeFace < nCubeFaces; cubeFace++)
{
DDSFile::SurfaceData *srcSurface = srcDDS->mSurfaces[cubeFace];
for (U32 currentMip = 0; currentMip < mipCount; currentMip++)
{
const U32 dataIndex = cubeFace * mipCount + currentMip;
const U8 *srcBits = srcSurface->mMips[currentMip];
const U32 mipSz = srcDDS->getSurfaceSize(currentMip);
U8 *dstBits = new U8[mipSz];
dstDataStore[dataIndex] = dstBits;
ThreadSafeRef<CompressJob> item(new CompressJob(srcBits, dstBits, srcDDS->getWidth(currentMip), srcDDS->getHeight(currentMip), compressFormat, compressQuality));
pThreadPool->queueWorkItem(item);
}
}
//wait for work items to finish
pThreadPool->waitForAllItems();
for (S32 cubeFace = 0; cubeFace < nCubeFaces; cubeFace++)
{
DDSFile::SurfaceData *pSrcSurface = srcDDS->mSurfaces[cubeFace];
for (U32 currentMip = 0; currentMip < mipCount; currentMip++)
{
const U32 dataIndex = cubeFace * mipCount + currentMip;
delete[] pSrcSurface->mMips[currentMip];
pSrcSurface->mMips[currentMip] = dstDataStore[dataIndex];
}
}
}
else
{
// The source surface is the original surface of the file
DDSFile::SurfaceData *pSrcSurface = 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 *pNewSurface = new DDSFile::SurfaceData();
//no point using threading if only 1 mip
const bool useThreading = bool(mipCount > 1);
for (U32 currentMip = 0; currentMip < mipCount; currentMip++)
{
const U8 *pSrcBits = pSrcSurface->mMips[currentMip];
const U32 mipSz = srcDDS->getSurfaceSize(currentMip);
U8 *pDstBits = new U8[mipSz];
pNewSurface->mMips.push_back(pDstBits);
if (useThreading)
{
// Create CompressJob item
ThreadSafeRef<CompressJob> item(new CompressJob(pSrcBits, pDstBits, srcDDS->getWidth(currentMip), srcDDS->getHeight(currentMip), compressFormat, compressQuality));
pThreadPool->queueWorkItem(item);
}
else
rawCompress(pSrcBits, pDstBits, srcDDS->getWidth(currentMip), srcDDS->getHeight(currentMip), compressFormat, compressQuality);
}
//block and wait for CompressJobs to finish
if(useThreading)
pThreadPool->waitForAllItems();
// Now delete the source surface and replace with new compressed surface
srcDDS->mSurfaces.pop_back();
delete pSrcSurface;
srcDDS->mSurfaces.push_back(pNewSurface);
}
return true;
}
bool decompress(const U8 *src, U8 *dstRGBA,const S32 width,const S32 height, const GFXFormat srcFormat)
{
if (!isCompressedFormat(srcFormat))
return false;
S32 squishFlag = _getSquishFormat(srcFormat);
squish::DecompressImage(dstRGBA, width, height, src, squishFlag);
return true;
}
void swizzleDDS(DDSFile *srcDDS, const Swizzle<U8, 4> &swizzle)
{
if (srcDDS->mFlags.test(DDSFile::CubeMapFlag))
{
for (S32 cubeFace = 0; cubeFace < DDSFile::Cubemap_Surface_Count; cubeFace++)
{
for (S32 i = 0; i < srcDDS->mMipMapCount; i++)
{
swizzle.InPlace(srcDDS->mSurfaces[cubeFace]->mMips[i], srcDDS->getSurfaceSize(i));
}
}
}
else
{
for (S32 i = 0; i < srcDDS->mMipMapCount; i++)
{
swizzle.InPlace(srcDDS->mSurfaces.last()->mMips[i], srcDDS->getSurfaceSize(i));
}
}
}
bool isCompressedFormat(const GFXFormat format)
{
if (format >= GFXFormatBC1 && format <= GFXFormatBC3_SRGB)
return true;
else
return false;
}
bool isAlphaFormat(const GFXFormat format)
{
switch (format)
{
case GFXFormatA8:
case GFXFormatA4L4:
case GFXFormatA8L8:
case GFXFormatR5G5B5A1:
case GFXFormatR8G8B8A8:
case GFXFormatB8G8R8A8:
case GFXFormatR16G16B16A16F:
case GFXFormatR32G32B32A32F:
case GFXFormatR10G10B10A2:
//case GFXFormatBC1://todo BC1 can store alpha
case GFXFormatBC2:
case GFXFormatBC3:
return true;
default:
return false;
}
}
bool isSRGBFormat(const GFXFormat format)
{
switch (format)
{
case GFXFormatR8G8B8_SRGB:
case GFXFormatR8G8B8A8_SRGB:
case GFXFormatBC1_SRGB:
case GFXFormatBC2_SRGB:
case GFXFormatBC3_SRGB:
return true;
default:
return false;
};
}
GFXFormat toSRGBFormat(const GFXFormat format)
{
switch (format)
{
case GFXFormatR8G8B8:
return GFXFormatR8G8B8_SRGB;
case GFXFormatR8G8B8X8:
case GFXFormatR8G8B8A8:
return GFXFormatR8G8B8A8_SRGB;
case GFXFormatBC1:
return GFXFormatBC1_SRGB;
case GFXFormatBC2:
return GFXFormatBC2_SRGB;
case GFXFormatBC3:
return GFXFormatBC3_SRGB;
default:
return format;
};
}
}

View file

@ -1,5 +1,5 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
// Copyright (c) 2016 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
@ -20,15 +20,43 @@
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _DDS_UTILS_H_
#define _DDS_UTILS_H_
#ifndef _IMAGE_UTILS_H_
#define _IMAGE_UTILS_H_
#ifndef _SWIZZLE_H_
#include "core/util/swizzle.h"
#endif
#ifndef _GFXENUMS_H_
#include "gfx/gfxEnums.h"
#endif
struct DDSFile;
namespace DDSUtil
namespace ImageUtil
{
bool squishDDS( DDSFile *srcDDS, const GFXFormat dxtFormat );
void swizzleDDS( DDSFile *srcDDS, const Swizzle<U8, 4> &swizzle );
enum CompressQuality
{
LowQuality,
MediumQuality,
HighQuality
};
// compress raw pixel data, expects rgba format
bool rawCompress(const U8 *srcRGBA, U8 *dst, const S32 width, const S32 height, const GFXFormat compressFormat, const CompressQuality compressQuality = LowQuality);
// compress DDSFile
bool ddsCompress(DDSFile *srcDDS, const GFXFormat compressFormat, const CompressQuality compressQuality = LowQuality);
// decompress compressed pixel data, dest data should be rgba format
bool decompress(const U8 *src, U8 *dstRGBA, const S32 width, const S32 height, const GFXFormat srcFormat);
//swizzle dds file
void swizzleDDS(DDSFile *srcDDS, const Swizzle<U8, 4> &swizzle);
//check if a GFXFormat is compressed
bool isCompressedFormat(const GFXFormat format);
bool isSRGBFormat(const GFXFormat format);
//check if a GFXFormat has an alpha channel
bool isAlphaFormat(const GFXFormat format);
//convert to sRGB format
GFXFormat toSRGBFormat(const GFXFormat format);
};
#endif

View file

@ -172,7 +172,7 @@ public:
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 LinearColorF& 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); }

View file

@ -173,6 +173,7 @@ ImplementEnumType( GFXFormat,
{ GFXFormatR8G8B8, "GFXFormatR8G8B8" },
{ GFXFormatR8G8B8A8, "GFXFormatR8G8B8A8" },
{ GFXFormatR8G8B8A8_SRGB, "GFXFormatR8G8B8A8_SRGB" },
{ GFXFormatR8G8B8X8, "GFXFormatR8G8B8X8" },
{ GFXFormatR32F, "GFXFormatR32F" },
{ GFXFormatR5G6B5, "GFXFormatR5G6B5" },
@ -182,11 +183,11 @@ ImplementEnumType( GFXFormat,
{ GFXFormatA8L8, "GFXFormatA8L8" },
{ GFXFormatA8, "GFXFormatA8" },
{ GFXFormatL8, "GFXFormatL8" },
{ GFXFormatDXT1, "GFXFormatDXT1" },
{ GFXFormatDXT2, "GFXFormatDXT2" },
{ GFXFormatDXT3, "GFXFormatDXT3" },
{ GFXFormatDXT4, "GFXFormatDXT4" },
{ GFXFormatDXT5, "GFXFormatDXT5" },
{ GFXFormatBC1, "GFXFormatBC1" },
{ GFXFormatBC2, "GFXFormatBC2" },
{ GFXFormatBC3, "GFXFormatBC3" },
{ GFXFormatBC4, "GFXFormatBC4" },
{ GFXFormatBC5, "GFXFormatBC5" },
{ GFXFormatD32, "GFXFormatD32" },
{ GFXFormatD24X8, "GFXFormatD24X8" },
{ GFXFormatD24S8, "GFXFormatD24S8" },

View file

@ -35,6 +35,23 @@ GFXCubemap::~GFXCubemap()
TEXMGR->releaseCubemap( this );
}
U32 GFXCubemap::_zUpFaceIndex(const U32 index)
{
switch (index)
{
case 2:
return 4;
case 3:
return 5;
case 4:
return 2;
case 5:
return 3;
default:
return index;
};
}
void GFXCubemap::initNormalize( U32 size )
{
Point3F axis[6] =
@ -83,7 +100,7 @@ void GFXCubemap::initNormalize( U32 size )
}
}
tex.set(bitmap, &GFXDefaultStaticDiffuseProfile, true, "Cubemap");
tex.set(bitmap, &GFXStaticTextureSRGBProfile, true, "Cubemap");
}
initStatic(faces);

View file

@ -47,6 +47,10 @@ protected:
/// Sets the cubemap file path.
void _setPath( const String &path ) { mPath = path; }
/// Get Z up face index of the cubemap. DDS files will be stored Y up
U32 _zUpFaceIndex(const U32 index);
U32 mMipMapLevels;
public:
/// Create a static cubemap from a list of 6 face textures.
@ -74,6 +78,9 @@ public:
// 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;
/// Get the number of mip maps
const U32 getMipMapLevels() const { return mMipMapLevels; }
};

View file

@ -145,7 +145,7 @@ GFXDevice::GFXDevice()
}
mGlobalAmbientColorDirty = false;
mGlobalAmbientColor = ColorF(0.0f, 0.0f, 0.0f, 1.0f);
mGlobalAmbientColor = LinearColorF(0.0f, 0.0f, 0.0f, 1.0f);
mLightMaterialDirty = false;
dMemset(&mCurrentLightMaterial, 0, sizeof(GFXLightMaterial));
@ -213,11 +213,11 @@ void GFXDevice::deviceInited()
// Initialize the static helper textures.
GBitmap temp( 2, 2, false, GFXFormatR8G8B8A8 );
temp.fill( ColorI::ONE );
GFXTexHandle::ONE.set( &temp, &GFXDefaultStaticDiffuseProfile, false, "GFXTexHandle::ONE" );
GFXTexHandle::ONE.set( &temp, &GFXStaticTextureSRGBProfile, false, "GFXTexHandle::ONE" );
temp.fill( ColorI::ZERO );
GFXTexHandle::ZERO.set( &temp, &GFXDefaultStaticDiffuseProfile, false, "GFXTexHandle::ZERO" );
GFXTexHandle::ZERO.set( &temp, &GFXStaticTextureSRGBProfile, false, "GFXTexHandle::ZERO" );
temp.fill( ColorI( 128, 128, 255 ) );
GFXTexHandle::ZUP.set( &temp, &GFXDefaultStaticNormalMapProfile, false, "GFXTexHandle::ZUP" );
GFXTexHandle::ZUP.set( &temp, &GFXNormalMapProfile, false, "GFXTexHandle::ZUP" );
}
bool GFXDevice::destroy()
@ -739,7 +739,7 @@ void GFXDevice::setLightMaterial(const GFXLightMaterial& mat)
mStateDirty = true;
}
void GFXDevice::setGlobalAmbientColor(const ColorF& color)
void GFXDevice::setGlobalAmbientColor(const LinearColorF& color)
{
if(mGlobalAmbientColor != color)
{
@ -1315,10 +1315,9 @@ DefineEngineFunction( getBestHDRFormat, GFXFormat, (),,
// Figure out the best HDR format. This is the smallest
// format which supports blending and filtering.
Vector<GFXFormat> formats;
//formats.push_back( GFXFormatR10G10B10A2 ); TODO: replace with SRGB format once DX9 is gone - BJR
formats.push_back( GFXFormatR16G16B16A16F );
formats.push_back( GFXFormatR16G16B16A16 );
GFXFormat format = GFX->selectSupportedFormat( &GFXDefaultRenderTargetProfile,
formats.push_back(GFXFormatR16G16B16A16F);
formats.push_back( GFXFormatR10G10B10A2 );
GFXFormat format = GFX->selectSupportedFormat( &GFXRenderTargetProfile,
formats,
true,
true,

View file

@ -543,7 +543,7 @@ protected:
bool mLightDirty[LIGHT_STAGE_COUNT];
bool mLightsDirty;
ColorF mGlobalAmbientColor;
LinearColorF mGlobalAmbientColor;
bool mGlobalAmbientColorDirty;
/// @}
@ -615,7 +615,7 @@ protected:
virtual void setTextureInternal(U32 textureUnit, const GFXTextureObject*texture) = 0;
virtual void setLightInternal(U32 lightStage, const GFXLightInfo light, bool lightEnable) = 0;
virtual void setGlobalAmbientInternal(ColorF color) = 0;
virtual void setGlobalAmbientInternal(LinearColorF color) = 0;
virtual void setLightMaterialInternal(const GFXLightMaterial mat) = 0;
virtual bool beginSceneInternal() = 0;
@ -827,7 +827,7 @@ public:
/// @{
///
virtual void clear( U32 flags, ColorI color, F32 z, U32 stencil ) = 0;
virtual void clear( U32 flags, const LinearColorF& color, F32 z, U32 stencil ) = 0;
virtual bool beginScene();
virtual void endScene();
virtual void beginField();
@ -928,7 +928,7 @@ public:
/// @{
void setLight(U32 stage, GFXLightInfo* light);
void setLightMaterial(const GFXLightMaterial& mat);
void setGlobalAmbientColor(const ColorF& color);
void setGlobalAmbientColor(const LinearColorF& color);
/// @}

View file

@ -278,7 +278,8 @@ U32 GFXDrawUtil::drawTextN( GFont *font, const Point2I &ptDraw, const UTF16 *in_
}
// Queue char for rendering..
mFontRenderBatcher->queueChar(c, ptX, mBitmapModulation);
GFXVertexColor color = mBitmapModulation;
mFontRenderBatcher->queueChar(c, ptX, color);
}
@ -474,7 +475,7 @@ void GFXDrawUtil::drawRect( const Point2F &upperLeft, const Point2F &lowerRight,
verts[8].point.set( upperLeft.x + ulOffset + nw.x, upperLeft.y + ulOffset + nw.y, 0.0f ); // same as 0
verts[9].point.set( upperLeft.x + ulOffset - nw.x, upperLeft.y + ulOffset - nw.y, 0.0f ); // same as 1
for (S32 i=0; i<10; i++)
for (S32 i = 0; i < 10; i++)
verts[i].color = color;
verts.unlock();
@ -530,8 +531,7 @@ void GFXDrawUtil::drawRectFill( const Point2F &upperLeft, const Point2F &lowerRi
verts[1].point.set( lowerRight.x + ne.x + ulOffset, upperLeft.y + ne.y + ulOffset, 0.0f);
verts[2].point.set( upperLeft.x - ne.x + ulOffset, lowerRight.y - ne.y + ulOffset, 0.0f);
verts[3].point.set( lowerRight.x - nw.x + ulOffset, lowerRight.y - nw.y + ulOffset, 0.0f);
for (S32 i=0; i<4; i++)
for (S32 i = 0; i < 4; i++)
verts[i].color = color;
verts.unlock();
@ -613,7 +613,6 @@ void GFXDrawUtil::drawLine( F32 x1, F32 y1, F32 z1, F32 x2, F32 y2, F32 z2, cons
verts[0].point.set( x1, y1, z1 );
verts[1].point.set( x2, y2, z2 );
verts[0].color = color;
verts[1].color = color;
@ -714,7 +713,6 @@ void GFXDrawUtil::_drawWireTriangle( const GFXStateBlockDesc &desc, const Point3
{
GFXVertexBufferHandle<GFXVertexPCT> verts(mDevice, 4, GFXBufferTypeVolatile);
verts.lock();
// Set up the line strip
verts[0].point = p0;
verts[0].color = color;
@ -747,7 +745,6 @@ void GFXDrawUtil::_drawSolidTriangle( const GFXStateBlockDesc &desc, const Point
{
GFXVertexBufferHandle<GFXVertexPCT> verts(mDevice, 3, GFXBufferTypeVolatile);
verts.lock();
// Set up the line strip
verts[0].point = p0;
verts[0].color = color;
@ -779,7 +776,6 @@ void GFXDrawUtil::drawPolygon( const GFXStateBlockDesc& desc, const Point3F* poi
const bool isWireframe = ( desc.fillMode == GFXFillWireframe );
const U32 numVerts = isWireframe ? numPoints + 1 : numPoints;
GFXVertexBufferHandle< GFXVertexPCT > verts( mDevice, numVerts, GFXBufferTypeVolatile );
verts.lock();
for( U32 i = 0; i < numPoints; ++ i )
{
@ -831,7 +827,6 @@ void GFXDrawUtil::_drawWireCube( const GFXStateBlockDesc &desc, const Point3F &s
verts.lock();
Point3F halfSize = size * 0.5f;
// setup 6 line loops
U32 vertexIndex = 0;
for(S32 i = 0; i < 6; i++)
@ -874,7 +869,6 @@ void GFXDrawUtil::_drawSolidCube( const GFXStateBlockDesc &desc, const Point3F &
verts.lock();
Point3F halfSize = size * 0.5f;
// setup 6 line loops
U32 vertexIndex = 0;
U32 idx;
@ -953,7 +947,6 @@ void GFXDrawUtil::_drawWirePolyhedron( const GFXStateBlockDesc &desc, const AnyP
GFXVertexBufferHandle< GFXVertexPCT > verts( mDevice, numEdges * 2, GFXBufferTypeVolatile);
// Fill it with the vertices for the edges.
verts.lock();
for( U32 i = 0; i < numEdges; ++ i )
{
@ -998,7 +991,6 @@ void GFXDrawUtil::_drawSolidPolyhedron( const GFXStateBlockDesc &desc, const Any
// put all the polyhedron's points in there.
GFXVertexBufferHandle< GFXVertexPCT > verts( mDevice, numPoints, GFXBufferTypeVolatile );
verts.lock();
for( U32 i = 0; i < numPoints; ++ i )
{
@ -1087,7 +1079,7 @@ void GFXDrawUtil::drawObjectBox( const GFXStateBlockDesc &desc, const Point3F &s
scaledObjMat.scale( size );
scaledObjMat.setPosition( pos );
//to linear is done in primbuilder
PrimBuild::color( color );
PrimBuild::begin( GFXLineList, 48 );
@ -1158,7 +1150,6 @@ void GFXDrawUtil::_drawSolidCapsule( const GFXStateBlockDesc &desc, const Point3
S32 numPoints = sizeof(circlePoints)/sizeof(Point2F);
GFXVertexBufferHandle<GFXVertexPCT> verts(mDevice, numPoints * 2 + 2, GFXBufferTypeVolatile);
verts.lock();
for (S32 i=0; i<numPoints + 1; i++)
{
S32 imod = i % numPoints;
@ -1270,7 +1261,6 @@ void GFXDrawUtil::drawCone( const GFXStateBlockDesc &desc, const Point3F &basePn
S32 numPoints = sizeof(circlePoints)/sizeof(Point2F);
GFXVertexBufferHandle<GFXVertexPCT> verts(mDevice, numPoints * 3 + 2, GFXBufferTypeVolatile);
verts.lock();
F32 sign = -1.f;
S32 indexDown = 0; //counting down from numPoints
S32 indexUp = 0; //counting up from 0
@ -1340,7 +1330,6 @@ void GFXDrawUtil::drawCylinder( const GFXStateBlockDesc &desc, const Point3F &ba
S32 numPoints = sizeof(circlePoints) / sizeof(Point2F);
GFXVertexBufferHandle<GFXVertexPCT> verts(mDevice, numPoints *4 + 2, GFXBufferTypeVolatile);
verts.lock();
F32 sign = -1.f;
S32 indexDown = 0; //counting down from numPoints
S32 indexUp = 0; //counting up from 0
@ -1379,7 +1368,6 @@ void GFXDrawUtil::drawCylinder( const GFXStateBlockDesc &desc, const Point3F &ba
verts[vertindex + 1].color = color;
}
verts.unlock();
mDevice->setStateBlockByDesc( desc );
@ -1452,7 +1440,6 @@ void GFXDrawUtil::drawSolidPlane( const GFXStateBlockDesc &desc, const Point3F &
{
GFXVertexBufferHandle<GFXVertexPCT> verts(mDevice, 4, GFXBufferTypeVolatile);
verts.lock();
verts[0].point = pos + Point3F( -size.x / 2.0f, -size.y / 2.0f, 0 );
verts[0].color = color;
verts[1].point = pos + Point3F( -size.x / 2.0f, size.y / 2.0f, 0 );
@ -1508,7 +1495,6 @@ void GFXDrawUtil::drawPlaneGrid( const GFXStateBlockDesc &desc, const Point3F &p
GFXVertexBufferHandle<GFXVertexPCT> verts( mDevice, numVertices, GFXBufferTypeVolatile );
verts.lock();
U32 vertCount = 0;
if( plane == PlaneXY || plane == PlaneXZ )

View file

@ -178,11 +178,12 @@ enum GFXFormat
// 24 bit texture formats...
GFXFormatR8G8B8,// first in group...
GFXFormatR8G8B8_SRGB,
// 32 bit texture formats...
GFXFormatR8G8B8A8,// first in group...
GFXFormatR8G8B8X8,
GFXFormatB8G8R8A8,
GFXFormatR8G8B8A8_SRGB,
GFXFormatR32F,
GFXFormatR16G16,
GFXFormatR16G16F,
@ -192,9 +193,6 @@ enum GFXFormat
GFXFormatD24S8,
GFXFormatD24FS8,
// sRGB formats
GFXFormatR8G8B8A8_SRGB,
// Guaranteed RGBA8 (for apis which really dont like bgr)
GFXFormatR8G8B8A8_LINEAR_FORCE,
@ -205,12 +203,16 @@ enum GFXFormat
// 128 bit texture formats...
GFXFormatR32G32B32A32F,// first in group...
// unknown size...
GFXFormatDXT1,// first in group...
GFXFormatDXT2,
GFXFormatDXT3,
GFXFormatDXT4,
GFXFormatDXT5,
// unknown size...Block compression
GFXFormatBC1, //dxt1
GFXFormatBC2, //dxt2/3
GFXFormatBC3, //dxt4/5
GFXFormatBC4, //3dc+ / ati1
GFXFormatBC5, //3dc / ati2
// compressed sRGB formats
GFXFormatBC1_SRGB,
GFXFormatBC2_SRGB,
GFXFormatBC3_SRGB,
GFXFormat_COUNT,
@ -220,7 +222,7 @@ enum GFXFormat
GFXFormat_32BIT = GFXFormatR8G8B8A8,
GFXFormat_64BIT = GFXFormatR16G16B16A16,
GFXFormat_128BIT = GFXFormatR32G32B32A32F,
GFXFormat_UNKNOWNSIZE = GFXFormatDXT1,
GFXFormat_UNKNOWNSIZE = GFXFormatBC1
};
/// Returns the byte size of the pixel for non-compressed formats.

View file

@ -49,7 +49,7 @@ void GFXGeneralFence::_init()
mInitialized = true;
// Allocate resources
mInitialized &= mRTTexHandle.set( 2, 2, GFXFormatR8G8B8X8, &GFXDefaultRenderTargetProfile, avar("%s() - mInitialized (line %d)", __FUNCTION__, __LINE__) );
mInitialized &= mRTTexHandle.set( 2, 2, GFXFormatR8G8B8X8, &GFXRenderTargetProfile, avar("%s() - mInitialized (line %d)", __FUNCTION__, __LINE__) );
mRenderTarget = GFX->allocRenderToTextureTarget();
mInitialized &= ( mRenderTarget != NULL );
@ -120,7 +120,7 @@ void GFXGeneralFence::_onTextureEvent( GFXTexCallbackCode code )
break;
case GFXResurrect:
mRTTexHandle.set( 2, 2, GFXFormatR8G8B8X8, &GFXDefaultRenderTargetProfile, avar("%s() - GFXGeneralFence->mRTTexHandle (line %d)", __FUNCTION__, __LINE__) );
mRTTexHandle.set( 2, 2, GFXFormatR8G8B8X8, &GFXRenderTargetProfile, avar("%s() - GFXGeneralFence->mRTTexHandle (line %d)", __FUNCTION__, __LINE__) );
break;
}
}
@ -132,7 +132,7 @@ void GFXGeneralFence::zombify()
void GFXGeneralFence::resurrect()
{
mRTTexHandle.set( 2, 2, GFXFormatR8G8B8X8, &GFXDefaultRenderTargetProfile, avar("%s() - mRTTexHandle (line %d)", __FUNCTION__, __LINE__) );
mRTTexHandle.set( 2, 2, GFXFormatR8G8B8X8, &GFXRenderTargetProfile, avar("%s() - mRTTexHandle (line %d)", __FUNCTION__, __LINE__) );
}
const String GFXGeneralFence::describeSelf() const

View file

@ -67,11 +67,11 @@ GFXFormatInfo::Data GFXFormatInfo::smFormatInfos[ GFXFormat_COUNT ] =
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
GFXFormatInfo::Data( 0, false, true, false ), // GFXFormatBC1
GFXFormatInfo::Data( 0, true, true, false ), // GFXFormatBC2
GFXFormatInfo::Data( 0, true, true, false ), // GFXFormatBC3
GFXFormatInfo::Data( 0, false, true, false ), // GFXFormatBC4
GFXFormatInfo::Data( 0, false, true, false ), // GFXFormatBC5
};
//-----------------------------------------------------------------------------

View file

@ -59,7 +59,7 @@
class Point2I;
class Point2F;
class ColorF;
class LinearColorF;
class MatrixF;
class GFXShader;
class GFXVertexFormat;
@ -176,7 +176,7 @@ public:
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 LinearColorF& 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;

View file

@ -281,6 +281,7 @@ GFXSamplerStateDesc::GFXSamplerStateDesc()
magFilter = GFXTextureFilterLinear;
minFilter = GFXTextureFilterLinear;
mipFilter = GFXTextureFilterLinear;
samplerFunc = GFXCmpNever;
maxAnisotropy = 1;
alphaArg1 = GFXTATexture;
alphaArg2 = GFXTADiffuse;

View file

@ -47,6 +47,8 @@ struct GFXSamplerStateDesc
GFXTextureFilterType minFilter;
GFXTextureFilterType mipFilter;
GFXCmpFunc samplerFunc;
/// The maximum anisotropy used when one of the filter types
/// is set to anisotropic.
///

View file

@ -134,6 +134,7 @@ void GFXStringEnumTranslate::init()
INIT_LOOKUPTABLE( GFXStringTextureFormat, GFXFormat, const char * );
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatR8G8B8 );
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatR8G8B8A8 );
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatR8G8B8A8_SRGB);
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatR8G8B8X8 );
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatB8G8R8A8 );
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatR32F );
@ -144,11 +145,11 @@ void GFXStringEnumTranslate::init()
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, GFXFormatBC1 );
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatBC2 );
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatBC3 );
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatBC4 );
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatBC5 );
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatD32 );
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatD24X8 );
GFX_STRING_ASSIGN_MACRO( GFXStringTextureFormat, GFXFormatD24S8 );

View file

@ -64,17 +64,17 @@ public:
Point3F mPos;
VectorF mDirection;
ColorF mColor;
ColorF mAmbient;
LinearColorF mColor;
LinearColorF mAmbient;
F32 mRadius;
F32 mInnerConeAngle;
F32 mOuterConeAngle;
/// @todo Revisit below (currently unused by fixed function lights)
Point3F position;
ColorF ambient;
ColorF diffuse;
ColorF specular;
LinearColorF ambient;
LinearColorF diffuse;
LinearColorF specular;
VectorF spotDirection;
F32 spotExponent;
F32 spotCutoff;
@ -88,10 +88,10 @@ public:
// Material definition for FF lighting
struct GFXLightMaterial
{
ColorF ambient;
ColorF diffuse;
ColorF specular;
ColorF emissive;
LinearColorF ambient;
LinearColorF diffuse;
LinearColorF specular;
LinearColorF emissive;
F32 shininess;
};

View file

@ -161,7 +161,7 @@ public:
enum RenderSlot
{
DepthStencil,
Color0, Color1, Color2, Color3, Color4,
Color0, Color1, Color2, Color3, Color4, Color5,
MaxRenderSlotId,
};

View file

@ -145,7 +145,7 @@ bool GFXTexHandle::set( U32 width, U32 height, U32 depth, void *pixels, GFXForma
free();
// Create and set the new texture.
StrongObjectRef::set( TEXMGR->createTexture( width, height, depth, pixels, format, profile ) );
StrongObjectRef::set( TEXMGR->createTexture( width, height, depth, pixels, format, profile,numMipLevels ) );
#ifdef TORQUE_DEBUG
if ( getPointer() )

View file

@ -26,7 +26,7 @@
#include "gfx/gfxDevice.h"
#include "gfx/gfxCardProfile.h"
#include "gfx/gfxStringEnumTranslate.h"
#include "gfx/bitmap/ddsUtils.h"
#include "gfx/bitmap/imageUtils.h"
#include "core/strings/stringFunctions.h"
#include "core/util/safeDelete.h"
#include "core/resourceManager.h"
@ -251,9 +251,11 @@ GFXTextureObject *GFXTextureManager::_lookupTexture( const char *hashName, const
{
GFXTextureObject *ret = hashFind( hashName );
// TODO: Profile checking HERE
//compare just the profile flags and not the entire profile, names could be different but otherwise identical flags
if (ret && (ret->mProfile->compareFlags(*profile)))
return ret;
return ret;
return NULL;
}
GFXTextureObject *GFXTextureManager::_lookupTexture( const DDSFile *ddsFile, const GFXTextureProfile *profile )
@ -370,9 +372,9 @@ GFXTextureObject *GFXTextureManager::_createTexture( GBitmap *bmp,
}
// If _validateTexParams kicked back a different format, than there needs to be
// a conversion
// a conversion unless it's a sRGB format
DDSFile *bmpDDS = NULL;
if( realBmp->getFormat() != realFmt )
if( realBmp->getFormat() != realFmt && !profile->isSRGB() )
{
const GFXFormat oldFmt = realBmp->getFormat();
@ -390,22 +392,20 @@ GFXTextureObject *GFXTextureManager::_createTexture( GBitmap *bmp,
// This shouldn't live here, I don't think
switch( realFmt )
{
case GFXFormatDXT1:
case GFXFormatDXT2:
case GFXFormatDXT3:
case GFXFormatDXT4:
case GFXFormatDXT5:
case GFXFormatBC1:
case GFXFormatBC2:
case GFXFormatBC3:
// If this is a Normal Map profile, than the data needs to be conditioned
// to use the swizzle trick
if( ret->mProfile->getType() == GFXTextureProfile::NormalMap )
{
PROFILE_START(DXT_DXTNMSwizzle);
static DXT5nmSwizzle sDXT5nmSwizzle;
DDSUtil::swizzleDDS( bmpDDS, sDXT5nmSwizzle );
ImageUtil::swizzleDDS( bmpDDS, sDXT5nmSwizzle );
PROFILE_END();
}
convSuccess = DDSUtil::squishDDS( bmpDDS, realFmt );
convSuccess = ImageUtil::ddsCompress( bmpDDS, realFmt );
break;
default:
AssertFatal(false, "Attempting to convert to a non-DXT format");
@ -534,7 +534,7 @@ GFXTextureObject *GFXTextureManager::_createTexture( DDSFile *dds,
GFXFormat fmt = dds->mFormat;
_validateTexParams( dds->getHeight(), dds->getWidth(), profile, numMips, fmt );
if( fmt != dds->mFormat )
if( fmt != dds->mFormat && !profile->isSRGB())
{
Con::errorf( "GFXTextureManager - failed to validate texture parameters for DDS file '%s'", fileName );
return NULL;
@ -629,50 +629,7 @@ GFXTextureObject *GFXTextureManager::createTexture( const Torque::Path &path, GF
// We need to handle path's that have had "incorrect"
// extensions parsed out of the file name
Torque::Path correctPath = path;
bool textureExt = false;
// Easiest case to handle is when there isn't an extension
if (path.getExtension().isEmpty())
textureExt = true;
// Since "dds" isn't registered with GBitmap currently we
// have to test it separately
if (sDDSExt.equal( path.getExtension(), String::NoCase ) )
textureExt = true;
// Now loop through the rest of the GBitmap extensions
// to see if we have any matches
for ( U32 i = 0; i < GBitmap::sRegistrations.size(); i++ )
{
// If we have gotten a match (either in this loop or before)
// then we can exit
if (textureExt)
break;
const GBitmap::Registration &reg = GBitmap::sRegistrations[i];
const Vector<String> &extensions = reg.extensions;
for ( U32 j = 0; j < extensions.size(); ++j )
{
if ( extensions[j].equal( path.getExtension(), String::NoCase ) )
{
// Found a valid texture extension
textureExt = true;
break;
}
}
}
// If we didn't find a valid texture extension then assume that
// the parsed out "extension" was actually intended to be part of
// the texture name so add it back
if (!textureExt)
{
correctPath.setFileName( Torque::Path::Join( path.getFileName(), '.', path.getExtension() ) );
correctPath.setExtension( String::EmptyString );
}
Torque::Path correctPath = validatePath(path);
// Check the cache first...
String pathNoExt = Torque::Path::Join( correctPath.getRoot(), ':', correctPath.getPath() );
@ -786,7 +743,7 @@ GFXTextureObject *GFXTextureManager::createTexture( U32 width, U32 height, GFXFo
GFXFormat checkFmt = format;
_validateTexParams( localWidth, localHeight, profile, numMips, checkFmt );
AssertFatal( checkFmt == format, "Anonymous texture didn't get the format it wanted." );
// AssertFatal( checkFmt == format, "Anonymous texture didn't get the format it wanted." );
GFXTextureObject *outTex = NULL;
@ -836,12 +793,13 @@ GFXTextureObject *GFXTextureManager::createTexture( U32 width,
U32 depth,
void *pixels,
GFXFormat format,
GFXTextureProfile *profile )
GFXTextureProfile *profile,
U32 numMipLevels)
{
PROFILE_SCOPE( GFXTextureManager_CreateTexture_3D );
// Create texture...
GFXTextureObject *ret = _createTextureObject( height, width, depth, format, profile, 1 );
GFXTextureObject *ret = _createTextureObject( height, width, depth, format, profile, numMipLevels );
if(!ret)
{
@ -868,6 +826,339 @@ GFXTextureObject *GFXTextureManager::createTexture( U32 width,
return ret;
}
Torque::Path GFXTextureManager::validatePath(const Torque::Path &path)
{
// We need to handle path's that have had "incorrect"
// extensions parsed out of the file name
Torque::Path correctPath = path;
bool textureExt = false;
// Easiest case to handle is when there isn't an extension
if (path.getExtension().isEmpty())
textureExt = true;
// Since "dds" isn't registered with GBitmap currently we
// have to test it separately
if (sDDSExt.equal(path.getExtension(), String::NoCase))
textureExt = true;
// Now loop through the rest of the GBitmap extensions
// to see if we have any matches
for (U32 i = 0; i < GBitmap::sRegistrations.size(); i++)
{
// If we have gotten a match (either in this loop or before)
// then we can exit
if (textureExt)
break;
const GBitmap::Registration &reg = GBitmap::sRegistrations[i];
const Vector<String> &extensions = reg.extensions;
for (U32 j = 0; j < extensions.size(); ++j)
{
if (extensions[j].equal(path.getExtension(), String::NoCase))
{
// Found a valid texture extension
textureExt = true;
break;
}
}
}
// If we didn't find a valid texture extension then assume that
// the parsed out "extension" was actually intended to be part of
// the texture name so add it back
if (!textureExt)
{
correctPath.setFileName(Torque::Path::Join(path.getFileName(), '.', path.getExtension()));
correctPath.setExtension(String::EmptyString);
}
return correctPath;
}
GBitmap *GFXTextureManager::loadUncompressedTexture(const Torque::Path &path, GFXTextureProfile *profile)
{
PROFILE_SCOPE(GFXTextureManager_loadUncompressedTexture);
GBitmap *retBitmap = NULL;
// Resource handles used for loading. Hold on to them
// throughout this function so that change notifications
// don't get added, then removed, and then re-added.
Resource< DDSFile > dds;
Resource< GBitmap > bitmap;
// We need to handle path's that have had "incorrect"
// extensions parsed out of the file name
Torque::Path correctPath = validatePath(path);
U32 scalePower = profile ? getTextureDownscalePower(profile) : 0;
// Check the cache first...
String pathNoExt = Torque::Path::Join(correctPath.getRoot(), ':', correctPath.getPath());
pathNoExt = Torque::Path::Join(pathNoExt, '/', correctPath.getFileName());
// If this is a valid file (has an extension) than load it
Path realPath;
if (Torque::FS::IsFile(correctPath))
{
PROFILE_SCOPE(GFXTextureManager_loadUncompressedTexture_INNNER1)
// Check for DDS
if (sDDSExt.equal(correctPath.getExtension(), String::NoCase))
{
dds = DDSFile::load(correctPath, scalePower);
if (dds != NULL)
{
realPath = dds.getPath();
retBitmap = new GBitmap();
if (!dds->decompressToGBitmap(retBitmap))
{
delete retBitmap;
retBitmap = NULL;
}
}
}
else // Let GBitmap take care of it
{
bitmap = GBitmap::load(correctPath);
if (bitmap != NULL)
{
realPath = bitmap.getPath();
retBitmap = new GBitmap(*bitmap);
if (scalePower &&
isPow2(retBitmap->getWidth()) &&
isPow2(retBitmap->getHeight()) &&
profile->canDownscale())
{
retBitmap->extrudeMipLevels();
retBitmap->chopTopMips(scalePower);
}
}
}
}
else
{
PROFILE_SCOPE(GFXTextureManager_loadUncompressedTexture_INNNER2)
// NOTE -- We should probably remove the code from GBitmap that tries different
// extensions for things GBitmap loads, and move it here. I think it should
// be a bit more involved than just a list of extensions. Some kind of
// extension registration thing, maybe.
// Check to see if there is a .DDS file with this name (if no extension is provided)
Torque::Path tryDDSPath = pathNoExt;
if (tryDDSPath.getExtension().isNotEmpty())
tryDDSPath.setFileName(tryDDSPath.getFullFileName());
tryDDSPath.setExtension(sDDSExt);
if (Torque::FS::IsFile(tryDDSPath))
{
dds = DDSFile::load(tryDDSPath, scalePower);
if (dds != NULL)
{
realPath = dds.getPath();
// Decompress dds into the GBitmap
retBitmap = new GBitmap();
if (!dds->decompressToGBitmap(retBitmap))
{
delete retBitmap;
retBitmap = NULL;
}
}
}
// Otherwise, retTexObj stays NULL, and fall through to the generic GBitmap
// load.
}
// If we still don't have a texture object yet, feed the correctPath to GBitmap and
// it will try a bunch of extensions
if (retBitmap == NULL)
{
PROFILE_SCOPE(GFXTextureManager_loadUncompressedTexture_INNNER3)
// Find and load the texture.
bitmap = GBitmap::load(correctPath);
if (bitmap != NULL)
{
retBitmap = new GBitmap(*bitmap);
if (scalePower &&
isPow2(retBitmap->getWidth()) &&
isPow2(retBitmap->getHeight()) &&
profile->canDownscale())
{
retBitmap->extrudeMipLevels();
retBitmap->chopTopMips(scalePower);
}
}
}
return retBitmap;
}
GFXTextureObject *GFXTextureManager::createCompositeTexture(const Torque::Path &pathR, const Torque::Path &pathG, const Torque::Path &pathB, const Torque::Path &pathA, U32 inputKey[4],
GFXTextureProfile *profile)
{
PROFILE_SCOPE(GFXTextureManager_createCompositeTexture);
String inputKeyStr = String::ToString("%d%d%d%d", inputKey[0], inputKey[1], inputKey[2], inputKey[3]);
String resourceTag = pathR.getFileName() + pathG.getFileName() + pathB.getFileName() + pathA.getFileName() + inputKeyStr; //associate texture object with a key combo
GFXTextureObject *cacheHit = _lookupTexture(resourceTag, profile);
if (cacheHit != NULL) return cacheHit;
GBitmap*bitmap[4];
bitmap[0] = loadUncompressedTexture(pathR, profile);
if (!pathG.isEmpty())
bitmap[1] = loadUncompressedTexture(pathG, profile);
else
bitmap[1] = NULL;
if (!pathB.isEmpty())
bitmap[2] = loadUncompressedTexture(pathB, profile);
else
bitmap[2] = NULL;
if (!pathA.isEmpty())
bitmap[3] = loadUncompressedTexture(pathA, profile);
else
bitmap[3] = NULL;
Path realPath;
GFXTextureObject *retTexObj = NULL;
realPath = validatePath(pathR); //associate path with r channel texture in.
retTexObj = createCompositeTexture(bitmap, inputKey, resourceTag, profile, false);
if (retTexObj)
{
// Store the path for later use.
retTexObj->mPath = resourceTag;
// Register the texture file for change notifications.
FS::AddChangeNotification(retTexObj->getPath(), this, &GFXTextureManager::_onFileChanged);
}
// Could put in a final check for 'retTexObj == NULL' here as an error message.
for (U32 i = 0; i < 4; i++)
{
if (bitmap[i])
{
bitmap[i]->deleteImage();
delete bitmap[i];
}
}
return retTexObj;
}
void GFXTextureManager::saveCompositeTexture(const Torque::Path &pathR, const Torque::Path &pathG, const Torque::Path &pathB, const Torque::Path &pathA, U32 inputKey[4],
const Torque::Path &saveAs,GFXTextureProfile *profile)
{
PROFILE_SCOPE(GFXTextureManager_saveCompositeTexture);
String inputKeyStr = String::ToString("%d%d%d%d", inputKey[0], inputKey[1], inputKey[2], inputKey[3]);
String resourceTag = pathR.getFileName() + pathG.getFileName() + pathB.getFileName() + pathA.getFileName() + inputKeyStr; //associate texture object with a key combo
GFXTextureObject *cacheHit = _lookupTexture(resourceTag, profile);
if (cacheHit != NULL)
{
cacheHit->dumpToDisk("png", saveAs.getFullPath());
return;
}
GBitmap*bitmap[4];
bitmap[0] = loadUncompressedTexture(pathR, profile);
if (!pathG.isEmpty())
bitmap[1] = loadUncompressedTexture(pathG, profile);
else
bitmap[1] = NULL;
if (!pathB.isEmpty())
bitmap[2] = loadUncompressedTexture(pathB, profile);
else
bitmap[2] = NULL;
if (!pathA.isEmpty())
bitmap[3] = loadUncompressedTexture(pathA, profile);
else
bitmap[3] = NULL;
Path realPath;
GFXTextureObject *retTexObj = NULL;
realPath = validatePath(pathR); //associate path with r channel texture in.
retTexObj = createCompositeTexture(bitmap, inputKey, resourceTag, profile, false);
if (retTexObj != NULL)
retTexObj->dumpToDisk("png", saveAs.getFullPath());
return;
}
DefineEngineFunction(saveCompositeTexture, void, (const char* pathR, const char* pathG, const char* pathB, const char* pathA,
const char * inputKeyString, const char* saveAs),
("", "", "", "", "", ""), "File1,file2,file3,file4,[chanels for r g b and a locations],saveAs")
{
U32 inputKey[4] = {0,0,0,0};
if (dStrcmp(inputKeyString, "") != 0)
{
dSscanf(inputKeyString, "%i %i %i %i", &inputKey[0], &inputKey[1], &inputKey[2], &inputKey[3]);
}
GFX->getTextureManager()->saveCompositeTexture(pathR, pathG, pathB, pathA, inputKey, saveAs, &GFXTexturePersistentProfile);
}
GFXTextureObject *GFXTextureManager::createCompositeTexture(GBitmap*bmp[4], U32 inputKey[4],
const String &resourceName, GFXTextureProfile *profile, bool deleteBmp)
{
if (!bmp[0])
{
Con::errorf(ConsoleLogEntry::General, "GFXTextureManager::createCompositeTexture() - Got NULL bitmap(R)!");
return NULL;
}
U8 rChan, gChan, bChan, aChan;
//pack additional bitmaps into the origional
for (U32 x = 0; x < bmp[0]->getWidth(); x++)
{
for (U32 y = 0; y < bmp[0]->getHeight(); y++)
{
rChan = bmp[0]->getChanelValueAt(x, y, inputKey[0]);
if (bmp[1])
gChan = bmp[1]->getChanelValueAt(x, y, inputKey[1]);
else
gChan = 255;
if (bmp[2])
bChan = bmp[2]->getChanelValueAt(x, y, inputKey[2]);
else
bChan = 255;
if (bmp[3])
aChan = bmp[3]->getChanelValueAt(x, y, inputKey[3]);
else
aChan = 255;
bmp[0]->setColor(x, y, ColorI(rChan, gChan, bChan, aChan));
}
}
GFXTextureObject *cacheHit = _lookupTexture(resourceName, profile);
if (cacheHit != NULL)
{
// Con::errorf("Cached texture '%s'", (resourceName.isNotEmpty() ? resourceName.c_str() : "unknown"));
if (deleteBmp)
delete bmp[0];
return cacheHit;
}
return _createTexture(bmp[0], resourceName, profile, deleteBmp, NULL);
}
GFXTextureObject* GFXTextureManager::_findPooledTexure( U32 width,
U32 height,
GFXFormat format,
@ -1033,13 +1324,16 @@ void GFXTextureManager::_validateTexParams( const U32 width, const U32 height,
GFXFormat testingFormat = inOutFormat;
if( profile->getCompression() != GFXTextureProfile::NONE )
{
const S32 offset = profile->getCompression() - GFXTextureProfile::DXT1;
testingFormat = GFXFormat( GFXFormatDXT1 + offset );
const S32 offset = profile->getCompression() - GFXTextureProfile::BC1;
testingFormat = GFXFormat( GFXFormatBC1 + offset );
// No auto-gen mips on compressed textures
autoGenSupp = false;
}
if (profile->isSRGB())
testingFormat = ImageUtil::toSRGBFormat(testingFormat);
// inOutFormat is not modified by this method
GFXCardProfiler* cardProfiler = GFX->getCardProfiler();
bool chekFmt = cardProfiler->checkFormat(testingFormat, profile, autoGenSupp);

View file

@ -116,7 +116,8 @@ public:
U32 depth,
void *pixels,
GFXFormat format,
GFXTextureProfile *profile );
GFXTextureProfile *profile,
U32 numMipLevels = 1);
virtual GFXTextureObject *createTexture( U32 width,
U32 height,
@ -125,6 +126,19 @@ public:
U32 numMipLevels,
S32 antialiasLevel);
Torque::Path validatePath(const Torque::Path &path);
GBitmap *loadUncompressedTexture(const Torque::Path &path, GFXTextureProfile *profile);
virtual GFXTextureObject *createCompositeTexture(const Torque::Path &pathR, const Torque::Path &pathG, const Torque::Path &pathB, const Torque::Path &pathA, U32 inputKey[4],
GFXTextureProfile *profile);
void saveCompositeTexture(const Torque::Path &pathR, const Torque::Path &pathG, const Torque::Path &pathB, const Torque::Path &pathA, U32 inputKey[4],
const Torque::Path &saveAs,GFXTextureProfile *profile);
virtual GFXTextureObject *createCompositeTexture(GBitmap*bmp[4], U32 inputKey[4],
const String &resourceName,
GFXTextureProfile *profile,
bool deleteBmp);
void deleteTexture( GFXTextureObject *texture );
void reloadTexture( GFXTextureObject *texture );

View file

@ -212,7 +212,7 @@ F32 GFXTextureObject::getMaxVCoord() const
U32 GFXTextureObject::getEstimatedSizeInBytes() const
{
// We have to deal with DDS specially.
if ( mFormat >= GFXFormatDXT1 )
if ( mFormat >= GFXFormatBC1 )
return DDSFile::getSizeInBytes( mFormat, mTextureSize.x, mTextureSize.y, mMipLevels );
// Else we need to calculate the size ourselves.

View file

@ -31,38 +31,58 @@
// Set up defaults...
GFX_ImplementTextureProfile(GFXDefaultRenderTargetProfile,
GFXTextureProfile::DiffuseMap,
GFXTextureProfile::PreserveSize | GFXTextureProfile::NoMipmap | GFXTextureProfile::RenderTarget,
GFX_ImplementTextureProfile(GFXRenderTargetProfile,
GFXTextureProfile::DiffuseMap,
GFXTextureProfile::PreserveSize | GFXTextureProfile::NoMipmap | GFXTextureProfile::RenderTarget,
GFXTextureProfile::NONE);
GFX_ImplementTextureProfile(GFXDefaultStaticDiffuseProfile,
GFXTextureProfile::DiffuseMap,
GFXTextureProfile::Static,
GFX_ImplementTextureProfile(GFXRenderTargetSRGBProfile,
GFXTextureProfile::DiffuseMap,
GFXTextureProfile::PreserveSize | GFXTextureProfile::NoMipmap | GFXTextureProfile::RenderTarget | GFXTextureProfile::SRGB,
GFXTextureProfile::NONE);
GFX_ImplementTextureProfile(GFXDefaultStaticNormalMapProfile,
GFXTextureProfile::NormalMap,
GFXTextureProfile::Static,
GFX_ImplementTextureProfile(GFXStaticTextureProfile, GFXTextureProfile::DiffuseMap,
GFXTextureProfile::Static,
GFXTextureProfile::NONE);
GFX_ImplementTextureProfile(GFXDefaultStaticDXT5nmProfile,
GFXTextureProfile::NormalMap,
GFXTextureProfile::Static,
GFXTextureProfile::DXT5);
GFX_ImplementTextureProfile(GFXDefaultPersistentProfile,
GFXTextureProfile::DiffuseMap,
GFXTextureProfile::PreserveSize | GFXTextureProfile::Static | GFXTextureProfile::KeepBitmap,
GFX_ImplementTextureProfile(GFXStaticTextureSRGBProfile,
GFXTextureProfile::DiffuseMap,
GFXTextureProfile::Static | GFXTextureProfile::SRGB,
GFXTextureProfile::NONE);
GFX_ImplementTextureProfile(GFXSystemMemProfile,
GFXTextureProfile::DiffuseMap,
GFX_ImplementTextureProfile(GFXTexturePersistentProfile,
GFXTextureProfile::DiffuseMap,
GFXTextureProfile::PreserveSize | GFXTextureProfile::Static | GFXTextureProfile::KeepBitmap,
GFXTextureProfile::NONE);
GFX_ImplementTextureProfile(GFXTexturePersistentSRGBProfile,
GFXTextureProfile::DiffuseMap,
GFXTextureProfile::PreserveSize | GFXTextureProfile::Static | GFXTextureProfile::KeepBitmap | GFXTextureProfile::SRGB,
GFXTextureProfile::NONE);
GFX_ImplementTextureProfile(GFXSystemMemTextureProfile,
GFXTextureProfile::DiffuseMap,
GFXTextureProfile::PreserveSize | GFXTextureProfile::NoMipmap | GFXTextureProfile::SystemMemory,
GFXTextureProfile::NONE);
GFX_ImplementTextureProfile(GFXDefaultZTargetProfile,
GFXTextureProfile::DiffuseMap,
GFXTextureProfile::PreserveSize | GFXTextureProfile::NoMipmap | GFXTextureProfile::ZTarget | GFXTextureProfile::NoDiscard,
GFX_ImplementTextureProfile(GFXNormalMapProfile,
GFXTextureProfile::NormalMap,
GFXTextureProfile::Static,
GFXTextureProfile::NONE);
GFX_ImplementTextureProfile(GFXNormalMapBC3Profile,
GFXTextureProfile::NormalMap,
GFXTextureProfile::Static,
GFXTextureProfile::BC3);
GFX_ImplementTextureProfile(GFXNormalMapBC5Profile,
GFXTextureProfile::NormalMap,
GFXTextureProfile::Static,
GFXTextureProfile::BC5);
GFX_ImplementTextureProfile(GFXZTargetProfile,
GFXTextureProfile::DiffuseMap,
GFXTextureProfile::PreserveSize | GFXTextureProfile::NoMipmap | GFXTextureProfile::ZTarget | GFXTextureProfile::NoDiscard,
GFXTextureProfile::NONE);
GFX_ImplementTextureProfile(GFXDynamicTextureProfile,
GFXTextureProfile::DiffuseMap,
GFXTextureProfile::Dynamic,
GFXTextureProfile::NONE);
GFX_ImplementTextureProfile(GFXDynamicTextureSRGBProfile,
GFXTextureProfile::DiffuseMap,
GFXTextureProfile::Dynamic | GFXTextureProfile::SRGB,
GFXTextureProfile::NONE);
//-----------------------------------------------------------------------------

View file

@ -86,6 +86,7 @@ public:
NoPadding = BIT(6), ///< Do not pad this texture if it's non pow2.
KeepBitmap = BIT(7), ///< Always keep a copy of this texture's bitmap. (Potentially in addition to the API managed copy?)
ZTarget = BIT(8), ///< This texture will be used as a Z target.
SRGB = BIT(9), ///< sRGB texture
/// Track and pool textures of this type for reuse.
///
@ -94,15 +95,15 @@ public:
/// the pool to contain unused textures which will remain
/// in memory until a flush occurs.
///
Pooled = BIT(9),
Pooled = BIT(10),
/// A hint that the device is not allowed to discard the content
/// of a target texture after presentation or deactivated.
///
/// This is mainly a depth buffer optimization.
NoDiscard = BIT(10),
NoDiscard = BIT(11),
/// Texture is managed by another process, thus should not be modified
NoModify = BIT(11)
};
@ -110,14 +111,17 @@ public:
enum Compression
{
NONE,
DXT1,
DXT2,
DXT3,
DXT4,
DXT5,
BC1,
BC2,
BC3,
BC4,
BC5,
};
GFXTextureProfile(const String &name, Types type, U32 flags, Compression compression = NONE);
// Equality operators
inline bool operator==(const GFXTextureProfile &in_Cmp) const { return (mName == in_Cmp.mName && mProfile == in_Cmp.mProfile); }
inline bool operator!=(const GFXTextureProfile &in_Cmp) const { return !(*this == in_Cmp); }
// Accessors
String getName() const { return mName; };
@ -167,15 +171,16 @@ public:
inline bool noMip() const { return testFlag(NoMipmap); }
inline bool isPooled() const { return testFlag(Pooled); }
inline bool canDiscard() const { return !testFlag(NoDiscard); }
inline bool canModify() const { return !testFlag(NoModify); }
inline bool isSRGB() const { return testFlag(SRGB); }
//compare profile flags for equality
inline bool compareFlags(const GFXTextureProfile& in_Cmp) const{ return (mProfile == in_Cmp.mProfile); }
private:
/// These constants control the packing for the profile; if you add flags, types, or
/// compression info then make sure these are giving enough bits!
enum Constants
{
TypeBits = 2,
FlagBits = 11,
FlagBits = 12,
CompressionBits = 3,
};
@ -203,23 +208,26 @@ private:
#define GFX_DeclareTextureProfile(name) extern GFXTextureProfile name
#define GFX_ImplementTextureProfile(name, type, flags, compression) GFXTextureProfile name(#name, type, flags, compression)
// Set up some defaults..
// Default Texture profiles
// Texture we can render to.
GFX_DeclareTextureProfile(GFXDefaultRenderTargetProfile);
// Standard diffuse texture that stays in system memory.
GFX_DeclareTextureProfile(GFXDefaultPersistentProfile);
// Generic diffusemap. This works in most cases.
GFX_DeclareTextureProfile(GFXDefaultStaticDiffuseProfile);
// Generic normal map.
GFX_DeclareTextureProfile(GFXDefaultStaticNormalMapProfile);
// DXT5 swizzled normal map
GFX_DeclareTextureProfile(GFXDefaultStaticDXT5nmProfile);
GFX_DeclareTextureProfile(GFXRenderTargetProfile);
GFX_DeclareTextureProfile(GFXRenderTargetSRGBProfile);
// Standard static diffuse textures
GFX_DeclareTextureProfile(GFXStaticTextureProfile);
GFX_DeclareTextureProfile(GFXStaticTextureSRGBProfile);
// Standard static diffuse textures that are persistent in memory
GFX_DeclareTextureProfile(GFXTexturePersistentProfile);
GFX_DeclareTextureProfile(GFXTexturePersistentSRGBProfile);
// Texture that resides in system memory - used to copy data to
GFX_DeclareTextureProfile(GFXSystemMemProfile);
GFX_DeclareTextureProfile(GFXSystemMemTextureProfile);
// normal map profiles
GFX_DeclareTextureProfile(GFXNormalMapProfile);
GFX_DeclareTextureProfile(GFXNormalMapBC3Profile);
GFX_DeclareTextureProfile(GFXNormalMapBC5Profile);
// Depth buffer texture
GFX_DeclareTextureProfile(GFXDefaultZTargetProfile);
GFX_DeclareTextureProfile(GFXZTargetProfile);
// Dynamic Texure
GFX_DeclareTextureProfile(GFXDynamicTextureProfile);
GFX_DeclareTextureProfile(GFXDynamicTextureSRGBProfile);
#endif

View file

@ -21,5 +21,6 @@
//-----------------------------------------------------------------------------
#include "gfx/gfxVertexColor.h"
#include "core/color.h"
Swizzle<U8, 4> *GFXVertexColor::mDeviceSwizzle = &Swizzles::null;
Swizzle<U8, 4> *GFXVertexColor::mDeviceSwizzle = &Swizzles::null;

View file

@ -26,43 +26,48 @@
#ifndef _SWIZZLE_H_
#include "core/util/swizzle.h"
#endif
class ColorI;
#include "core/color.h"
class GFXVertexColor
{
private:
U32 packedColorData;
U32 mPackedColorData;
static Swizzle<U8, 4> *mDeviceSwizzle;
public:
static void setSwizzle( Swizzle<U8, 4> *val ) { mDeviceSwizzle = val; }
GFXVertexColor() : packedColorData( 0xFFFFFFFF ) {} // White with full alpha
GFXVertexColor() : mPackedColorData( 0xFFFFFFFF ) {} // White with full alpha
GFXVertexColor( const ColorI &color ) { set( color ); }
void set( U8 red, U8 green, U8 blue, U8 alpha = 255 )
{
packedColorData = red << 0 | green << 8 | blue << 16 | alpha << 24;
mDeviceSwizzle->InPlace( &packedColorData, sizeof( packedColorData ) );
//we must set the color in linear space
LinearColorF linearColor = LinearColorF(ColorI(red, green, blue, alpha));
mPackedColorData = linearColor.getRGBAPack();
mDeviceSwizzle->InPlace( &mPackedColorData, sizeof( mPackedColorData ) );
}
void set( const ColorI &color )
{
mDeviceSwizzle->ToBuffer( &packedColorData, (U8 *)&color, sizeof( packedColorData ) );
//we must set the color in linear space
LinearColorF linearColor = LinearColorF(color);
mPackedColorData = linearColor.getRGBAPack();
mDeviceSwizzle->InPlace(&mPackedColorData, sizeof(mPackedColorData));
}
GFXVertexColor &operator=( const ColorI &color ) { set( color ); return *this; }
operator const U32 *() const { return &packedColorData; }
const U32& getPackedColorData() const { return packedColorData; }
operator const U32 *() const { return &mPackedColorData; }
const U32& getPackedColorData() const { return mPackedColorData; }
void getColor( ColorI *color ) const
void getColor( ColorI *outColor ) const
{
mDeviceSwizzle->ToBuffer( color, &packedColorData, sizeof( packedColorData ) );
}
ColorI linearColor;
mDeviceSwizzle->ToBuffer( &linearColor, &mPackedColorData, sizeof( mPackedColorData ) );
//convert color back to srgb space
*outColor = linearColor.fromLinear();
}
};
#endif

View file

@ -28,6 +28,7 @@
#include "gfx/gfxTextureManager.h"
#include "gfx/gfxCardProfile.h"
#include "gfx/bitmap/ddsFile.h"
#include "gfx/bitmap/imageUtils.h"
GLenum GFXGLCubemap::faceList[6] =
@ -71,11 +72,11 @@ void GFXGLCubemap::fillCubeTextures(GFXTexHandle* faces)
U32 reqWidth = faces[0]->getWidth();
U32 reqHeight = faces[0]->getHeight();
GFXFormat regFaceFormat = faces[0]->getFormat();
const bool isCompressed = isCompressedFormat(regFaceFormat);
const bool isCompressed = ImageUtil::isCompressedFormat(regFaceFormat);
mWidth = reqWidth;
mHeight = reqHeight;
mFaceFormat = regFaceFormat;
mMipLevels = getMax( (U32)1, faces[0]->mMipLevels);
mMipMapLevels = getMax( (U32)1, faces[0]->mMipLevels);
AssertFatal(reqWidth == reqHeight, "GFXGLCubemap::fillCubeTextures - Width and height must be equal!");
for(U32 i = 0; i < 6; i++)
@ -90,7 +91,7 @@ void GFXGLCubemap::fillCubeTextures(GFXTexHandle* faces)
GFXGLTextureObject* glTex = static_cast<GFXGLTextureObject*>(faces[i].getPointer());
if( isCompressed )
{
for( U32 mip = 0; mip < mMipLevels; ++mip )
for( U32 mip = 0; mip < mMipMapLevels; ++mip )
{
const U32 mipWidth = getMax( U32(1), faces[i]->getWidth() >> mip );
const U32 mipHeight = getMax( U32(1), faces[i]->getHeight() >> mip );
@ -136,26 +137,16 @@ void GFXGLCubemap::initStatic( DDSFile *dds )
AssertFatal( dds->isCubemap(), "GFXGLCubemap::initStatic - Got non-cubemap DDS file!" );
AssertFatal( dds->mSurfaces.size() == 6, "GFXGLCubemap::initStatic - DDS has less than 6 surfaces!" );
// HACK: I cannot put the genie back in the bottle and assign a
// DDSFile pointer back to a Resource<>.
//
// So we do a second lookup which works out ok for now, but shows
// the weakness in the ResourceManager not having a common base
// reference type.
//
mDDSFile = ResourceManager::get().load( dds->getSourcePath() );
AssertFatal( mDDSFile == dds, "GFXGLCubemap::initStatic - Couldn't find DDSFile resource!" );
mWidth = dds->getWidth();
mHeight = dds->getHeight();
mFaceFormat = dds->getFormat();
mMipLevels = dds->getMipLevels();
mMipMapLevels = dds->getMipLevels();
const bool isCompressed = ImageUtil::isCompressedFormat(mFaceFormat);
glGenTextures(1, &mCubemap);
PRESERVE_CUBEMAP_TEXTURE();
glBindTexture(GL_TEXTURE_CUBE_MAP, mCubemap);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, mMipLevels - 1);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, mMipMapLevels - 1);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
@ -173,12 +164,19 @@ void GFXGLCubemap::initStatic( DDSFile *dds )
continue;
}
// convert to Z up
const U32 faceIndex = _zUpFaceIndex(i);
// Now loop thru the mip levels!
for (U32 mip = 0; mip < mMipLevels; ++mip)
for (U32 mip = 0; mip < mMipMapLevels; ++mip)
{
const U32 mipWidth = getMax( U32(1), mWidth >> mip );
const U32 mipHeight = getMax( U32(1), mHeight >> mip );
glCompressedTexImage2D(faceList[i], mip, GFXGLTextureInternalFormat[mFaceFormat], mipWidth, mipHeight, 0, dds->getSurfaceSize(mip), dds->mSurfaces[i]->mMips[mip]);
if (isCompressed)
glCompressedTexImage2D(faceList[faceIndex], mip, GFXGLTextureInternalFormat[mFaceFormat], mipWidth, mipHeight, 0, dds->getSurfaceSize(mip), dds->mSurfaces[i]->mMips[mip]);
else
glTexImage2D(faceList[faceIndex], mip, GFXGLTextureInternalFormat[mFaceFormat], mipWidth, mipHeight, 0,
GFXGLTextureFormat[mFaceFormat], GFXGLTextureType[mFaceFormat], dds->mSurfaces[i]->mMips[mip]);
}
}
}
@ -187,13 +185,13 @@ void GFXGLCubemap::initDynamic(U32 texSize, GFXFormat faceFormat)
{
mDynamicTexSize = texSize;
mFaceFormat = faceFormat;
const bool isCompressed = isCompressedFormat(faceFormat);
mMipLevels = getMax( (U32)1, getMaxMipmaps( texSize, texSize, 1 ) );
const bool isCompressed = ImageUtil::isCompressedFormat(faceFormat);
mMipMapLevels = getMax( (U32)1, getMaxMipmaps( texSize, texSize, 1 ) );
glGenTextures(1, &mCubemap);
PRESERVE_CUBEMAP_TEXTURE();
glBindTexture(GL_TEXTURE_CUBE_MAP, mCubemap);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, mMipLevels - 1);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, mMipMapLevels - 1);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
@ -204,9 +202,9 @@ void GFXGLCubemap::initDynamic(U32 texSize, GFXFormat faceFormat)
for(U32 i = 0; i < 6; i++)
{
if( isCompressedFormat(faceFormat) )
if( ImageUtil::isCompressedFormat(faceFormat) )
{
for( U32 mip = 0; mip < mMipLevels; ++mip )
for( U32 mip = 0; mip < mMipMapLevels; ++mip )
{
const U32 mipSize = getMax( U32(1), texSize >> mip );
const U32 mipDataSize = getCompressedSurfaceSize( mFaceFormat, texSize, texSize, mip );

View file

@ -46,7 +46,6 @@ public:
// Convenience methods for GFXGLTextureTarget
U32 getWidth() { return mWidth; }
U32 getHeight() { return mHeight; }
U32 getNumMipLevels() { return mMipLevels; }
U32 getHandle() { return mCubemap; }
// GFXResource interface
@ -73,7 +72,6 @@ protected:
// Self explanatory
U32 mWidth;
U32 mHeight;
U32 mMipLevels;
GFXFormat mFaceFormat;
GFXTexHandle mTextures[6]; ///< Keep refs to our textures for resurrection of static cubemaps

View file

@ -180,6 +180,9 @@ void GFXGLDevice::initGLState()
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
//enable sRGB
glEnable(GL_FRAMEBUFFER_SRGB);
}
void GFXGLDevice::vsyncCallback()
@ -450,7 +453,7 @@ void GFXGLDevice::endSceneInternal()
mCanCurrentlyRender = false;
}
void GFXGLDevice::clear(U32 flags, ColorI color, F32 z, U32 stencil)
void GFXGLDevice::clear(U32 flags, const LinearColorF& color, F32 z, U32 stencil)
{
// Make sure we have flushed our render target state.
_updateRenderTargets();
@ -470,10 +473,7 @@ void GFXGLDevice::clear(U32 flags, ColorI color, F32 z, U32 stencil)
glColorMask(true, true, true, true);
glDepthMask(true);
glStencilMask(0xFFFFFFFF);
ColorF c = color;
glClearColor(c.red, c.green, c.blue, c.alpha);
glClearColor(color.red, color.green, color.blue, color.alpha);
glClearDepth(z);
glClearStencil(stencil);
@ -581,7 +581,8 @@ void GFXGLDevice::drawPrimitive( GFXPrimitiveType primType, U32 vertexStart, U32
{
preDrawPrimitive();
vertexStart += mCurrentVB[0]->mBufferVertexOffset;
if(mCurrentVB[0])
vertexStart += mCurrentVB[0]->mBufferVertexOffset;
if(mDrawInstancesCount)
glDrawArraysInstanced(GFXGLPrimType[primType], vertexStart, primCountToIndexCount(primType, primitiveCount), mDrawInstancesCount);
@ -629,7 +630,7 @@ void GFXGLDevice::setLightMaterialInternal(const GFXLightMaterial mat)
// ONLY NEEDED ON FFP
}
void GFXGLDevice::setGlobalAmbientInternal(ColorF color)
void GFXGLDevice::setGlobalAmbientInternal(LinearColorF color)
{
// ONLY NEEDED ON FFP
}

View file

@ -116,7 +116,7 @@ public:
virtual GFXShader* createShader();
virtual void clear( U32 flags, ColorI color, F32 z, U32 stencil );
virtual void clear( U32 flags, const LinearColorF& color, F32 z, U32 stencil );
virtual bool beginSceneInternal();
virtual void endSceneInternal();
@ -171,7 +171,7 @@ protected:
virtual void setLightInternal(U32 lightStage, const GFXLightInfo light, bool lightEnable);
virtual void setLightMaterialInternal(const GFXLightMaterial mat);
virtual void setGlobalAmbientInternal(ColorF color);
virtual void setGlobalAmbientInternal(LinearColorF color);
/// @name State Initalization.
/// @{

View file

@ -142,11 +142,17 @@ void GFXGLEnumTranslate::init()
GFXGLTextureInternalFormat[GFXFormatD24X8] = GL_DEPTH24_STENCIL8;
GFXGLTextureInternalFormat[GFXFormatD24S8] = GL_DEPTH24_STENCIL8;
GFXGLTextureInternalFormat[GFXFormatR16G16B16A16] = GL_RGBA16;
GFXGLTextureInternalFormat[GFXFormatDXT1] = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
GFXGLTextureInternalFormat[GFXFormatDXT2] = GL_ZERO;
GFXGLTextureInternalFormat[GFXFormatDXT3] = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
GFXGLTextureInternalFormat[GFXFormatDXT4] = GL_ZERO;
GFXGLTextureInternalFormat[GFXFormatDXT5] = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
GFXGLTextureInternalFormat[GFXFormatBC1] = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
GFXGLTextureInternalFormat[GFXFormatBC2] = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
GFXGLTextureInternalFormat[GFXFormatBC3] = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
GFXGLTextureInternalFormat[GFXFormatBC4] = GL_COMPRESSED_RED_RGTC1;
GFXGLTextureInternalFormat[GFXFormatBC5] = GL_COMPRESSED_RG_RGTC2;
//sRGB
GFXGLTextureInternalFormat[GFXFormatR8G8B8_SRGB] = GL_SRGB8;
GFXGLTextureInternalFormat[GFXFormatR8G8B8A8_SRGB] = GL_SRGB8_ALPHA8;
GFXGLTextureInternalFormat[GFXFormatBC1_SRGB] = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;
GFXGLTextureInternalFormat[GFXFormatBC2_SRGB] = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT;
GFXGLTextureInternalFormat[GFXFormatBC3_SRGB] = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
GFXGLTextureFormat[GFXFormatA8] = GL_RED;
GFXGLTextureFormat[GFXFormatL8] = GL_RED;
@ -163,11 +169,17 @@ void GFXGLEnumTranslate::init()
GFXGLTextureFormat[GFXFormatD24X8] = GL_DEPTH_STENCIL;
GFXGLTextureFormat[GFXFormatD24S8] = GL_DEPTH_STENCIL;
GFXGLTextureFormat[GFXFormatR16G16B16A16] = GL_RGBA;
GFXGLTextureFormat[GFXFormatDXT1] = GL_RGBA;
GFXGLTextureFormat[GFXFormatDXT2] = GL_ZERO;
GFXGLTextureFormat[GFXFormatDXT3] = GL_RGBA;
GFXGLTextureFormat[GFXFormatDXT4] = GL_ZERO;
GFXGLTextureFormat[GFXFormatDXT5] = GL_RGBA;
GFXGLTextureFormat[GFXFormatBC1] = GL_RGBA;
GFXGLTextureFormat[GFXFormatBC2] = GL_RGBA;
GFXGLTextureFormat[GFXFormatBC3] = GL_RGBA;
GFXGLTextureFormat[GFXFormatBC4] = GL_RED;
GFXGLTextureFormat[GFXFormatBC5] = GL_RG;
//sRGB
GFXGLTextureFormat[GFXFormatR8G8B8_SRGB] = GL_RGB;
GFXGLTextureFormat[GFXFormatR8G8B8A8_SRGB] = GL_RGBA;
GFXGLTextureFormat[GFXFormatBC1_SRGB] = GL_RGBA;
GFXGLTextureFormat[GFXFormatBC2_SRGB] = GL_RGBA;
GFXGLTextureFormat[GFXFormatBC3_SRGB] = GL_RGBA;
GFXGLTextureType[GFXFormatA8] = GL_UNSIGNED_BYTE;
GFXGLTextureType[GFXFormatL8] = GL_UNSIGNED_BYTE;
@ -184,13 +196,18 @@ void GFXGLEnumTranslate::init()
GFXGLTextureType[GFXFormatD24X8] = GL_UNSIGNED_INT_24_8;
GFXGLTextureType[GFXFormatD24S8] = GL_UNSIGNED_INT_24_8;
GFXGLTextureType[GFXFormatR16G16B16A16] = GL_UNSIGNED_SHORT;
GFXGLTextureType[GFXFormatDXT1] = GL_UNSIGNED_BYTE;
GFXGLTextureType[GFXFormatDXT2] = GL_ZERO;
GFXGLTextureType[GFXFormatDXT3] = GL_UNSIGNED_BYTE;
GFXGLTextureType[GFXFormatDXT4] = GL_ZERO;
GFXGLTextureType[GFXFormatDXT5] = GL_UNSIGNED_BYTE;
GFXGLTextureType[GFXFormatBC1] = GL_UNSIGNED_BYTE;
GFXGLTextureType[GFXFormatBC2] = GL_UNSIGNED_BYTE;
GFXGLTextureType[GFXFormatBC3] = GL_UNSIGNED_BYTE;
GFXGLTextureType[GFXFormatBC4] = GL_UNSIGNED_BYTE;
GFXGLTextureType[GFXFormatBC5] = GL_UNSIGNED_BYTE;
// sRGB
GFXGLTextureType[GFXFormatR8G8B8_SRGB] = GL_UNSIGNED_BYTE;
GFXGLTextureType[GFXFormatR8G8B8A8_SRGB] = GL_UNSIGNED_BYTE;
GFXGLTextureType[GFXFormatBC1_SRGB] = GL_UNSIGNED_BYTE;
GFXGLTextureType[GFXFormatBC2_SRGB] = GL_UNSIGNED_BYTE;
GFXGLTextureType[GFXFormatBC3_SRGB] = GL_UNSIGNED_BYTE;
GFXGLTextureType[GFXFormatR8G8B8A8_SRGB] = GL_SRGB8_ALPHA8;
static GLint Swizzle_GFXFormatA8[] = { GL_NONE, GL_NONE, GL_NONE, GL_RED };
static GLint Swizzle_GFXFormatL[] = { GL_RED, GL_RED, GL_RED, GL_ALPHA };

View file

@ -197,7 +197,7 @@ void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const PlaneF& fv)
internalSet(handle, fv);
}
void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const ColorF& fv)
void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const LinearColorF& fv)
{
internalSet(handle, fv);
}
@ -423,17 +423,14 @@ bool GFXGLShader::_init()
Vector<GFXShaderMacro> macros;
macros.merge( mMacros );
macros.merge( smGlobalMacros );
// Add the shader version to the macros.
const U32 mjVer = (U32)mFloor( mPixVersion );
const U32 mnVer = (U32)( ( mPixVersion - F32( mjVer ) ) * 10.01f );
macros.increment();
macros.last().name = "TORQUE_SM";
macros.last().value = String::ToString( mjVer * 10 + mnVer );
macros.last().value = 40;
macros.increment();
macros.last().name = "TORQUE_VERTEX_SHADER";
macros.last().value = "";
macros.last().value = "";
// Default to true so we're "successful" if a vertex/pixel shader wasn't specified.
bool compiledVertexShader = true;
bool compiledPixelShader = true;

View file

@ -121,7 +121,7 @@ public:
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 LinearColorF& 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);

View file

@ -58,7 +58,13 @@ GFXGLStateBlock::GFXGLStateBlock(const GFXStateBlockDesc& desc) :
glSamplerParameteri(id, GL_TEXTURE_WRAP_S, GFXGLTextureAddress[ssd.addressModeU]);
glSamplerParameteri(id, GL_TEXTURE_WRAP_T, GFXGLTextureAddress[ssd.addressModeV]);
glSamplerParameteri(id, GL_TEXTURE_WRAP_R, GFXGLTextureAddress[ssd.addressModeW]);
if(static_cast< GFXGLDevice* >( GFX )->supportsAnisotropic() )
//compare modes
const bool comparison = ssd.samplerFunc != GFXCmpNever;
glSamplerParameteri(id, GL_TEXTURE_COMPARE_MODE, comparison ? GL_COMPARE_R_TO_TEXTURE_ARB : GL_NONE );
glSamplerParameteri(id, GL_TEXTURE_COMPARE_FUNC, GFXGLCmpFunc[ssd.samplerFunc]);
if (static_cast< GFXGLDevice* >(GFX)->supportsAnisotropic())
glSamplerParameterf(id, GL_TEXTURE_MAX_ANISOTROPY_EXT, ssd.maxAnisotropy);
mSamplersMap[ssd] = id;
@ -99,7 +105,7 @@ void GFXGLStateBlock::activate(const GFXGLStateBlock* oldState)
#define STATE_CHANGE(state) (!oldState || oldState->mDesc.state != mDesc.state)
#define TOGGLE_STATE(state, enum) if(mDesc.state) glEnable(enum); else glDisable(enum)
#define CHECK_TOGGLE_STATE(state, enum) if(!oldState || oldState->mDesc.state != mDesc.state) {if(mDesc.state) glEnable(enum); else glDisable(enum);}
#define CHECK_TOGGLE_STATE(state, enum) if(!oldState || oldState->mDesc.state != mDesc.state) if(mDesc.state) glEnable(enum); else glDisable(enum)
// Blending
CHECK_TOGGLE_STATE(blendEnable, GL_BLEND);

View file

@ -92,8 +92,10 @@ void GFXGLTextureManager::innerCreateTexture( GFXGLTextureObject *retTex,
bool forceMips)
{
// No 24 bit formats. They trigger various oddities because hardware (and Apple's drivers apparently...) don't natively support them.
if(format == GFXFormatR8G8B8)
if (format == GFXFormatR8G8B8)
format = GFXFormatR8G8B8A8;
else if (format == GFXFormatR8G8B8_SRGB)
format = GFXFormatR8G8B8A8_SRGB;
retTex->mFormat = format;
retTex->mIsZombie = false;
@ -110,7 +112,7 @@ void GFXGLTextureManager::innerCreateTexture( GFXGLTextureObject *retTex,
// Create it
// @todo OPENGL - Creating mipmaps for compressed formats. Not supported on OpenGL ES and bugged on AMD. We use mipmaps present on file.
if( forceMips && !retTex->mIsNPoT2 && !isCompressedFormat(format) )
if( forceMips && !retTex->mIsNPoT2 && !ImageUtil::isCompressedFormat(format) )
{
retTex->mMipLevels = numMipLevels > 1 ? numMipLevels : 0;
}
@ -159,7 +161,7 @@ void GFXGLTextureManager::innerCreateTexture( GFXGLTextureObject *retTex,
{
//If it wasn't for problems on amd drivers this next part could be really simplified and we wouldn't need to go through manually creating our
//mipmap pyramid and instead just use glGenerateMipmap
if(isCompressedFormat(format))
if(ImageUtil::isCompressedFormat(format))
{
AssertFatal(binding == GL_TEXTURE_2D,
"GFXGLTextureManager::innerCreateTexture - Only compressed 2D textures are supported");
@ -226,40 +228,32 @@ void GFXGLTextureManager::innerCreateTexture( GFXGLTextureObject *retTex,
// loadTexture - GBitmap
//-----------------------------------------------------------------------------
static void _fastTextureLoad(GFXGLTextureObject* texture, GBitmap* pDL)
static void _textureUpload(const S32 width, const S32 height,const S32 bytesPerPixel,const GFXGLTextureObject* texture, const GFXFormat fmt, const U8* data,const S32 mip=0, Swizzle<U8, 4> *pSwizzle = NULL)
{
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, texture->getBuffer());
U32 bufSize = pDL->getWidth(0) * pDL->getHeight(0) * pDL->getBytesPerPixel();
U32 bufSize = width * height * bytesPerPixel;
glBufferData(GL_PIXEL_UNPACK_BUFFER, bufSize, NULL, GL_STREAM_DRAW);
if(pDL->getFormat() == GFXFormatR8G8B8A8 || pDL->getFormat() == GFXFormatR8G8B8X8)
if(pSwizzle)
{
PROFILE_SCOPE(Swizzle32_Upload);
U8* pboMemory = (U8*)dMalloc(bufSize);
GFX->getDeviceSwizzle32()->ToBuffer(pboMemory, pDL->getBits(0), bufSize);
glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, bufSize, pboMemory );
pSwizzle->ToBuffer(pboMemory, data, bufSize);
glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, bufSize, pboMemory);
dFree(pboMemory);
}
else
{
PROFILE_SCOPE(SwizzleNull_Upload);
glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, bufSize, pDL->getBits(0) );
glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, bufSize, data);
}
if(texture->getBinding() == GL_TEXTURE_2D)
glTexSubImage2D(texture->getBinding(), 0, 0, 0, pDL->getWidth(0), pDL->getHeight(0), GFXGLTextureFormat[pDL->getFormat()], GFXGLTextureType[pDL->getFormat()], NULL);
else
glTexSubImage1D(texture->getBinding(), 0, 0, (pDL->getWidth(0) > 1 ? pDL->getWidth(0) : pDL->getHeight(0)), GFXGLTextureFormat[pDL->getFormat()], GFXGLTextureType[pDL->getFormat()], NULL);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
}
static void _slowTextureLoad(GFXGLTextureObject* texture, GBitmap* pDL)
{
if(texture->getBinding() == GL_TEXTURE_2D)
glTexSubImage2D(texture->getBinding(), 0, 0, 0, pDL->getWidth(0), pDL->getHeight(0), GFXGLTextureFormat[pDL->getFormat()], GFXGLTextureType[pDL->getFormat()], pDL->getBits(0));
else
glTexSubImage1D(texture->getBinding(), 0, 0, (pDL->getWidth(0) > 1 ? pDL->getWidth(0) : pDL->getHeight(0)), GFXGLTextureFormat[pDL->getFormat()], GFXGLTextureType[pDL->getFormat()], pDL->getBits(0));
if (texture->getBinding() == GL_TEXTURE_2D)
glTexSubImage2D(texture->getBinding(), mip, 0, 0, width, height, GFXGLTextureFormat[fmt], GFXGLTextureType[fmt], NULL);
else
glTexSubImage1D(texture->getBinding(), mip, 0, (width > 1 ? width : height), GFXGLTextureFormat[fmt], GFXGLTextureType[fmt], NULL);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
}
bool GFXGLTextureManager::_loadTexture(GFXTextureObject *aTexture, GBitmap *pDL)
@ -276,27 +270,22 @@ bool GFXGLTextureManager::_loadTexture(GFXTextureObject *aTexture, GBitmap *pDL)
// No 24bit formats.
if(pDL->getFormat() == GFXFormatR8G8B8)
pDL->setFormat(GFXFormatR8G8B8A8);
else if (pDL->getFormat() == GFXFormatR8G8B8_SRGB)
pDL->setFormat(GFXFormatR8G8B8A8_SRGB);
// Bind to edit
PRESERVE_TEXTURE(texture->getBinding());
glBindTexture(texture->getBinding(), texture->getHandle());
texture->mFormat = pDL->getFormat();
if(pDL->getFormat() == GFXFormatR8G8B8A8 || pDL->getFormat() == GFXFormatR8G8B8X8)
_fastTextureLoad(texture, pDL);
else
_slowTextureLoad(texture, pDL);
_textureUpload(pDL->getWidth(),pDL->getHeight(),pDL->getBytesPerPixel(),texture,pDL->getFormat(), pDL->getBits(), 0);
if(texture->getMipLevels() != 1)
glGenerateMipmap(texture->getBinding());
if(!ImageUtil::isCompressedFormat(pDL->getFormat()))
glGenerateMipmap(texture->getBinding());
return true;
}
bool GFXGLTextureManager::_loadTexture(GFXTextureObject *aTexture, DDSFile *dds)
{
PROFILE_SCOPE(GFXGLTextureManager_loadTextureDDS);
AssertFatal(!(dds->mFormat == GFXFormatDXT2 || dds->mFormat == GFXFormatDXT4), "GFXGLTextureManager::_loadTexture - OpenGL does not support DXT2 or DXT4 compressed textures");
GFXGLTextureObject* texture = static_cast<GFXGLTextureObject*>(aTexture);
AssertFatal(texture->getBinding() == GL_TEXTURE_2D,
@ -307,42 +296,36 @@ bool GFXGLTextureManager::_loadTexture(GFXTextureObject *aTexture, DDSFile *dds)
PRESERVE_TEXTURE(texture->getBinding());
glBindTexture(texture->getBinding(), texture->getHandle());
texture->mFormat = dds->mFormat;
U32 numMips = dds->mSurfaces[0]->mMips.size();
const GFXFormat fmt = texture->mFormat;
for(U32 i = 0; i < numMips; i++)
{
PROFILE_SCOPE(GFXGLTexMan_loadSurface);
if(isCompressedFormat(dds->mFormat))
if(ImageUtil::isCompressedFormat(texture->mFormat))
{
if((!isPow2(dds->getWidth()) || !isPow2(dds->getHeight())))
if((!isPow2(dds->getWidth()) || !isPow2(dds->getHeight())) && GFX->getCardProfiler()->queryProfile("GL::Workaround::noCompressedNPoTTextures"))
{
U32 squishFlag = squish::kDxt1;
switch (dds->mFormat)
{
case GFXFormatDXT3:
squishFlag = squish::kDxt3;
break;
case GFXFormatDXT5:
squishFlag = squish::kDxt5;
break;
default:
break;
}
U8* uncompressedTex = new U8[dds->getWidth(i) * dds->getHeight(i) * 4];
squish::DecompressImage(uncompressedTex, dds->getWidth(i), dds->getHeight(i), dds->mSurfaces[0]->mMips[i], squishFlag);
ImageUtil::decompress(dds->mSurfaces[0]->mMips[i],uncompressedTex, dds->getWidth(i), dds->getHeight(i), fmt);
glTexSubImage2D(texture->getBinding(), i, 0, 0, dds->getWidth(i), dds->getHeight(i), GL_RGBA, GL_UNSIGNED_BYTE, uncompressedTex);
delete[] uncompressedTex;
}
else
glCompressedTexSubImage2D(texture->getBinding(), i, 0, 0, dds->getWidth(i), dds->getHeight(i), GFXGLTextureInternalFormat[dds->mFormat], dds->getSurfaceSize(dds->getHeight(), dds->getWidth(), i), dds->mSurfaces[0]->mMips[i]);
glCompressedTexSubImage2D(texture->getBinding(), i, 0, 0, dds->getWidth(i), dds->getHeight(i), GFXGLTextureInternalFormat[fmt], dds->getSurfaceSize(dds->getHeight(), dds->getWidth(), i), dds->mSurfaces[0]->mMips[i]);
}
else
glTexSubImage2D(texture->getBinding(), i, 0, 0, dds->getWidth(i), dds->getHeight(i), GFXGLTextureFormat[dds->mFormat], GFXGLTextureType[dds->mFormat], dds->mSurfaces[0]->mMips[i]);
{
Swizzle<U8, 4> *pSwizzle = NULL;
if (fmt == GFXFormatR8G8B8A8 || fmt == GFXFormatR8G8B8X8 || fmt == GFXFormatR8G8B8A8_SRGB || fmt == GFXFormatR8G8B8A8_LINEAR_FORCE || fmt == GFXFormatB8G8R8A8)
pSwizzle = &Swizzles::bgra;
_textureUpload(dds->getWidth(i), dds->getHeight(i),dds->mBytesPerPixel, texture, fmt, dds->mSurfaces[0]->mMips[i],i, pSwizzle);
}
}
if(numMips !=1 && !isCompressedFormat(dds->mFormat))
if(numMips !=1 && !ImageUtil::isCompressedFormat(texture->mFormat))
glGenerateMipmap(texture->getBinding());
return true;

View file

@ -57,7 +57,7 @@ GFXGLTextureObject::~GFXGLTextureObject()
GFXLockedRect* GFXGLTextureObject::lock(U32 mipLevel, RectI *inRect)
{
AssertFatal(mBinding != GL_TEXTURE_3D, "GFXGLTextureObject::lock - We don't support locking 3D textures yet");
//AssertFatal(mBinding != GL_TEXTURE_3D, "GFXGLTextureObject::lock - We don't support locking 3D textures yet");
U32 width = mTextureSize.x >> mipLevel;
U32 height = mTextureSize.y >> mipLevel;
@ -76,7 +76,7 @@ GFXLockedRect* GFXGLTextureObject::lock(U32 mipLevel, RectI *inRect)
mLockedRect.pitch = mLockedRectRect.extent.x * mBytesPerTexel;
// CodeReview [ags 12/19/07] This one texel boundary is necessary to keep the clipmap code from crashing. Figure out why.
U32 size = (mLockedRectRect.extent.x + 1) * (mLockedRectRect.extent.y + 1) * mBytesPerTexel;
U32 size = (mLockedRectRect.extent.x + 1) * (mLockedRectRect.extent.y + 1) * getDepth() * mBytesPerTexel;
AssertFatal(!mFrameAllocatorMark && !mFrameAllocatorPtr, "");
mFrameAllocatorMark = FrameAllocator::getWaterMark();
mFrameAllocatorPtr = (U8*)FrameAllocator::alloc( size );
@ -103,8 +103,11 @@ void GFXGLTextureObject::unlock(U32 mipLevel)
glBindTexture(mBinding, mHandle);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, mBuffer);
glBufferData(GL_PIXEL_UNPACK_BUFFER, (mLockedRectRect.extent.x + 1) * (mLockedRectRect.extent.y + 1) * mBytesPerTexel, mFrameAllocatorPtr, GL_STREAM_DRAW);
if(mBinding == GL_TEXTURE_2D)
S32 z = getDepth();
if (mBinding == GL_TEXTURE_3D)
glTexSubImage3D(mBinding, mipLevel, mLockedRectRect.point.x, mLockedRectRect.point.y, z,
mLockedRectRect.extent.x, mLockedRectRect.extent.y, z, GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], NULL);
else if(mBinding == GL_TEXTURE_2D)
glTexSubImage2D(mBinding, mipLevel, mLockedRectRect.point.x, mLockedRectRect.point.y,
mLockedRectRect.extent.x, mLockedRectRect.extent.y, GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], NULL);
else if(mBinding == GL_TEXTURE_1D)
@ -146,12 +149,13 @@ bool GFXGLTextureObject::copyToBmp(GBitmap * bmp)
// 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, "GFXGLTextureObject::copyToBmp - invalid format");
AssertFatal(bmp->getFormat() == GFXFormatR8G8B8A8 || bmp->getFormat() == GFXFormatR8G8B8, "GFXGLTextureObject::copyToBmp - invalid format");
if(mFormat != GFXFormatR8G8B8A8)
AssertFatal(mFormat == GFXFormatR8G8B8A8 || mFormat == GFXFormatR8G8B8A8_SRGB , "GFXGLTextureObject::copyToBmp - invalid format");
AssertFatal(bmp->getFormat() == GFXFormatR8G8B8A8 || bmp->getFormat() == GFXFormatR8G8B8 || bmp->getFormat() == GFXFormatR8G8B8A8_SRGB, "GFXGLTextureObject::copyToBmp - invalid format");
if(mFormat != GFXFormatR8G8B8A8 && mFormat != GFXFormatR8G8B8A8_SRGB)
return false;
if(bmp->getFormat() != GFXFormatR8G8B8A8 && bmp->getFormat() != GFXFormatR8G8B8)
if(bmp->getFormat() != GFXFormatR8G8B8A8 && bmp->getFormat() != GFXFormatR8G8B8 && bmp->getFormat() != GFXFormatR8G8B8A8_SRGB )
return false;
AssertFatal(bmp->getWidth() == getWidth(), "GFXGLTextureObject::copyToBmp - invalid size");
@ -253,7 +257,7 @@ U8* GFXGLTextureObject::getTextureData( U32 mip )
AssertFatal( mMipLevels, "");
mip = (mip < mMipLevels) ? mip : 0;
const U32 dataSize = isCompressedFormat(mFormat)
const U32 dataSize = ImageUtil::isCompressedFormat(mFormat)
? getCompressedSurfaceSize( mFormat, mTextureSize.x, mTextureSize.y, mip )
: (mTextureSize.x >> mip) * (mTextureSize.y >> mip) * mBytesPerTexel;
@ -261,7 +265,7 @@ U8* GFXGLTextureObject::getTextureData( U32 mip )
PRESERVE_TEXTURE(mBinding);
glBindTexture(mBinding, mHandle);
if( isCompressedFormat(mFormat) )
if( ImageUtil::isCompressedFormat(mFormat) )
glGetCompressedTexImage( mBinding, mip, data );
else
glGetTexImage(mBinding, mip, GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], data);

View file

@ -103,7 +103,7 @@ public:
virtual U32 getWidth() { return mTex->getWidth(); }
virtual U32 getHeight() { return mTex->getHeight(); }
virtual U32 getDepth() { return 0; }
virtual bool hasMips() { return mTex->getNumMipLevels() != 1; }
virtual bool hasMips() { return mTex->getMipMapLevels() != 1; }
virtual GLenum getBinding() { return GFXGLCubemap::getEnumForFaceNumber(mFace); }
virtual GFXFormat getFormat() { return mTex->getFormat(); }
virtual bool isCompatible(const GFXGLTextureObject* tex)
@ -162,7 +162,7 @@ void _GFXGLTextureTargetFBOImpl::applyState()
PRESERVE_FRAMEBUFFER();
glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
glEnable(GL_FRAMEBUFFER_SRGB);
bool drawbufs[16];
int bufsize = 0;
for (int i = 0; i < 16; i++)

View file

@ -26,6 +26,7 @@
#include "core/util/preprocessorHelpers.h"
#include "gfx/gl/gfxGLEnumTranslate.h"
#include "gfx/gl/gfxGLStateCache.h"
#include "gfx/bitmap/imageUtils.h"
inline U32 getMaxMipmaps(U32 width, U32 height, U32 depth)
{
@ -59,27 +60,10 @@ inline GLenum minificationFilter(U32 minFilter, U32 mipFilter, U32 /*mipLevels*/
}
}
// Check if format is compressed format.
// Even though dxt2/4 are not supported, they are included because they are a compressed format.
// Assert checks on supported formats are done elsewhere.
inline bool isCompressedFormat( GFXFormat format )
{
bool compressed = false;
if(format == GFXFormatDXT1 || format == GFXFormatDXT2
|| format == GFXFormatDXT3
|| format == GFXFormatDXT4
|| format == GFXFormatDXT5 )
{
compressed = true;
}
return compressed;
}
//Get the surface size of a compressed mip map level - see ddsLoader.cpp
inline U32 getCompressedSurfaceSize(GFXFormat format,U32 width, U32 height, U32 mipLevel=0 )
{
if(!isCompressedFormat(format))
if(!ImageUtil::isCompressedFormat(format))
return 0;
// Bump by the mip level.
@ -87,7 +71,7 @@ inline U32 getCompressedSurfaceSize(GFXFormat format,U32 width, U32 height, U32
width = getMax(U32(1), width >> mipLevel);
U32 sizeMultiple = 0;
if(format == GFXFormatDXT1)
if(format == GFXFormatBC1 || format == GFXFormatBC1_SRGB)
sizeMultiple = 8;
else
sizeMultiple = 16;

View file

@ -36,8 +36,8 @@ GFX_ImplementTextureProfile( BackBufferDepthProfile,
GFXTextureProfile::NONE );
GFXGLWindowTarget::GFXGLWindowTarget(PlatformWindow *win, GFXDevice *d)
: GFXWindowTarget(win), mDevice(d), mContext(NULL), mCopyFBO(0)
, mFullscreenContext(NULL), mBackBufferFBO(0), mSecondaryWindow(false)
: GFXWindowTarget(win), mDevice(d), mContext(NULL), mFullscreenContext(NULL)
, mCopyFBO(0), mBackBufferFBO(0)
{
win->appEvent.notify(this, &GFXGLWindowTarget::_onAppSignal);
}
@ -52,14 +52,7 @@ GFXGLWindowTarget::~GFXGLWindowTarget()
void GFXGLWindowTarget::resetMode()
{
// Do some validation...
bool fullscreen = mWindow->getVideoMode().fullScreen;
if (fullscreen && mSecondaryWindow)
{
AssertFatal(false, "GFXGLWindowTarget::resetMode - Cannot go fullscreen with secondary window!");
}
if(fullscreen != mWindow->isFullscreen())
if(mWindow->getVideoMode().fullScreen != mWindow->isFullscreen())
{
_teardownCurrentMode();
_setupNewMode();
@ -118,9 +111,10 @@ void GFXGLWindowTarget::resolveTo(GFXTextureObject* obj)
inline void GFXGLWindowTarget::_setupAttachments()
{
glBindFramebuffer( GL_FRAMEBUFFER, mBackBufferFBO);
glEnable(GL_FRAMEBUFFER_SRGB);
GFXGL->getOpenglCache()->setCacheBinded(GL_FRAMEBUFFER, mBackBufferFBO);
const Point2I dstSize = getSize();
mBackBufferColorTex.set(dstSize.x, dstSize.y, getFormat(), &PostFxTargetProfile, "backBuffer");
mBackBufferColorTex.set(dstSize.x, dstSize.y, getFormat(), &GFXRenderTargetSRGBProfile, "backBuffer");
GFXGLTextureObject *color = static_cast<GFXGLTextureObject*>(mBackBufferColorTex.getPointer());
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color->getHandle(), 0);
mBackBufferDepthTex.set(dstSize.x, dstSize.y, GFXFormatD24S8, &BackBufferDepthProfile, "backBuffer");

View file

@ -39,7 +39,7 @@ public:
virtual GFXFormat getFormat()
{
// TODO: Fix me!
return GFXFormatR8G8B8A8;
return GFXFormatR8G8B8A8_SRGB;
}
void makeActive();
virtual bool present();
@ -50,9 +50,6 @@ public:
virtual void resolveTo(GFXTextureObject* obj);
void _onAppSignal(WindowId wnd, S32 event);
// create pixel format for the window
void createPixelFormat();
private:
friend class GFXGLDevice;
@ -61,8 +58,6 @@ private:
GFXTexHandle mBackBufferColorTex, mBackBufferDepthTex;
Point2I size;
GFXDevice* mDevice;
/// Is this a secondary window
bool mSecondaryWindow;
void* mContext;
void* mFullscreenContext;
void _teardownCurrentMode();

View file

@ -86,6 +86,7 @@ void GFXGLDevice::enumerateAdapters( Vector<GFXAdapter*> &adapterList )
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, 1);
SDL_GLContext tempContext = SDL_GL_CreateContext( tempWindow );
if( !tempContext )
@ -191,21 +192,19 @@ U32 GFXGLDevice::getTotalVideoMemory()
GFXWindowTarget *GFXGLDevice::allocWindowTarget( PlatformWindow *window )
{
GFXGLWindowTarget* ggwt = new GFXGLWindowTarget(window, this);
AssertFatal(!mContext, "This GFXGLDevice is already assigned to a window");
GFXGLWindowTarget* ggwt = 0;
if( !mContext )
{
// no context, init the device now
init(window->getVideoMode(), window);
ggwt = new GFXGLWindowTarget(window, this);
ggwt->registerResourceWithDevice(this);
ggwt->mContext = mContext;
}
//first window
if (!mContext)
{
init(window->getVideoMode(), window);
ggwt->mSecondaryWindow = false;
}
else
ggwt->mSecondaryWindow = true;
ggwt->registerResourceWithDevice(this);
ggwt->mContext = mContext;
return ggwt;
return ggwt;
}
GFXFence* GFXGLDevice::_createPlatformSpecificFence()

View file

@ -41,12 +41,7 @@ namespace GL
void gglPerformExtensionBinds(void *context)
{
#ifdef TORQUE_OS_WIN
if (!gladLoadWGL(wglGetCurrentDC()))
{
AssertFatal(false, "Unable to load GLAD WGL extensions. Make sure your OpenGL drivers are up to date!");
}
#endif
}
}

View file

@ -255,6 +255,14 @@ void GFXGLDevice::init( const GFXVideoMode &mode, PlatformWindow *window )
HDC hdcGL = GetDC( hwnd );
AssertFatal( hdcGL != NULL, "Failed to create device context" );
// Create pixel format descriptor...
PIXELFORMATDESCRIPTOR pfd;
CreatePixelFormat( &pfd, 32, 0, 0, false ); // 32 bit color... We do not need depth or stencil, OpenGL renders into a FBO and then copy the image to window
if( !SetPixelFormat( hdcGL, ChoosePixelFormat( hdcGL, &pfd ), &pfd ) )
{
AssertFatal( false, "GFXGLDevice::init - cannot get the one and only pixel format we check for." );
}
int OGL_MAJOR = 3;
int OGL_MINOR = 2;
@ -269,7 +277,7 @@ void GFXGLDevice::init( const GFXVideoMode &mode, PlatformWindow *window )
if (!wglMakeCurrent(hdcGL, tempGLRC))
AssertFatal(false, "Couldn't make temp GL context.");
if( gglHasWExtension( ARB_create_context) )
if( gglHasWExtension(hdcGL, ARB_create_context) )
{
int const create_attribs[] = {
WGL_CONTEXT_MAJOR_VERSION_ARB, OGL_MAJOR,
@ -322,21 +330,13 @@ U32 GFXGLDevice::getTotalVideoMemory()
//------------------------------------------------------------------------------
GFXWindowTarget *GFXGLDevice::allocWindowTarget(PlatformWindow *window)
GFXWindowTarget *GFXGLDevice::allocWindowTarget( PlatformWindow *window )
{
AssertFatal(!mContext, "");
init(window->getVideoMode(), window);
GFXGLWindowTarget *ggwt = new GFXGLWindowTarget(window, this);
ggwt->registerResourceWithDevice(this);
ggwt->createPixelFormat();
//first window
if (!mContext)
{
init(window->getVideoMode(), window);
ggwt->mSecondaryWindow = false;
}
else
ggwt->mSecondaryWindow = true;
ggwt->mContext = mContext;
AssertFatal(ggwt->mContext, "GFXGLDevice::allocWindowTarget - failed to allocate window target!");
@ -364,22 +364,6 @@ void GFXGLWindowTarget::_setupNewMode()
{
}
void GFXGLWindowTarget::createPixelFormat()
{
HWND hwnd = GETHWND(mWindow);
// Create a device context
HDC hdcGL = GetDC(hwnd);
AssertFatal(hdcGL != NULL, "GFXGLWindowTarget::createPixelFormat() - Failed to create device context");
// Create pixel format descriptor...
PIXELFORMATDESCRIPTOR pfd;
CreatePixelFormat(&pfd, 32, 0, 0, false); // 32 bit color... We do not need depth or stencil, OpenGL renders into a FBO and then copy the image to window
if (!SetPixelFormat(hdcGL, ChoosePixelFormat(hdcGL, &pfd), &pfd))
{
AssertFatal(false, "GFXGLWindowTarget::createPixelFormat() - cannot get the one and only pixel format we check for.");
}
}
void GFXGLWindowTarget::_makeContextCurrent()
{
HWND hwnd = GETHWND(getWindow());

View file

@ -301,9 +301,9 @@ void color( const ColorI &inColor )
mCurColor = inColor;
}
void color( const ColorF &inColor )
void color( const LinearColorF &inColor )
{
mCurColor = inColor;
mCurColor = LinearColorF(inColor).toColorI();
}
void color3i( U8 red, U8 green, U8 blue )

View file

@ -69,7 +69,7 @@ namespace PrimBuild
inline void vertex3i( S32 x, S32 y, S32 z ) { vertex3f((F32)x, (F32)y, (F32)z); }
void color( const ColorI & );
void color( const ColorF & );
void color( const LinearColorF & );
void color3i( U8 red, U8 green, U8 blue );
void color4i( U8 red, U8 green, U8 blue, U8 alpha );
void color3f( F32 red, F32 green, F32 blue );

View file

@ -100,7 +100,7 @@ void CubemapData::createMap()
{
if( !mCubeFaceFile[i].isEmpty() )
{
if(!mCubeFace[i].set(mCubeFaceFile[i], &GFXDefaultStaticDiffuseProfile, avar("%s() - mCubeFace[%d] (line %d)", __FUNCTION__, i, __LINE__) ))
if(!mCubeFace[i].set(mCubeFaceFile[i], &GFXStaticTextureSRGBProfile, avar("%s() - mCubeFace[%d] (line %d)", __FUNCTION__, i, __LINE__) ))
{
Con::errorf("CubemapData::createMap - Failed to load texture '%s'", mCubeFaceFile[i].c_str());
initSuccess = false;
@ -123,7 +123,7 @@ void CubemapData::updateFaces()
{
if( !mCubeFaceFile[i].isEmpty() )
{
if(!mCubeFace[i].set(mCubeFaceFile[i], &GFXDefaultStaticDiffuseProfile, avar("%s() - mCubeFace[%d] (line %d)", __FUNCTION__, i, __LINE__) ))
if(!mCubeFace[i].set(mCubeFaceFile[i], &GFXStaticTextureProfile, avar("%s() - mCubeFace[%d] (line %d)", __FUNCTION__, i, __LINE__) ))
{
initSuccess = false;
Con::errorf("CubemapData::createMap - Failed to load texture '%s'", mCubeFaceFile[i].c_str());

View file

@ -139,7 +139,7 @@ void DebugDrawer::setupStateBlocks()
mRenderAlpha = GFX->createStateBlock(d);
}
void DebugDrawer::drawBoxOutline(const Point3F &a, const Point3F &b, const ColorF &color)
void DebugDrawer::drawBoxOutline(const Point3F &a, const Point3F &b, const LinearColorF &color)
{
Point3F point0(a.x, a.y, a.z);
Point3F point1(a.x, b.y, a.z);
@ -170,7 +170,7 @@ void DebugDrawer::drawBoxOutline(const Point3F &a, const Point3F &b, const Color
drawLine(point3, point7, color);
}
void DebugDrawer::drawTransformedBoxOutline(const Point3F &a, const Point3F &b, const ColorF &color, const MatrixF& transform)
void DebugDrawer::drawTransformedBoxOutline(const Point3F &a, const Point3F &b, const LinearColorF &color, const MatrixF& transform)
{
Point3F point0(a.x, a.y, a.z);
Point3F point1(a.x, b.y, a.z);
@ -234,16 +234,23 @@ void DebugDrawer::render(bool clear)
// Set up the state block...
GFXStateBlockRef currSB;
if(p->type==DebugPrim::Capsule){
if(p->type==DebugPrim::Capsule)
{
currSB = mRenderAlpha;
}else if(p->useZ){
}
else if(p->useZ)
{
currSB = mRenderZOnSB;
}else{
}
else
{
currSB = mRenderZOffSB;
}
GFX->setStateBlock( currSB );
Point3F d;
const ColorI color = p->color.toColorI();
switch(p->type)
{
@ -265,20 +272,23 @@ void DebugDrawer::render(bool clear)
Point3F &start = p->a, &end = p->b;
Point3F direction = end - start;
F32 length = direction.len();
if( length>ARROW_LENGTH ){
if( length>ARROW_LENGTH )
{
//cylinder with arrow on end
direction *= (1.0f/length);
Point3F baseArrow = end - (direction*ARROW_LENGTH);
GFX->getDrawUtil()->drawCone(currSB->getDesc(), baseArrow, end, ARROW_RADIUS, p->color);
GFX->getDrawUtil()->drawCylinder(currSB->getDesc(), start, baseArrow, CYLINDER_RADIUS, p->color);
}else if( length>0 ){
GFX->getDrawUtil()->drawCone(currSB->getDesc(), baseArrow, end, ARROW_RADIUS, color);
GFX->getDrawUtil()->drawCylinder(currSB->getDesc(), start, baseArrow, CYLINDER_RADIUS, color);
}
else if( length>0 )
{
//short, so just draw arrow
GFX->getDrawUtil()->drawCone(currSB->getDesc(), start, end, ARROW_RADIUS, p->color);
GFX->getDrawUtil()->drawCone(currSB->getDesc(), start, end, ARROW_RADIUS, color);
}
}
break;
case DebugPrim::Capsule:
GFX->getDrawUtil()->drawCapsule(currSB->getDesc(), p->a, p->b.x, p->b.y, p->color);
GFX->getDrawUtil()->drawCapsule(currSB->getDesc(), p->a, p->b.x, p->b.y, color);
break;
case DebugPrim::OutlinedText:
{
@ -288,26 +298,26 @@ void DebugDrawer::render(bool clear)
{
GFX->setClipRect(GFX->getViewport());
Point2I where = Point2I(result.x, result.y);
GFX->getDrawUtil()->setBitmapModulation(p->color2);
//only switch statement that uses p->color2
GFX->getDrawUtil()->setBitmapModulation(p->color2.toColorI());
GFX->getDrawUtil()->drawText(mFont, Point2I(where.x-1, where.y), p->mText);
GFX->getDrawUtil()->drawText(mFont, Point2I(where.x+1, where.y), p->mText);
GFX->getDrawUtil()->drawText(mFont, Point2I(where.x, where.y-1), p->mText);
GFX->getDrawUtil()->drawText(mFont, Point2I(where.x, where.y+1), p->mText);
GFX->getDrawUtil()->setBitmapModulation(p->color);
GFX->getDrawUtil()->setBitmapModulation(color);
GFX->getDrawUtil()->drawText(mFont, where, p->mText);
}
}
break;
case DebugPrim::Box:
d = p->a - p->b;
GFX->getDrawUtil()->drawCube(currSB->getDesc(), d * 0.5, (p->a + p->b) * 0.5, p->color);
GFX->getDrawUtil()->drawCube(currSB->getDesc(), d * 0.5, (p->a + p->b) * 0.5, color);
break;
case DebugPrim::Line:
PrimBuild::begin( GFXLineStrip, 2);
PrimBuild::color(p->color);
PrimBuild::color(color);
PrimBuild::vertex3fv(p->a);
PrimBuild::vertex3fv(p->b);
@ -321,7 +331,7 @@ void DebugDrawer::render(bool clear)
if (MathUtils::mProjectWorldToScreen(p->a, &result, GFX->getViewport(), GFX->getWorldMatrix(), GFX->getProjectionMatrix()))
{
GFX->setClipRect(GFX->getViewport());
GFX->getDrawUtil()->setBitmapModulation(p->color);
GFX->getDrawUtil()->setBitmapModulation(color);
GFX->getDrawUtil()->drawText(mFont, Point2I(result.x, result.y), p->mText);
}
}
@ -346,7 +356,7 @@ void DebugDrawer::render(bool clear)
#endif
}
void DebugDrawer::drawBox(const Point3F &a, const Point3F &b, const ColorF &color)
void DebugDrawer::drawBox(const Point3F &a, const Point3F &b, const LinearColorF &color)
{
if(isFrozen || !isDrawing)
return;
@ -364,7 +374,7 @@ void DebugDrawer::drawBox(const Point3F &a, const Point3F &b, const ColorF &colo
mHead = n;
}
void DebugDrawer::drawLine(const Point3F &a, const Point3F &b, const ColorF &color)
void DebugDrawer::drawLine(const Point3F &a, const Point3F &b, const LinearColorF &color)
{
if(isFrozen || !isDrawing)
return;
@ -382,7 +392,7 @@ void DebugDrawer::drawLine(const Point3F &a, const Point3F &b, const ColorF &col
mHead = n;
}
void DebugDrawer::drawCapsule(const Point3F &a, const F32 &radius, const F32 &height, const ColorF &color)
void DebugDrawer::drawCapsule(const Point3F &a, const F32 &radius, const F32 &height, const LinearColorF &color)
{
if(isFrozen || !isDrawing)
return;
@ -402,7 +412,7 @@ void DebugDrawer::drawCapsule(const Point3F &a, const F32 &radius, const F32 &he
}
void DebugDrawer::drawDirectionLine(const Point3F &a, const Point3F &b, const ColorF &color)
void DebugDrawer::drawDirectionLine(const Point3F &a, const Point3F &b, const LinearColorF &color)
{
if(isFrozen || !isDrawing)
return;
@ -420,7 +430,7 @@ void DebugDrawer::drawDirectionLine(const Point3F &a, const Point3F &b, const Co
mHead = n;
}
void DebugDrawer::drawOutlinedText(const Point3F& pos, const String& text, const ColorF &color, const ColorF &colorOutline)
void DebugDrawer::drawOutlinedText(const Point3F& pos, const String& text, const LinearColorF &color, const LinearColorF &colorOutline)
{
if(isFrozen || !isDrawing)
return;
@ -439,7 +449,7 @@ void DebugDrawer::drawOutlinedText(const Point3F& pos, const String& text, const
mHead = n;
}
void DebugDrawer::drawTri(const Point3F &a, const Point3F &b, const Point3F &c, const ColorF &color)
void DebugDrawer::drawTri(const Point3F &a, const Point3F &b, const Point3F &c, const LinearColorF &color)
{
if(isFrozen || !isDrawing)
return;
@ -458,7 +468,7 @@ void DebugDrawer::drawTri(const Point3F &a, const Point3F &b, const Point3F &c,
mHead = n;
}
void DebugDrawer::drawPolyhedron( const AnyPolyhedron& polyhedron, const ColorF& color )
void DebugDrawer::drawPolyhedron( const AnyPolyhedron& polyhedron, const LinearColorF& color )
{
const PolyhedronData::Edge* edges = polyhedron.getEdges();
const Point3F* points = polyhedron.getPoints();
@ -534,11 +544,11 @@ void DebugDrawer::drawPolyhedronDebugInfo( const AnyPolyhedron& polyhedron, cons
p.convolve( scale );
transform.mulP( p );
drawText( p, String::ToString( "%i: (%.2f, %.2f, %.2f)", i, p.x, p.y, p.z ), ColorF::WHITE );
drawText( p, String::ToString( "%i: (%.2f, %.2f, %.2f)", i, p.x, p.y, p.z ), LinearColorF::WHITE );
}
}
void DebugDrawer::drawText(const Point3F& pos, const String& text, const ColorF &color)
void DebugDrawer::drawText(const Point3F& pos, const String& text, const LinearColorF &color)
{
if(isFrozen || !isDrawing)
return;
@ -571,13 +581,13 @@ void DebugDrawer::setLastZTest(bool enabled)
mHead->useZ = enabled;
}
DefineEngineMethod( DebugDrawer, drawLine, void, ( Point3F a, Point3F b, ColorF color ), ( ColorF::WHITE ),
DefineEngineMethod( DebugDrawer, drawLine, void, ( Point3F a, Point3F b, LinearColorF color ), ( LinearColorF::WHITE ),
"Draws a line primitive between two 3d points." )
{
object->drawLine( a, b, color );
}
DefineEngineMethod( DebugDrawer, drawBox, void, ( Point3F a, Point3F b, ColorF color ), ( ColorF::WHITE ),
DefineEngineMethod( DebugDrawer, drawBox, void, ( Point3F a, Point3F b, LinearColorF color ), ( LinearColorF::WHITE ),
"Draws an axis aligned box primitive within the two 3d points." )
{
object->drawBox( a, b, color );

View file

@ -122,19 +122,19 @@ public:
///
/// @{
void drawBoxOutline(const Point3F &a, const Point3F &b, const ColorF &color = ColorF(1.0f, 1.0f, 1.0f));
void drawTransformedBoxOutline(const Point3F &a, const Point3F &b, const ColorF &color, const MatrixF& transform);
void drawBoxOutline(const Point3F &a, const Point3F &b, const LinearColorF &color = LinearColorF(1.0f, 1.0f, 1.0f));
void drawTransformedBoxOutline(const Point3F &a, const Point3F &b, const LinearColorF &color, const MatrixF& transform);
void drawBox(const Point3F &a, const Point3F &b, const ColorF &color = ColorF(1.0f,1.0f,1.0f));
void drawLine(const Point3F &a, const Point3F &b, const ColorF &color = ColorF(1.0f,1.0f,1.0f));
void drawTri(const Point3F &a, const Point3F &b, const Point3F &c, const ColorF &color = ColorF(1.0f,1.0f,1.0f));
void drawText(const Point3F& pos, const String& text, const ColorF &color = ColorF(1.0f,1.0f,1.0f));
void drawCapsule(const Point3F &a, const F32 &radius, const F32 &height, const ColorF &color = ColorF(1.0f, 1.0f, 1.0f));
void drawDirectionLine(const Point3F &a, const Point3F &b, const ColorF &color = ColorF(1.0f, 1.0f, 1.0f));
void drawOutlinedText(const Point3F& pos, const String& text, const ColorF &color = ColorF(1.0f, 1.0f, 1.0f), const ColorF &colorOutline = ColorF(0.0f, 0.0f, 0.0f));
void drawBox(const Point3F &a, const Point3F &b, const LinearColorF &color = LinearColorF(1.0f,1.0f,1.0f));
void drawLine(const Point3F &a, const Point3F &b, const LinearColorF &color = LinearColorF(1.0f,1.0f,1.0f));
void drawTri(const Point3F &a, const Point3F &b, const Point3F &c, const LinearColorF &color = LinearColorF(1.0f,1.0f,1.0f));
void drawText(const Point3F& pos, const String& text, const LinearColorF &color = LinearColorF(1.0f,1.0f,1.0f));
void drawCapsule(const Point3F &a, const F32 &radius, const F32 &height, const LinearColorF &color = LinearColorF(1.0f, 1.0f, 1.0f));
void drawDirectionLine(const Point3F &a, const Point3F &b, const LinearColorF &color = LinearColorF(1.0f, 1.0f, 1.0f));
void drawOutlinedText(const Point3F& pos, const String& text, const LinearColorF &color = LinearColorF(1.0f, 1.0f, 1.0f), const LinearColorF &colorOutline = LinearColorF(0.0f, 0.0f, 0.0f));
/// Render a wireframe view of the given polyhedron.
void drawPolyhedron( const AnyPolyhedron& polyhedron, const ColorF& color = ColorF( 1.f, 1.f, 1.f ) );
void drawPolyhedron( const AnyPolyhedron& polyhedron, const LinearColorF& color = LinearColorF( 1.f, 1.f, 1.f ) );
/// Render the plane indices, edge indices, edge direction indicators, and point coordinates
/// of the given polyhedron for debugging.
@ -169,8 +169,8 @@ private:
struct DebugPrim
{
/// Color used for this primitive.
ColorF color;
ColorF color2;
LinearColorF color;
LinearColorF color2;
/// Points used to store positional data. Exact semantics determined by type.
Point3F a, b, c;

View file

@ -353,6 +353,9 @@ void GFXSamplerStateData::initPersistFields()
addField("resultArg", TypeGFXTextureArgument, Offset(mState.resultArg, GFXSamplerStateData),
"The selection of the destination register for the result of this stage. The default is GFXTACurrent." );
addField("samplerFunc", TypeGFXCmpFunc, Offset(mState.samplerFunc, GFXSamplerStateData),
"Compares sampled data against existing sampled data. The default is GFXCmpNever.");
}
/// Copies the data of this object into desc