#if defined(DX11_SUPPORTED)
#if _MSC_VER >= 1700
#pragma warning( disable: 4005 )
#endif
#pragma warning (disable:4239)
#include <stdio.h>
#include "DX11ResourceManager.h"
#include <maya/MGlobal.h>
#include <maya/MString.h>
#include <maya/MFnCamera.h>
#include <maya/MAngle.h>
#include <maya/MPoint.h>
#include <maya/MVector.h>
#include <maya/MItDag.h>
#include <maya/MMatrix.h>
#include <maya/MDagPath.h>
#include <maya/MFnDagNode.h>
#include <maya/MBoundingBox.h>
#include <maya/MNodeMessage.h>
#include <maya/MPlug.h>
#include <maya/MPlugArray.h>
#include <maya/MFnLight.h>
#include <maya/MFnSpotLight.h>
#include <maya/MColor.h>
#include <maya/MFloatMatrix.h>
void geometryDirtyCallback( void* clientData )
{
GeometryItem *item = (GeometryItem *)clientData;
if (item)
{
item->m_objectDirtyMonitor = 0;
}
}
{
GeometryItem *item = (GeometryItem *)clientData;
if (item)
{
item->m_objectChangeMonitor = 0;
}
}
{
TextureItem *item = (TextureItem *)clientData;
if (item)
{
item->m_objectChangeMonitor = 0;
}
}
void geometryDeleteCallback(
MObject &node,
void* clientData )
{
GeometryItem *item = (GeometryItem *)clientData;
if (item)
{
item->m_objectDeleteMonitor = 0;
}
}
void textureDeleteCallback(
MObject &node,
void* clientData )
{
TextureItem *item = (TextureItem *)clientData;
if (item)
{
item->m_objectDeleteMonitor = 0;
}
}
DX11ResourceManager::DX11ResourceManager()
{
initializeDefaultCamera();
}
DX11ResourceManager::~DX11ResourceManager()
{
const bool onlyInvalidItems = false;
clearResources(onlyInvalidItems, true);
}
void
DX11ResourceManager::initializeDefaultCamera()
{
m_camera.m_vEyePt = XMFLOAT3( 0.0f, 10.0f, -10.0f );
m_camera.m_vLookatPt = XMFLOAT3( 0.0f, 0.0f, 0.0f );
m_camera.m_vUpVec = XMFLOAT3( 0.0f, 1.0f, 0.0f );
m_camera.m_FieldOfView = 45.0f;
m_camera.m_nearClip = 0.1f;
m_camera.m_farClip = 1000.0f;
}
bool
DX11ResourceManager::translateCamera(
const MDagPath &cameraPath )
{
bool translatedCamera = false;
{
if ( !status ) {
status.
perror(
"MFnCamera constructor");
}
else
{
translatedCamera = true;
double horizontalFieldOfView =
MAngle( camera.horizontalFieldOfView()
).asDegrees();
double nearClippingPlane = camera.nearClippingPlane();
double farClippingPlane = camera.farClippingPlane();
m_camera.m_vEyePt = XMFLOAT3((
float)eyePoint.
x, (
float)eyePoint.
y, (
float)eyePoint.
z);
m_camera.m_vLookatPt = XMFLOAT3((
float)lookAtPt.
x, (
float)lookAtPt.
y, (
float)lookAtPt.
z);
m_camera.m_vUpVec = XMFLOAT3((
float)upDirection.
x, (
float)upDirection.
y, (
float)upDirection.
z);
m_camera.m_FieldOfView = (float)horizontalFieldOfView;
m_camera.m_nearClip = (float)nearClippingPlane;
m_camera.m_farClip = (float)farClippingPlane;
m_camera.m_isOrtho = camera.isOrtho();
}
}
else
{
initializeDefaultCamera();
}
return translatedCamera;
}
D3DGeometry* DX11ResourceManager::getGeometry(
const MDagPath& dagPath, ID3D11Device* D3D)
{
D3DGeometry* Geometry = NULL;
GeometryItem *itemFound = NULL;
GeometryItemList::const_iterator it, end_it;
end_it = m_geometryItemList.end();
for (it = m_geometryItemList.begin(); it != end_it; it++)
{
GeometryItem *item = *it;
if (item && item->m_objectPath == dagPath)
{
itemFound = item;
}
}
if (!itemFound)
{
itemFound = new GeometryItem;
itemFound->m_objectPath = dagPath;
Geometry = itemFound->m_objectGeometry = new D3DGeometry();
if (Geometry)
{
Geometry->Populate( dagPath, D3D);
}
itemFound->m_objectDeleteMonitor =
itemFound->m_objectChangeMonitor = 0;
itemFound->m_objectChangeMonitor =
m_geometryItemList.push_back( itemFound );
}
else
{
Geometry = itemFound->m_objectGeometry;
}
return Geometry;
}
D3DTexture* DX11ResourceManager::getTexture(
MObject& textureNode)
{
D3DTexture* Texture = NULL;
TextureItem *itemFound = NULL;
TextureItemList::const_iterator it, end_it;
end_it = m_textureItemList.end();
for (it = m_textureItemList.begin(); it != end_it; it++)
{
TextureItem *item = *it;
if (item && item->m_mayaNode.object() == textureNode)
{
itemFound = item;
}
}
if (!itemFound)
{
itemFound = new TextureItem();
itemFound->m_mayaNode = textureNode;
Texture = itemFound->m_texture = new D3DTexture( textureNode);
itemFound->m_objectDeleteMonitor =
itemFound->m_objectChangeMonitor =
m_textureItemList.push_back( itemFound );
}
else
{
Texture = itemFound->m_texture;
}
return Texture;
}
static HRESULT CompileShaderFromFile( const char* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut )
{
HRESULT hr = S_OK;
#ifndef D3DCOMPILE_ENABLE_STRICTNESS
#define D3DCOMPILE_ENABLE_STRICTNESS D3D10_SHADER_ENABLE_STRICTNESS
#define D3DCOMPILE_DEBUG D3D10_SHADER_DEBUG
#endif
DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;
#if defined( DEBUG ) || defined( _DEBUG )
dwShaderFlags |= D3DCOMPILE_DEBUG;
#endif
ID3DBlob* pErrorBlob;
hr = D3DX11CompileFromFile( szFileName, NULL, NULL, szEntryPoint, szShaderModel,
dwShaderFlags, 0, NULL, ppBlobOut, &pErrorBlob, NULL );
if( FAILED(hr) )
{
if( pErrorBlob != NULL )
if( pErrorBlob ) pErrorBlob->Release();
return hr;
}
if( pErrorBlob ) pErrorBlob->Release();
return S_OK;
}
bool
DX11ResourceManager::initializeDefaultSurfaceEffect(
const MString& effectsLocation, ID3D11Device* D3D,
const D3D11_INPUT_ELEMENT_DESC* layout, int numLayoutElements )
{
HRESULT hres;
MString effectLocation = effectsLocation +
"\\" + effectName +
".hlsl";
ID3DBlob* pVSBlob = NULL;
hres = CompileShaderFromFile( effectLocation.
asChar(), vsName.
asChar(),
"vs_4_0", &pVSBlob );
if (FAILED(hres))
{
return false;
}
ID3D11VertexShader* pVertexShader = NULL;
hres = D3D->CreateVertexShader( pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), NULL, &pVertexShader );
if (FAILED(hres))
{
pVSBlob->Release();
return false;
}
ID3D11InputLayout* pVertexLayout = NULL;
hres = D3D->CreateInputLayout( layout, numLayoutElements, pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), &pVertexLayout );
pVSBlob->Release();
if (FAILED(hres))
{
return false;
}
ID3DBlob* pPSBlob = NULL;
hres = CompileShaderFromFile( effectLocation.
asChar(), psName.
asChar(),
"ps_4_0", &pPSBlob );
if (FAILED(hres))
{
pVertexShader->Release();
pVertexLayout->Release();
return false;
}
ID3D11PixelShader* pPixelShader = NULL;
hres = D3D->CreatePixelShader( pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), NULL, &pPixelShader );
pPSBlob->Release();
if (FAILED(hres))
{
pVertexShader->Release();
pVertexLayout->Release();
return false;
}
SurfaceEffectItem *pei = new SurfaceEffectItem;
if (pei)
{
pei->fVertexShader = pVertexShader;
pei->fPixelShader = pPixelShader;
pei->fInputLayout = pVertexLayout;
m_SurfaceEffectItemList[ effectName.asChar() ] = pei;
}
return true;
}
void
DX11ResourceManager::clearResources(bool onlyInvalidItems, bool clearShaders)
{
GeometryItemList::const_iterator git, end_git;
end_git = m_geometryItemList.end();
for (git = m_geometryItemList.begin(); git != end_git; git++)
{
GeometryItem *item = *git;
if (item)
{
if (!onlyInvalidItems || (onlyInvalidItems && !(item->m_objectPath.isValid() )))
{
if (item->m_objectGeometry)
{
delete item->m_objectGeometry;
item->m_objectGeometry = NULL;
}
if (item->m_objectDeleteMonitor)
{
item->m_objectDeleteMonitor = 0;
}
if (item->m_objectChangeMonitor)
{
item->m_objectChangeMonitor = 0;
}
if (item->m_objectDirtyMonitor)
{
item->m_objectDirtyMonitor = 0;
}
}
}
}
if (!onlyInvalidItems)
m_geometryItemList.clear();
TextureItemList::const_iterator tit, end_tit;
end_tit = m_textureItemList.end();
for (tit = m_textureItemList.begin(); tit != end_tit; tit++)
{
TextureItem *item = *tit;
if (item)
{
if (!onlyInvalidItems || (onlyInvalidItems && !(item->m_mayaNode.isValid() )))
{
if (item->m_texture)
{
delete item->m_texture;
item->m_texture = NULL;
}
if (item->m_objectDeleteMonitor)
{
item->m_objectDeleteMonitor = 0;
}
if (item->m_objectChangeMonitor)
{
item->m_objectChangeMonitor = 0;
}
}
}
}
if (!onlyInvalidItems)
m_textureItemList.clear();
if (clearShaders)
{
{
SurfaceEffectItemList::const_iterator eit, end_eit;
end_eit = m_SurfaceEffectItemList.end();
for (eit = m_SurfaceEffectItemList.begin(); eit != end_eit; eit++)
{
SurfaceEffectItem *item = eit->second;
if (item)
{
if (item->fVertexShader)
item->fVertexShader->Release();
if (item->fPixelShader)
item->fPixelShader->Release();
if (item->fInputLayout)
item->fInputLayout->Release();
delete item;
}
}
m_SurfaceEffectItemList.clear();
}
}
}
#endif