Merge branch 'PBR_ProbeArrayGLWIP' of https://github.com/Azaezel/Torque3D into development

This commit is contained in:
Areloch 2019-05-06 01:50:45 -05:00
commit 82881f0875
407 changed files with 47737 additions and 6168 deletions

View file

@ -31,10 +31,10 @@ GFXD3D11Cubemap::GFXD3D11Cubemap() : mTexture(NULL), mSRView(NULL), mDSView(NULL
mDynamic = false;
mAutoGenMips = false;
mFaceFormat = GFXFormatR8G8B8A8;
for (U32 i = 0; i < CubeFaces; i++)
{
mRTView[i] = NULL;
for(U32 j=0; j < MaxMipMaps; j++)
mRTView[i][j] = NULL;
}
}
@ -50,7 +50,8 @@ void GFXD3D11Cubemap::releaseSurfaces()
for (U32 i = 0; i < CubeFaces; i++)
{
SAFE_RELEASE(mRTView[i]);
for (U32 j = 0; j < MaxMipMaps; j++)
SAFE_RELEASE(mRTView[i][j]);
}
SAFE_RELEASE(mDSView);
@ -93,7 +94,7 @@ void GFXD3D11Cubemap::initStatic(GFXTexHandle *faces)
desc.Width = mTexSize;
desc.Height = mTexSize;
desc.MipLevels = mAutoGenMips ? 0 : mMipMapLevels;
desc.ArraySize = 6;
desc.ArraySize = CubeFaces;
desc.Format = GFXD3D11TextureFormat[mFaceFormat];
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
@ -175,7 +176,7 @@ void GFXD3D11Cubemap::initStatic(DDSFile *dds)
continue;
// convert to Z up
const U32 faceIndex = _zUpFaceIndex(currentFace);
const U32 faceIndex = zUpFaceIndex(currentFace);
for(U32 currentMip = 0; currentMip < mMipMapLevels; currentMip++)
{
@ -209,16 +210,20 @@ void GFXD3D11Cubemap::initStatic(DDSFile *dds)
}
}
void GFXD3D11Cubemap::initDynamic(U32 texSize, GFXFormat faceFormat)
void GFXD3D11Cubemap::initDynamic(U32 texSize, GFXFormat faceFormat, U32 mipLevels)
{
if(!mDynamic)
GFXTextureManager::addEventDelegate(this, &GFXD3D11Cubemap::_onTextureEvent);
mDynamic = true;
mAutoGenMips = true;
mTexSize = texSize;
mFaceFormat = faceFormat;
mMipMapLevels = 0;
if (!mipLevels)
mAutoGenMips = true;
mMipMapLevels = mipLevels;
bool compressed = ImageUtil::isCompressedFormat(mFaceFormat);
UINT bindFlags = D3D11_BIND_SHADER_RESOURCE;
@ -233,7 +238,7 @@ void GFXD3D11Cubemap::initDynamic(U32 texSize, GFXFormat faceFormat)
desc.Width = mTexSize;
desc.Height = mTexSize;
desc.MipLevels = 0;
desc.MipLevels = mMipMapLevels;
desc.ArraySize = 6;
desc.Format = GFXD3D11TextureFormat[mFaceFormat];
desc.SampleDesc.Count = 1;
@ -249,7 +254,7 @@ void GFXD3D11Cubemap::initDynamic(U32 texSize, GFXFormat faceFormat)
D3D11_SHADER_RESOURCE_VIEW_DESC SMViewDesc;
SMViewDesc.Format = GFXD3D11TextureFormat[mFaceFormat];
SMViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
SMViewDesc.TextureCube.MipLevels = -1;
SMViewDesc.TextureCube.MipLevels = mAutoGenMips ? -1 : mMipMapLevels;
SMViewDesc.TextureCube.MostDetailedMip = 0;
hr = D3D11DEVICE->CreateShaderResourceView(mTexture, &SMViewDesc, &mSRView);
@ -274,18 +279,21 @@ void GFXD3D11Cubemap::initDynamic(U32 texSize, GFXFormat faceFormat)
viewDesc.Format = desc.Format;
viewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
viewDesc.Texture2DArray.ArraySize = 1;
viewDesc.Texture2DArray.MipSlice = 0;
for (U32 i = 0; i < CubeFaces; i++)
{
viewDesc.Texture2DArray.FirstArraySlice = i;
hr = D3D11DEVICE->CreateRenderTargetView(mTexture, &viewDesc, &mRTView[i]);
{
viewDesc.Texture2DArray.FirstArraySlice = i;
for (U32 j = 0; j < mMipMapLevels; j++)
{
viewDesc.Texture2DArray.MipSlice = j;
hr = D3D11DEVICE->CreateRenderTargetView(mTexture, &viewDesc, &mRTView[i][j]);
if(FAILED(hr))
{
AssertFatal(false, "GFXD3D11Cubemap::initDynamic - CreateRenderTargetView call failure");
}
}
if (FAILED(hr))
{
AssertFatal(false, "GFXD3D11Cubemap::initDynamic - CreateRenderTargetView call failure");
}
}
}
D3D11_TEXTURE2D_DESC depthTexDesc;
depthTexDesc.Width = mTexSize;
@ -352,16 +360,11 @@ ID3D11ShaderResourceView* GFXD3D11Cubemap::getSRView()
return mSRView;
}
ID3D11RenderTargetView* GFXD3D11Cubemap::getRTView(U32 faceIdx)
ID3D11RenderTargetView* GFXD3D11Cubemap::getRTView(U32 faceIdx, U32 mipIndex)
{
AssertFatal(faceIdx < CubeFaces, "GFXD3D11Cubemap::getRTView - face index out of bounds");
return mRTView[faceIdx];
}
ID3D11RenderTargetView** GFXD3D11Cubemap::getRTViewArray()
{
return mRTView;
return mRTView[faceIdx][mipIndex];
}
ID3D11DepthStencilView* GFXD3D11Cubemap::getDSView()
@ -372,4 +375,197 @@ ID3D11DepthStencilView* GFXD3D11Cubemap::getDSView()
ID3D11Texture2D* GFXD3D11Cubemap::get2DTex()
{
return mTexture;
}
//-----------------------------------------------------------------------------
// Cubemap Array
//-----------------------------------------------------------------------------
GFXD3D11CubemapArray::GFXD3D11CubemapArray() : mTexture(NULL), mSRView(NULL)
{
}
GFXD3D11CubemapArray::~GFXD3D11CubemapArray()
{
SAFE_RELEASE(mSRView);
SAFE_RELEASE(mTexture);
}
//TODO: really need a common private 'init' function to avoid code double up with these init* functions
void GFXD3D11CubemapArray::init(GFXCubemapHandle *cubemaps, const U32 cubemapCount)
{
AssertFatal(cubemaps, "GFXD3D11CubemapArray::initStatic - Got null GFXCubemapHandle!");
AssertFatal(*cubemaps, "GFXD3D11CubemapArray::initStatic - Got empty cubemap!");
//all cubemaps must be the same size,format and number of mipmaps. Grab the details from the first cubemap
mSize = cubemaps[0]->getSize();
mFormat = cubemaps[0]->getFormat();
mMipMapLevels = cubemaps[0]->getMipMapLevels();
mNumCubemaps = cubemapCount;
//create texture object
UINT bindFlags = D3D11_BIND_SHADER_RESOURCE;
UINT miscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
D3D11_TEXTURE2D_DESC desc;
ZeroMemory(&desc, sizeof(D3D11_TEXTURE2D_DESC));
desc.Width = mSize;
desc.Height = mSize;
desc.MipLevels = mMipMapLevels;
desc.ArraySize = CubeFaces * cubemapCount;
desc.Format = GFXD3D11TextureFormat[mFormat];
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = bindFlags;
desc.MiscFlags = miscFlags;
desc.CPUAccessFlags = 0;
HRESULT hr = D3D11DEVICE->CreateTexture2D(&desc, NULL, &mTexture);
if (FAILED(hr))
AssertFatal(false, "GFXD3D11CubemapArray::initStatic - CreateTexture2D failure");
for (U32 i = 0; i < cubemapCount; i++)
{
GFXD3D11Cubemap *cubeObj = static_cast<GFXD3D11Cubemap*>((GFXCubemap*)cubemaps[i]);
//yes checking the first one(cubemap at index 0) is pointless but saves a further if statement
if (cubemaps[i]->getSize() != mSize || cubemaps[i]->getFormat() != mFormat || cubemaps[i]->getMipMapLevels() != mMipMapLevels)
{
Con::printf("Trying to add an invalid Cubemap to a CubemapArray");
//destroy array here first
AssertFatal(false, "GFXD3D11CubemapArray::initStatic - invalid cubemap");
}
for (U32 face = 0; face < CubeFaces; face++)
{
const U32 arraySlice = face + CubeFaces * i;
for (U32 currentMip = 0; currentMip < mMipMapLevels; currentMip++)
{
const U32 srcSubResource = D3D11CalcSubresource(currentMip, face, mMipMapLevels);
const U32 dstSubResource = D3D11CalcSubresource(currentMip, arraySlice, mMipMapLevels);
D3D11DEVICECONTEXT->CopySubresourceRegion(mTexture, dstSubResource, 0, 0, 0, cubeObj->get2DTex(), srcSubResource, NULL);
}
}
}
//create shader resource view
D3D11_SHADER_RESOURCE_VIEW_DESC SMViewDesc;
SMViewDesc.Format = GFXD3D11TextureFormat[mFormat];
SMViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBEARRAY;
SMViewDesc.TextureCubeArray.MipLevels = mMipMapLevels;
SMViewDesc.TextureCubeArray.MostDetailedMip = 0;
SMViewDesc.TextureCubeArray.NumCubes = mNumCubemaps;
SMViewDesc.TextureCubeArray.First2DArrayFace = 0;
hr = D3D11DEVICE->CreateShaderResourceView(mTexture, &SMViewDesc, &mSRView);
if (FAILED(hr))
AssertFatal(false, "GFXD3D11CubemapArray::initStatic - shader resource view creation failure");
}
//Just allocate the cubemap array but we don't upload any data
void GFXD3D11CubemapArray::init(const U32 cubemapCount, const U32 cubemapFaceSize, const GFXFormat format)
{
mSize = cubemapFaceSize;
mMipMapLevels = ImageUtil::getMaxMipCount(cubemapFaceSize, cubemapFaceSize);
mNumCubemaps = cubemapCount;
mFormat = format;
//create texture object
UINT bindFlags = D3D11_BIND_SHADER_RESOURCE;
UINT miscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
D3D11_TEXTURE2D_DESC desc;
ZeroMemory(&desc, sizeof(D3D11_TEXTURE2D_DESC));
desc.Width = mSize;
desc.Height = mSize;
desc.MipLevels = mMipMapLevels;
desc.ArraySize = CubeFaces * cubemapCount;
desc.Format = GFXD3D11TextureFormat[mFormat];
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = bindFlags;
desc.MiscFlags = miscFlags;
desc.CPUAccessFlags = 0;
HRESULT hr = D3D11DEVICE->CreateTexture2D(&desc, NULL, &mTexture);
if (FAILED(hr))
AssertFatal(false, "GFXD3D11CubemapArray::initStatic - CreateTexture2D failure");
//create shader resource view
D3D11_SHADER_RESOURCE_VIEW_DESC SMViewDesc;
SMViewDesc.Format = GFXD3D11TextureFormat[mFormat];
SMViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBEARRAY;
SMViewDesc.TextureCubeArray.MipLevels = mMipMapLevels;
SMViewDesc.TextureCubeArray.MostDetailedMip = 0;
SMViewDesc.TextureCubeArray.NumCubes = mNumCubemaps;
SMViewDesc.TextureCubeArray.First2DArrayFace = 0;
hr = D3D11DEVICE->CreateShaderResourceView(mTexture, &SMViewDesc, &mSRView);
if (FAILED(hr))
AssertFatal(false, "GFXD3D11CubemapArray::initStatic - shader resource view creation failure");
}
void GFXD3D11CubemapArray::updateTexture(const GFXCubemapHandle &cubemap, const U32 slot)
{
AssertFatal(slot <= mNumCubemaps, "GFXD3D11CubemapArray::updateTexture - trying to update a cubemap texture that is out of bounds!");
AssertFatal(mFormat == cubemap->getFormat(), "GFXD3D11CubemapArray::updateTexture - Destination format doesn't match");
AssertFatal(mSize == cubemap->getSize(), "GFXD3D11CubemapArray::updateTexture - Destination size doesn't match");
AssertFatal(mMipMapLevels == cubemap->getMipMapLevels(), "GFXD3D11CubemapArray::updateTexture - Destination mip levels doesn't match");
GFXD3D11Cubemap *pCubeObj = static_cast<GFXD3D11Cubemap*>((GFXCubemap*)cubemap);
ID3D11Resource *pDstRes = pCubeObj->get2DTex();
for (U32 face = 0; face < CubeFaces; face++)
{
const U32 arraySlice = face + CubeFaces * slot;
for (U32 currentMip = 0; currentMip < mMipMapLevels; currentMip++)
{
const U32 srcSubResource = D3D11CalcSubresource(currentMip, face, mMipMapLevels);
const U32 dstSubResource = D3D11CalcSubresource(currentMip, arraySlice, mMipMapLevels);
D3D11DEVICECONTEXT->CopySubresourceRegion(mTexture, dstSubResource, 0, 0, 0, pDstRes, srcSubResource, NULL);
}
}
}
void GFXD3D11CubemapArray::copyTo(GFXCubemapArray *pDstCubemap)
{
AssertFatal(pDstCubemap, "GFXD3D11CubemapArray::copyTo - Got null GFXCubemapArray");
AssertFatal(pDstCubemap->getNumCubemaps() > mNumCubemaps, "GFXD3D11CubemapArray::copyTo - Destination too small");
AssertFatal(pDstCubemap->getFormat() == mFormat, "GFXD3D11CubemapArray::copyTo - Destination format doesn't match");
AssertFatal(pDstCubemap->getSize() == mSize, "GFXD3D11CubemapArray::copyTo - Destination size doesn't match");
AssertFatal(pDstCubemap->getMipMapLevels() == mMipMapLevels, "GFXD3D11CubemapArray::copyTo - Destination mip levels doesn't match");
GFXD3D11CubemapArray *pDstCube = static_cast<GFXD3D11CubemapArray*>(pDstCubemap);
ID3D11Resource *pDstRes = pDstCube->get2DTex();
for (U32 cubeMap = 0; cubeMap < mNumCubemaps; cubeMap++)
{
for (U32 face = 0; face < CubeFaces; face++)
{
const U32 arraySlice = face + CubeFaces * cubeMap;
for (U32 currentMip = 0; currentMip < mMipMapLevels; currentMip++)
{
const U32 subResource = D3D11CalcSubresource(currentMip, arraySlice, mMipMapLevels);
D3D11DEVICECONTEXT->CopySubresourceRegion(pDstRes, subResource, 0, 0, 0, mTexture, subResource, NULL);
}
}
}
}
void GFXD3D11CubemapArray::setToTexUnit(U32 tuNum)
{
D3D11DEVICECONTEXT->PSSetShaderResources(tuNum, 1, &mSRView);
}
void GFXD3D11CubemapArray::zombify()
{
// Static cubemaps are handled by D3D
}
void GFXD3D11CubemapArray::resurrect()
{
// Static cubemaps are handled by D3D
}

View file

