#if _MSC_VER >= 1700
#pragma warning( disable: 4005 )
#endif
#include <assert.h>
#include <stdio.h>
#include <iostream>
#include "DX11ViewportRenderer.h"
#include <maya/MGlobal.h>
#include <maya/MString.h>
#include <maya/MRenderingInfo.h>
#include <maya/MRenderTarget.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/MFnMesh.h>
#include <maya/MItMeshPolygon.h>
#include <maya/MBoundingBox.h>
#include <maya/MImage.h>
#include <maya/MDrawTraversal.h>
#include <maya/MGeometryManager.h>
#include <maya/MGeometry.h>
#include <maya/MGeometryData.h>
#include <maya/MGeometryPrimitive.h>
#include <maya/MNodeMessage.h>
#include <maya/MPlug.h>
#include <maya/MPlugArray.h>
#include <maya/MFnSet.h>
#include <maya/MFnNumericData.h>
#include <maya/MItDependencyGraph.h>
#include <maya/MMatrix.h>
#include <stdio.h>
#include <maya/MFnLight.h>
#include <maya/MFnSpotLight.h>
#include <maya/MPxHardwareShader.h>
#include <maya/MRenderProfile.h>
#include <windows.h>
#if defined(DX11_SUPPORTED)
struct ScreenSpaceVertex
{
XMVECTOR position;
XMFLOAT2A texCoord;
};
#endif
DX11ViewportRenderer::DX11ViewportRenderer()
{
fUIName.set( "DX11 Renderer");
m_Version = 11.0f;
m_renderWidth = 640;
m_renderHeight = 480;
#if defined(DX11_SUPPORTED)
m_hWnd = 0;
m_pD3DDevice = 0;
m_pD3DDeviceCtx = 0;
m_pNormalRS = 0;
m_pWireframeRS = 0;
m_pTextureOutput = 0;
m_pTextureOutputView = 0;
m_readBackBuffer.create(m_renderWidth, m_renderHeight, 4);
m_readBackBuffer.setRGBA( true );
m_pBoundsVertexBuffer = 0;
m_pBoundsIndexBuffer = 0;
m_pBoundsConstantBuffer = 0;
m_pFixedFunctionConstantBuffer = 0;
m_wantFloatingPointTargets = false;
m_pTextureInterm = 0;
m_pTextureIntermView = 0;
m_pDepthStencil = 0;
m_pDepthStencilView = 0;
m_pTextureReadBack = 0;
m_requireDepthStencilReadback = false;
#endif
}
DX11ViewportRenderer::~DX11ViewportRenderer()
{
uninitialize();
}
unsigned int DX11ViewportRenderer::overrideThenStandardExclusion() const
{
return ~(unsigned int)kExcludeManipulators;
}
LRESULT CALLBACK D3DWindowProc( HWND hWnd,
UINT msg,
WPARAM wParam,
LPARAM lParam )
{
switch( msg )
{
case WM_CLOSE:
{
}
break;
case WM_DESTROY:
{
}
break;
default:
{
return DefWindowProc( hWnd, msg, wParam, lParam );
}
break;
}
return 0;
}
#if defined(DX11_SUPPORTED)
bool
DX11ViewportRenderer::buildRenderTargets(unsigned int width, unsigned int height)
{
HRESULT hr = -1;
if (width == m_renderWidth &&
height == m_renderHeight &&
m_pTextureInterm &&
m_pTextureOutput)
{
return true;
}
m_renderWidth = width;
m_renderHeight = height;
if (m_pTextureInterm)
{
m_pTextureInterm->Release();
m_pTextureInterm = NULL;
}
if (m_pTextureIntermView)
{
m_pTextureIntermView->Release();
m_pTextureIntermView = NULL;
}
if (!m_pTextureInterm)
{
D3D11_TEXTURE2D_DESC td;
ZeroMemory( &td, sizeof td );
td.Width = m_renderWidth;
td.Height = m_renderHeight;
td.MipLevels = 1;
td.ArraySize = 1;
td.Format = m_intermediateTargetFormat;
td.SampleDesc.Count = 1;
td.SampleDesc.Quality = 0;
td.Usage = D3D11_USAGE_DEFAULT;
td.BindFlags = D3D11_BIND_RENDER_TARGET;
td.CPUAccessFlags = 0;
td.MiscFlags = 0;
hr = m_pD3DDevice->CreateTexture2D( &td, NULL, &m_pTextureInterm );
m_intermediateTargetFormat = m_outputTargetFormat;
if ( FAILED(hr) )
{
td.Format = m_intermediateTargetFormat;
hr = m_pD3DDevice->CreateTexture2D( &td, NULL, &m_pTextureInterm );
}
if ( FAILED(hr) )
{
return false;
}
}
if (m_pTextureInterm)
{
hr = m_pD3DDevice->CreateRenderTargetView( m_pTextureInterm, NULL, &m_pTextureIntermView );
if ( FAILED(hr) )
{
return false;
}
}
if ( m_pDepthStencil )
{
m_pDepthStencil->Release();
m_pDepthStencil = 0;
}
if ( m_pDepthStencilView )
{
m_pDepthStencilView->Release();
m_pDepthStencilView = 0;
}
if ( !m_pDepthStencil )
{
D3D11_TEXTURE2D_DESC td;
ZeroMemory( &td, sizeof td );
td.Width = m_renderWidth;
td.Height = m_renderHeight;
td.MipLevels = 1;
td.ArraySize = 1;
td.Format = m_depthStencilFormat;
td.SampleDesc.Count = 1;
td.SampleDesc.Quality = 0;
td.Usage = D3D11_USAGE_DEFAULT;
td.BindFlags = D3D11_BIND_DEPTH_STENCIL;
td.CPUAccessFlags = 0;
td.MiscFlags = 0;
hr = m_pD3DDevice->CreateTexture2D( &td, NULL, &m_pDepthStencil );
if ( FAILED(hr) )
{
return false;
}
}
if ( m_pDepthStencil )
{
hr = m_pD3DDevice->CreateDepthStencilView( m_pDepthStencil, NULL, &m_pDepthStencilView );
if ( FAILED(hr) )
{
return false;
}
}
assert( !m_wantFloatingPointTargets );
if (m_wantFloatingPointTargets)
{
}
else
{
m_pTextureOutput = m_pTextureInterm;
m_pTextureOutputView = m_pTextureIntermView;
}
if (m_pTextureReadBack)
{
m_pTextureReadBack->Release();
m_pTextureReadBack= 0;
}
if (!m_pTextureReadBack)
{
D3D11_TEXTURE2D_DESC td;
ZeroMemory( &td, sizeof td );
td.Width = m_renderWidth;
td.Height = m_renderHeight;
td.MipLevels = 1;
td.ArraySize = 1;
td.Format = m_intermediateTargetFormat;
td.SampleDesc.Count = 1;
td.SampleDesc.Quality = 0;
td.Usage = D3D11_USAGE_STAGING;
td.BindFlags = 0;
td.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
td.MiscFlags = 0;
hr = m_pD3DDevice->CreateTexture2D( &td, NULL, &m_pTextureReadBack );
if (FAILED(hr))
{
return false;
}
}
return (m_pTextureOutput && m_pTextureOutputView && m_pTextureInterm &&
m_pTextureIntermView && m_pTextureReadBack);
#if defined(DEPTH_REQUIRED)
if (m_pDepthStencilSurface)
{
m_pDepthStencilSurface->Release();
m_pDepthStencilSurface = 0;
}
if (m_requireDepthStencilReadback && !m_pDepthStencilSurface)
{
hr = m_pD3DDevice->CreateDepthStencilSurface(
m_renderWidth, m_renderHeight, m_depthStencilFormat, D3DMULTISAMPLE_NONE,
0, FALSE,
&m_pDepthStencilSurface, NULL );
if (FAILED(hr))
{
MGlobal::displayWarning(
"DX11 renderer : Failed to create depth/stencil surface. Depth read back will not be available.");
}
}
#endif
}
bool
DX11ViewportRenderer::createBoundsBuffers()
{
HRESULT hr;
BoundsVertex vertices[] =
{
{ XMFLOAT3( -1.0f, -1.0f, -1.0f ) },
{ XMFLOAT3( -1.0f, -1.0f, 1.0f ) },
{ XMFLOAT3( -1.0f, 1.0f, -1.0f ) },
{ XMFLOAT3( -1.0f, 1.0f, 1.0f ) },
{ XMFLOAT3( 1.0f, -1.0f, -1.0f ) },
{ XMFLOAT3( 1.0f, -1.0f, 1.0f ) },
{ XMFLOAT3( 1.0f, 1.0f, -1.0f ) },
{ XMFLOAT3( 1.0f, 1.0f, 1.0f ) },
};
D3D11_BUFFER_DESC bd;
ZeroMemory( &bd, sizeof(bd) );
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof( BoundsVertex ) * 8;
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = 0;
D3D11_SUBRESOURCE_DATA InitData;
ZeroMemory( &InitData, sizeof(InitData) );
InitData.pSysMem = vertices;
hr = m_pD3DDevice->CreateBuffer( &bd, &InitData, &m_pBoundsVertexBuffer );
if ( FAILED( hr ) )
return false;
WORD indices[] =
{
0, 1,
1, 3,
3, 2,
2, 0,
4, 5,
5, 7,
7, 6,
6, 4,
0, 4,
1, 5,
2, 6,
3, 7,
};
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof( WORD ) * 24;
bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
bd.CPUAccessFlags = 0;
InitData.pSysMem = indices;
hr = m_pD3DDevice->CreateBuffer( &bd, &InitData, &m_pBoundsIndexBuffer );
if ( FAILED( hr ) )
return false;
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof( BoundsConstants );
bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
bd.CPUAccessFlags = 0;
hr = m_pD3DDevice->CreateBuffer( &bd, NULL, &m_pBoundsConstantBuffer );
if ( FAILED( hr ) )
return false;
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof( FixedFunctionConstants );
bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
bd.CPUAccessFlags = 0;
hr = m_pD3DDevice->CreateBuffer( &bd, NULL, &m_pFixedFunctionConstantBuffer );
if ( FAILED( hr ) )
return false;
return true;
}
bool
DX11ViewportRenderer::createRasterizerStates()
{
HRESULT hr;
D3D11_RASTERIZER_DESC rd;
rd.FillMode = D3D11_FILL_SOLID;
rd.CullMode = D3D11_CULL_BACK;
rd.FrontCounterClockwise = TRUE;
rd.DepthBias = 0;
rd.SlopeScaledDepthBias = 0.0f;
rd.DepthBiasClamp = 0.0f;
rd.DepthClipEnable = TRUE;
rd.ScissorEnable = FALSE;
rd.MultisampleEnable = FALSE;
rd.AntialiasedLineEnable = FALSE;
hr = m_pD3DDevice->CreateRasterizerState( &rd, &m_pNormalRS );
if ( FAILED( hr ) )
return false;
rd.FillMode = D3D11_FILL_WIREFRAME;
hr = m_pD3DDevice->CreateRasterizerState( &rd, &m_pWireframeRS );
if ( FAILED( hr ) )
return false;
return true;
}
#endif
DX11ViewportRenderer::initialize()
{
#if defined(DX11_SUPPORTED)
MString wantFloatingPoint(
"D3D_RENDERER_FLOAT_TARGETS");
int value;
{
m_wantFloatingPointTargets = true;
}
else
{
m_wantFloatingPointTargets = (value != 0);
}
m_wantFloatingPointTargets = false;
if (!m_hWnd)
{
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, (WNDPROC) D3DWindowProc, 0L, 0L,
GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
"DX11 Viewport Renderer", NULL };
if (RegisterClassEx( &wc ))
{
m_hWnd = CreateWindow( "DX11 Viewport Renderer", "DX11 Viewport Renderer",
WS_OVERLAPPEDWINDOW, 0, 0, m_renderWidth, m_renderHeight,
NULL, NULL, wc.hInstance, NULL );
}
}
HRESULT hr;
if (m_wantFloatingPointTargets)
{
m_intermediateTargetFormat = DXGI_FORMAT_R16G16B16A16_FLOAT;
}
else
{
m_intermediateTargetFormat = DXGI_FORMAT_R8G8B8A8_UNORM;
}
m_outputTargetFormat = DXGI_FORMAT_R8G8B8A8_UNORM;
if (m_requireDepthStencilReadback)
{
m_depthStencilFormat = DXGI_FORMAT_D32_FLOAT;
}
else
m_depthStencilFormat = DXGI_FORMAT_D24_UNORM_S8_UINT;
if (m_hWnd)
{
if (!m_pD3DDevice)
{
hr = D3D11CreateDevice( NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, NULL,
0, D3D11_SDK_VERSION,
&m_pD3DDevice, NULL, NULL );
if (FAILED(hr))
{
}
if ( FAILED(hr) )
{
m_pD3DDevice = 0;
}
}
}
if (m_pD3DDevice)
{
m_pD3DDevice->GetImmediateContext( &m_pD3DDeviceCtx );
}
if (m_pD3DDevice)
{
bool success = buildRenderTargets(640, 480);
if ( success )
success = createBoundsBuffers();
if ( success )
success = createRasterizerStates();
if ( success )
{
bool loaded;
{
D3D11_INPUT_ELEMENT_DESC layout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
const int numLayoutElements = sizeof layout/sizeof layout[0];
loaded = m_resourceManager.initializeDefaultSurfaceEffect( shaderLocation, m_pD3DDevice, "Maya_fixedFunction",
"mainVS", "mainPS", layout, numLayoutElements );
}
{
D3D11_INPUT_ELEMENT_DESC layout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
const int numLayoutElements = sizeof layout/sizeof layout[0];
loaded = m_resourceManager.initializeDefaultSurfaceEffect( shaderLocation, m_pD3DDevice, "Maya_unlit",
"mainVS", "mainPS", layout, numLayoutElements );
}
if (m_hWnd && m_pD3DDevice && m_pD3DDeviceCtx && m_pTextureOutput && m_pTextureOutputView &&
m_pTextureInterm && m_pTextureIntermView )
{
}
}
}
{
uninitialize();
}
#else
#endif
return status;
}
DX11ViewportRenderer::uninitialize()
{
#if defined(DX11_SUPPORTED)
if ( m_pTextureOutput )
{
if (m_pTextureOutput != m_pTextureInterm)
m_pTextureOutput->Release();
m_pTextureOutput = 0;
}
if ( m_pTextureOutputView )
{
if (m_pTextureOutputView != m_pTextureIntermView)
m_pTextureOutputView->Release();
m_pTextureOutputView = 0;
}
if ( m_pTextureInterm )
{
m_pTextureInterm->Release();
m_pTextureInterm = 0;
}
if ( m_pTextureIntermView )
{
m_pTextureIntermView->Release();
m_pTextureIntermView = 0;
}
if ( m_pTextureReadBack )
{
m_pTextureReadBack->Release();
m_pTextureReadBack = 0;
}
if ( m_pDepthStencil )
{
m_pDepthStencil->Release();
m_pDepthStencil = 0;
}
if ( m_pDepthStencilView )
{
m_pDepthStencilView->Release();
m_pDepthStencilView = 0;
}
if ( m_pBoundsVertexBuffer != NULL )
{
m_pBoundsVertexBuffer->Release();
m_pBoundsVertexBuffer = 0;
}
if ( m_pBoundsIndexBuffer != NULL )
{
m_pBoundsIndexBuffer->Release();
m_pBoundsIndexBuffer = 0;
}
if ( m_pBoundsConstantBuffer != NULL )
{
m_pBoundsConstantBuffer->Release();
m_pBoundsConstantBuffer = 0;
}
if ( m_pFixedFunctionConstantBuffer != NULL )
{
m_pFixedFunctionConstantBuffer->Release();
m_pFixedFunctionConstantBuffer = 0;
}
m_resourceManager.clearResources(false, true);
if ( m_pNormalRS )
{
m_pNormalRS->Release();
m_pNormalRS = 0;
}
if ( m_pWireframeRS )
{
m_pWireframeRS->Release();
m_pWireframeRS = 0;
}
if ( m_pD3DDeviceCtx )
{
m_pD3DDeviceCtx->Release();
m_pD3DDeviceCtx = 0;
}
if ( m_pD3DDevice )
{
m_pD3DDevice->Release();
m_pD3DDevice = 0;
}
if (m_hWnd)
{
ReleaseDC( m_hWnd, GetDC(m_hWnd ));
DestroyWindow(m_hWnd);
UnregisterClass("DX11 Viewport Renderer", GetModuleHandle(NULL));
m_hWnd = 0;
}
#endif
}
{
#if defined(DX11_SUPPORTED)
unsigned int currentWidth = target.
width();
unsigned int currentHeight = target.
height();
if (!buildRenderTargets(currentWidth, currentHeight))
#endif
#if defined(DX11_SUPPORTED)
if ( m_resourceManager.translateCamera( cameraPath ) )
{
if ( renderToTarget( renderInfo ) )
{
if ( requireReadBack )
{
if (readFromTargetToSystemMemory())
{
{
unsigned int targetW = target.
width();
unsigned int targetH = target.
height();
unsigned int m_readBackBufferWidth, m_readBackBufferHeight;
m_readBackBuffer.getSize(m_readBackBufferWidth, m_readBackBufferHeight);
if (m_readBackBufferWidth && m_readBackBufferHeight)
{
if (m_readBackBufferWidth > targetW ||
m_readBackBufferHeight > targetH)
{
m_readBackBuffer.resize(targetW, targetH);
}
else
{
(short)(targetW/2 - m_readBackBufferWidth/2),
(short)(targetH/2 - m_readBackBufferHeight/2));
}
}
}
else
{
}
}
else
}
else
{
}
}
else
}
else
{
}
#else
#endif
return status;
}
bool
float version )
{
return ((api == m_API) && (version == m_Version) );
}
bool
{
return (override == fRenderingOverride);
}
#if defined(DX11_SUPPORTED)
bool
DX11ViewportRenderer::translateCamera(
const MRenderingInfo &renderInfo )
{
return m_resourceManager.translateCamera( cameraPath );
else
return false;
}
void
DX11ViewportRenderer::clearResources(bool onlyInvalidItems, bool clearShaders)
{
m_resourceManager.clearResources( onlyInvalidItems, clearShaders );
}
{
MPlug shaderPlug = fnNode.findPlug(
"surfaceShader");
bool asSrc = false;
bool asDst = true;
shaderPlug.
connectedTo( connectedPlugs, asDst, asSrc );
if (connectedPlugs.
length() != 1)
else
return connectedPlugs[0].node();
}
}
bool DX11ViewportRenderer::drawSurface(
const MDagPath &dagPath,
bool active,
bool templated)
{
bool drewSurface = false;
{
float color[3] = {0.6f, 0.3f, 0.0f};
if (active)
{
color[0] = 1.0f;
color[1] = 1.0f;
color[2] = 1.0f;
}
else if (templated)
{
color[0] = 1.0f;
color[1] = 0.686f;
color[2] = 0.686f;
}
drawBounds( matrix, box, color);
return true;
}
{
bool drewWithHwShader = false;
{
if (!fnMesh.getConnectedSetsAndMembers(instanceNum, sets, comps, true))
for (
unsigned i=0; i<sets.
length(); i++ )
{
if (status == MS::kFailure) {
continue;
}
MObject shaderNode = findShader(set);
{
if (hwShader)
{
{
}
}
}
}
}
D3DGeometry* Geometry = m_resourceManager.getGeometry( dagPath, m_pD3DDevice);
if( Geometry)
{
XMMATRIX objectToWorld = XMMATRIX
(
);
FixedFunctionConstants cb;
if (!drewWithHwShader)
{
bool drewGeometryWithShader = false;
if (!drewGeometryWithShader)
{
float diffuse[3];
if (active)
{
if (templated)
{
m_pD3DDeviceCtx->RSSetState( m_pWireframeRS );
diffuse[0] = 1.0f; diffuse[1] = 0.686f; diffuse[2] = 0.686f;
}
else
{
m_pD3DDeviceCtx->RSSetState( m_pNormalRS );
diffuse[0] = 0.6f; diffuse[1] = 0.6f; diffuse[2] = 0.6f;
}
}
else
{
if (templated)
{
m_pD3DDeviceCtx->RSSetState( m_pWireframeRS );
diffuse[0] = 1.0f; diffuse[1] = 0.686f; diffuse[2] = 0.686f;
}
else
{
m_pD3DDeviceCtx->RSSetState( m_pNormalRS );
diffuse[0] = 0.5f; diffuse[1] = 0.5f; diffuse[2] = 0.5f;
}
}
XMVECTOR det;
cb.wvIT = XMMatrixInverse( &det, objectToWorld * m_currentViewMatrix );
cb.wvp = XMMatrixTranspose( objectToWorld * m_currentViewMatrix * m_currentProjectionMatrix );
cb.wv = XMMatrixTranspose( objectToWorld * m_currentViewMatrix );
cb.lightDir = XMFLOAT4( 0.0f, 0.0f, 1.0f, 0.0f );
cb.lightColor = XMFLOAT4( 1.0f, 1.0f, 1.0f, 0.0f );
cb.ambientLight = XMFLOAT4( 0.2f, 0.2f, 0.2f, 0.0f );
cb.diffuseMaterial = XMFLOAT4( diffuse[0], diffuse[1], diffuse[2], 0.0f );
cb.specularColor = XMFLOAT4( 0.2f, 0.2f, 0.2f, 0.0f );
cb.diffuseCoeff = 1.0f;
cb.shininess = 16.0f;
cb.transparency = 1.0f;
m_pD3DDeviceCtx->UpdateSubresource( m_pFixedFunctionConstantBuffer, 0, NULL, &cb, 0, 0 );
SurfaceEffectItemList::const_iterator it = m_resourceManager.getSurfaceEffectItemList().find( "Maya_fixedFunction" );
if ( it == m_resourceManager.getSurfaceEffectItemList().end() )
return false;
const SurfaceEffectItem* sei = it->second;
m_pD3DDeviceCtx->VSSetShader( sei->fVertexShader, NULL, 0 );
m_pD3DDeviceCtx->VSSetConstantBuffers( 0, 1, &m_pFixedFunctionConstantBuffer );
m_pD3DDeviceCtx->IASetInputLayout( sei->fInputLayout );
m_pD3DDeviceCtx->PSSetShader( sei->fPixelShader, NULL, 0 );
m_pD3DDeviceCtx->PSSetConstantBuffers( 0, 1, &m_pFixedFunctionConstantBuffer );
Geometry->Render( m_pD3DDeviceCtx );
drewSurface = true;
}
}
if ( drewSurface && active )
{
bool drawActiveWithBounds = false;
if (drawActiveWithBounds)
{
float color[3] = {1.0f, 1.0f, 1.0f};
drawBounds( matrix, box, color );
}
else
{
cb.lightColor = XMFLOAT4( 0.0f, 0.0f, 0.0f, 0.0f );
cb.ambientLight = XMFLOAT4( 1.0f, 1.0f, 1.0f, 0.0f );
cb.diffuseMaterial = XMFLOAT4( 1.0f, 1.0f, 1.0f, 0.0f );
cb.specularColor = XMFLOAT4( 0.0f, 0.0f, 0.0f, 0.0f );
m_pD3DDeviceCtx->UpdateSubresource( m_pFixedFunctionConstantBuffer, 0, NULL, &cb, 0, 0 );
m_pD3DDeviceCtx->RSSetState( m_pWireframeRS );
Geometry->Render( m_pD3DDeviceCtx );
}
}
}
}
return drewSurface;
}
bool DX11ViewportRenderer::drawScene(
const MRenderingInfo &renderInfo)
{
bool useDrawTraversal = true;
float groundPlaneColor[3] = { 0.8f, 0.8f, 0.8f };
if (useDrawTraversal)
{
{
if (!trav)
{
return true;
}
{
return true;
}
unsigned int i;
for (i=0; i<numItems; i++)
{
{
bool drawIt = false;
continue;
bool active = false;
bool templated = false;
{
drawIt = true;
{
active = true;
}
{
templated = true;
}
}
{
drawBounds( matrix, box, groundPlaneColor );
}
if (drawIt)
{
drawSurface( path, active, templated );
}
}
}
if (trav)
delete trav;
bool onlyInvalidItems = true;
clearResources( onlyInvalidItems, false );
}
}
else
{
MItDag dagIterator( traversalType, filter, &status);
for ( ; !dagIterator.isDone(); dagIterator.next() )
{
status = dagIterator.getPath(dagPath);
if ( !status ) {
status.
perror(
"MItDag::getPath");
continue;
}
if ( !status ) {
status.
perror(
"MFnDagNode constructor");
continue;
}
drawBounds( matrix, box, groundPlaneColor );
}
}
return true;
}
bool DX11ViewportRenderer::drawBounds(
const MMatrix &matrix,
const MBoundingBox &box,
float color[3] )
{
XMMATRIX mat = XMMATRIX
(
);
float minVal[3] = { (float)minPt.
x, (
float)minPt.
y, (float)minPt.
z };
float maxVal[3] = { (float)maxPt.
x, (
float)maxPt.
y, (float)maxPt.
z };
XMMATRIX bounds( 0.5f*(maxVal[0]-minVal[0]), 0.0f, 0.0f, 0.0f,
0.0f, 0.5f*(maxVal[1]-minVal[1]), 0.0f, 0.0f,
0.0f, 0.0f, 0.5f*(maxVal[2]-minVal[2]), 0.0f,
0.5f*(maxVal[0]+minVal[0]), 0.5f*(maxVal[1]+minVal[1]), 0.5f*(maxVal[2]+minVal[2]), 1.0f );
UINT stride = sizeof( BoundsVertex );
UINT offset = 0;
m_pD3DDeviceCtx->IASetVertexBuffers( 0, 1, &m_pBoundsVertexBuffer, &stride, &offset );
m_pD3DDeviceCtx->IASetIndexBuffer( m_pBoundsIndexBuffer, DXGI_FORMAT_R16_UINT, 0 );
BoundsConstants cb;
cb.fWVP = XMMatrixTranspose( bounds * mat * m_currentViewMatrix * m_currentProjectionMatrix );
cb.fDiffuseMaterial = XMFLOAT3( color[0], color[1], color[2] );
m_pD3DDeviceCtx->UpdateSubresource( m_pBoundsConstantBuffer, 0, NULL, &cb, 0, 0 );
m_pD3DDeviceCtx->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_LINELIST );
SurfaceEffectItemList::const_iterator it = m_resourceManager.getSurfaceEffectItemList().find( "Maya_unlit" );
if ( it == m_resourceManager.getSurfaceEffectItemList().end() )
return false;
const SurfaceEffectItem* sei = it->second;
m_pD3DDeviceCtx->VSSetShader( sei->fVertexShader, NULL, 0 );
m_pD3DDeviceCtx->VSSetConstantBuffers( 0, 1, &m_pBoundsConstantBuffer );
m_pD3DDeviceCtx->IASetInputLayout( sei->fInputLayout );
m_pD3DDeviceCtx->PSSetShader( sei->fPixelShader, NULL, 0 );
m_pD3DDeviceCtx->PSSetConstantBuffers( 0, 1, &m_pBoundsConstantBuffer );
m_pD3DDeviceCtx->DrawIndexed( 24, 0, 0 );
return true;
}
bool DX11ViewportRenderer::renderToTarget(
const MRenderingInfo &renderInfo )
{
{
return false;
}
if (!m_pD3DDevice || !m_pD3DDeviceCtx || !m_pTextureOutput || !m_pTextureInterm)
return false;
ID3D11RenderTargetView* targets[] = { m_pTextureIntermView };
m_pD3DDeviceCtx->OMSetRenderTargets( 1, targets, m_pDepthStencilView );
{
setupMatrices( renderInfo );
m_pD3DDeviceCtx->RSSetState( m_pNormalRS );
float clearColor[4] = { 0.0f, 0.125f, 0.6f, 1.0f };
m_pD3DDeviceCtx->ClearRenderTargetView( m_pTextureIntermView, clearColor );
if ( m_pDepthStencilView )
m_pD3DDeviceCtx->ClearDepthStencilView( m_pDepthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0 );
drawScene(renderInfo);
}
return true;
}
bool DX11ViewportRenderer::setupMatrices(
const MRenderingInfo &info )
{
if (!m_pD3DDevice || !m_pD3DDeviceCtx)
return false;
D3D11_VIEWPORT vp;
vp.Width = (float)m_renderWidth;
vp.Height = (float)m_renderHeight;
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
vp.TopLeftX = 0;
vp.TopLeftY = 0;
m_pD3DDeviceCtx->RSSetViewports( 1, &vp );
m_currentViewMatrix = XMMATRIX( (
float)view.
matrix[0][0], (
float)view.
matrix[0][1], (
float)view.
matrix[0][2], (
float)view.
matrix[0][3],
m_currentProjectionMatrix = XMMATRIX( (
float)projection.
matrix[0][0], (
float)projection.
matrix[0][1], (
float)projection.
matrix[0][2], (
float)projection.
matrix[0][3],
(
float)projection.
matrix[1][0], (
float)projection.
matrix[1][1], (
float)projection.
matrix[1][2], (
float)projection.
matrix[1][3],
(
float)projection.
matrix[2][0], (
float)projection.
matrix[2][1], (
float)projection.
matrix[2][2], (
float)projection.
matrix[2][3],
(
float)projection.
matrix[3][0], (
float)projection.
matrix[3][1], (
float)projection.
matrix[3][2], (
float)projection.
matrix[3][3]);
return true;
}
bool DX11ViewportRenderer::readFromTargetToSystemMemory()
{
if (!m_pD3DDevice || !m_pTextureOutput || m_renderWidth==0 || m_renderHeight == 0 ||
!m_pTextureReadBack)
return false;
bool readBuffer = false;
HRESULT hr;
#if defined(_DUMP_SURFACE_READBACK_CONTENTS_)
bool dumpToFile= false;
if (dumpToFile)
{
const char fileName[] = "c:\\temp\\d3dDump.jpg";
HRESULT hres = D3DXSaveSurfaceToFile( fileName, D3DXIFF_JPG,
m_pTextureOutputSurface, NULL , NULL );
if (hres != D3D_OK)
{
}
}
#endif
m_pD3DDeviceCtx->CopyResource( m_pTextureReadBack, m_pTextureOutput );
D3D11_MAPPED_SUBRESOURCE resource;
hr = m_pD3DDeviceCtx->Map( m_pTextureReadBack, 0, D3D11_MAP_READ, 0, &resource );
if ( FAILED(hr) )
{
return false;
}
INT pitch = resource.RowPitch;
BYTE *data = (BYTE *)resource.pData;
const unsigned int bytesPerPixel = 4;
unsigned int m_readBackBufferWidth = 0;
unsigned int m_readBackBufferHeight = 0;
m_readBackBuffer.getSize(m_readBackBufferWidth, m_readBackBufferHeight);
BYTE *m_readBackBufferPtr = NULL;
bool replaceReadBackBuffer = false;
if (!m_readBackBufferWidth || !m_readBackBufferHeight ||
m_readBackBufferWidth != m_renderWidth ||
m_readBackBufferHeight != m_renderHeight)
{
m_readBackBuffer.resize(m_renderWidth, m_renderHeight, false);
m_readBackBuffer.getSize(m_readBackBufferWidth, m_readBackBufferHeight);
if (m_readBackBufferWidth != m_renderWidth ||
m_readBackBufferHeight != m_renderHeight)
{
return false;
}
m_readBackBufferPtr = (BYTE *)(m_readBackBuffer.pixels());
}
else
m_readBackBufferPtr = (BYTE *)(m_readBackBuffer.pixels());
if (m_readBackBufferPtr)
{
unsigned int myLineSize = m_renderWidth * bytesPerPixel;
unsigned int offsetMyData = (m_renderHeight-1) * myLineSize;
unsigned int offsetData = 0;
unsigned int i;
for ( i=0 ; i < m_renderHeight; i++ )
{
memcpy( m_readBackBufferPtr + offsetMyData,
data + offsetData,
myLineSize );
offsetMyData -= myLineSize;
offsetData += pitch;
}
readBuffer = true;
}
if (replaceReadBackBuffer)
{
m_readBackBuffer.setPixels( m_readBackBufferPtr, m_renderWidth,
m_renderHeight );
delete[] m_readBackBufferPtr;
}
m_readBackBufferPtr = 0;
m_pD3DDeviceCtx->Unmap( m_pTextureReadBack, 0 );
return readBuffer;
}
#endif