@ -29,13 +29,14 @@
#include "gfx/gfxTarget.h"
const U32 CubeFaces = 6;
const U32 MaxMipMaps = 13; //todo this needs a proper static value somewhere to sync up with other classes like GBitmap
class GFXD3D11Cubemap : public GFXCubemap
{
public:
virtual void initStatic( GFXTexHandle *faces );
virtual void initStatic( DDSFile *dds );
virtual void initDynamic( U32 texSize, GFXFormat faceFormat = GFXFormatR8G8B8A8 );
virtual void initDynamic( U32 texSize, GFXFormat faceFormat = GFXFormatR8G8B8A8, U32 mipLevels = 0);
virtual void setToTexUnit( U32 tuNum );
virtual U32 getSize() const { return mTexSize; }
virtual GFXFormat getFormat() const { return mFaceFormat; }
@ -47,10 +48,11 @@ public:
virtual void zombify();
virtual void resurrect();
virtual bool isInitialized() { return mTexture ? true : false; }
// Get functions
ID3D11ShaderResourceView* getSRView();
ID3D11RenderTargetView* getRTView(U32 faceIdx);
ID3D11RenderTargetView** getRTViewArray();
ID3D11RenderTargetView* getRTView(U32 faceIdx, U32 mipIndex=0);
ID3D11DepthStencilView* getDSView();
ID3D11Texture2D* get2DTex();
@ -61,7 +63,7 @@ private:
ID3D11Texture2D* mTexture;
ID3D11ShaderResourceView* mSRView; // for shader resource input
ID3D11RenderTargetView* mRTView[CubeFaces]; // for render targets, 6 faces of the cubemap
ID3D11RenderTargetView* mRTView[CubeFaces][MaxMipMaps]; // for render targets, 6 faces of the cubemap
ID3D11DepthStencilView* mDSView; //render target view for depth stencil
bool mAutoGenMips;
@ -76,4 +78,30 @@ private:
void _onTextureEvent(GFXTexCallbackCode code);
};
class GFXD3D11CubemapArray : public GFXCubemapArray
{
public:
GFXD3D11CubemapArray();
virtual ~GFXD3D11CubemapArray();
virtual void init(GFXCubemapHandle *cubemaps, const U32 cubemapCount);
virtual void init(const U32 cubemapCount, const U32 cubemapFaceSize, const GFXFormat format);
virtual void updateTexture(const GFXCubemapHandle &cubemap, const U32 slot);
virtual void copyTo(GFXCubemapArray *pDstCubemap);
virtual void setToTexUnit(U32 tuNum);
ID3D11ShaderResourceView* getSRView() { return mSRView; }
ID3D11Texture2D* get2DTex() { return mTexture; }
// GFXResource interface
virtual void zombify();
virtual void resurrect();
private:
friend class GFXD3D11TextureTarget;
friend class GFXD3D11Device;
ID3D11Texture2D *mTexture;
ID3D11ShaderResourceView* mSRView; // for shader resource input
};
#endif

View file

@ -38,12 +38,14 @@
#include "gfx/D3D11/screenshotD3D11.h"
#include "materials/shaderData.h"
#include "shaderGen/shaderGen.h"
#include <d3d9.h> //d3dperf
#ifdef TORQUE_DEBUG
#include "d3d11sdklayers.h"
#endif
#pragma comment(lib, "dxgi.lib")
#pragma comment(lib, "d3d9.lib") //d3dperf
#pragma comment(lib, "d3d11.lib")
class GFXPCD3D11RegisterDevice
@ -90,9 +92,6 @@ GFXD3D11Device::GFXD3D11Device(U32 index)
mAdapterIndex = index;
mD3DDevice = NULL;
mD3DDeviceContext = NULL;
mD3DDevice1 = NULL;
mD3DDeviceContext1 = NULL;
mUserAnnotation = NULL;
mVolatileVB = NULL;
mCurrentPB = NULL;
@ -126,7 +125,6 @@ GFXD3D11Device::GFXD3D11Device(U32 index)
mCurrentConstBuffer = NULL;
mOcclusionQuerySupported = false;
mCbufferPartialSupported = false;
mDebugLayers = false;
@ -166,8 +164,6 @@ GFXD3D11Device::~GFXD3D11Device()
SAFE_RELEASE(mDeviceBackBufferView);
SAFE_RELEASE(mDeviceDepthStencil);
SAFE_RELEASE(mDeviceBackbuffer);
SAFE_RELEASE(mUserAnnotation);
SAFE_RELEASE(mD3DDeviceContext1);
SAFE_RELEASE(mD3DDeviceContext);
SAFE_DELETE(mCardProfiler);
@ -185,7 +181,6 @@ GFXD3D11Device::~GFXD3D11Device()
#endif
SAFE_RELEASE(mSwapChain);
SAFE_RELEASE(mD3DDevice1);
SAFE_RELEASE(mD3DDevice);
}
@ -439,6 +434,7 @@ void GFXD3D11Device::init(const GFXVideoMode &mode, PlatformWindow *window)
AssertFatal(window, "GFXD3D11Device::init - must specify a window!");
HWND winHwnd = (HWND)window->getSystemWindow( PlatformWindow::WindowSystem_Windows );
SetFocus(winHwnd);
UINT createDeviceFlags = D3D11_CREATE_DEVICE_SINGLETHREADED | D3D11_CREATE_DEVICE_BGRA_SUPPORT;
#ifdef TORQUE_DEBUG
@ -449,7 +445,7 @@ void GFXD3D11Device::init(const GFXVideoMode &mode, PlatformWindow *window)
DXGI_SWAP_CHAIN_DESC d3dpp = setupPresentParams(mode, winHwnd);
// TODO support at least feature level 10 to match GL
D3D_FEATURE_LEVEL pFeatureLevels[] = { D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0 };
D3D_FEATURE_LEVEL pFeatureLevels[] = { D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1 };
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 and swap chain using the information in the d3dpp struct
@ -489,26 +485,6 @@ void GFXD3D11Device::init(const GFXVideoMode &mode, PlatformWindow *window)
#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)
{
@ -689,9 +665,9 @@ GFXWindowTarget * GFXD3D11Device::allocWindowTarget(PlatformWindow *window)
return gdwt;
}
GFXTextureTarget* GFXD3D11Device::allocRenderToTextureTarget()
GFXTextureTarget* GFXD3D11Device::allocRenderToTextureTarget(bool genMips)
{
GFXD3D11TextureTarget *targ = new GFXD3D11TextureTarget();
GFXD3D11TextureTarget *targ = new GFXD3D11TextureTarget(genMips);
targ->registerResourceWithDevice(this);
return targ;
@ -933,6 +909,25 @@ void GFXD3D11Device::setShaderConstBufferInternal(GFXShaderConstBuffer* buffer)
//-----------------------------------------------------------------------------
void GFXD3D11Device::copyResource(GFXTextureObject *pDst, GFXCubemap *pSrc, const U32 face)
{
AssertFatal(pDst, "GFXD3D11Device::copyResource: Destination texture is null");
AssertFatal(pSrc, "GFXD3D11Device::copyResource: Source cubemap is null");
GFXD3D11TextureObject *pD3DDst = static_cast<GFXD3D11TextureObject*>(pDst);
GFXD3D11Cubemap *pD3DSrc = static_cast<GFXD3D11Cubemap*>(pSrc);
const U32 mipLevels = pD3DSrc->getMipMapLevels();
for (U32 mip = 0; mip < mipLevels; mip++)
{
const U32 srcSubResource = D3D11CalcSubresource(mip, face, mipLevels);
const U32 dstSubResource = D3D11CalcSubresource(mip, 0, mipLevels);
mD3DDeviceContext->CopySubresourceRegion(pD3DDst->get2DTex(), dstSubResource, 0, 0, 0, pD3DSrc->get2DTex(), srcSubResource, NULL);
}
}
//-----------------------------------------------------------------------------
void GFXD3D11Device::clear(U32 flags, const LinearColorF& color, F32 z, U32 stencil)
{
// Make sure we have flushed our render target state.
@ -940,15 +935,22 @@ void GFXD3D11Device::clear(U32 flags, const LinearColorF& color, F32 z, U32 sten
UINT depthstencilFlag = 0;
ID3D11RenderTargetView* rtView = NULL;
//TODO: current support is 5 render targets, clean this up
ID3D11RenderTargetView* rtView[5] = { NULL };
ID3D11DepthStencilView* dsView = NULL;
mD3DDeviceContext->OMGetRenderTargets(1, &rtView, &dsView);
mD3DDeviceContext->OMGetRenderTargets(5, rtView, &dsView);
const FLOAT clearColor[4] = { color.red, color.green, color.blue, color.alpha };
if (flags & GFXClearTarget && rtView)
mD3DDeviceContext->ClearRenderTargetView(rtView, clearColor);
{
for (U32 i = 0; i < 5; i++)
{
if (rtView[i])
mD3DDeviceContext->ClearRenderTargetView(rtView[i], clearColor);
}
}
if (flags & GFXClearZBuffer)
depthstencilFlag |= D3D11_CLEAR_DEPTH;
@ -959,10 +961,30 @@ void GFXD3D11Device::clear(U32 flags, const LinearColorF& color, F32 z, U32 sten
if (depthstencilFlag && dsView)
mD3DDeviceContext->ClearDepthStencilView(dsView, depthstencilFlag, z, stencil);
SAFE_RELEASE(rtView);
for (U32 i = 0; i < 5; i++)
SAFE_RELEASE(rtView[i]);
SAFE_RELEASE(dsView);
}
void GFXD3D11Device::clearColorAttachment(const U32 attachment, const LinearColorF& color)
{
GFXD3D11TextureTarget *pTarget = static_cast<GFXD3D11TextureTarget*>(mCurrentRT.getPointer());
ID3D11RenderTargetView* rtView = NULL;
if (!pTarget)
{
rtView = mDeviceBackBufferView;// we are using the default backbuffer
}
else
{
//attachment + 1 to skip past DepthStencil which is first in the list
rtView = static_cast<ID3D11RenderTargetView*>(pTarget->mTargetViews[attachment + 1]);
}
const FLOAT clearColor[4] = { color.red, color.green, color.blue, color.alpha };
mD3DDeviceContext->ClearRenderTargetView(rtView, clearColor);
}
void GFXD3D11Device::endSceneInternal()
{
mCanCurrentlyRender = false;
@ -1837,32 +1859,38 @@ GFXCubemap * GFXD3D11Device::createCubemap()
return cube;
}
GFXCubemapArray * GFXD3D11Device::createCubemapArray()
{
GFXD3D11CubemapArray* cubeArray = new GFXD3D11CubemapArray();
cubeArray->registerResourceWithDevice(this);
return cubeArray;
}
// Debug events
//------------------------------------------------------------------------------
void GFXD3D11Device::enterDebugEvent(ColorI color, const char *name)
{
if (mUserAnnotation)
{
WCHAR eventName[260];
MultiByteToWideChar(CP_ACP, 0, name, -1, eventName, 260);
mUserAnnotation->BeginEvent(eventName);
}
// BJGFIX
WCHAR eventName[260];
MultiByteToWideChar(CP_ACP, 0, name, -1, eventName, 260);
D3DPERF_BeginEvent(D3DCOLOR_ARGB(color.alpha, color.red, color.green, color.blue),
(LPCWSTR)&eventName);
}
//------------------------------------------------------------------------------
void GFXD3D11Device::leaveDebugEvent()
{
if (mUserAnnotation)
mUserAnnotation->EndEvent();
D3DPERF_EndEvent();
}
//------------------------------------------------------------------------------
void GFXD3D11Device::setDebugMarker(ColorI color, const char *name)
{
if (mUserAnnotation)
{
WCHAR eventName[260];
MultiByteToWideChar(CP_ACP, 0, name, -1, eventName, 260);
mUserAnnotation->SetMarker(eventName);
}
// BJGFIX
WCHAR eventName[260];
MultiByteToWideChar(CP_ACP, 0, name, -1, eventName, 260);
D3DPERF_SetMarker(D3DCOLOR_ARGB(color.alpha, color.red, color.green, color.blue),
(LPCWSTR)&eventName);
}

View file

@ -39,9 +39,6 @@
#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;
@ -71,7 +68,7 @@ private:
virtual void enumerateVideoModes();
virtual GFXWindowTarget *allocWindowTarget(PlatformWindow *window);
virtual GFXTextureTarget *allocRenderToTextureTarget();
virtual GFXTextureTarget *allocRenderToTextureTarget(bool genMips = true);
virtual void enterDebugEvent(ColorI color, const char *name);
virtual void leaveDebugEvent();
@ -129,10 +126,6 @@ protected:
IDXGISwapChain *mSwapChain;
ID3D11Device* mD3DDevice;
ID3D11DeviceContext* mD3DDeviceContext;
// DX 11.1
ID3D11Device1* mD3DDevice1;
ID3D11DeviceContext1* mD3DDeviceContext1;
ID3DUserDefinedAnnotation* mUserAnnotation;
GFXShaderRef mGenericShader[GS_COUNT];
GFXShaderConstBufferRef mGenericShaderBuffer[GS_COUNT];
@ -153,7 +146,6 @@ protected:
DXGI_SAMPLE_DESC mMultisampleDesc;
bool mOcclusionQuerySupported;
bool mCbufferPartialSupported;
U32 mDrawInstancesCount;
@ -237,6 +229,7 @@ public:
U32 getAdaterIndex() const { return mAdapterIndex; }
virtual GFXCubemap *createCubemap();
virtual GFXCubemapArray *createCubemapArray();
virtual F32 getPixelShaderVersion() const { return mPixVersion; }
virtual void setPixelShaderVersion( F32 version ){ mPixVersion = version;}
@ -246,9 +239,16 @@ public:
virtual U32 getNumRenderTargets() const { return 8; }
// }
// Copy methods
// {
virtual void copyResource(GFXTextureObject *pDst, GFXCubemap *pSrc, const U32 face);
// }
// Misc rendering control
// {
virtual void clear( U32 flags, const LinearColorF& color, F32 z, U32 stencil );
virtual void clearColorAttachment(const U32 attachment, const LinearColorF& color);
virtual bool beginSceneInternal();
virtual void endSceneInternal();
@ -297,9 +297,6 @@ 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 reset( DXGI_SWAP_CHAIN_DESC &d3dpp );
@ -325,7 +322,7 @@ public:
// grab the sampler map
const SamplerMap &getSamplersMap() const { return mSamplersMap; }
SamplerMap &getSamplersMap() { return mSamplersMap; }
SamplerMap &getSamplersMap(){ return mSamplersMap; }
};
#endif

View file

@ -67,6 +67,7 @@ void GFXD3D11EnumTranslate::init()
GFXD3D11TextureFormat[GFXFormatR16F] = DXGI_FORMAT_R16_FLOAT;
GFXD3D11TextureFormat[GFXFormatR16G16F] = DXGI_FORMAT_R16G16_FLOAT;
GFXD3D11TextureFormat[GFXFormatR10G10B10A2] = DXGI_FORMAT_R10G10B10A2_UNORM;
GFXD3D11TextureFormat[GFXFormatR11G11B10] = DXGI_FORMAT_R11G11B10_FLOAT;
GFXD3D11TextureFormat[GFXFormatD32] = DXGI_FORMAT_UNKNOWN;
GFXD3D11TextureFormat[GFXFormatD24X8] = DXGI_FORMAT_UNKNOWN;
GFXD3D11TextureFormat[GFXFormatD24S8] = DXGI_FORMAT_D24_UNORM_S8_UINT;

View file

@ -32,7 +32,8 @@
GFXD3D11OcclusionQuery::GFXD3D11OcclusionQuery(GFXDevice *device)
: GFXOcclusionQuery(device),
mQuery(NULL)
mQuery(NULL),
mTesting(false)
{
#ifdef TORQUE_GATHER_METRICS
mTimer = PlatformTimer::create();
@ -73,8 +74,11 @@ bool GFXD3D11OcclusionQuery::begin()
AssertISV(hRes != E_OUTOFMEMORY, "GFXD3D11OcclusionQuery::begin - Out of memory");
}
// Add a begin marker to the command buffer queue.
D3D11DEVICECONTEXT->Begin(mQuery);
if (!mTesting)
{
D3D11DEVICECONTEXT->Begin(mQuery);
mTesting = true;
}
#ifdef TORQUE_GATHER_METRICS
mBeginFrame = GuiTSCtrl::getFrameCount();
@ -90,6 +94,7 @@ void GFXD3D11OcclusionQuery::end()
// Add an end marker to the command buffer queue.
D3D11DEVICECONTEXT->End(mQuery);
mTesting = false;
#ifdef TORQUE_GATHER_METRICS
AssertFatal( mBeginFrame == GuiTSCtrl::getFrameCount(), "GFXD3D11OcclusionQuery::end - ended query on different frame than begin!" );

View file

@ -34,7 +34,7 @@ class GFXD3D11OcclusionQuery : public GFXOcclusionQuery
{
private:
mutable ID3D11Query *mQuery;
bool mTesting;
#ifdef TORQUE_GATHER_METRICS
U32 mBeginFrame;
U32 mTimeSinceEnd;

View file

@ -561,7 +561,7 @@ const String GFXD3D11ShaderConstBuffer::describeSelf() const
GenericConstBufferLayout::ParamDesc pd;
mVertexConstBufferLayout->getDesc(i, pd);
ret += String::ToString(" Constant name: %s", pd.name);
ret += String::ToString(" Constant name: %s", pd.name.c_str());
}
return ret;
@ -1384,7 +1384,8 @@ void GFXD3D11Shader::_buildSamplerShaderConstantHandles( Vector<GFXShaderConstDe
const GFXShaderConstDesc &desc = *iter;
AssertFatal( desc.constType == GFXSCT_Sampler ||
desc.constType == GFXSCT_SamplerCube,
desc.constType == GFXSCT_SamplerCube ||
desc.constType == GFXSCT_SamplerCubeArray,
"GFXD3D11Shader::_buildSamplerShaderConstantHandles - Invalid samplerDescription type!" );
GFXD3D11ShaderConstHandle *handle;

View file

@ -59,15 +59,18 @@ GFXD3D11StateBlock::GFXD3D11StateBlock(const GFXStateBlockDesc& desc)
ZeroMemory(&mBlendDesc, sizeof(D3D11_BLEND_DESC));
mBlendDesc.AlphaToCoverageEnable = false;
mBlendDesc.IndependentBlendEnable = mDesc.separateAlphaBlendEnable;
mBlendDesc.IndependentBlendEnable = false;
mBlendDesc.RenderTarget[0].BlendEnable = mDesc.blendEnable;
//color
mBlendDesc.RenderTarget[0].BlendOp = GFXD3D11BlendOp[mDesc.blendOp];
mBlendDesc.RenderTarget[0].BlendOpAlpha = GFXD3D11BlendOp[mDesc.separateAlphaBlendOp];
mBlendDesc.RenderTarget[0].DestBlend = GFXD3D11Blend[mDesc.blendDest];
mBlendDesc.RenderTarget[0].DestBlendAlpha = GFXD3D11Blend[mDesc.separateAlphaBlendDest];
mBlendDesc.RenderTarget[0].SrcBlend = GFXD3D11Blend[mDesc.blendSrc];
mBlendDesc.RenderTarget[0].SrcBlendAlpha = GFXD3D11Blend[mDesc.separateAlphaBlendSrc];
//alpha
mBlendDesc.RenderTarget[0].BlendOpAlpha = GFXD3D11BlendOp[mDesc.separateAlphaBlendEnable ? mDesc.separateAlphaBlendOp : mDesc.blendOp];
mBlendDesc.RenderTarget[0].SrcBlendAlpha = GFXD3D11Blend[mDesc.separateAlphaBlendEnable ? mDesc.separateAlphaBlendSrc : mDesc.blendSrc];
mBlendDesc.RenderTarget[0].DestBlendAlpha = GFXD3D11Blend[mDesc.separateAlphaBlendEnable ? mDesc.separateAlphaBlendDest : mDesc.blendDest];
//target write mask
mBlendDesc.RenderTarget[0].RenderTargetWriteMask = mColorMask;
HRESULT hr = D3D11DEVICE->CreateBlendState(&mBlendDesc, &mBlendState);

View file

@ -28,7 +28,7 @@
#include "gfx/gfxStringEnumTranslate.h"
#include "windowManager/win32/win32Window.h"
GFXD3D11TextureTarget::GFXD3D11TextureTarget()
GFXD3D11TextureTarget::GFXD3D11TextureTarget(bool genMips)
: mTargetSize( Point2I::Zero ),
mTargetFormat( GFXFormatR8G8B8A8 )
{
@ -39,6 +39,8 @@ GFXD3D11TextureTarget::GFXD3D11TextureTarget()
mTargetViews[i] = NULL;
mTargetSRViews[i] = NULL;
}
mGenMips = genMips;
}
GFXD3D11TextureTarget::~GFXD3D11TextureTarget()
@ -215,7 +217,7 @@ void GFXD3D11TextureTarget::attachTexture( RenderSlot slot, GFXCubemap *tex, U32
mTargets[slot] = cube->get2DTex();
mTargets[slot]->AddRef();
mTargetViews[slot] = cube->getRTView(face);
mTargetViews[slot] = cube->getRTView(face, mipLevel);
mTargetViews[slot]->AddRef();
mTargetSRViews[slot] = cube->getSRView();
mTargetSRViews[slot]->AddRef();
@ -262,6 +264,9 @@ void GFXD3D11TextureTarget::activate()
void GFXD3D11TextureTarget::deactivate()
{
if (!mGenMips)
return;
//re-gen mip maps
for (U32 i = 0; i < 6; i++)
{
@ -347,7 +352,23 @@ GFXFormat GFXD3D11WindowTarget::getFormat()
bool GFXD3D11WindowTarget::present()
{
return (D3D11->getSwapChain()->Present(!D3D11->smDisableVSync, 0) == S_OK);
HRESULT hr = D3D11->getSwapChain()->Present(!D3D11->smDisableVSync, 0);
if (hr == DXGI_ERROR_DEVICE_REMOVED)
{
HRESULT result = D3D11->getDevice()->GetDeviceRemovedReason();
if (result == DXGI_ERROR_DEVICE_HUNG)
AssertFatal(false,"DXGI_ERROR_DEVICE_HUNG");
else if (result == DXGI_ERROR_DEVICE_REMOVED)
AssertFatal(false, "DXGI_ERROR_DEVICE_REMOVED");
else if (result == DXGI_ERROR_DEVICE_RESET)
AssertFatal(false, "DXGI_ERROR_DEVICE_RESET");
else if (result == DXGI_ERROR_DRIVER_INTERNAL_ERROR)
AssertFatal(false, "DXGI_ERROR_DRIVER_INTERNAL_ERROR");
else if (result == DXGI_ERROR_INVALID_CALL)
AssertFatal(false, "DXGI_ERROR_INVALID_CALL");
}
return (hr == S_OK);
}
void GFXD3D11WindowTarget::setImplicitSwapChain()
@ -370,7 +391,6 @@ void GFXD3D11WindowTarget::resetMode()
mSize = Point2I(mPresentationParams.BufferDesc.Width, mPresentationParams.BufferDesc.Height);
mWindow->setSuppressReset(false);
GFX->beginReset();
}
void GFXD3D11WindowTarget::zombify()

View file

@ -51,7 +51,7 @@ class GFXD3D11TextureTarget : public GFXTextureTarget
public:
GFXD3D11TextureTarget();
GFXD3D11TextureTarget(bool genMips);
~GFXD3D11TextureTarget();
// Public interface.

View file

@ -177,25 +177,31 @@ 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 || mFormat == GFXFormatR8G8B8A8_SRGB, "copyToBmp: invalid format");
if (mFormat != GFXFormatR8G8B8A8 && mFormat != GFXFormatR8G8B8A8_LINEAR_FORCE && mFormat != GFXFormatR8G8B8A8_SRGB)
AssertFatal(mFormat == GFXFormatR16G16B16A16F || mFormat == GFXFormatR8G8B8A8 || mFormat == GFXFormatR8G8B8A8_LINEAR_FORCE || mFormat == GFXFormatR8G8B8A8_SRGB, "copyToBmp: invalid format");
if (mFormat != GFXFormatR16G16B16A16F && mFormat != GFXFormatR8G8B8A8 && mFormat != GFXFormatR8G8B8A8_LINEAR_FORCE && mFormat != GFXFormatR8G8B8A8_SRGB)
return false;
PROFILE_START(GFXD3D11TextureObject_copyToBmp);
AssertFatal(bmp->getWidth() == getWidth(), "GFXD3D11TextureObject::copyToBmp - source/dest width does not match");
AssertFatal(bmp->getHeight() == getHeight(), "GFXD3D11TextureObject::copyToBmp - source/dest height does not match");
const U32 width = getWidth();
const U32 height = getHeight();
const U32 mipLevels = getMipLevels();
bmp->setHasTransparency(mHasTransparency);
// set some constants
const U32 sourceBytesPerPixel = 4;
U32 sourceBytesPerPixel = 4;
U32 destBytesPerPixel = 0;
const GFXFormat fmt = bmp->getFormat();
if (fmt == GFXFormatR8G8B8A8 || fmt == GFXFormatR8G8B8A8_LINEAR_FORCE || fmt == GFXFormatR8G8B8A8_SRGB)
bool fp16 = false;//is rgba16f format?
if (fmt == GFXFormatR16G16B16A16F)
{
destBytesPerPixel = 8;
sourceBytesPerPixel = 8;
fp16 = true;
}
else if (fmt == GFXFormatR8G8B8A8 || fmt == GFXFormatR8G8B8A8_LINEAR_FORCE || fmt == GFXFormatR8G8B8A8_SRGB)
destBytesPerPixel = 4;
else if(bmp->getFormat() == GFXFormatR8G8B8)
destBytesPerPixel = 3;
@ -221,52 +227,66 @@ bool GFXD3D11TextureObject::copyToBmp(GBitmap* bmp)
//copy the classes texture to the staging texture
D3D11DEVICECONTEXT->CopyResource(pStagingTexture, mD3DTexture);
//map the staging resource
D3D11_MAPPED_SUBRESOURCE mappedRes;
hr = D3D11DEVICECONTEXT->Map(pStagingTexture, 0, D3D11_MAP_READ, 0, &mappedRes);
if (FAILED(hr))
for (U32 mip = 0; mip < mipLevels; mip++)
{
//cleanup
SAFE_RELEASE(pStagingTexture);
Con::errorf("GFXD3D11TextureObject::copyToBmp - Failed to map staging texture");
return false;
}
// set pointers
const U8* srcPtr = (U8*)mappedRes.pData;
U8* destPtr = bmp->getWritableBits();
// we will want to skip over any D3D cache data in the source texture
const S32 sourceCacheSize = mappedRes.RowPitch - width * sourceBytesPerPixel;
AssertFatal(sourceCacheSize >= 0, "GFXD3D11TextureObject::copyToBmp - cache size is less than zero?");
// copy data into bitmap
for (U32 row = 0; row < height; ++row)
{
for (U32 col = 0; col < width; ++col)
const U32 width = bmp->getWidth(mip);
const U32 height = bmp->getHeight(mip);
//map the staging resource
D3D11_MAPPED_SUBRESOURCE mappedRes;
const U32 subResource = D3D11CalcSubresource(mip, 0, mipLevels);
hr = D3D11DEVICECONTEXT->Map(pStagingTexture, subResource, D3D11_MAP_READ, 0, &mappedRes);
if (FAILED(hr))
{
destPtr[0] = srcPtr[2]; // red
destPtr[1] = srcPtr[1]; // green
destPtr[2] = srcPtr[0]; // blue
if (destBytesPerPixel == 4)
destPtr[3] = srcPtr[3]; // alpha
// go to next pixel in src
srcPtr += sourceBytesPerPixel;
// go to next pixel in dest
destPtr += destBytesPerPixel;
//cleanup
SAFE_RELEASE(pStagingTexture);
Con::errorf("GFXD3D11TextureObject::copyToBmp - Failed to map staging texture");
return false;
}
// skip past the cache data for this row (if any)
srcPtr += sourceCacheSize;
// set pointers
const U8* srcPtr = (U8*)mappedRes.pData;
U8* destPtr = bmp->getWritableBits(mip);
// we will want to skip over any D3D cache data in the source texture
const S32 sourceCacheSize = mappedRes.RowPitch - width * sourceBytesPerPixel;
AssertFatal(sourceCacheSize >= 0, "GFXD3D11TextureObject::copyToBmp - cache size is less than zero?");
// copy data into bitmap
for (U32 row = 0; row < height; ++row)
{
for (U32 col = 0; col < width; ++col)
{
//we can just copy data straight in with RGBA16F format
if (fp16)
{
dMemcpy(destPtr, srcPtr, sizeof(U16) * 4);
}
else
{
destPtr[0] = srcPtr[2]; // red
destPtr[1] = srcPtr[1]; // green
destPtr[2] = srcPtr[0]; // blue
if (destBytesPerPixel == 4)
destPtr[3] = srcPtr[3]; // alpha
}
// go to next pixel in src
srcPtr += sourceBytesPerPixel;
// go to next pixel in dest
destPtr += destBytesPerPixel;
}
// skip past the cache data for this row (if any)
srcPtr += sourceCacheSize;
}
// assert if we stomped or underran memory
AssertFatal(U32(destPtr - bmp->getWritableBits(mip)) == width * height * destBytesPerPixel, "GFXD3D11TextureObject::copyToBmp - memory error");
AssertFatal(U32(srcPtr - (U8*)mappedRes.pData) == height * mappedRes.RowPitch, "GFXD3D11TextureObject::copyToBmp - memory error");
D3D11DEVICECONTEXT->Unmap(pStagingTexture, subResource);
}
// assert if we stomped or underran memory
AssertFatal(U32(destPtr - bmp->getWritableBits()) == width * height * destBytesPerPixel, "GFXD3D11TextureObject::copyToBmp - memory error");
AssertFatal(U32(srcPtr - (U8*)mappedRes.pData) == height * mappedRes.RowPitch, "GFXD3D11TextureObject::copyToBmp - memory error");
D3D11DEVICECONTEXT->Unmap(pStagingTexture, 0);
SAFE_RELEASE(pStagingTexture);
PROFILE_END();

View file

@ -151,7 +151,7 @@ private:
public:
virtual void initStatic( GFXTexHandle *faces ) { };
virtual void initStatic( DDSFile *dds ) { };
virtual void initDynamic( U32 texSize, GFXFormat faceFormat = GFXFormatR8G8B8A8 ) { };
virtual void initDynamic( U32 texSize, GFXFormat faceFormat = GFXFormatR8G8B8A8, U32 mipLevels = 0) { };
virtual U32 getSize() const { return 0; }
virtual GFXFormat getFormat() const { return GFXFormatR8G8B8A8; }
@ -161,6 +161,23 @@ public:
virtual void resurrect() {}
};
class GFXNullCubemapArray : public GFXCubemapArray
{
friend class GFXDevice;
private:
// should only be called by GFXDevice
virtual void setToTexUnit(U32 tuNum) { };
public:
virtual void init(GFXCubemapHandle *cubemaps, const U32 cubemapCount) { };
virtual void init(const U32 cubemapCount, const U32 cubemapFaceSize, const GFXFormat format) { };
virtual void updateTexture(const GFXCubemapHandle &cubemap, const U32 slot) { };
virtual void copyTo(GFXCubemapArray *pDstCubemap) { }
virtual ~GFXNullCubemapArray() {};
virtual void zombify() {}
virtual void resurrect() {}
};
class GFXNullVertexBuffer : public GFXVertexBuffer
{
unsigned char* tempBuf;
@ -295,6 +312,11 @@ GFXCubemap* GFXNullDevice::createCubemap()
return new GFXNullCubemap();
};
GFXCubemapArray* GFXNullDevice::createCubemapArray()
{
return new GFXNullCubemapArray();
};
void GFXNullDevice::enumerateAdapters( Vector<GFXAdapter*> &adapterList )
{
// Add the NULL renderer

View file

@ -129,12 +129,13 @@ protected:
public:
virtual GFXCubemap * createCubemap();
virtual GFXCubemapArray *createCubemapArray();
virtual F32 getFillConventionOffset() const { return 0.0f; };
///@}
virtual GFXTextureTarget *allocRenderToTextureTarget(){return NULL;};
virtual GFXTextureTarget *allocRenderToTextureTarget(bool genMips=true){return NULL;};
virtual GFXWindowTarget *allocWindowTarget(PlatformWindow *window)
{
return new GFXNullWindowTarget();
@ -149,8 +150,9 @@ public:
virtual GFXShader* createShader() { return NULL; };
virtual void copyResource(GFXTextureObject *pDst, GFXCubemap *pSrc, const U32 face) { };
virtual void clear( U32 flags, const LinearColorF& color, F32 z, U32 stencil ) { };
virtual void clearColorAttachment(const U32 attachment, const LinearColorF& color) { };
virtual bool beginSceneInternal() { return true; };
virtual void endSceneInternal() { };

View file

@ -174,9 +174,57 @@ void bitmapExtrudeRGBA_c(const void *srcMip, void *mip, U32 srcHeight, U32 srcWi
}
}
void bitmapExtrudeFPRGBA_c(const void *srcMip, void *mip, U32 srcHeight, U32 srcWidth)
{
const U16 *src = (const U16 *)srcMip;
U16 *dst = (U16 *)mip;
U32 stride = srcHeight != 1 ? (srcWidth) * 8 : 0;
U32 width = srcWidth >> 1;
U32 height = srcHeight >> 1;
if (width == 0) width = 1;
if (height == 0) height = 1;
if (srcWidth != 1)
{
for (U32 y = 0; y < height; y++)
{
for (U32 x = 0; x < width; x++)
{
*dst++ = (U32(*src) + U32(src[4]) + U32(src[stride]) + U32(src[stride + 4]) + 2) >> 2;
src++;
*dst++ = (U32(*src) + U32(src[4]) + U32(src[stride]) + U32(src[stride + 4]) + 2) >> 2;
src++;
*dst++ = (U32(*src) + U32(src[4]) + U32(src[stride]) + U32(src[stride + 4]) + 2) >> 2;
src++;
*dst++ = (U32(*src) + U32(src[4]) + U32(src[stride]) + U32(src[stride + 4]) + 2) >> 2;
src += 5;
}
src += stride; // skip
}
}
else
{
for (U32 y = 0; y < height; y++)
{
*dst++ = (U32(*src) + U32(src[stride]) + 1) >> 1;
src++;
*dst++ = (U32(*src) + U32(src[stride]) + 1) >> 1;
src++;
*dst++ = (U32(*src) + U32(src[stride]) + 1) >> 1;
src++;
*dst++ = (U32(*src) + U32(src[stride]) + 1) >> 1;
src += 5;
src += stride; // skip
}
}
}
void (*bitmapExtrude5551)(const void *srcMip, void *mip, U32 height, U32 width) = bitmapExtrude5551_c;
void (*bitmapExtrudeRGB)(const void *srcMip, void *mip, U32 srcHeight, U32 srcWidth) = bitmapExtrudeRGB_c;
void (*bitmapExtrudeRGBA)(const void *srcMip, void *mip, U32 srcHeight, U32 srcWidth) = bitmapExtrudeRGBA_c;
void (*bitmapExtrudeFPRGBA)(const void *srcMip, void *mip, U32 srcHeight, U32 srcWidth) = bitmapExtrudeFPRGBA_c;
//--------------------------------------------------------------------------

View file

@ -30,6 +30,7 @@
extern void (*bitmapExtrude5551)(const void *srcMip, void *mip, U32 height, U32 width);
extern void (*bitmapExtrudeRGB)(const void *srcMip, void *mip, U32 height, U32 width);
extern void (*bitmapExtrudeRGBA)(const void *srcMip, void *mip, U32 height, U32 width);
extern void(*bitmapExtrudeFPRGBA)(const void *srcMip, void *mip, U32 height, U32 width);
extern void (*bitmapConvertRGB_to_5551)(U8 *src, U32 pixels);
extern void (*bitmapConvertRGB_to_1555)(U8 *src, U32 pixels);
extern void (*bitmapConvertRGB_to_RGBX)( U8 **src, U32 pixels );

View file

@ -0,0 +1,123 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "gfx/bitmap/cubemapSaver.h"
#include "platform/platform.h"
#include "gfx/bitmap/ddsFile.h"
#include "gfx/bitmap/imageUtils.h"
#include "gfx/gfxDevice.h"
#include "gfx/gfxTransformSaver.h"
#include "gfx/gfxTextureManager.h"
#include "materials/shaderData.h"
#include "core/stream/fileStream.h"
#include "math/mathUtils.h"
#include "math/mTransform.h"
namespace CubemapSaver
{
const U32 CubeFaces = 6;
bool save(GFXCubemapHandle cubemap, const Torque::Path &path, GFXFormat compressionFormat)
{
if (!cubemap.isValid())
{
Con::errorf("CubemapSaver: cubemap handle is not valid");
return false;
}
GFXCubemap *pCubemap = cubemap.getPointer();
const U32 faceSize = pCubemap->getSize();
const U32 mipLevels = pCubemap->getMipMapLevels();
GFXFormat targetFmt = pCubemap->getFormat();
//setup render targets
GFXTexHandle pTextures[CubeFaces];
for (U32 face = 0; face < CubeFaces; face++)
{
pTextures[face].set(faceSize, faceSize, targetFmt,
&GFXStaticTextureProfile, avar("%s() - (line %d)", __FUNCTION__, __LINE__),
mipLevels, GFXTextureManager::AA_MATCH_BACKBUFFER);
// yep t3d has funky z up, need to change the face order
GFX->copyResource(pTextures[face], pCubemap, GFXCubemap::zUpFaceIndex(face) );
}
GBitmap *pBitmaps[CubeFaces];
bool error = false;
const bool compressedFormat = ImageUtil::isCompressedFormat(compressionFormat);
const bool hasMips = mipLevels > 1 ? true : false;
for (U32 i = 0; i < CubeFaces; i++)
{
pBitmaps[i] = new GBitmap(faceSize, faceSize, hasMips, targetFmt);
bool result = pTextures[i].copyToBmp(pBitmaps[i]);
if (!result)
{
Con::errorf("CubemapSaver: cubemap number %u failed to copy", i);
error = true;
}
}
if (!error)
{
DDSFile *pDds = DDSFile::createDDSCubemapFileFromGBitmaps(pBitmaps);
if (pDds)
{
// compressed and floating point don't need swizzling
if (!compressedFormat && targetFmt != GFXFormatR16G16B16A16F)
ImageUtil::swizzleDDS(pDds, Swizzles::bgra);
if(compressedFormat)
ImageUtil::ddsCompress(pDds, compressionFormat);
FileStream stream;
stream.open(path, Torque::FS::File::Write);
if (stream.getStatus() == Stream::Ok)
pDds->write(stream);
else
Con::errorf("CubemapSaver: failed to open file stream for file %s", path.getFullPath().c_str());
SAFE_DELETE(pDds);
}
}
//cleanup
for (U32 i = 0; i < CubeFaces; i++)
SAFE_DELETE(pBitmaps[i]);
return true;
}
bool getBitmaps(GFXCubemapHandle cubemap, GFXFormat compressionFormat, GBitmap* faceBitmaps[6])
{
if (!cubemap.isValid())
{
Con::errorf("CubemapSaver: cubemap handle is not valid");
return false;
}
return false;
}
}

View file

@ -0,0 +1,41 @@
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#ifndef _CUBEMAP_SAVER_H_
#define _CUBEMAP_SAVER_H_
#ifndef _GFXCUBEMAP_H_
#include "gfx/gfxCubemap.h"
#endif
#ifndef __RESOURCE_H__
#include "core/resource.h"
#endif
namespace CubemapSaver
{
// save cubemap handle to a dds cubemap with optional compression
bool save(GFXCubemapHandle cubemap, const Torque::Path &path, GFXFormat compressionFormat = GFXFormatR8G8B8A8);
bool getBitmaps(GFXCubemapHandle cubemap, GFXFormat compressionFormat, GBitmap* faceBitmaps[6]);
};
#endif

View file

@ -619,6 +619,7 @@ namespace dds
//float
case D3DFMT_R16F: return GFXFormatR16F;
case D3DFMT_R32F: return GFXFormatR32F;
case D3DFMT_G16R16F: return GFXFormatR16G16F;
case D3DFMT_A16B16G16R16F: return GFXFormatR16G16B16A16F;
case D3DFMT_A32B32G32R32F: return GFXFormatR32G32B32A32F;
//compressed
@ -655,6 +656,7 @@ namespace dds
//float
case DXGI_FORMAT_R16_FLOAT: return GFXFormatR16F;
case DXGI_FORMAT_R32_FLOAT: return GFXFormatR32F;
case DXGI_FORMAT_R16G16_FLOAT: return GFXFormatR16G16F;
case DXGI_FORMAT_R16G16B16A16_FLOAT: return GFXFormatR16G16B16A16F;
case DXGI_FORMAT_R32G32B32A32_FLOAT: return GFXFormatR32G32B32A32F;
//compressed
@ -731,6 +733,7 @@ namespace dds
case D3DFMT_ATI2: return GFXFormatBC5;
case D3DFMT_A16B16G16R16F: return GFXFormatR16G16B16A16F;
case D3DFMT_A32B32G32R32F: return GFXFormatR32G32B32A32F;
case D3DFMT_G16R16F: return GFXFormatR16G16F;
default:
{
Con::errorf("dds::getGFXFormatFourcc: unknown format");
@ -739,6 +742,132 @@ namespace dds
}
}
const U32 getBitsPerPixel(DXGI_FORMAT fmt)
{
switch (fmt)
{
case DXGI_FORMAT_R32G32B32A32_TYPELESS:
case DXGI_FORMAT_R32G32B32A32_FLOAT:
case DXGI_FORMAT_R32G32B32A32_UINT:
case DXGI_FORMAT_R32G32B32A32_SINT:
return 128;
case DXGI_FORMAT_R32G32B32_TYPELESS:
case DXGI_FORMAT_R32G32B32_FLOAT:
case DXGI_FORMAT_R32G32B32_UINT:
case DXGI_FORMAT_R32G32B32_SINT:
return 96;
case DXGI_FORMAT_R16G16B16A16_TYPELESS:
case DXGI_FORMAT_R16G16B16A16_FLOAT:
case DXGI_FORMAT_R16G16B16A16_UNORM:
case DXGI_FORMAT_R16G16B16A16_UINT:
case DXGI_FORMAT_R16G16B16A16_SNORM:
case DXGI_FORMAT_R16G16B16A16_SINT:
case DXGI_FORMAT_R32G32_TYPELESS:
case DXGI_FORMAT_R32G32_FLOAT:
case DXGI_FORMAT_R32G32_UINT:
case DXGI_FORMAT_R32G32_SINT:
case DXGI_FORMAT_R32G8X24_TYPELESS:
case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
return 64;
case DXGI_FORMAT_R10G10B10A2_TYPELESS:
case DXGI_FORMAT_R10G10B10A2_UNORM:
case DXGI_FORMAT_R10G10B10A2_UINT:
case DXGI_FORMAT_R11G11B10_FLOAT:
case DXGI_FORMAT_R8G8B8A8_TYPELESS:
case DXGI_FORMAT_R8G8B8A8_UNORM:
case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
case DXGI_FORMAT_R8G8B8A8_UINT:
case DXGI_FORMAT_R8G8B8A8_SNORM:
case DXGI_FORMAT_R8G8B8A8_SINT:
case DXGI_FORMAT_R16G16_TYPELESS:
case DXGI_FORMAT_R16G16_FLOAT:
case DXGI_FORMAT_R16G16_UNORM:
case DXGI_FORMAT_R16G16_UINT:
case DXGI_FORMAT_R16G16_SNORM:
case DXGI_FORMAT_R16G16_SINT:
case DXGI_FORMAT_R32_TYPELESS:
case DXGI_FORMAT_D32_FLOAT:
case DXGI_FORMAT_R32_FLOAT:
case DXGI_FORMAT_R32_UINT:
case DXGI_FORMAT_R32_SINT:
case DXGI_FORMAT_R24G8_TYPELESS:
case DXGI_FORMAT_D24_UNORM_S8_UINT:
case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:
case DXGI_FORMAT_R8G8_B8G8_UNORM:
case DXGI_FORMAT_G8R8_G8B8_UNORM:
case DXGI_FORMAT_B8G8R8A8_UNORM:
case DXGI_FORMAT_B8G8R8X8_UNORM:
case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
case DXGI_FORMAT_B8G8R8A8_TYPELESS:
case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
case DXGI_FORMAT_B8G8R8X8_TYPELESS:
case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
return 32;
case DXGI_FORMAT_R8G8_TYPELESS:
case DXGI_FORMAT_R8G8_UNORM:
case DXGI_FORMAT_R8G8_UINT:
case DXGI_FORMAT_R8G8_SNORM:
case DXGI_FORMAT_R8G8_SINT:
case DXGI_FORMAT_R16_TYPELESS:
case DXGI_FORMAT_R16_FLOAT:
case DXGI_FORMAT_D16_UNORM:
case DXGI_FORMAT_R16_UNORM:
case DXGI_FORMAT_R16_UINT:
case DXGI_FORMAT_R16_SNORM:
case DXGI_FORMAT_R16_SINT:
case DXGI_FORMAT_B5G6R5_UNORM:
case DXGI_FORMAT_B5G5R5A1_UNORM:
return 16;
case DXGI_FORMAT_R8_TYPELESS:
case DXGI_FORMAT_R8_UNORM:
case DXGI_FORMAT_R8_UINT:
case DXGI_FORMAT_R8_SNORM:
case DXGI_FORMAT_R8_SINT:
case DXGI_FORMAT_A8_UNORM:
return 8;
case DXGI_FORMAT_R1_UNORM:
return 1;
case DXGI_FORMAT_BC1_TYPELESS:
case DXGI_FORMAT_BC1_UNORM:
case DXGI_FORMAT_BC1_UNORM_SRGB:
case DXGI_FORMAT_BC4_TYPELESS:
case DXGI_FORMAT_BC4_UNORM:
case DXGI_FORMAT_BC4_SNORM:
return 4;
case DXGI_FORMAT_BC2_TYPELESS:
case DXGI_FORMAT_BC2_UNORM:
case DXGI_FORMAT_BC2_UNORM_SRGB:
case DXGI_FORMAT_BC3_TYPELESS:
case DXGI_FORMAT_BC3_UNORM:
case DXGI_FORMAT_BC3_UNORM_SRGB:
case DXGI_FORMAT_BC5_TYPELESS:
case DXGI_FORMAT_BC5_UNORM:
case DXGI_FORMAT_BC5_SNORM:
case DXGI_FORMAT_BC6H_TYPELESS:
case DXGI_FORMAT_BC6H_UF16:
case DXGI_FORMAT_BC6H_SF16:
case DXGI_FORMAT_BC7_TYPELESS:
case DXGI_FORMAT_BC7_UNORM:
case DXGI_FORMAT_BC7_UNORM_SRGB:
return 8;
default:
return 0;
}
}
const bool validateHeader(const DDS_HEADER &header)
{
if (header.size != DDS_HEADER_SIZE)

View file

@ -272,7 +272,7 @@ bool DDSFile::readHeader(Stream &s)
mFlags.set(CompressedData);
else
{
mBytesPerPixel = header.ddspf.bpp / 8;
mBytesPerPixel = dds::getBitsPerPixel(dx10header.dxgiFormat) / 8;
mFlags.set(RGBData);
}
@ -294,7 +294,34 @@ bool DDSFile::readHeader(Stream &s)
mFlags.set(CompressedData);
else
{
mBytesPerPixel = header.ddspf.bpp / 8;
switch (header.ddspf.fourCC)
{
case 36: // D3DFMT_A16B16G16R16
mBytesPerPixel = 8;
break;
case 110: // D3DFMT_Q16W16V16U16
mBytesPerPixel = 8;
break;
case 111: // D3DFMT_R16F
mBytesPerPixel = 2;
break;
case 112: // D3DFMT_G16R16F
mBytesPerPixel = 4;
break;
case 113: // D3DFMT_A16B16G16R16F
mBytesPerPixel = 8;
break;
case 114: // D3DFMT_R32F
mBytesPerPixel = 4;
break;
case 115: // D3DFMT_G32R32F
mBytesPerPixel = 8;
break;
case 116: // D3DFMT_A32B32G32R32F
mBytesPerPixel = 16;
break;
}
mFlags.set(RGBData);
}
}
@ -370,8 +397,8 @@ bool DDSFile::read(Stream &s, U32 dropMipCount)
}
// Load all the mips.
for(S32 l=0; l<mMipMapCount; l++)
mSurfaces[i]->readNextMip(this, s, mHeight, mWidth, l, l < dropMipCount );
for(S32 mip=0; mip<mMipMapCount; mip++)
mSurfaces[i]->readNextMip(this, s, mHeight, mWidth, mip, mip < dropMipCount );
}
}
@ -456,6 +483,8 @@ bool DDSFile::writeHeader( Stream &s )
{
surfaceFlags |= DDS_SURFACE_FLAGS_CUBEMAP;
cubemapFlags |= DDS_CUBEMAP_ALLFACES;
if (hasDx10Header)
dx10header.miscFlag = dds::D3D10_RESOURCE_MISC_TEXTURECUBE;
}
//volume texture
@ -712,9 +741,10 @@ DDSFile *DDSFile::createDDSCubemapFileFromGBitmaps(GBitmap **gbmps)
//all cubemaps have the same dimensions and formats
GBitmap *pBitmap = gbmps[0];
if (pBitmap->getFormat() != GFXFormatR8G8B8A8)
GFXFormat fmt = pBitmap->getFormat();
if (fmt != GFXFormatR8G8B8A8 && fmt != GFXFormatR16G16B16A16F)
{
Con::errorf("createDDSCubemapFileFromGBitmaps: Only GFXFormatR8G8B8A8 supported for now");
Con::errorf("createDDSCubemapFileFromGBitmaps: unsupported format");
return NULL;
}

View file

@ -297,12 +297,16 @@ void GBitmap::allocateBitmap(const U32 in_width, const U32 in_height, const bool
case GFXFormatR8G8B8X8:
case GFXFormatR8G8B8A8: mBytesPerPixel = 4;
break;
case GFXFormatL16:
case GFXFormatR5G6B5:
case GFXFormatR5G5B5A1: mBytesPerPixel = 2;
break;
default:
AssertFatal(false, "GBitmap::GBitmap: misunderstood format specifier");
break;
case GFXFormatR16G16B16A16F:
case GFXFormatR16G16B16A16: mBytesPerPixel = 8;
break;
default:
AssertFatal(false, "GBitmap::GBitmap: misunderstood format specifier");
break;
}
// Set up the mip levels, if necessary...
@ -371,9 +375,13 @@ void GBitmap::allocateBitmapWithMips(const U32 in_width, const U32 in_height, co
case GFXFormatR8G8B8X8:
case GFXFormatR8G8B8A8: mBytesPerPixel = 4;
break;
case GFXFormatL16:
case GFXFormatR5G6B5:
case GFXFormatR5G5B5A1: mBytesPerPixel = 2;
break;
case GFXFormatR16G16B16A16F:
case GFXFormatR16G16B16A16: mBytesPerPixel = 8;
break;
default:
AssertFatal(false, "GBitmap::GBitmap: misunderstood format specifier");
break;
@ -447,6 +455,13 @@ void GBitmap::extrudeMipLevels(bool clearBorders)
bitmapExtrudeRGBA(getBits(i - 1), getWritableBits(i), getHeight(i-1), getWidth(i-1));
break;
}
case GFXFormatR16G16B16A16F:
{
for (U32 i = 1; i < mNumMipLevels; i++)
bitmapExtrudeFPRGBA(getBits(i - 1), getWritableBits(i), getHeight(i - 1), getWidth(i - 1));
break;
}
default:
break;
@ -679,6 +694,7 @@ bool GBitmap::checkForTransparency()
{
// Non-transparent formats
case GFXFormatL8:
case GFXFormatL16:
case GFXFormatR8G8B8:
case GFXFormatR5G6B5:
break;
@ -754,7 +770,8 @@ bool GBitmap::getColor(const U32 x, const U32 y, ColorI& rColor) const
case GFXFormatL8:
rColor.set( *pLoc, *pLoc, *pLoc, *pLoc );
break;
case GFXFormatL16:
rColor.set(U8(U16((pLoc[0] << 8) + pLoc[2])), 0, 0, 0);
case GFXFormatR8G8B8:
case GFXFormatR8G8B8X8:
rColor.set( pLoc[0], pLoc[1], pLoc[2], 255 );
@ -803,6 +820,10 @@ bool GBitmap::setColor(const U32 x, const U32 y, const ColorI& rColor)
*pLoc = rColor.alpha;
break;
case GFXFormatL16:
dMemcpy(pLoc, &rColor, 2 * sizeof(U8));
break;
case GFXFormatR8G8B8:
dMemcpy( pLoc, &rColor, 3 * sizeof( U8 ) );
break;
@ -1122,6 +1143,7 @@ bool GBitmap::read(Stream& io_rStream)
break;
case GFXFormatR8G8B8A8: mBytesPerPixel = 4;
break;
case GFXFormatL16:
case GFXFormatR5G6B5:
case GFXFormatR5G5B5A1: mBytesPerPixel = 2;
break;

View file

@ -301,4 +301,9 @@ namespace ImageUtil
return format;
};
}
U32 getMaxMipCount(const U32 width, const U32 height)
{
return mFloor(mLog2(mMax(width, height))) + 1;
}
}

View file

@ -29,6 +29,9 @@
#ifndef _GFXENUMS_H_
#include "gfx/gfxEnums.h"
#endif
#ifndef _MMATHFN_H_
#include "math/mMathFn.h"
#endif
struct DDSFile;
@ -57,6 +60,8 @@ namespace ImageUtil
//convert to sRGB format
GFXFormat toSRGBFormat(const GFXFormat format);
U32 getMaxMipCount(const U32 width, const U32 height);
};
#endif

View file

@ -240,7 +240,7 @@ static bool sReadPNG(Stream &stream, GBitmap *bitmap)
png_set_expand(png_ptr);
if (bit_depth == 16)
format = GFXFormatR5G6B5;
format = GFXFormatL16;
else
format = GFXFormatA8;
}
@ -276,7 +276,7 @@ static bool sReadPNG(Stream &stream, GBitmap *bitmap)
AssertFatal(rowBytes == width * 4,
"Error, our rowbytes are incorrect for this transform... (4)");
}
else if (format == GFXFormatR5G6B5)
else if (format == GFXFormatL16)
{
AssertFatal(rowBytes == width * 2,
"Error, our rowbytes are incorrect for this transform... (2)");

View file

@ -26,6 +26,13 @@
#include "gfx/gfxTextureManager.h"
GFXCubemap::GFXCubemap()
{
mPath = "";
mMipMapLevels = 0;
mInitialized = false;
}
GFXCubemap::~GFXCubemap()
{
// If we're not dynamic and we were loaded from a
@ -35,7 +42,7 @@ GFXCubemap::~GFXCubemap()
TEXMGR->releaseCubemap( this );
}
U32 GFXCubemap::_zUpFaceIndex(const U32 index)
U32 GFXCubemap::zUpFaceIndex(const U32 index)
{
switch (index)
{
@ -124,3 +131,10 @@ bool GFXCubemapHandle::set( const String &cubemapDDS )
return isValid();
}
const String GFXCubemapArray::describeSelf() const
{
// We've got nothing
return String();
}

View file

@ -47,10 +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;
bool mInitialized;
public:
/// Create a static cubemap from a list of 6 face textures.
@ -59,11 +59,12 @@ public:
/// Create a static cubemap from a DDS cubemap file.
virtual void initStatic( DDSFile *dds ) = 0;
///
virtual void initDynamic( U32 texSize, GFXFormat faceFormat = GFXFormatR8G8B8A8 ) = 0;
///create dynamic cubemap. mipLevels 0 is auto create mips, otherwise the value is how many mip levels you wish the cubemap to have
virtual void initDynamic( U32 texSize, GFXFormat faceFormat = GFXFormatR8G8B8A8, U32 mipLevels = 0 ) = 0;
void initNormalize(U32 size);
GFXCubemap();
virtual ~GFXCubemap();
/// Returns the size of the faces.
@ -72,6 +73,9 @@ public:
/// Returns the face texture format.
virtual GFXFormat getFormat() const = 0;
/// Returns if this cubemap has been initialized
virtual bool isInitialized() { return false; }
/// Returns the cubemap file path set at creation.
const String& getPath() const { return mPath; }
@ -81,6 +85,9 @@ public:
/// Get the number of mip maps
const U32 getMipMapLevels() const { return mMipMapLevels; }
/// Get Z up face index of the cubemap. DDS files will be stored Y up
static U32 zUpFaceIndex(const U32 index);
};
@ -99,5 +106,58 @@ public:
void free() { StrongObjectRef::set( NULL ); }
};
/// Cubemap array - data lives on the GPU only with this class, but the data is not immutable so it can be updated
class GFXCubemapArray : public StrongRefBase, public GFXResource
{
friend class GFXDevice;
friend class GFXTextureManager;
protected:
/// should only be called by GFXDevice
virtual void setToTexUnit( U32 tuNum ) = 0;
/// number of cubemaps in the array
U32 mNumCubemaps;
/// cubemap face size
U32 mSize;
/// number of mip levels
U32 mMipMapLevels;
/// format
GFXFormat mFormat;
public:
virtual ~GFXCubemapArray() {};
/// Initialize from an array of cubemaps
virtual void init(GFXCubemapHandle *cubemaps, const U32 cubemapCount) = 0;
/// Initialize cubemapCount number of blank cubemaps in the array
virtual void init(const U32 cubemapCount, const U32 cubemapFaceSize, const GFXFormat format) = 0;
/// Update cubemap in the array
virtual void updateTexture(const GFXCubemapHandle &cubemap, const U32 slot) = 0;
/// Copy this cubemap to another - destination must be same format, same face size & at-least the same size(or larger)
virtual void copyTo(GFXCubemapArray *pDstCubemap) = 0;
/// Return number of textures in the array
const U32 getNumCubemaps() const { return mNumCubemaps; }
/// Get the number of mip maps
const U32 getMipMapLevels() const { return mMipMapLevels; }
/// Returns the size of the faces.
const U32 getSize() const { return mSize; }
/// Returns the format
const GFXFormat getFormat() const { return mFormat; }
virtual const String describeSelf() const;
};
/// A reference counted handle to a cubemap array resource.
class GFXCubemapArrayHandle : public StrongRefPtr<GFXCubemapArray>
{
public:
GFXCubemapArrayHandle() {}
GFXCubemapArrayHandle(GFXCubemapArray *cubemapArray) { StrongRefPtr<GFXCubemapArray>::set(cubemapArray); }
/// Releases the texture handle.
void free() { StrongObjectRef::set(NULL); }
};
#endif // GFXCUBEMAP

View file

@ -131,6 +131,8 @@ GFXDevice::GFXDevice()
mNewTexture[i] = NULL;
mCurrentCubemap[i] = NULL;
mNewCubemap[i] = NULL;
mCurrentCubemapArray[i] = NULL;
mNewCubemapArray[i] = NULL;
mTexType[i] = GFXTDT_Normal;
mTextureMatrix[i].identity();
@ -262,6 +264,8 @@ GFXDevice::~GFXDevice()
mNewTexture[i] = NULL;
mCurrentCubemap[i] = NULL;
mNewCubemap[i] = NULL;
mCurrentCubemapArray[i] = NULL;
mNewCubemapArray[i] = NULL;
}
mCurrentRT = NULL;
@ -398,6 +402,15 @@ void GFXDevice::updateStates(bool forceSetAll /*=false*/)
setTextureInternal(i, NULL);
}
break;
case GFXTDT_CubeArray:
{
mCurrentCubemapArray[i] = mNewCubemapArray[i];
if (mCurrentCubemapArray[i])
mCurrentCubemapArray[i]->setToTexUnit(i);
else
setTextureInternal(i, NULL);
}
break;
default:
AssertFatal(false, "Unknown texture type!");
break;
@ -537,6 +550,15 @@ void GFXDevice::updateStates(bool forceSetAll /*=false*/)
setTextureInternal(i, NULL);
}
break;
case GFXTDT_CubeArray:
{
mCurrentCubemapArray[i] = mNewCubemapArray[i];
if (mCurrentCubemapArray[i])
mCurrentCubemapArray[i]->setToTexUnit(i);
else
setTextureInternal(i, NULL);
}
break;
default:
AssertFatal(false, "Unknown texture type!");
break;
@ -777,30 +799,60 @@ void GFXDevice::setTexture( U32 stage, GFXTextureObject *texture )
// Clear out the cubemaps
mNewCubemap[stage] = NULL;
mCurrentCubemap[stage] = NULL;
mNewCubemapArray[stage] = NULL;
mCurrentCubemapArray[stage] = NULL;
}
//-----------------------------------------------------------------------------
// Set cube texture
//-----------------------------------------------------------------------------
void GFXDevice::setCubeTexture( U32 stage, GFXCubemap *texture )
void GFXDevice::setCubeTexture( U32 stage, GFXCubemap *cubemap )
{
AssertFatal(stage < getNumSamplers(), "GFXDevice::setTexture - out of range stage!");
if ( mTexType[stage] == GFXTDT_Cube &&
( ( mTextureDirty[stage] && mNewCubemap[stage].getPointer() == texture ) ||
( !mTextureDirty[stage] && mCurrentCubemap[stage].getPointer() == texture ) ) )
( ( mTextureDirty[stage] && mNewCubemap[stage].getPointer() == cubemap) ||
( !mTextureDirty[stage] && mCurrentCubemap[stage].getPointer() == cubemap) ) )
return;
mStateDirty = true;
mTexturesDirty = true;
mTextureDirty[stage] = true;
mNewCubemap[stage] = texture;
mNewCubemap[stage] = cubemap;
mTexType[stage] = GFXTDT_Cube;
// Clear out the normal textures
// Clear out textures
mNewTexture[stage] = NULL;
mCurrentTexture[stage] = NULL;
mNewCubemapArray[stage] = NULL;
mCurrentCubemapArray[stage] = NULL;
}
//-----------------------------------------------------------------------------
// Set cube texture array
//-----------------------------------------------------------------------------
void GFXDevice::setCubeArrayTexture(U32 stage, GFXCubemapArray *cubemapArray)
{
AssertFatal(stage < getNumSamplers(), avar("GFXDevice::setTexture - out of range stage! %i>%i", stage, getNumSamplers()));
if (mTexType[stage] == GFXTDT_CubeArray &&
((mTextureDirty[stage] && mNewCubemapArray[stage].getPointer() == cubemapArray) ||
(!mTextureDirty[stage] && mCurrentCubemapArray[stage].getPointer() == cubemapArray)))
return;
mStateDirty = true;
mTexturesDirty = true;
mTextureDirty[stage] = true;
mNewCubemapArray[stage] = cubemapArray;
mTexType[stage] = GFXTDT_CubeArray;
// Clear out textures
mNewTexture[stage] = NULL;
mCurrentTexture[stage] = NULL;
mNewCubemap[stage] = NULL;
mCurrentCubemap[stage] = NULL;
}
//------------------------------------------------------------------------------

View file

@ -497,13 +497,16 @@ protected:
enum TexDirtyType
{
GFXTDT_Normal,
GFXTDT_Cube
GFXTDT_Cube,
GFXTDT_CubeArray
};
GFXTexHandle mCurrentTexture[TEXTURE_STAGE_COUNT];
GFXTexHandle mNewTexture[TEXTURE_STAGE_COUNT];
GFXCubemapHandle mCurrentCubemap[TEXTURE_STAGE_COUNT];
GFXCubemapHandle mNewCubemap[TEXTURE_STAGE_COUNT];
GFXCubemapArrayHandle mCurrentCubemapArray[TEXTURE_STAGE_COUNT];
GFXCubemapArrayHandle mNewCubemapArray[TEXTURE_STAGE_COUNT];
TexDirtyType mTexType[TEXTURE_STAGE_COUNT];
bool mTextureDirty[TEXTURE_STAGE_COUNT];
@ -753,6 +756,7 @@ protected:
public:
virtual GFXCubemap * createCubemap() = 0;
virtual GFXCubemapArray *createCubemapArray() = 0;
inline GFXTextureManager *getTextureManager()
{
@ -778,7 +782,7 @@ public:
/// Allocate a target for doing render to texture operations, with no
/// depth/stencil buffer.
virtual GFXTextureTarget *allocRenderToTextureTarget()=0;
virtual GFXTextureTarget *allocRenderToTextureTarget(bool genMips = true) = 0;
/// Allocate a target for a given window.
virtual GFXWindowTarget *allocWindowTarget(PlatformWindow *window)=0;
@ -809,7 +813,6 @@ public:
virtual U32 getNumRenderTargets() const = 0;
virtual void setShader( GFXShader *shader, bool force = false ) {}
virtual void disableShaders( bool force = false ) {} // TODO Remove when T3D 4.0
/// Set the buffer! (Actual set happens on the next draw call, just like textures, state blocks, etc)
void setShaderConstBuffer(GFXShaderConstBuffer* buffer);
@ -823,11 +826,19 @@ public:
//-----------------------------------------------------------------------------
/// @name Copying methods
/// @{
virtual void copyResource(GFXTextureObject *pDst, GFXCubemap *pSrc, const U32 face) = 0;
/// @}
/// @name Rendering methods
/// @{
///
virtual void clear( U32 flags, const LinearColorF& color, F32 z, U32 stencil ) = 0;
virtual void clearColorAttachment(const U32 attachment, const LinearColorF& color) = 0;
virtual bool beginScene();
virtual void endScene();
virtual void beginField();
@ -938,8 +949,9 @@ public:
/// @{
///
void setTexture(U32 stage, GFXTextureObject*texture);
void setTexture(U32 stage, GFXTextureObject *texture);
void setCubeTexture( U32 stage, GFXCubemap *cubemap );
void setCubeArrayTexture( U32 stage, GFXCubemapArray *cubemapArray);
inline GFXTextureObject* getCurrentTexture( U32 stage ) { return mCurrentTexture[stage]; }
/// @}

View file

@ -188,6 +188,7 @@ enum GFXFormat
GFXFormatR16G16,
GFXFormatR16G16F,
GFXFormatR10G10B10A2,
GFXFormatR11G11B10,
GFXFormatD32,
GFXFormatD24X8,
GFXFormatD24S8,
@ -597,7 +598,8 @@ enum GFXShaderConstType
GFXSCT_Int4,
// Samplers
GFXSCT_Sampler,
GFXSCT_SamplerCube
GFXSCT_SamplerCube,
GFXSCT_SamplerCubeArray
};

View file

@ -196,6 +196,12 @@ public:
///
/// By default, this method will resolve all color targets.
virtual void resolve()=0;
/// Returns true if the automatic generation of mip maps is enabled
inline bool isGenMipsEnabled() const { return mGenMips; }
protected:
bool mGenMips;
};
typedef StrongRefPtr<GFXTarget> GFXTargetRef;

View file

@ -52,6 +52,11 @@ GFXTexHandle::GFXTexHandle( const String &texName, GFXTextureProfile *profile, c
set( texName, profile, desc );
}
GFXTexHandle::GFXTexHandle(const String &texNameR, const String &texNameG, const String &texNameB, const String &texNameA, U32 inputKey[4], GFXTextureProfile *profile, const String &desc)
{
set(texNameR, texNameG, texNameB, texNameA, inputKey, profile, desc);
}
bool GFXTexHandle::set( const String &texName, GFXTextureProfile *profile, const String &desc )
{
// Clear the existing texture first, so that
@ -70,6 +75,24 @@ bool GFXTexHandle::set( const String &texName, GFXTextureProfile *profile, const
return isValid();
}
bool GFXTexHandle::set(const String &texNameR, const String &texNameG, const String &texNameB, const String &texNameA, U32 inputKey[4], GFXTextureProfile *profile, const String &desc)
{
// Clear the existing texture first, so that
// its memory is free for the new allocation.
free();
// Create and set the new texture.
AssertFatal( texNameR.isNotEmpty(), "Texture name is empty" );
StrongObjectRef::set( TEXMGR->createCompositeTexture( texNameR, texNameG, texNameB, texNameA, inputKey, profile ) );
#ifdef TORQUE_DEBUG
if ( getPointer() )
getPointer()->mDebugDescription = desc;
#endif
return isValid();
}
GFXTexHandle::GFXTexHandle( GBitmap *bmp, GFXTextureProfile *profile, bool deleteBmp, const String &desc )
{
set( bmp, profile, deleteBmp, desc );

View file

@ -46,6 +46,10 @@ public:
GFXTexHandle( const String &texName, GFXTextureProfile *profile, const String &desc );
bool set( const String &texName, GFXTextureProfile *profile, const String &desc );
// load composite
GFXTexHandle(const String &texNameR, const String &texNameG, const String &texNameB, const String &texNameA, U32 inputKey[4], GFXTextureProfile *profile, const String &desc);
bool set( const String &texNameR, const String &texNameG, const String &texNameB, const String &texNameA, U32 inputKey[4], GFXTextureProfile *profile, const String &desc );
// register texture
GFXTexHandle( GBitmap *bmp, GFXTextureProfile *profile, bool deleteBmp, const String &desc );
bool set( GBitmap *bmp, GFXTextureProfile *profile, bool deleteBmp, const String &desc );

View file

@ -1122,7 +1122,8 @@ GFXTextureObject *GFXTextureManager::createCompositeTexture(GBitmap*bmp[4], U32
}
U8 rChan, gChan, bChan, aChan;
GBitmap *outBitmap = new GBitmap();
outBitmap->allocateBitmap(bmp[0]->getWidth(), bmp[0]->getHeight(),false, GFXFormatR8G8B8A8);
//pack additional bitmaps into the origional
for (U32 x = 0; x < bmp[0]->getWidth(); x++)
{
@ -1145,7 +1146,7 @@ GFXTextureObject *GFXTextureManager::createCompositeTexture(GBitmap*bmp[4], U32
else
aChan = 255;
bmp[0]->setColor(x, y, ColorI(rChan, gChan, bChan, aChan));
outBitmap->setColor(x, y, ColorI(rChan, gChan, bChan, aChan));
}
}
@ -1153,12 +1154,15 @@ GFXTextureObject *GFXTextureManager::createCompositeTexture(GBitmap*bmp[4], U32
if (cacheHit != NULL)
{
// Con::errorf("Cached texture '%s'", (resourceName.isNotEmpty() ? resourceName.c_str() : "unknown"));
if (deleteBmp)
delete bmp[0];
if (deleteBmp)
{
delete outBitmap;
delete[] bmp;
}
return cacheHit;
}
return _createTexture(bmp[0], resourceName, profile, deleteBmp, NULL);
return _createTexture(outBitmap, resourceName, profile, deleteBmp, NULL);
}
GFXTextureObject* GFXTextureManager::_findPooledTexure( U32 width,

View file

@ -31,7 +31,7 @@
#include "gfx/bitmap/imageUtils.h"
GLenum GFXGLCubemap::faceList[6] =
static GLenum faceList[6] =
{
GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
@ -55,6 +55,11 @@ GFXGLCubemap::~GFXGLCubemap()
GFXTextureManager::removeEventDelegate( this, &GFXGLCubemap::_onTextureEvent );
}
GLenum GFXGLCubemap::getEnumForFaceNumber(U32 face)
{
return faceList[face];
}
void GFXGLCubemap::fillCubeTextures(GFXTexHandle* faces)
{
AssertFatal( faces, "");
@ -126,6 +131,7 @@ void GFXGLCubemap::initStatic(GFXTexHandle* faces)
glGenTextures(1, &mCubemap);
fillCubeTextures(faces);
}
mInitialized = true;
}
void GFXGLCubemap::initStatic( DDSFile *dds )
@ -165,7 +171,7 @@ void GFXGLCubemap::initStatic( DDSFile *dds )
}
// convert to Z up
const U32 faceIndex = _zUpFaceIndex(i);
const U32 faceIndex = zUpFaceIndex(i);
// Now loop thru the mip levels!
for (U32 mip = 0; mip < mMipMapLevels; ++mip)
@ -179,9 +185,10 @@ void GFXGLCubemap::initStatic( DDSFile *dds )
GFXGLTextureFormat[mFaceFormat], GFXGLTextureType[mFaceFormat], dds->mSurfaces[i]->mMips[mip]);
}
}
mInitialized = true;
}
void GFXGLCubemap::initDynamic(U32 texSize, GFXFormat faceFormat)
void GFXGLCubemap::initDynamic(U32 texSize, GFXFormat faceFormat, U32 mipLevels)
{
mDynamicTexSize = texSize;
mFaceFormat = faceFormat;
@ -220,6 +227,7 @@ void GFXGLCubemap::initDynamic(U32 texSize, GFXFormat faceFormat)
if( !isCompressed )
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
mInitialized = true;
}
void GFXGLCubemap::zombify()
@ -277,3 +285,215 @@ void GFXGLCubemap::_onTextureEvent( GFXTexCallbackCode code )
else
tmResurrect();
}
U8* GFXGLCubemap::getTextureData(U32 face, U32 mip)
{
AssertFatal(mMipMapLevels, "");
mip = (mip < mMipMapLevels) ? mip : 0;
const U32 bytesPerTexel = 8; //TODO make work with more formats!!!!!
const U32 dataSize = ImageUtil::isCompressedFormat(mFaceFormat)
? getCompressedSurfaceSize(mFaceFormat, mWidth, mHeight, mip)
: (mWidth >> mip) * (mHeight >> mip) * bytesPerTexel;
U8* data = new U8[dataSize];
PRESERVE_TEXTURE(GL_TEXTURE_CUBE_MAP);
glBindTexture(GL_TEXTURE_CUBE_MAP, mCubemap);
if (ImageUtil::isCompressedFormat(mFaceFormat))
glGetCompressedTexImage(faceList[face], mip, data);
else
glGetTexImage(faceList[face], mip, GFXGLTextureFormat[mFaceFormat], GFXGLTextureType[mFaceFormat], data);
return data;
}
//-----------------------------------------------------------------------------
// Cubemap Array
//-----------------------------------------------------------------------------
GFXGLCubemapArray::GFXGLCubemapArray()
{
}
GFXGLCubemapArray::~GFXGLCubemapArray()
{
glDeleteTextures(1, &mCubemap);
}
//TODO: really need a common private 'init' function to avoid code double up with these init* functions
void GFXGLCubemapArray::init(GFXCubemapHandle *cubemaps, const U32 cubemapCount)
{
AssertFatal(cubemaps, "GFXGLCubemapArray- Got null GFXCubemapHandle!");
AssertFatal(*cubemaps, "GFXGLCubemapArray - Got empty cubemap!");
//all cubemaps must be the same size,format and number of mipmaps. Grab the details from the first cubemap
mSize = cubemaps[0]->getSize();
mFormat = cubemaps[0]->getFormat();
mMipMapLevels = cubemaps[0]->getMipMapLevels();
mNumCubemaps = cubemapCount;
const bool isCompressed = ImageUtil::isCompressedFormat(mFormat);
glGenTextures(1, &mCubemap);
PRESERVE_CUBEMAP_ARRAY_TEXTURE();
glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, mCubemap);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAX_LEVEL, mMipMapLevels - 1);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
for (U32 i = 0; i < cubemapCount; i++)
{
GFXGLCubemap* glTex = static_cast<GFXGLCubemap*>(cubemaps[i].getPointer());
for (U32 face = 0; face < 6; face++)
{
for (U32 currentMip = 0; currentMip < mMipMapLevels; currentMip++)
{
U8 *pixelData = glTex->getTextureData(face, currentMip);
glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, mCubemap);
const U32 mipSize = getMax(U32(1), mSize >> currentMip);
if (isCompressed)
{
const U32 mipDataSize = getCompressedSurfaceSize(mFormat, mSize, mSize, currentMip);
glCompressedTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, currentMip, 0, 0, i * 6 + face, mipSize, mipSize, 1, GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], pixelData);
}
else
{
glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, currentMip, 0, 0, i * 6 + face, mipSize, mipSize, 1, GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], pixelData);
}
glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, 0);
delete[] pixelData;
}
}
}
}
//Just allocate the cubemap array but we don't upload any data
void GFXGLCubemapArray::init(const U32 cubemapCount, const U32 cubemapFaceSize, const GFXFormat format)
{
//all cubemaps must be the same size,format and number of mipmaps. Grab the details from the first cubemap
mSize = cubemapFaceSize;
mFormat = format;
mMipMapLevels = ImageUtil::getMaxMipCount(cubemapFaceSize, cubemapFaceSize);
mNumCubemaps = cubemapCount;
const bool isCompressed = ImageUtil::isCompressedFormat(mFormat);
glGenTextures(1, &mCubemap);
PRESERVE_CUBEMAP_ARRAY_TEXTURE();
glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, mCubemap);
for (U32 i = 0; i < mMipMapLevels; i++)
{
const U32 mipSize = getMax(U32(1), mSize >> i);
glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i, GFXGLTextureInternalFormat[mFormat], mipSize, mipSize, cubemapCount * 6, 0, GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], NULL);
}
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAX_LEVEL, mMipMapLevels - 1);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
}
void GFXGLCubemapArray::updateTexture(const GFXCubemapHandle &cubemap, const U32 slot)
{
AssertFatal(slot <= mNumCubemaps, "GFXD3D11CubemapArray::updateTexture - trying to update a cubemap texture that is out of bounds!");
if (!cubemap->isInitialized())
return;
const bool isCompressed = ImageUtil::isCompressedFormat(mFormat);
GFXGLCubemap* glTex = static_cast<GFXGLCubemap*>(cubemap.getPointer());
for (U32 face = 0; face < 6; face++)
{
for (U32 currentMip = 0; currentMip < mMipMapLevels; currentMip++)
{
U8 *pixelData = glTex->getTextureData(face, currentMip);
glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, mCubemap);
const U32 mipSize = getMax(U32(1), mSize >> currentMip);
if (isCompressed)
{
const U32 mipDataSize = getCompressedSurfaceSize(mFormat, mSize, mSize, currentMip);
glCompressedTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, currentMip, 0, 0, slot * 6 + face, mipSize, mipSize, 1, GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], pixelData);
}
else
{
glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, currentMip, 0, 0, slot * 6 + face, mipSize, mipSize, 1, GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], pixelData);
}
glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, 0);
delete[] pixelData;
}
}
}
void GFXGLCubemapArray::copyTo(GFXCubemapArray *pDstCubemap)
{
AssertFatal(pDstCubemap, "GFXGLCubemapArray::copyTo - Got null GFXCubemapArray");
const U32 dstCount = pDstCubemap->getNumCubemaps();
const GFXFormat dstFmt = pDstCubemap->getFormat();
const U32 dstSize = pDstCubemap->getSize();
const U32 dstMips = pDstCubemap->getMipMapLevels();
AssertFatal(dstCount > mNumCubemaps, "GFXGLCubemapArray::copyTo - Destination too small");
AssertFatal(dstFmt == mFormat, "GFXGLCubemapArray::copyTo - Destination format doesn't match");
AssertFatal(dstSize == mSize, "GFXGLCubemapArray::copyTo - Destination size doesn't match");
AssertFatal(dstMips == mMipMapLevels, "GFXGLCubemapArray::copyTo - Destination mip levels doesn't match");
GFXGLCubemapArray* pDstCube = static_cast<GFXGLCubemapArray*>(pDstCubemap);
for (U32 cubeMap = 0; cubeMap < mNumCubemaps; cubeMap++)
{
for (U32 face = 0; face < CubeFaces; face++)
{
for (U32 currentMip = 0; currentMip < mMipMapLevels; currentMip++)
//U32 currentMip = 0;
{
//U8 *pixelData = pDstCube->get->getTextureData(face, currentMip);
const U32 mipSize = getMax(U32(1), mSize >> currentMip);
/*if (isCompressed)
{
const U32 mipDataSize = getCompressedSurfaceSize(mFormat, mSize, mSize, currentMip);
glCompressedTexImage2D(faceList[face], currentMip, GFXGLTextureInternalFormat[mFormat], mipSize, mipSize, 0, mipDataSize, pixelData);
}
else
{*/ //TODO figure out xyzOffsets
glCopyImageSubData(mCubemap, GL_TEXTURE_CUBE_MAP_ARRAY, currentMip, 0, 0, cubeMap * face, pDstCube->mCubemap, GL_TEXTURE_CUBE_MAP_ARRAY, currentMip, 0, 0, cubeMap * face, mipSize, mipSize, 6);
//glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, mCubemap);
//glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, currentMip, 0, 0, 0, mipSize, mipSize, CubeFaces, GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], pixelData);
//}
//delete[] pixelData;
}
}
}
}
void GFXGLCubemapArray::setToTexUnit(U32 tuNum)
{
static_cast<GFXGLDevice*>(getOwningDevice())->setCubemapArrayInternal(tuNum, this);
}
void GFXGLCubemapArray::bind(U32 textureUnit) const
{
glActiveTexture(GL_TEXTURE0 + textureUnit);
glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, mCubemap);
static_cast<GFXGLDevice*>(getOwningDevice())->getOpenglCache()->setCacheBindedTex(textureUnit, GL_TEXTURE_CUBE_MAP_ARRAY, mCubemap);
GFXGLStateBlockRef sb = static_cast<GFXGLDevice*>(GFX)->getCurrentStateBlock();
AssertFatal(sb, "GFXGLCubemap::bind - No active stateblock!");
if (!sb)
return;
const GFXSamplerStateDesc& ssd = sb->getDesc().samplers[textureUnit];
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, minificationFilter(ssd.minFilter, ssd.mipFilter, 0));
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GFXGLTextureFilter[ssd.magFilter]);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_S, GFXGLTextureAddress[ssd.addressModeU]);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_T, GFXGLTextureAddress[ssd.addressModeV]);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_R, GFXGLTextureAddress[ssd.addressModeW]);
}

View file

@ -30,6 +30,9 @@
#include "core/resource.h"
#endif
const U32 CubeFaces = 6;
const U32 MaxMipMaps = 13; //todo this needs a proper static value somewhere to sync up with other classes like GBitmap
class GFXGLCubemap : public GFXCubemap
{
@ -39,10 +42,12 @@ public:
virtual void initStatic( GFXTexHandle *faces );
virtual void initStatic( DDSFile *dds );
virtual void initDynamic( U32 texSize, GFXFormat faceFormat = GFXFormatR8G8B8A8 );
virtual void initDynamic( U32 texSize, GFXFormat faceFormat = GFXFormatR8G8B8A8, U32 mipLevels = 0);
virtual U32 getSize() const { return mWidth; }
virtual GFXFormat getFormat() const { return mFaceFormat; }
virtual bool isInitialized() { return mCubemap != 0 ? true : false; }
// Convenience methods for GFXGLTextureTarget
U32 getWidth() { return mWidth; }
U32 getHeight() { return mHeight; }
@ -55,7 +60,11 @@ public:
/// Called by texCB; this is to ensure that all textures have been resurrected before we attempt to res the cubemap.
void tmResurrect();
static GLenum getEnumForFaceNumber(U32 face) { return faceList[face]; } ///< Performs lookup to get a GLenum for the given face number
static GLenum getEnumForFaceNumber(U32 face);///< Performs lookup to get a GLenum for the given face number
/// @return An array containing the texture data
/// @note You are responsible for deleting the returned data! (Use delete[])
U8* getTextureData(U32 face, U32 mip = 0);
protected:
@ -85,7 +94,29 @@ protected:
virtual void bind(U32 textureUnit) const; ///< Notifies our owning device that we want to be set to the given texture unit (used for GL internal state tracking)
void fillCubeTextures(GFXTexHandle* faces); ///< Copies the textures in faces into the cubemap
static GLenum faceList[6]; ///< Lookup table
};
class GFXGLCubemapArray : public GFXCubemapArray
{
public:
GFXGLCubemapArray();
virtual ~GFXGLCubemapArray();
//virtual void initStatic(GFXCubemapHandle *cubemaps, const U32 cubemapCount);
virtual void init(GFXCubemapHandle *cubemaps, const U32 cubemapCount);
virtual void init(const U32 cubemapCount, const U32 cubemapFaceSize, const GFXFormat format);
virtual void updateTexture(const GFXCubemapHandle &cubemap, const U32 slot);
virtual void copyTo(GFXCubemapArray *pDstCubemap);
virtual void setToTexUnit(U32 tuNum);
// GFXResource interface
virtual void zombify() {}
virtual void resurrect() {}
protected:
friend class GFXGLDevice;
void bind(U32 textureUnit) const;
GLuint mCubemap; ///< Internal GL handle
};
#endif

View file

@ -448,6 +448,13 @@ GFXCubemap* GFXGLDevice::createCubemap()
return cube;
};
GFXCubemapArray *GFXGLDevice::createCubemapArray()
{
GFXGLCubemapArray* cubeArray = new GFXGLCubemapArray();
cubeArray->registerResourceWithDevice(this);
return cubeArray;
}
void GFXGLDevice::endSceneInternal()
{
// nothing to do for opengl
@ -495,6 +502,12 @@ void GFXGLDevice::clear(U32 flags, const LinearColorF& color, F32 z, U32 stencil
glStencilMask(desc->stencilWriteMask);
}
void GFXGLDevice::clearColorAttachment(const U32 attachment, const LinearColorF& color)
{
const GLfloat clearColor[4] = { color.red, color.green, color.blue, color.alpha };
glClearBufferfv(GL_COLOR, attachment, clearColor);
}
// Given a primitive type and a number of primitives, return the number of indexes/vertexes used.
inline GLsizei GFXGLDevice::primCountToIndexCount(GFXPrimitiveType primType, U32 primitiveCount)
{
@ -669,6 +682,22 @@ void GFXGLDevice::setCubemapInternal(U32 textureUnit, const GFXGLCubemap* textur
}
}
void GFXGLDevice::setCubemapArrayInternal(U32 textureUnit, const GFXGLCubemapArray* texture)
{
if (texture)
{
mActiveTextureType[textureUnit] = GL_TEXTURE_CUBE_MAP_ARRAY;
texture->bind(textureUnit);
}
else if (mActiveTextureType[textureUnit] != GL_ZERO)
{
glActiveTexture(GL_TEXTURE0 + textureUnit);
glBindTexture(mActiveTextureType[textureUnit], 0);
getOpenglCache()->setCacheBindedTex(textureUnit, mActiveTextureType[textureUnit], 0);
mActiveTextureType[textureUnit] = GL_ZERO;
}
}
void GFXGLDevice::setMatrix( GFXMatrixType mtype, const MatrixF &mat )
{
// ONLY NEEDED ON FFP
@ -749,9 +778,9 @@ void GFXGLDevice::setStateBlockInternal(GFXStateBlock* block, bool force)
//------------------------------------------------------------------------------
GFXTextureTarget * GFXGLDevice::allocRenderToTextureTarget()
GFXTextureTarget * GFXGLDevice::allocRenderToTextureTarget(bool genMips)
{
GFXGLTextureTarget *targ = new GFXGLTextureTarget();
GFXGLTextureTarget *targ = new GFXGLTextureTarget(genMips);
targ->registerResourceWithDevice(this);
return targ;
}

View file

@ -39,6 +39,7 @@ class GFXGLVertexBuffer;
class GFXGLPrimitiveBuffer;
class GFXGLTextureTarget;
class GFXGLCubemap;
class GFXGLCubemapArray;
class GFXGLStateCache;
class GFXGLVertexDecl;
@ -81,6 +82,7 @@ public:
virtual U32 getTotalVideoMemory();
virtual GFXCubemap * createCubemap();
virtual GFXCubemapArray *createCubemapArray();
virtual F32 getFillConventionOffset() const { return 0.0f; }
@ -91,7 +93,7 @@ public:
/// @{
///
virtual GFXTextureTarget *allocRenderToTextureTarget();
virtual GFXTextureTarget *allocRenderToTextureTarget(bool genMips = true);
virtual GFXWindowTarget *allocWindowTarget(PlatformWindow *window);
virtual void _updateRenderTargets();
@ -115,8 +117,10 @@ public:
virtual U32 getNumRenderTargets() const;
virtual GFXShader* createShader();
//TODO: implement me!
virtual void copyResource(GFXTextureObject *pDst, GFXCubemap *pSrc, const U32 face) {};
virtual void clear( U32 flags, const LinearColorF& color, F32 z, U32 stencil );
virtual void clearColorAttachment(const U32 attachment, const LinearColorF& color);
virtual bool beginSceneInternal();
virtual void endSceneInternal();
@ -167,7 +171,8 @@ protected:
virtual void setShaderConstBufferInternal(GFXShaderConstBuffer* buffer);
virtual void setTextureInternal(U32 textureUnit, const GFXTextureObject*texture);
virtual void setCubemapInternal(U32 cubemap, const GFXGLCubemap* texture);
virtual void setCubemapInternal(U32 textureUnit, const GFXGLCubemap* texture);
virtual void setCubemapArrayInternal(U32 textureUnit, const GFXGLCubemapArray* texture);
virtual void setLightInternal(U32 lightStage, const GFXLightInfo light, bool lightEnable);
virtual void setLightMaterialInternal(const GFXLightMaterial mat);
@ -204,11 +209,12 @@ private:
friend class GFXGLTextureObject;
friend class GFXGLCubemap;
friend class GFXGLCubemapArray;
friend class GFXGLWindowTarget;
friend class GFXGLPrimitiveBuffer;
friend class GFXGLVertexBuffer;
static GFXAdapter::CreateDeviceInstanceDelegate mCreateDeviceInstance;
static GFXAdapter::CreateDeviceInstanceDelegate mCreateDeviceInstance;
U32 mAdapterIndex;

View file

@ -138,6 +138,7 @@ void GFXGLEnumTranslate::init()
GFXGLTextureInternalFormat[GFXFormatR8G8B8X8] = GL_RGBA8;
GFXGLTextureInternalFormat[GFXFormatB8G8R8A8] = GL_RGBA8;
GFXGLTextureInternalFormat[GFXFormatR10G10B10A2] = GL_RGB10_A2;
GFXGLTextureInternalFormat[GFXFormatR11G11B10] = GL_R11F_G11F_B10F;
GFXGLTextureInternalFormat[GFXFormatD32] = GL_DEPTH_COMPONENT32;
GFXGLTextureInternalFormat[GFXFormatD24X8] = GL_DEPTH24_STENCIL8;
GFXGLTextureInternalFormat[GFXFormatD24S8] = GL_DEPTH24_STENCIL8;
@ -165,6 +166,7 @@ void GFXGLEnumTranslate::init()
GFXGLTextureFormat[GFXFormatR8G8B8X8] = GL_RGBA;
GFXGLTextureFormat[GFXFormatB8G8R8A8] = GL_BGRA;
GFXGLTextureFormat[GFXFormatR10G10B10A2] = GL_RGBA;
GFXGLTextureFormat[GFXFormatR11G11B10] = GL_RGB;
GFXGLTextureFormat[GFXFormatD32] = GL_DEPTH_COMPONENT;
GFXGLTextureFormat[GFXFormatD24X8] = GL_DEPTH_STENCIL;
GFXGLTextureFormat[GFXFormatD24S8] = GL_DEPTH_STENCIL;
@ -192,6 +194,7 @@ void GFXGLEnumTranslate::init()
GFXGLTextureType[GFXFormatR8G8B8X8] = GL_UNSIGNED_BYTE;
GFXGLTextureType[GFXFormatB8G8R8A8] = GL_UNSIGNED_BYTE;;
GFXGLTextureType[GFXFormatR10G10B10A2] = GL_UNSIGNED_INT_10_10_10_2;
GFXGLTextureType[GFXFormatR11G11B10] = GL_UNSIGNED_INT_10F_11F_11F_REV;
GFXGLTextureType[GFXFormatD32] = GL_UNSIGNED_INT;
GFXGLTextureType[GFXFormatD24X8] = GL_UNSIGNED_INT_24_8;
GFXGLTextureType[GFXFormatD24S8] = GL_UNSIGNED_INT_24_8;

View file

@ -25,7 +25,9 @@
#include "gfx/gl/tGL/tGL.h"
GFXGLOcclusionQuery::GFXGLOcclusionQuery(GFXDevice* device) :
GFXOcclusionQuery(device), mQuery(-1)
GFXOcclusionQuery(device),
mQuery(-1),
mTesting(false)
{
}
@ -37,16 +39,29 @@ GFXGLOcclusionQuery::~GFXGLOcclusionQuery()
bool GFXGLOcclusionQuery::begin()
{
if(mQuery == -1)
if (GFXDevice::getDisableOcclusionQuery())
return true;
if (!glIsQuery(mQuery))
glGenQueries(1, &mQuery);
glBeginQuery(GL_SAMPLES_PASSED, mQuery);
if (!mTesting)
{
glBeginQuery(GL_SAMPLES_PASSED, mQuery);
mTesting = true;
}
return true;
}
void GFXGLOcclusionQuery::end()
{
if (GFXDevice::getDisableOcclusionQuery())
return;
if (!glIsQuery(mQuery))
return;
glEndQuery(GL_SAMPLES_PASSED);
mTesting = false;
}
GFXOcclusionQuery::OcclusionQueryStatus GFXGLOcclusionQuery::getStatus(bool block, U32* data)
@ -55,16 +70,33 @@ GFXOcclusionQuery::OcclusionQueryStatus GFXGLOcclusionQuery::getStatus(bool bloc
// then your system is GPU bound.
PROFILE_SCOPE(GFXGLOcclusionQuery_getStatus);
if(mQuery == -1)
if (GFXDevice::getDisableOcclusionQuery())
return NotOccluded;
if (!glIsQuery(mQuery))
return NotOccluded;
GLint numPixels = 0;
GLint queryDone = false;
if (block)
queryDone = true;
{
while (!queryDone)
{
//If we're stalled out, proceed with worst-case scenario -BJR
if (GFX->mFrameTime->getElapsedMs()>4)
{
this->begin();
this->end();
return NotOccluded;
}
glGetQueryObjectiv(mQuery, GL_QUERY_RESULT_AVAILABLE, &queryDone);
}
}
else
{
glGetQueryObjectiv(mQuery, GL_QUERY_RESULT_AVAILABLE, &queryDone);
}
if (queryDone)
glGetQueryObjectiv(mQuery, GL_QUERY_RESULT, &numPixels);

View file

@ -44,6 +44,7 @@ public:
private:
U32 mQuery;
bool mTesting;
};
#endif // _GFX_GL_OCCLUSIONQUERY_H_

View file

@ -80,6 +80,7 @@ static U32 shaderConstTypeSize(GFXShaderConstType type)
case GFXSCT_Int:
case GFXSCT_Sampler:
case GFXSCT_SamplerCube:
case GFXSCT_SamplerCubeArray:
return 4;
case GFXSCT_Float2:
case GFXSCT_Int2:
@ -625,6 +626,9 @@ void GFXGLShader::initConstantDescs()
case GL_SAMPLER_CUBE:
desc.constType = GFXSCT_SamplerCube;
break;
case GL_SAMPLER_CUBE_MAP_ARRAY:
desc.constType = GFXSCT_SamplerCubeArray;
break;
default:
AssertFatal(false, "GFXGLShader::initConstantDescs - unrecognized uniform type");
// If we don't recognize the constant don't add its description.
@ -656,7 +660,7 @@ void GFXGLShader::initHandles()
HandleMap::Iterator handle = mHandles.find(desc.name);
S32 sampler = -1;
if(desc.constType == GFXSCT_Sampler || desc.constType == GFXSCT_SamplerCube)
if(desc.constType == GFXSCT_Sampler || desc.constType == GFXSCT_SamplerCube || desc.constType == GFXSCT_SamplerCubeArray)
{
S32 idx = mSamplerNamesOrdered.find_next(desc.name);
AssertFatal(idx != -1, "");
@ -699,7 +703,7 @@ void GFXGLShader::initHandles()
for (HandleMap::Iterator iter = mHandles.begin(); iter != mHandles.end(); ++iter)
{
GFXGLShaderConstHandle* handle = iter->value;
if(handle->isValid() && (handle->getType() == GFXSCT_Sampler || handle->getType() == GFXSCT_SamplerCube))
if(handle->isValid() && (handle->getType() == GFXSCT_Sampler || handle->getType() == GFXSCT_SamplerCube || handle->getType() == GFXSCT_SamplerCubeArray))
{
// Set sampler number on our program.
glUniform1i(handle->mLocation, handle->mSamplerNum);
@ -831,6 +835,7 @@ void GFXGLShader::setConstantsFromBuffer(GFXGLShaderConstBuffer* buffer)
case GFXSCT_Int:
case GFXSCT_Sampler:
case GFXSCT_SamplerCube:
case GFXSCT_SamplerCubeArray:
glUniform1iv(handle->mLocation, handle->mDesc.arraySize, (GLint*)(mConstBuffer + handle->mOffset));
break;
case GFXSCT_Int2:

View file

@ -20,11 +20,11 @@ public:
class TextureUnit
{
public:
TextureUnit() : mTexture1D(0), mTexture2D(0), mTexture3D(0), mTextureCube(0)
TextureUnit() : mTexture1D(0), mTexture2D(0), mTexture3D(0), mTextureCube(0), mTextureCubeArray(0)
{
}
GLuint mTexture1D, mTexture2D, mTexture3D, mTextureCube;
GLuint mTexture1D, mTexture2D, mTexture3D, mTextureCube, mTextureCubeArray;
};
/// after glBindTexture
@ -45,6 +45,9 @@ public:
case GL_TEXTURE_CUBE_MAP:
mTextureUnits[mActiveTexture].mTextureCube = handle;
break;
case GL_TEXTURE_CUBE_MAP_ARRAY:
mTextureUnits[mActiveTexture].mTextureCubeArray = handle;
break;
default:
AssertFatal(0, avar("GFXGLStateCache::setCacheBindedTex - binding (%x) not supported.", biding) );
return;
@ -68,6 +71,9 @@ public:
case GL_TEXTURE_CUBE_MAP:
mTextureUnits[mActiveTexture].mTextureCube = handle;
break;
case GL_TEXTURE_CUBE_MAP_ARRAY:
mTextureUnits[mActiveTexture].mTextureCubeArray = handle;
break;
case GL_FRAMEBUFFER:
mBindedFBO_W = mBindedFBO_R = handle;
break;
@ -101,6 +107,8 @@ public:
return mTextureUnits[mActiveTexture].mTexture1D;
case GL_TEXTURE_CUBE_MAP:
return mTextureUnits[mActiveTexture].mTextureCube;
case GL_TEXTURE_CUBE_MAP_ARRAY:
return mTextureUnits[mActiveTexture].mTextureCubeArray;
case GL_DRAW_FRAMEBUFFER:
return mBindedFBO_W;
case GL_READ_FRAMEBUFFER:

View file

@ -149,14 +149,9 @@ 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 || 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 && bmp->getFormat() != GFXFormatR8G8B8A8_SRGB )
return false;
AssertFatal(mFormat == GFXFormatR16G16B16A16F || mFormat == GFXFormatR8G8B8A8 || mFormat == GFXFormatR8G8B8A8_LINEAR_FORCE || mFormat == GFXFormatR8G8B8A8_SRGB, "copyToBmp: invalid format");
if (mFormat != GFXFormatR16G16B16A16F && mFormat != GFXFormatR8G8B8A8 && mFormat != GFXFormatR8G8B8A8_LINEAR_FORCE && mFormat != GFXFormatR8G8B8A8_SRGB)
return false;
AssertFatal(bmp->getWidth() == getWidth(), "GFXGLTextureObject::copyToBmp - invalid size");
AssertFatal(bmp->getHeight() == getHeight(), "GFXGLTextureObject::copyToBmp - invalid size");
@ -168,11 +163,6 @@ bool GFXGLTextureObject::copyToBmp(GBitmap * bmp)
U8 dstBytesPerPixel = GFXFormat_getByteSize( bmp->getFormat() );
U8 srcBytesPerPixel = GFXFormat_getByteSize( mFormat );
if(dstBytesPerPixel == srcBytesPerPixel)
{
glGetTexImage(mBinding, 0, GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], bmp->getWritableBits());
return true;
}
FrameAllocatorMarker mem;
@ -183,16 +173,23 @@ bool GFXGLTextureObject::copyToBmp(GBitmap * bmp)
glGetTexImage(mBinding, 0, GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], orig);
PROFILE_START(GFXGLTextureObject_copyToBmp_pixCopy);
for(int i = 0; i < srcPixelCount; ++i)
if (mFormat == GFXFormatR16G16B16A16F)
{
dest[0] = orig[0];
dest[1] = orig[1];
dest[2] = orig[2];
if(dstBytesPerPixel == 4)
dest[3] = orig[3];
dMemcpy(dest, orig, sizeof(U16) * 4);
}
else
{
for (int i = 0; i < srcPixelCount; ++i)
{
dest[0] = orig[0];
dest[1] = orig[1];
dest[2] = orig[2];
if (dstBytesPerPixel == 4)
dest[3] = orig[3];
orig += srcBytesPerPixel;
dest += dstBytesPerPixel;
orig += srcBytesPerPixel;
dest += dstBytesPerPixel;
}
}
PROFILE_END();

View file

@ -136,6 +136,7 @@ class _GFXGLTextureTargetFBOImpl : public _GFXGLTextureTargetImpl
{
public:
GLuint mFramebuffer;
bool mGenMips;
_GFXGLTextureTargetFBOImpl(GFXGLTextureTarget* target);
virtual ~_GFXGLTextureTargetFBOImpl();
@ -147,6 +148,7 @@ public:
_GFXGLTextureTargetFBOImpl::_GFXGLTextureTargetFBOImpl(GFXGLTextureTarget* target)
{
mGenMips = target->isGenMipsEnabled();
mTarget = target;
glGenFramebuffers(1, &mFramebuffer);
}
@ -245,6 +247,9 @@ void _GFXGLTextureTargetFBOImpl::finish()
glBindFramebuffer(GL_FRAMEBUFFER, 0);
GFXGL->getOpenglCache()->setCacheBinded(GL_FRAMEBUFFER, 0);
if (!mGenMips)
return;
for(int i = 0; i < GFXGL->getNumRenderTargets(); ++i)
{
_GFXGLTargetDesc* color = mTarget->getTargetDesc( static_cast<GFXTextureTarget::RenderSlot>(GFXTextureTarget::Color0+i ) );
@ -263,8 +268,9 @@ void _GFXGLTextureTargetFBOImpl::finish()
}
// Actual GFXGLTextureTarget interface
GFXGLTextureTarget::GFXGLTextureTarget() : mCopyFboSrc(0), mCopyFboDst(0)
GFXGLTextureTarget::GFXGLTextureTarget(bool genMips) : mCopyFboSrc(0), mCopyFboDst(0)
{
mGenMips = genMips;
for(U32 i=0; i<MaxRenderSlotId; i++)
mTargets[i] = NULL;

View file

@ -45,7 +45,7 @@ class _GFXGLTextureTargetImpl;
class GFXGLTextureTarget : public GFXTextureTarget
{
public:
GFXGLTextureTarget();
GFXGLTextureTarget(bool genMips);
virtual ~GFXGLTextureTarget();
virtual const Point2I getSize();

View file

@ -191,6 +191,9 @@ GFXGLPreserveTexture TORQUE_CONCAT(preserve_, __LINE__) (GL_TEXTURE_3D, GL_TEXTU
#define PRESERVE_CUBEMAP_TEXTURE() \
GFXGLPreserveTexture TORQUE_CONCAT(preserve_, __LINE__) (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BINDING_CUBE_MAP, (GFXGLPreserveInteger::BindFn)glBindTexture)
#define PRESERVE_CUBEMAP_ARRAY_TEXTURE() \
GFXGLPreserveTexture TORQUE_CONCAT(preserve_, __LINE__) (GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_BINDING_CUBE_MAP_ARRAY, (GFXGLPreserveInteger::BindFn)glBindTexture)
#define _GET_TEXTURE_BINDING(binding) \
binding == GL_TEXTURE_2D ? GL_TEXTURE_BINDING_2D : (binding == GL_TEXTURE_3D ? GL_TEXTURE_BINDING_3D : GL_TEXTURE_BINDING_1D )

View file

@ -34,6 +34,7 @@
#include "scene/sceneManager.h"
#include "console/engineAPI.h"
#include "math/mathUtils.h"
#include "gfx/bitmap/cubemapSaver.h"
IMPLEMENT_CONOBJECT( CubemapData );
@ -111,7 +112,7 @@ void CubemapData::createMap()
{
if (!mCubeFaceFile[i].isEmpty())
{
if (!mCubeFace[i].set(mCubeFaceFile[i], &GFXStaticTextureProfile, 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;
@ -145,7 +146,7 @@ void CubemapData::updateFaces()
{
if (!mCubeFaceFile[i].isEmpty())
{
if (!mCubeFace[i].set(mCubeFaceFile[i], &GFXStaticTextureProfile, 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__)))
{
initSuccess = false;
Con::errorf("CubemapData::createMap - Failed to load texture '%s'", mCubeFaceFile[i].c_str());
@ -163,6 +164,11 @@ void CubemapData::updateFaces()
}
}
void CubemapData::setCubemapFile(FileName newCubemapFile)
{
mCubeMapFile = newCubemapFile;
}
void CubemapData::setCubeFaceFile(U32 index, FileName newFaceFile)
{
if (index >= 6)
@ -171,6 +177,14 @@ void CubemapData::setCubeFaceFile(U32 index, FileName newFaceFile)
mCubeFaceFile[index] = newFaceFile;
}
void CubemapData::setCubeFaceTexture(U32 index, GFXTexHandle newFaceTexture)
{
if (index >= 6)
return;
mCubeFace[index] = newFaceTexture;
}
DefineEngineMethod( CubemapData, updateFaces, void, (),,
"Update the assigned cubemaps faces." )
{
@ -183,3 +197,18 @@ DefineEngineMethod( CubemapData, getFilename, const char*, (),,
{
return object->getFilename();
}
DefineEngineMethod(CubemapData, save, void, (const char* filename, const GFXFormat format), ("", GFXFormatBC1),
"Returns the script filename of where the CubemapData object was "
"defined. This is used by the material editor.")
{
if (filename == "")
filename = object->getName();
//add dds extension if needed
String finalName = String(filename);
if(!finalName.endsWith(".dds") || !finalName.endsWith(".DDS"))
finalName += String(".dds");
CubemapSaver::save(object->mCubemap, finalName, format);
}

View file

@ -63,7 +63,12 @@ public:
// Update a static cubemap @ pos
void updateFaces();
void setCubemapFile(FileName newCubemapFile);
void setCubeFaceFile(U32 index, FileName newFaceFile);
void setCubeFaceTexture(U32 index, GFXTexHandle newFaceTexture);
GFXTexHandle* getCubeMapFace(U32 faceIdx) { return &mCubeFace[faceIdx]; }
protected: