diff options
Diffstat (limited to 'PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9')
22 files changed, 5099 insertions, 0 deletions
diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9Renderer.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9Renderer.cpp new file mode 100644 index 00000000..2c650e4b --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9Renderer.cpp @@ -0,0 +1,1183 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D9) + +#include "D3D9Renderer.h" + +#include <RendererDesc.h> + +#include <RendererProjection.h> + +#include <RendererVertexBufferDesc.h> +#include "D3D9RendererVertexBuffer.h" + +#include <RendererIndexBufferDesc.h> +#include "D3D9RendererIndexBuffer.h" + +#include <RendererInstanceBufferDesc.h> +#include "D3D9RendererInstanceBuffer.h" + +#include <RendererMeshDesc.h> +#include <RendererMeshContext.h> +#include "D3D9RendererMesh.h" + +#include <RendererMaterialDesc.h> +#include <RendererMaterialInstance.h> +#include "D3D9RendererMaterial.h" + +#include <RendererLightDesc.h> +#include <RendererDirectionalLightDesc.h> +#include "D3D9RendererDirectionalLight.h" +#include <RendererSpotLightDesc.h> +#include "D3D9RendererSpotLight.h" + +#include <RendererTexture2DDesc.h> +#include "D3D9RendererTexture2D.h" + +#include <RendererTargetDesc.h> +#include "D3D9RendererTarget.h" + +#include <SamplePlatform.h> + +using namespace SampleRenderer; + +void SampleRenderer::convertToD3D9(D3DCOLOR &dxcolor, const RendererColor &color) +{ + const float inv255 = 1.0f / 255.0f; + dxcolor = D3DXCOLOR(color.r*inv255, color.g*inv255, color.b*inv255, color.a*inv255); +} + +void SampleRenderer::convertToD3D9(float *dxvec, const PxVec3 &vec) +{ + dxvec[0] = vec.x; + dxvec[1] = vec.y; + dxvec[2] = vec.z; +} + +void SampleRenderer::convertToD3D9(D3DMATRIX &dxmat, const physx::PxMat44 &mat) +{ + PxMat44 mat44 = mat.getTranspose(); + memcpy(&dxmat._11, mat44.front(), 4 * 4 * sizeof (float)); +} + +void SampleRenderer::convertToD3D9(D3DMATRIX &dxmat, const RendererProjection &mat) +{ + float temp[16]; + mat.getColumnMajor44(temp); + for(PxU32 r=0; r<4; r++) + for(PxU32 c=0; c<4; c++) + { + dxmat.m[r][c] = temp[c*4+r]; + } +} + +/****************************** +* D3D9Renderer::D3DXInterface * +******************************/ + +D3D9Renderer::D3DXInterface::D3DXInterface(void) +{ + memset(this, 0, sizeof(*this)); +#if defined(RENDERER_WINDOWS) +#define D3DX_DLL "d3dx9_" RENDERER_TEXT2(D3DX_SDK_VERSION) ".dll" + + m_library = LoadLibraryA(D3DX_DLL); + if(!m_library) + { + MessageBoxA(0, "Unable to load " D3DX_DLL ". Please install the latest DirectX End User Runtime available at www.microsoft.com/directx.", "Renderer Error.", MB_OK); + } + if(m_library) + { +#define FIND_D3DX_FUNCTION(_name) \ +m_##_name = (LP##_name)GetProcAddress(m_library, #_name); \ +RENDERER_ASSERT(m_##_name, "Unable to find D3DX9 Function " #_name " in " D3DX_DLL "."); + + FIND_D3DX_FUNCTION(D3DXCompileShaderFromFileA) + FIND_D3DX_FUNCTION(D3DXGetVertexShaderProfile) + FIND_D3DX_FUNCTION(D3DXGetPixelShaderProfile) + FIND_D3DX_FUNCTION(D3DXSaveSurfaceToFileInMemory) + FIND_D3DX_FUNCTION(D3DXCreateBuffer) + FIND_D3DX_FUNCTION(D3DXSaveSurfaceToFileA) + FIND_D3DX_FUNCTION(D3DXGetShaderConstantTable) + +#undef FIND_D3DX_FUNCTION + } + +#define D3DCOMPILER_DLL "D3DCompiler_" RENDERER_TEXT2(D3DX_SDK_VERSION) ".dll" + m_compiler_library = LoadLibraryA(D3DCOMPILER_DLL); + if(!m_library) + { + MessageBoxA(0, "Unable to load " D3DCOMPILER_DLL ". Please install the latest DirectX End User Runtime available at www.microsoft.com/directx.", "Renderer Error.", MB_OK); + } + + +#undef D3DX_DLL +#endif +} + +D3D9Renderer::D3DXInterface::~D3DXInterface(void) +{ +#if defined(RENDERER_WINDOWS) + if(m_library) + { + FreeLibrary(m_library); + m_library = 0; + FreeLibrary(m_compiler_library); + m_compiler_library = 0; + } +#endif +} + +#if defined(RENDERER_WINDOWS) +#define CALL_D3DX_FUNCTION(_name, _params) if(m_##_name) result = m_##_name _params; +#else +#define CALL_D3DX_FUNCTION(_name, _params) result = _name _params; +#endif + +HRESULT D3D9Renderer::D3DXInterface::CompileShaderFromFileA(LPCSTR srcFile, CONST D3DXMACRO *defines, LPD3DXINCLUDE include, LPCSTR functionName, LPCSTR profile, DWORD flags, LPD3DXBUFFER *shader, LPD3DXBUFFER *errorMsgs, LPD3DXCONSTANTTABLE *constantTable) +{ + + HRESULT result = D3DERR_NOTAVAILABLE; + CALL_D3DX_FUNCTION(D3DXCompileShaderFromFileA, (srcFile, defines, include, functionName, profile, flags, shader, errorMsgs, constantTable)); + return result; + +} + +HRESULT D3D9Renderer::D3DXInterface::GetShaderConstantTable(const DWORD* pFunction, LPD3DXCONSTANTTABLE *constantTable) +{ + HRESULT result = D3DERR_NOTAVAILABLE; + CALL_D3DX_FUNCTION(D3DXGetShaderConstantTable, (pFunction, constantTable)); + return result; +} + +HRESULT D3D9Renderer::D3DXInterface::SaveSurfaceToFileA( LPCSTR pDestFile, D3DXIMAGE_FILEFORMAT DestFormat, LPDIRECT3DSURFACE9 pSrcSurface, CONST PALETTEENTRY* pSrcPalette, CONST RECT* pSrcRect) +{ + + HRESULT result = D3DERR_NOTAVAILABLE; + CALL_D3DX_FUNCTION(D3DXSaveSurfaceToFileA, (pDestFile, DestFormat, pSrcSurface, pSrcPalette, pSrcRect)); + return result; + +} + +LPCSTR D3D9Renderer::D3DXInterface::GetVertexShaderProfile(LPDIRECT3DDEVICE9 device) +{ + + LPCSTR result = 0; + CALL_D3DX_FUNCTION(D3DXGetVertexShaderProfile, (device)); + return result; + +} + +LPCSTR D3D9Renderer::D3DXInterface::GetPixelShaderProfile(LPDIRECT3DDEVICE9 device) +{ + LPCSTR result = 0; + CALL_D3DX_FUNCTION(D3DXGetPixelShaderProfile, (device)); + return result; +} + +HRESULT D3D9Renderer::D3DXInterface::SaveSurfaceToFileInMemory(LPD3DXBUFFER *ppDestBuf, D3DXIMAGE_FILEFORMAT DestFormat, LPDIRECT3DSURFACE9 pSrcSurface, const PALETTEENTRY *pSrcPalette, const RECT *pSrcRect) +{ + HRESULT result = D3DERR_NOTAVAILABLE; + CALL_D3DX_FUNCTION(D3DXSaveSurfaceToFileInMemory, (ppDestBuf, DestFormat, pSrcSurface, pSrcPalette, pSrcRect)); + return result; +} + +HRESULT D3D9Renderer::D3DXInterface::CreateBuffer(DWORD NumBytes, LPD3DXBUFFER *ppBuffer) +{ + HRESULT result = D3DERR_NOTAVAILABLE; + CALL_D3DX_FUNCTION(D3DXCreateBuffer, (NumBytes, ppBuffer)); + return result; +} + + +#undef CALL_D3DX_FUNCTION + +/********************************** +* D3D9Renderer::ShaderEnvironment * +**********************************/ + +D3D9Renderer::ShaderEnvironment::ShaderEnvironment(void) +{ + memset(this, 0, sizeof(*this)); +} + +/*************** +* D3D9Renderer * +***************/ + +D3D9Renderer::D3D9Renderer(IDirect3D9* inDirect3d, const char* devName, PxU32 dispWidth, PxU32 dispHeight, IDirect3DDevice9* inDevice, bool inIsDeviceEx, const char* assetDir) + : Renderer( DRIVER_DIRECT3D9, NULL, assetDir ) +{ + initialize(inIsDeviceEx); + m_d3d = inDirect3d; + strcpy_s( m_deviceName, 256, devName ); + m_displayWidth = dispWidth; + m_displayHeight = dispHeight; + m_d3dDevice = inDevice; + //Users must call + // checkResize(false); + // onDeviceReset(); +} + + +void D3D9Renderer::initialize( bool isDeviceEx ) +{ + m_textVDecl = NULL; + m_useShadersForTextRendering = true; + m_pixelCenterOffset = 0.5f; + m_displayWidth = 0; + m_displayHeight = 0; + m_displayBuffer = 0; + m_d3d = 0; + m_d3dDevice = 0; + m_d3dDepthStencilSurface = 0; + m_d3dSurface = 0; + m_d3dSwapChain = 0; + m_d3dSwapDepthStencilSurface = 0; + m_d3dSwapSurface = 0; + m_isDeviceEx = isDeviceEx; + + m_viewMatrix = PxMat44(PxIdentity); +} + +D3D9Renderer::D3D9Renderer(const RendererDesc &desc, const char* assetDir) : +Renderer (DRIVER_DIRECT3D9, desc.errorCallback, assetDir) +{ + initialize(false); + SampleFramework::SamplePlatform* m_platform = SampleFramework::SamplePlatform::platform(); + m_d3d = static_cast<IDirect3D9*>(m_platform->initializeD3D9()); + RENDERER_ASSERT(m_d3d, "Could not create Direct3D9 Interface."); + if(m_d3d) + { + memset(&m_d3dPresentParams, 0, sizeof(m_d3dPresentParams)); + m_d3dPresentParams.Windowed = 1; + m_d3dPresentParams.SwapEffect = D3DSWAPEFFECT_DISCARD; + m_d3dPresentParams.BackBufferFormat = D3DFMT_X8R8G8B8; + m_d3dPresentParams.EnableAutoDepthStencil = 0; + m_d3dPresentParams.AutoDepthStencilFormat = D3DFMT_D24S8; + m_d3dPresentParams.PresentationInterval = desc.vsync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE; + + HRESULT res = m_platform->initializeD3D9Display(&m_d3dPresentParams, + m_deviceName, + m_displayWidth, + m_displayHeight, + &m_d3dDevice); + + RENDERER_ASSERT(res==D3D_OK, "Failed to create Direct3D9 Device."); + if(res==D3D_OK) + { + m_d3dPresentParamsChanged = false; + checkResize(false); + onDeviceReset(); + } + } +} + +D3D9Renderer::~D3D9Renderer(void) +{ + assert(!m_textVDecl); + SampleFramework::SamplePlatform* m_platform = SampleFramework::SamplePlatform::platform(); + + releaseAllMaterials(); + + releaseSwapchain(); + + if(m_d3dDepthStencilSurface) + { + m_d3dDevice->SetDepthStencilSurface(NULL); + m_platform->D3D9BlockUntilNotBusy(m_d3dDepthStencilSurface); + m_d3dDepthStencilSurface->Release(); + } + m_platform->D3D9DeviceBlockUntilIdle(); + if(m_d3dDevice) m_d3dDevice->Release(); + if(m_d3d) m_d3d->Release(); + if(m_displayBuffer) m_displayBuffer->Release(); +} + +bool D3D9Renderer::checkResize(bool isDeviceLost) +{ + bool isDeviceReset = false; +#if defined(RENDERER_WINDOWS) + if(SampleFramework::SamplePlatform::platform()->getWindowHandle() && m_d3dDevice) + { + PxU32 width = 0; + PxU32 height = 0; + SampleFramework::SamplePlatform::platform()->getWindowSize(width, height); + if(width && height && (width != m_displayWidth || height != m_displayHeight) || isDeviceLost) + { + bool needsReset = (m_displayWidth&&m_displayHeight&&(isDeviceLost||!useSwapchain()) ? true : false); + m_displayWidth = width; + m_displayHeight = height; + + m_d3dPresentParams.BackBufferWidth = (UINT)m_displayWidth; + m_d3dPresentParams.BackBufferHeight = (UINT)m_displayHeight; + + D3DVIEWPORT9 viewport = {0}; + m_d3dDevice->GetViewport(&viewport); + viewport.Width = (DWORD)m_displayWidth; + viewport.Height = (DWORD)m_displayHeight; + viewport.MinZ = 0.0f; + viewport.MaxZ = 1.0f; + + if(needsReset) + { + physx::PxU64 res = m_d3dDevice->TestCooperativeLevel(); + if(res == D3D_OK || res == D3DERR_DEVICENOTRESET) //if device is lost, device has to be ready for reset + { + onDeviceLost(); + isDeviceReset = resetDevice(); + if (isDeviceReset) + { + onDeviceReset(); + m_d3dDevice->SetViewport(&viewport); + } + } + } + else + { + if(m_d3dSurface == NULL) + m_d3dDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &m_d3dSurface); + buildSwapchain(); + m_d3dDevice->SetViewport(&viewport); + } + } + } +#endif + return isDeviceReset; +} + +bool D3D9Renderer::resetDevice(void) +{ + + HRESULT res = m_d3dDevice->Reset(&m_d3dPresentParams); + RENDERER_ASSERT(res == D3D_OK, "Failed to reset Direct3D9 Device."); + if(res == D3D_OK) + { + m_d3dPresentParamsChanged = false; + return true; + } + else + { + return false; + } +} + +void D3D9Renderer::buildSwapchain(void) +{ + if (!useSwapchain()) + return; + +#if RENDERER_ENABLE_DIRECT3D9_SWAPCHAIN + // Set the DX9 surfaces back to the originals + m_d3dDevice->SetRenderTarget(0, m_d3dSurface); + m_d3dDevice->SetDepthStencilSurface(m_d3dDepthStencilSurface); + + // Release the swapchain resources + releaseSwapchain(); + + // Recreate the swapchain resources + m_d3dDevice->CreateAdditionalSwapChain(&m_d3dPresentParams, &m_d3dSwapChain); + m_d3dSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &m_d3dSwapSurface); + m_d3dDevice->CreateDepthStencilSurface(m_displayWidth,m_displayHeight,D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, false, &m_d3dSwapDepthStencilSurface, 0); + + // Re-assign the DX9 surfaces to use the swapchain + m_d3dDevice->SetRenderTarget(0, m_d3dSwapSurface); + m_d3dDevice->SetDepthStencilSurface(m_d3dSwapDepthStencilSurface); +#endif +} + +void SampleRenderer::D3D9Renderer::releaseSwapchain() +{ +#if RENDERER_ENABLE_DIRECT3D9_SWAPCHAIN + if(m_d3dSwapChain) + { + m_d3dSwapChain->Release(); + m_d3dSwapChain = 0; + } + if(m_d3dSwapDepthStencilSurface) + { + m_d3dSwapDepthStencilSurface->Release(); + m_d3dSwapDepthStencilSurface = 0; + } + if(m_d3dSwapSurface) + { + m_d3dSwapSurface->Release(); + m_d3dSwapSurface = 0; + } +#endif +} + +bool SampleRenderer::D3D9Renderer::useSwapchain() const +{ + return RENDERER_ENABLE_DIRECT3D9_SWAPCHAIN==1; +} + +bool SampleRenderer::D3D9Renderer::validSwapchain() const +{ +#if RENDERER_ENABLE_DIRECT3D9_SWAPCHAIN + return m_d3dSwapChain && m_d3dSwapDepthStencilSurface && m_d3dSwapSurface; +#else + return false; +#endif +} + +HRESULT SampleRenderer::D3D9Renderer::presentSwapchain() +{ +#if RENDERER_ENABLE_DIRECT3D9_SWAPCHAIN + RENDERER_ASSERT(m_d3dSwapChain, "Invalid D3D9 swapchain"); + if(m_d3dSwapChain) + return m_d3dSwapChain->Present(0, 0, 0, 0, 0); + else +#endif + return D3DERR_NOTAVAILABLE; +} + +void D3D9Renderer::releaseDepthStencilSurface(void) +{ + if(m_d3dDepthStencilSurface) + { + m_d3dDepthStencilSurface->Release(); + m_d3dDepthStencilSurface = 0; + } +} + +void D3D9Renderer::onDeviceLost(void) +{ + notifyResourcesLostDevice(); + if(m_d3dDepthStencilSurface) + { + m_d3dDepthStencilSurface->Release(); + m_d3dDepthStencilSurface = 0; + } + if (m_d3dSurface) + { + m_d3dSurface->Release(); + m_d3dSurface = 0; + } + releaseSwapchain(); +} + +void D3D9Renderer::onDeviceReset(void) +{ + if(m_d3dDevice) + { + // set out initial states... + m_d3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); +#if defined(RENDERER_WINDOWS) + m_d3dDevice->SetRenderState(D3DRS_LIGHTING, 0); +#endif + m_d3dDevice->SetRenderState(D3DRS_ZENABLE, 1); + m_d3dDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &m_d3dSurface); + buildDepthStencilSurface(); + buildSwapchain(); + } + notifyResourcesResetDevice(); +} + +void D3D9Renderer::buildDepthStencilSurface(void) +{ + if(m_d3dDevice) + { + PxU32 width = m_displayWidth; + PxU32 height = m_displayHeight; + if(m_d3dDepthStencilSurface) + { + D3DSURFACE_DESC dssdesc; + m_d3dDepthStencilSurface->GetDesc(&dssdesc); + if(width != (PxU32)dssdesc.Width || height != (PxU32)dssdesc.Height) + { + m_d3dDepthStencilSurface->Release(); + m_d3dDepthStencilSurface = 0; + } + } + if(!m_d3dDepthStencilSurface) + { + const D3DFORMAT depthFormat = D3DFMT_D24S8; + const D3DMULTISAMPLE_TYPE multisampleType = D3DMULTISAMPLE_NONE; + const DWORD multisampleQuality = 0; + const BOOL discard = 0; + IDirect3DSurface9 *depthSurface = 0; + HRESULT result = m_d3dDevice->CreateDepthStencilSurface((UINT)width, (UINT)height, depthFormat, multisampleType, multisampleQuality, discard, &depthSurface, 0); + RENDERER_ASSERT(result == D3D_OK, "Failed to create Direct3D9 DepthStencil Surface."); + if(result == D3D_OK) + { + m_d3dDepthStencilSurface = depthSurface; + } + } + m_d3dDevice->SetDepthStencilSurface(m_d3dDepthStencilSurface); + } +} + +// clears the offscreen buffers. +void D3D9Renderer::clearBuffers(void) +{ + if(m_d3dDevice) + { + const DWORD flags = D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL; + m_d3dDevice->Clear(0, NULL, flags, D3DCOLOR_RGBA(getClearColor().r, getClearColor().g, getClearColor().b, getClearColor().a), 1.0f, 0); + } +} + +// presents the current color buffer to the screen. +// returns true on device reset and if buffers need to be rewritten. +bool D3D9Renderer::swapBuffers(void) +{ + bool isDeviceReset = false; + if(m_d3dDevice) + { + HRESULT result = S_OK; + if (useSwapchain() && validSwapchain()) + result = presentSwapchain(); + else + result = SampleFramework::SamplePlatform::platform()->D3D9Present(); + RENDERER_ASSERT(result == D3D_OK || result == D3DERR_DEVICELOST, "Unknown Direct3D9 error when swapping buffers."); + if(result == D3D_OK || result == D3DERR_DEVICELOST) + { + isDeviceReset = checkResize(result == D3DERR_DEVICELOST || m_d3dPresentParamsChanged); + } + } + return isDeviceReset; +} + +void D3D9Renderer::getWindowSize(PxU32 &width, PxU32 &height) const +{ + RENDERER_ASSERT(m_displayHeight * m_displayWidth > 0, "variables not initialized properly"); + width = m_displayWidth; + height = m_displayHeight; +} + +RendererVertexBuffer *D3D9Renderer::createVertexBuffer(const RendererVertexBufferDesc &desc) +{ + PX_PROFILE_ZONE("D3D9Renderer_createVertexBuffer",0); + D3D9RendererVertexBuffer *vb = 0; + if(m_d3dDevice) + { + RENDERER_ASSERT(desc.isValid(), "Invalid Vertex Buffer Descriptor."); + if(desc.isValid()) + { + vb = new D3D9RendererVertexBuffer(*m_d3dDevice, *this, desc); + } + } + if(vb) addResource(*vb); + return vb; +} + +RendererIndexBuffer *D3D9Renderer::createIndexBuffer(const RendererIndexBufferDesc &desc) +{ + PX_PROFILE_ZONE("D3D9Renderer_createIndexBuffer",0); + D3D9RendererIndexBuffer *ib = 0; + if(m_d3dDevice) + { + RENDERER_ASSERT(desc.isValid(), "Invalid Index Buffer Descriptor."); + if(desc.isValid()) + { + ib = new D3D9RendererIndexBuffer(*m_d3dDevice, *this, desc); + } + } + if(ib) addResource(*ib); + return ib; +} + +RendererInstanceBuffer *D3D9Renderer::createInstanceBuffer(const RendererInstanceBufferDesc &desc) +{ + PX_PROFILE_ZONE("D3D9Renderer_createInstanceBuffer",0); + D3D9RendererInstanceBuffer *ib = 0; + if(m_d3dDevice) + { + RENDERER_ASSERT(desc.isValid(), "Invalid Instance Buffer Descriptor."); + if(desc.isValid()) + { + ib = new D3D9RendererInstanceBuffer(*m_d3dDevice, *this, desc); + } + } + if(ib) addResource(*ib); + return ib; +} + +RendererTexture2D *D3D9Renderer::createTexture2D(const RendererTexture2DDesc &desc) +{ + PX_PROFILE_ZONE("D3D9Renderer_createTexture2D",0); + D3D9RendererTexture2D *texture = 0; + if(m_d3dDevice) + { + RENDERER_ASSERT(desc.isValid(), "Invalid Texture 2D Descriptor."); + if(desc.isValid()) + { + texture = new D3D9RendererTexture2D(*m_d3dDevice, *this, desc); + } + } + if(texture) addResource(*texture); + return texture; +} + +RendererTexture3D *D3D9Renderer::createTexture3D(const RendererTexture3DDesc &desc) +{ + //RENDERER_ASSERT(0, "Not implemented!"); + // TODO: Properly implement. + return 0; +} + +RendererTarget *D3D9Renderer::createTarget(const RendererTargetDesc &desc) +{ + PX_PROFILE_ZONE("D3D9Renderer_createTarget",0); + RendererTarget *target = 0; +#if defined(RENDERER_ENABLE_DIRECT3D9_TARGET) + D3D9RendererTarget *d3dTarget = 0; + RENDERER_ASSERT(desc.isValid(), "Invalid Target Descriptor."); + if(desc.isValid()) + { + d3dTarget = new D3D9RendererTarget(*m_d3dDevice, desc); + } + if(d3dTarget) addResource(*d3dTarget); + target = d3dTarget; +#endif + return target; +} + +RendererMaterial *D3D9Renderer::createMaterial(const RendererMaterialDesc &desc) +{ + RendererMaterial *mat = hasMaterialAlready(desc); + RENDERER_ASSERT(desc.isValid(), "Invalid Material Descriptor."); + if(!mat && desc.isValid()) + { + PX_PROFILE_ZONE("D3D9Renderer_createMaterial",0); + mat = new D3D9RendererMaterial(*this, desc); + + registerMaterial(desc, mat); + } + return mat; +} + +RendererMesh *D3D9Renderer::createMesh(const RendererMeshDesc &desc) +{ + PX_PROFILE_ZONE("D3D9Renderer_createMesh",0); + D3D9RendererMesh *mesh = 0; + RENDERER_ASSERT(desc.isValid(), "Invalid Mesh Descriptor."); + if(desc.isValid()) + { + mesh = new D3D9RendererMesh(*this, desc); + } + return mesh; +} + +RendererLight *D3D9Renderer::createLight(const RendererLightDesc &desc) +{ + PX_PROFILE_ZONE("D3D9Renderer_createLight",0); + RendererLight *light = 0; + if(m_d3dDevice) + { + RENDERER_ASSERT(desc.isValid(), "Invalid Light Descriptor."); + if(desc.isValid()) + { + switch(desc.type) + { + case RendererLight::TYPE_DIRECTIONAL: + light = new D3D9RendererDirectionalLight(*this, *(RendererDirectionalLightDesc*)&desc); + break; + case RendererLight::TYPE_SPOT: + light = new D3D9RendererSpotLight(*this, *(RendererSpotLightDesc*)&desc); + break; + default: + RENDERER_ASSERT(0, "Not implemented!"); + } + } + } + return light; +} + +void D3D9Renderer::setVsync(bool on) +{ + UINT newVal = on ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE; + m_d3dPresentParamsChanged |= m_d3dPresentParams.PresentationInterval != newVal; + m_d3dPresentParams.PresentationInterval = newVal; + //RENDERER_ASSERT(0, "Not implemented!"); +} + +void D3D9Renderer::disableDepthTest() +{ + m_d3dDevice->SetRenderState(D3DRS_ZENABLE, 0); +} + +void D3D9Renderer::enableDepthTest() +{ + m_d3dDevice->SetRenderState(D3DRS_ZENABLE, 1); +} + +bool D3D9Renderer::beginRender(void) +{ + bool ok = false; + if(m_d3dDevice) + { + ok = m_d3dDevice->BeginScene() == D3D_OK; + } + return ok; +} + +void D3D9Renderer::endRender(void) +{ + if(m_d3dDevice) + { + m_d3dDevice->EndScene(); + } +} + +void D3D9Renderer::bindViewProj(const physx::PxMat44 &eye, const RendererProjection &proj) +{ + m_viewMatrix = eye.inverseRT(); + convertToD3D9(m_environment.viewMatrix, m_viewMatrix); + convertToD3D9(m_environment.projMatrix, proj); + + const PxVec3 eyePosition = eye.getPosition(); + const PxVec3 eyeDirection = -eye.getBasis(2); + memcpy(m_environment.eyePosition, &eyePosition.x, sizeof(float)*3); + memcpy(m_environment.eyeDirection, &eyeDirection.x, sizeof(float)*3); +} + +void D3D9Renderer::bindFogState(const RendererColor &fogColor, float fogDistance) +{ + const float inv255 = 1.0f / 255.0f; + + m_environment.fogColorAndDistance[0] = fogColor.r*inv255; + m_environment.fogColorAndDistance[1] = fogColor.g*inv255; + m_environment.fogColorAndDistance[2] = fogColor.b*inv255; + m_environment.fogColorAndDistance[3] = fogDistance; +} + +void D3D9Renderer::bindAmbientState(const RendererColor &ambientColor) +{ + convertToD3D9(m_environment.ambientColor, ambientColor); +} + +void D3D9Renderer::bindDeferredState(void) +{ + RENDERER_ASSERT(0, "Not implemented!"); +} + +void D3D9Renderer::bindMeshContext(const RendererMeshContext &context) +{ + physx::PxMat44 model; + physx::PxMat44 modelView; + if(context.transform) model = *context.transform; + else model = PxMat44(PxIdentity); + modelView = m_viewMatrix * model; + + convertToD3D9(m_environment.modelMatrix, model); + convertToD3D9(m_environment.modelViewMatrix, modelView); + + // it appears that D3D winding is backwards, so reverse them... + DWORD cullMode = D3DCULL_CCW; + switch(context.cullMode) + { + case RendererMeshContext::CLOCKWISE: + cullMode = context.negativeScale ? D3DCULL_CW : D3DCULL_CCW; + break; + case RendererMeshContext::COUNTER_CLOCKWISE: + cullMode = context.negativeScale ? D3DCULL_CCW : D3DCULL_CW; + break; + case RendererMeshContext::NONE: + cullMode = D3DCULL_NONE; + break; + default: + RENDERER_ASSERT(0, "Invalid Cull Mode"); + } + if (!blendingCull() && NULL != context.material && context.material->getBlending()) + cullMode = D3DCULL_NONE; + + m_d3dDevice->SetRenderState(D3DRS_CULLMODE, cullMode); + + DWORD fillMode = D3DFILL_SOLID; + switch(context.fillMode) + { + case RendererMeshContext::SOLID: + fillMode = D3DFILL_SOLID; + break; + case RendererMeshContext::LINE: + fillMode = D3DFILL_WIREFRAME; + break; + case RendererMeshContext::POINT: + fillMode = D3DFILL_POINT; + break; + } + m_d3dDevice->SetRenderState(D3DRS_FILLMODE, fillMode); + + RENDERER_ASSERT(context.numBones <= RENDERER_MAX_BONES, "Too many bones."); + if(context.boneMatrices && context.numBones>0 && context.numBones <= RENDERER_MAX_BONES) + { + for(PxU32 i=0; i<context.numBones; i++) + { + convertToD3D9(m_environment.boneMatrices[i], context.boneMatrices[i]); + } + m_environment.numBones = context.numBones; + } +} + +void D3D9Renderer::beginMultiPass(void) +{ + if(m_d3dDevice) + { + m_d3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, 1); + m_d3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE); + m_d3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); + m_d3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_EQUAL); + } +} + +void D3D9Renderer::endMultiPass(void) +{ + if(m_d3dDevice) + { + m_d3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, 0); + m_d3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESS); + } +} + +void D3D9Renderer::beginTransparentMultiPass(void) +{ + if(m_d3dDevice) + { + setEnableBlendingOverride(true); + m_d3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, 1); + m_d3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + m_d3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); + //m_d3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_EQUAL); + m_d3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL); + m_d3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, false); + } +} + +void D3D9Renderer::endTransparentMultiPass(void) +{ + if(m_d3dDevice) + { + setEnableBlendingOverride(false); + m_d3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, 0); + m_d3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESS); + m_d3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, true); + } +} + +void D3D9Renderer::renderDeferredLight(const RendererLight &light) +{ + RENDERER_ASSERT(0, "Not implemented!"); +} + +PxU32 D3D9Renderer::convertColor(const RendererColor& color) const +{ + D3DCOLOR outColor; + convertToD3D9(outColor, color); + + return outColor; +} + +bool D3D9Renderer::isOk(void) const +{ + bool ok = true; + if(!m_d3d) ok = false; + if(!m_d3dDevice) ok = false; +#if defined(RENDERER_WINDOWS) + ok = SampleFramework::SamplePlatform::platform()->isD3D9ok(); + if(!m_d3dx.m_library) ok = false; + // note: we could assert m_compiler_library here too, but actually loading that one is optional, so the app still may work without it. +#endif + return ok; +} + +void D3D9Renderer::addResource(D3D9RendererResource &resource) +{ + RENDERER_ASSERT(resource.m_d3dRenderer==0, "Resource already in added to the Renderer!"); + if(resource.m_d3dRenderer==0) + { + resource.m_d3dRenderer = this; + m_resources.push_back(&resource); + } +} + +void D3D9Renderer::removeResource(D3D9RendererResource &resource) +{ + RENDERER_ASSERT(resource.m_d3dRenderer==this, "Resource not part of this Renderer!"); + if(resource.m_d3dRenderer==this) + { + resource.m_d3dRenderer = 0; + const PxU32 numResources = (PxU32)m_resources.size(); + for (PxU32 i = 0; i < numResources; i++) + { + if(m_resources[i] == &resource) + { + // the order of resources needs to remain intact, otherwise a render target that has a dependency on a texture might get onDeviceReset'ed earlier which is an error + m_resources.erase(m_resources.begin() + i); + break; + } + } + } +} + +void D3D9Renderer::notifyResourcesLostDevice(void) +{ + const PxU32 numResources = (PxU32)m_resources.size(); + for(PxU32 i=0; i<numResources; i++) + { + m_resources[i]->onDeviceLost(); + } +} + +void D3D9Renderer::notifyResourcesResetDevice(void) +{ + const PxU32 numResources = (PxU32)m_resources.size(); + for(PxU32 i=0; i<numResources; i++) + { + m_resources[i]->onDeviceReset(); + } +} + + +/////////////////////////////////////////////////////////////////////////////// + +static DWORD gCullMode; +static DWORD gAlphaBlendEnable; +static DWORD gSrcBlend; +static DWORD gDstBlend; +static DWORD gFillMode; +static DWORD gZWrite; + +bool D3D9Renderer::initTexter() +{ + if(!Renderer::initTexter()) + return false; + + if(!m_textVDecl) + { + D3DVERTEXELEMENT9 vdecl[4]; + vdecl[0].Stream = 0; + vdecl[0].Offset = 0; + vdecl[0].Type = D3DDECLTYPE_FLOAT4; + vdecl[0].Method = D3DDECLMETHOD_DEFAULT; +#if defined(RENDERER_XBOX360) + vdecl[0].Usage = D3DDECLUSAGE_POSITION; // PT: D3DDECLUSAGE_POSITIONT is not available on Xbox +#endif +#if defined(RENDERER_WINDOWS) + vdecl[0].Usage = D3DDECLUSAGE_POSITIONT; +#endif + vdecl[0].UsageIndex = 0; + + vdecl[1].Stream = 0; + vdecl[1].Offset = 4*4; + vdecl[1].Type = D3DDECLTYPE_D3DCOLOR; + vdecl[1].Method = D3DDECLMETHOD_DEFAULT; + vdecl[1].Usage = D3DDECLUSAGE_COLOR; + vdecl[1].UsageIndex = 0; + + vdecl[2].Stream = 0; + vdecl[2].Offset = 4*4 + 4; + vdecl[2].Type = D3DDECLTYPE_FLOAT2; + vdecl[2].Method = D3DDECLMETHOD_DEFAULT; + vdecl[2].Usage = D3DDECLUSAGE_TEXCOORD; + vdecl[2].UsageIndex = 0; + + vdecl[3].Stream = 0xFF; + vdecl[3].Offset = 0; + vdecl[3].Type = (DWORD)D3DDECLTYPE_UNUSED; + vdecl[3].Method = 0; + vdecl[3].Usage = 0; + vdecl[3].UsageIndex = 0; + + m_d3dDevice->CreateVertexDeclaration(vdecl, &m_textVDecl); + if(!m_textVDecl) + { + closeTexter(); + return false; + } + } + + return true; +} + +void D3D9Renderer::closeTexter() +{ + if(m_textVDecl) + { + IDirect3DVertexDeclaration9* currDecl = NULL; + m_d3dDevice->GetVertexDeclaration(&currDecl); + if (currDecl == m_textVDecl) + { + m_d3dDevice->SetVertexDeclaration(NULL); + } + m_textVDecl->Release(); + m_textVDecl = NULL; + } + + Renderer::closeTexter(); +} + + +void D3D9Renderer::setupTextRenderStates() +{ + // PT: save render states. Let's just hope this isn't a pure device, else the Get method won't work + m_d3dDevice->GetRenderState(D3DRS_CULLMODE, &gCullMode); + m_d3dDevice->GetRenderState(D3DRS_ALPHABLENDENABLE, &gAlphaBlendEnable); + m_d3dDevice->GetRenderState(D3DRS_SRCBLEND, &gSrcBlend); + m_d3dDevice->GetRenderState(D3DRS_DESTBLEND, &gDstBlend); + m_d3dDevice->GetRenderState(D3DRS_FILLMODE, &gFillMode); + m_d3dDevice->GetRenderState(D3DRS_ZWRITEENABLE, &gZWrite); + + // PT: setup render states for text rendering + m_d3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + m_d3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true); + m_d3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + m_d3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + m_d3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); + m_d3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, false); + +#if defined(RENDERER_XBOX360) + // PT: D3DDECLUSAGE_POSITIONT is not available on Xbox, this is the workaround + m_d3dDevice->SetRenderState(D3DRS_VIEWPORTENABLE, false); +#endif +} + +void D3D9Renderer::resetTextRenderStates() +{ + // PT: restore render states. We want text rendering not to interfere with existing render states. + // For example the text should never be rendered in wireframe, even if the scene is. + m_d3dDevice->SetRenderState(D3DRS_CULLMODE, gCullMode); + m_d3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, gAlphaBlendEnable); + m_d3dDevice->SetRenderState(D3DRS_SRCBLEND, gSrcBlend); + m_d3dDevice->SetRenderState(D3DRS_DESTBLEND, gDstBlend); + m_d3dDevice->SetRenderState(D3DRS_FILLMODE, gFillMode); + m_d3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, gZWrite); +#if defined(RENDERER_XBOX360) + m_d3dDevice->SetRenderState(D3DRS_VIEWPORTENABLE, true); +#endif +} + +void D3D9Renderer::renderTextBuffer(const void* vertices, PxU32 nbVerts, const PxU16* indices, PxU32 nbIndices, RendererMaterial* material) +{ + PX_UNUSED(material); + // PT: font texture must have been selected prior to calling this function + const int PrimCount = nbIndices/3; + const int Stride = sizeof(TextVertex); + + if(m_textVDecl && FAILED(m_d3dDevice->SetVertexDeclaration(m_textVDecl))) + { + assert(0); + return; + } + + DWORD hr = m_d3dDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, nbVerts, PrimCount, indices, D3DFMT_INDEX16, vertices, Stride); + if(FAILED(hr)) + { + // printf("Error!\n"); + } +} + +void D3D9Renderer::renderLines2D(const void* vertices, PxU32 nbVerts) +{ + const int PrimCount = nbVerts-1; + const int Stride = sizeof(TextVertex); + + if(m_textVDecl && FAILED(m_d3dDevice->SetVertexDeclaration(m_textVDecl))) + { + assert(0); + return; + } + + DWORD hr = m_d3dDevice->DrawPrimitiveUP(D3DPT_LINESTRIP, PrimCount, vertices, Stride); + if(FAILED(hr)) + { + // printf("Error!\n"); + } +} + +void D3D9Renderer::setupScreenquadRenderStates() +{ + m_d3dDevice->GetRenderState(D3DRS_CULLMODE, &gCullMode); + m_d3dDevice->GetRenderState(D3DRS_FILLMODE, &gFillMode); + + m_d3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + m_d3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); + + m_d3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, false); +#if defined(RENDERER_XBOX360) + m_d3dDevice->SetRenderState(D3DRS_VIEWPORTENABLE, false); +#endif +} + +void D3D9Renderer::resetScreenquadRenderStates() +{ + m_d3dDevice->SetRenderState(D3DRS_CULLMODE, gCullMode); + m_d3dDevice->SetRenderState(D3DRS_FILLMODE, gFillMode); + m_d3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, true); +#if defined(RENDERER_XBOX360) + m_d3dDevice->SetRenderState(D3DRS_VIEWPORTENABLE, true); +#endif +} + +bool D3D9Renderer::captureScreen( PxU32 &width, PxU32& height, PxU32& sizeInBytes, const void*& screenshotData ) +{ +#if defined(RENDERER_XBOX360) + return false; +#else + bool bSuccess = false; + + IDirect3DSurface9* backBuffer = NULL; + if (useSwapchain() && validSwapchain()) + { +#if RENDERER_ENABLE_DIRECT3D9_SWAPCHAIN + bSuccess = SUCCEEDED(m_d3dSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &backBuffer)); +#endif + } + else + { + bSuccess = SUCCEEDED(m_d3dDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backBuffer)); + } + + if (bSuccess) + { + bSuccess = false; + if(m_displayBuffer) + { + m_displayBuffer->Release(); + m_displayBuffer = 0; + } + + if(SUCCEEDED(m_d3dx.SaveSurfaceToFileInMemory(&m_displayBuffer, D3DXIFF_BMP, backBuffer, NULL, NULL))) + { + getWindowSize(width, height); + sizeInBytes = (physx::PxU32)m_displayBuffer->GetBufferSize(); + screenshotData = m_displayBuffer->GetBufferPointer(); + bSuccess = true; + } + backBuffer->Release(); + } + + return bSuccess; +#endif +} + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D9) + diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9Renderer.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9Renderer.h new file mode 100644 index 00000000..645d2314 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9Renderer.h @@ -0,0 +1,299 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +#ifndef D3D9_RENDERER_H +#define D3D9_RENDERER_H + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D9) + +#include <Renderer.h> +#include <vector> + +#if defined(RENDERER_DEBUG) + //#define D3D_DEBUG_INFO 1 +#endif + +#if defined(RENDERER_XBOX360) +#include <xtl.h> +#endif +#include <d3d9.h> +#include <d3dx9.h> + +// Enables/Disables use of non-managed resources for vertex/instance buffers. +// Disabled for now as it appears to actually slow us down significantly on particles. +#if defined(RENDERER_XBOX360) +#define RENDERER_ENABLE_DYNAMIC_VB_POOLS 0 +#define RENDERER_ENABLE_DIRECT3D9_SWAPCHAIN 0 +#else +#define RENDERER_ENABLE_DYNAMIC_VB_POOLS 1 +#define RENDERER_ENABLE_DIRECT3D9_SWAPCHAIN 1 +#endif +struct IDirect3DSwapChain9; + +namespace SampleRenderer +{ + + class RendererDesc; + class RendererColor; + + void convertToD3D9(D3DCOLOR &dxcolor, const RendererColor &color); + void convertToD3D9(float *dxvec, const PxVec3 &vec); + void convertToD3D9(D3DMATRIX &dxmat, const physx::PxMat44 &mat); + void convertToD3D9(D3DMATRIX &dxmat, const RendererProjection &mat); + + class D3D9RendererResource; + + class D3D9Renderer : public Renderer + { + friend class D3D9RendererResource; + public: + class D3DXInterface + { + friend class D3D9Renderer; + private: + D3DXInterface(void); + ~D3DXInterface(void); + + public: + HRESULT CompileShaderFromFileA(LPCSTR srcFile, CONST D3DXMACRO *defines, LPD3DXINCLUDE include, LPCSTR functionName, LPCSTR profile, DWORD flags, LPD3DXBUFFER *shader, LPD3DXBUFFER *errorMsgs, LPD3DXCONSTANTTABLE *constantTable); + HRESULT GetShaderConstantTable(const DWORD* pFunction, LPD3DXCONSTANTTABLE *constantTable); + LPCSTR GetVertexShaderProfile(LPDIRECT3DDEVICE9 device); + LPCSTR GetPixelShaderProfile(LPDIRECT3DDEVICE9 device); + HRESULT SaveSurfaceToFileInMemory(LPD3DXBUFFER *ppDestBuf, D3DXIMAGE_FILEFORMAT DestFormat, LPDIRECT3DSURFACE9 pSrcSurface, const PALETTEENTRY *pSrcPalette, const RECT *pSrcRect); + HRESULT CreateBuffer(DWORD NumBytes, LPD3DXBUFFER *ppBuffer); + HRESULT SaveSurfaceToFileA( LPCSTR pDestFile, D3DXIMAGE_FILEFORMAT DestFormat, LPDIRECT3DSURFACE9 pSrcSurface, CONST PALETTEENTRY* pSrcPalette, CONST RECT* pSrcRect); + + public: +#if defined(RENDERER_WINDOWS) + HMODULE m_library; + HMODULE m_compiler_library; + +#define DEFINE_D3DX_FUNCTION(_name, _return, _params) \ + typedef _return (WINAPI* LP##_name) _params; \ + LP##_name m_##_name; + + DEFINE_D3DX_FUNCTION(D3DXCompileShaderFromFileA, HRESULT, (LPCSTR, CONST D3DXMACRO*, LPD3DXINCLUDE, LPCSTR, LPCSTR, DWORD, LPD3DXBUFFER*, LPD3DXBUFFER*, LPD3DXCONSTANTTABLE *)) + DEFINE_D3DX_FUNCTION(D3DXGetVertexShaderProfile, LPCSTR, (LPDIRECT3DDEVICE9)); + DEFINE_D3DX_FUNCTION(D3DXGetPixelShaderProfile, LPCSTR, (LPDIRECT3DDEVICE9)); + DEFINE_D3DX_FUNCTION(D3DXSaveSurfaceToFileInMemory, HRESULT, (LPD3DXBUFFER*, D3DXIMAGE_FILEFORMAT, LPDIRECT3DSURFACE9, const PALETTEENTRY*, const RECT*)); + DEFINE_D3DX_FUNCTION(D3DXSaveSurfaceToFileA, HRESULT, (LPCSTR ,D3DXIMAGE_FILEFORMAT , LPDIRECT3DSURFACE9 , CONST PALETTEENTRY* , CONST RECT* )); + DEFINE_D3DX_FUNCTION(D3DXGetShaderConstantTable, HRESULT, (const DWORD* , LPD3DXCONSTANTTABLE*)); + DEFINE_D3DX_FUNCTION(D3DXCreateBuffer, HRESULT, (DWORD, LPD3DXBUFFER*)); + +#undef DEFINE_D3DX_FUNCTION +#endif + }; + + class ShaderEnvironment + { + public: + D3DMATRIX modelMatrix; + D3DMATRIX viewMatrix; + D3DMATRIX projMatrix; + D3DMATRIX modelViewMatrix; + D3DMATRIX modelViewProjMatrix; + + D3DXMATRIX boneMatrices[RENDERER_MAX_BONES]; + PxU32 numBones; + + float fogColorAndDistance[4]; + + float eyePosition[3]; + float eyeDirection[3]; + + D3DCOLOR ambientColor; + + D3DCOLOR lightColor; + float lightIntensity; + float lightDirection[3]; + float lightPosition[3]; + float lightInnerRadius; + float lightOuterRadius; + float lightInnerCone; + float lightOuterCone; + IDirect3DTexture9 *lightShadowMap; + D3DXMATRIX lightShadowMatrix; + + public: + ShaderEnvironment(void); + }; + + protected: + D3D9Renderer(IDirect3D9* inDirect3d, const char* devName, PxU32 dispWidth, PxU32 dispHeight, IDirect3DDevice9* inDevice, bool isDeviceEx, const char* assetDir); + void initialize(bool isDeviceEx); + + public: + D3D9Renderer(const RendererDesc &desc, const char* assetDir); + virtual ~D3D9Renderer(void); + + IDirect3DDevice9 *getD3DDevice(void) { return m_d3dDevice; } + D3DXInterface &getD3DX(void) { return m_d3dx; } + ShaderEnvironment &getShaderEnvironment(void) { return m_environment; } + const ShaderEnvironment &getShaderEnvironment(void) const { return m_environment; } + + protected: + virtual bool checkResize(bool isDeviceLost); + void buildDepthStencilSurface(void); + void buildSwapchain(); + void releaseSwapchain(); + bool useSwapchain() const; + bool validSwapchain() const; + HRESULT presentSwapchain(); + + void releaseDepthStencilSurface(void); + public: + bool resetDevice(void); + void onDeviceLost(void); + void onDeviceReset(void); + + public: + // clears the offscreen buffers. + virtual void clearBuffers(void); + + // presents the current color buffer to the screen. + // returns true on device reset and if buffers need to be rewritten. + virtual bool swapBuffers(void); + + // get the device pointer (void * abstraction) + virtual void *getDevice() { return static_cast<void*>(getD3DDevice()); } + + // get the window size + void getWindowSize(PxU32 &width, PxU32 &height) const; + + // gets a handle to the current frame's data, in bitmap format + // note: subsequent calls will invalidate any previously returned data + // return true on successful screenshot capture + virtual bool captureScreen(PxU32 &width, PxU32& height, PxU32& sizeInBytes, const void*& screenshotData); + + virtual RendererVertexBuffer *createVertexBuffer( const RendererVertexBufferDesc &desc); + virtual RendererIndexBuffer *createIndexBuffer( const RendererIndexBufferDesc &desc); + virtual RendererInstanceBuffer *createInstanceBuffer(const RendererInstanceBufferDesc &desc); + virtual RendererTexture2D *createTexture2D( const RendererTexture2DDesc &desc); + virtual RendererTexture3D *createTexture3D( const RendererTexture3DDesc &desc); + virtual RendererTarget *createTarget( const RendererTargetDesc &desc); + virtual RendererMaterial *createMaterial( const RendererMaterialDesc &desc); + virtual RendererMesh *createMesh( const RendererMeshDesc &desc); + virtual RendererLight *createLight( const RendererLightDesc &desc); + + virtual void disableDepthTest(); + virtual void enableDepthTest(); + + virtual void setVsync(bool on); + + virtual bool initTexter(); + virtual void closeTexter(); + + virtual bool beginRender(void); + virtual void endRender(void); + + bool canUseManagedResources() { return !m_isDeviceEx; } + + virtual void bindViewProj(const physx::PxMat44 &eye, const RendererProjection &proj); + virtual void bindFogState(const RendererColor &fogColor, float fogDistance); + virtual void bindAmbientState(const RendererColor &ambientColor); + virtual void bindDeferredState(void); + virtual void bindMeshContext(const RendererMeshContext &context); + virtual void beginMultiPass(void); + virtual void endMultiPass(void); + virtual void beginTransparentMultiPass(void); + virtual void endTransparentMultiPass(void); + virtual void renderDeferredLight(const RendererLight &light); + virtual PxU32 convertColor(const RendererColor& color) const; + + virtual bool isOk(void) const; + + virtual void setupTextRenderStates(); + virtual void resetTextRenderStates(); + virtual void renderTextBuffer(const void* vertices, PxU32 nbVerts, const PxU16* indices, PxU32 nbIndices, RendererMaterial* material); + virtual void renderLines2D(const void* vertices, PxU32 nbVerts); + virtual void setupScreenquadRenderStates(); + virtual void resetScreenquadRenderStates(); + + private: + void addResource(D3D9RendererResource &resource); + void removeResource(D3D9RendererResource &resource); + void notifyResourcesLostDevice(void); + void notifyResourcesResetDevice(void); + + protected: + PxU32 m_displayWidth; + PxU32 m_displayHeight; + ID3DXBuffer *m_displayBuffer; + + IDirect3D9 *m_d3d; + IDirect3DDevice9 *m_d3dDevice; + IDirect3DSurface9 *m_d3dDepthStencilSurface; + IDirect3DSurface9 *m_d3dSurface; + + IDirect3DSwapChain9 *m_d3dSwapChain; + IDirect3DSurface9 *m_d3dSwapDepthStencilSurface; + IDirect3DSurface9 *m_d3dSwapSurface; + private: + bool m_isDeviceEx; //implications all over the place + + D3DXInterface m_d3dx; + + ShaderEnvironment m_environment; + + D3DPRESENT_PARAMETERS m_d3dPresentParams; + bool m_d3dPresentParamsChanged; + + physx::PxMat44 m_viewMatrix; + + // non-managed resources... + std::vector<D3D9RendererResource*> m_resources; + + IDirect3DVertexDeclaration9* m_textVDecl; + }; + + class D3D9RendererResource + { + friend class D3D9Renderer; + public: + D3D9RendererResource(void) + { + m_d3dRenderer = 0; + } + + virtual ~D3D9RendererResource(void) + { + if(m_d3dRenderer) m_d3dRenderer->removeResource(*this); + } + + public: + virtual void onDeviceLost(void)=0; + virtual void onDeviceReset(void)=0; + + private: + D3D9Renderer *m_d3dRenderer; + }; + +} // namespace SampleRenderer + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D9) +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererDirectionalLight.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererDirectionalLight.cpp new file mode 100644 index 00000000..e76c20e0 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererDirectionalLight.cpp @@ -0,0 +1,56 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D9) + +#include "D3D9RendererDirectionalLight.h" + +using namespace SampleRenderer; + +D3D9RendererDirectionalLight::D3D9RendererDirectionalLight(D3D9Renderer &renderer, const RendererDirectionalLightDesc &desc) : + RendererDirectionalLight(desc), + m_renderer(renderer) +{ + +} + +D3D9RendererDirectionalLight::~D3D9RendererDirectionalLight(void) +{ + +} + +void D3D9RendererDirectionalLight::bind(void) const +{ + D3D9Renderer::ShaderEnvironment &shaderEnv = m_renderer.getShaderEnvironment(); + convertToD3D9(shaderEnv.lightColor, m_color); + shaderEnv.lightIntensity = m_intensity; + convertToD3D9(shaderEnv.lightDirection, m_direction); +} + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D9) diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererDirectionalLight.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererDirectionalLight.h new file mode 100644 index 00000000..1e5f8b6b --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererDirectionalLight.h @@ -0,0 +1,56 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +#ifndef D3D9_RENDERER_DIRECTIONAL_LIGHT_H +#define D3D9_RENDERER_DIRECTIONAL_LIGHT_H + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D9) + +#include <RendererDirectionalLight.h> + +#include "D3D9Renderer.h" + +namespace SampleRenderer +{ + + class D3D9RendererDirectionalLight : public RendererDirectionalLight + { + public: + D3D9RendererDirectionalLight(D3D9Renderer &renderer, const RendererDirectionalLightDesc &desc); + virtual ~D3D9RendererDirectionalLight(void); + + virtual void bind(void) const; + + private: + D3D9Renderer &m_renderer; + }; + +} // namespace SampleRenderer + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D9) +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererIndexBuffer.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererIndexBuffer.cpp new file mode 100644 index 00000000..af56f974 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererIndexBuffer.cpp @@ -0,0 +1,161 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D9) + +#include "D3D9RendererIndexBuffer.h" +#include <RendererIndexBufferDesc.h> + +#if PX_WINDOWS +#include <task/PxTask.h> +#endif + +using namespace SampleRenderer; + +static D3DFORMAT getD3D9Format(RendererIndexBuffer::Format format) +{ + D3DFORMAT d3dFormat = D3DFMT_UNKNOWN; + switch(format) + { + case RendererIndexBuffer::FORMAT_UINT16: d3dFormat = D3DFMT_INDEX16; break; + case RendererIndexBuffer::FORMAT_UINT32: d3dFormat = D3DFMT_INDEX32; break; + } + RENDERER_ASSERT(d3dFormat != D3DFMT_UNKNOWN, "Unable to convert to D3DFORMAT."); + return d3dFormat; +} + +D3D9RendererIndexBuffer::D3D9RendererIndexBuffer(IDirect3DDevice9 &d3dDevice, D3D9Renderer& renderer, const RendererIndexBufferDesc &desc) : + RendererIndexBuffer(desc), + m_d3dDevice(d3dDevice) +{ + m_d3dIndexBuffer = 0; + + m_usage = D3DUSAGE_WRITEONLY; + m_pool = renderer.canUseManagedResources() ? D3DPOOL_MANAGED : D3DPOOL_DEFAULT; + PxU32 indexSize = getFormatByteSize(desc.format); + m_format = getD3D9Format(desc.format); + m_bufferSize = indexSize * desc.maxIndices; + +#if RENDERER_ENABLE_DYNAMIC_VB_POOLS + if(desc.hint == RendererIndexBuffer::HINT_DYNAMIC ) + { + m_usage = desc.registerInCUDA ? 0 : D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY; + m_pool = D3DPOOL_DEFAULT; + } +#endif + + onDeviceReset(); + + if(m_d3dIndexBuffer) + { + m_maxIndices = desc.maxIndices; + } +} + +D3D9RendererIndexBuffer::~D3D9RendererIndexBuffer(void) +{ + if(m_d3dIndexBuffer) + { +#if PX_WINDOWS && PX_SUPPORT_GPU_PHYSX + if(m_interopContext && m_registeredInCUDA) + { + m_registeredInCUDA = !m_interopContext->unregisterResourceInCuda(m_InteropHandle); + } +#endif + m_d3dIndexBuffer->Release(); + } +} + +void D3D9RendererIndexBuffer::onDeviceLost(void) +{ + m_registeredInCUDA = false; + + if(m_pool != D3DPOOL_MANAGED && m_d3dIndexBuffer) + { +#if PX_WINDOWS && PX_SUPPORT_GPU_PHYSX + if(m_interopContext && m_registeredInCUDA) + { + m_registeredInCUDA = !m_interopContext->unregisterResourceInCuda(m_InteropHandle); + } +#endif + m_d3dIndexBuffer->Release(); + m_d3dIndexBuffer = 0; + } +} + +void D3D9RendererIndexBuffer::onDeviceReset(void) +{ + if(!m_d3dIndexBuffer) + { + m_d3dDevice.CreateIndexBuffer(m_bufferSize, m_usage, m_format, m_pool, &m_d3dIndexBuffer, 0); + RENDERER_ASSERT(m_d3dIndexBuffer, "Failed to create Direct3D9 Index Buffer."); +#if PX_WINDOWS && PX_SUPPORT_GPU_PHYSX + if(m_interopContext && m_d3dIndexBuffer && m_mustBeRegisteredInCUDA) + { + m_registeredInCUDA = m_interopContext->registerResourceInCudaD3D(m_InteropHandle, m_d3dIndexBuffer); + } +#endif + } +} + +void *D3D9RendererIndexBuffer::lock(void) +{ + void *buffer = 0; + if(m_d3dIndexBuffer) + { + const Format format = getFormat(); + const PxU32 maxIndices = getMaxIndices(); + const PxU32 bufferSize = maxIndices * getFormatByteSize(format); + if(bufferSize > 0) + { + m_d3dIndexBuffer->Lock(0, (UINT)bufferSize, &buffer, 0); + } + } + return buffer; +} + +void D3D9RendererIndexBuffer::unlock(void) +{ + if(m_d3dIndexBuffer) + { + m_d3dIndexBuffer->Unlock(); + } +} + +void D3D9RendererIndexBuffer::bind(void) const +{ + m_d3dDevice.SetIndices(m_d3dIndexBuffer); +} + +void D3D9RendererIndexBuffer::unbind(void) const +{ + m_d3dDevice.SetIndices(0); +} + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D9) diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererIndexBuffer.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererIndexBuffer.h new file mode 100644 index 00000000..7a8ac9d7 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererIndexBuffer.h @@ -0,0 +1,70 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +#ifndef D3D9_RENDERER_INDEXBUFFER_H +#define D3D9_RENDERER_INDEXBUFFER_H + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D9) + +#include <RendererIndexBuffer.h> +#include "D3D9Renderer.h" + +namespace SampleRenderer +{ + + class D3D9RendererIndexBuffer : public RendererIndexBuffer, public D3D9RendererResource + { + public: + D3D9RendererIndexBuffer(IDirect3DDevice9 &d3dDevice, D3D9Renderer& renderer, const RendererIndexBufferDesc &desc); + virtual ~D3D9RendererIndexBuffer(void); + + public: + virtual void *lock(void); + virtual void unlock(void); + + private: + virtual void bind(void) const; + virtual void unbind(void) const; + + virtual void onDeviceLost(void); + virtual void onDeviceReset(void); + + private: + IDirect3DDevice9 &m_d3dDevice; + IDirect3DIndexBuffer9 *m_d3dIndexBuffer; + + DWORD m_usage; + D3DPOOL m_pool; + UINT m_bufferSize; + D3DFORMAT m_format; + }; + +} // namespace SampleRenderer + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D9) +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererInstanceBuffer.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererInstanceBuffer.cpp new file mode 100644 index 00000000..573baba9 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererInstanceBuffer.cpp @@ -0,0 +1,266 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. + +#include <RendererConfig.h> +#if defined(RENDERER_ENABLE_DIRECT3D9) + +#include "D3D9RendererInstanceBuffer.h" +#include <RendererInstanceBufferDesc.h> + +#if PX_WINDOWS +#include <task/PxTask.h> +#endif + +using namespace SampleRenderer; + +static D3DVERTEXELEMENT9 buildVertexElement(WORD stream, WORD offset, D3DDECLTYPE type, BYTE method, BYTE usage, BYTE usageIndex) +{ + D3DVERTEXELEMENT9 element; + element.Stream = stream; + element.Offset = offset; +#if defined(RENDERER_WINDOWS) + element.Type = (BYTE)type; +#else + element.Type = type; +#endif + element.Method = method; + element.Usage = usage; + element.UsageIndex = usageIndex; + return element; +} + +static D3DDECLTYPE getD3DType(RendererInstanceBuffer::Format format) +{ + D3DDECLTYPE d3dType = D3DDECLTYPE_UNUSED; + switch(format) + { + case RendererInstanceBuffer::FORMAT_FLOAT1: d3dType = D3DDECLTYPE_FLOAT1; break; + case RendererInstanceBuffer::FORMAT_FLOAT2: d3dType = D3DDECLTYPE_FLOAT2; break; + case RendererInstanceBuffer::FORMAT_FLOAT3: d3dType = D3DDECLTYPE_FLOAT3; break; + case RendererInstanceBuffer::FORMAT_FLOAT4: d3dType = D3DDECLTYPE_FLOAT4; break; + } + RENDERER_ASSERT(d3dType != D3DDECLTYPE_UNUSED, "Invalid Direct3D9 vertex type."); + return d3dType; +} + +static D3DDECLUSAGE getD3DUsage(RendererInstanceBuffer::Semantic semantic, PxU8 &usageIndex) +{ + D3DDECLUSAGE d3dUsage = D3DDECLUSAGE_FOG; + usageIndex = 0; + switch(semantic) + { + case RendererInstanceBuffer::SEMANTIC_POSITION: + d3dUsage = D3DDECLUSAGE_TEXCOORD; + usageIndex = RENDERER_INSTANCE_POSITION_CHANNEL; + break; + case RendererInstanceBuffer::SEMANTIC_NORMALX: + d3dUsage = D3DDECLUSAGE_TEXCOORD; + usageIndex = RENDERER_INSTANCE_NORMALX_CHANNEL; + break; + case RendererInstanceBuffer::SEMANTIC_NORMALY: + d3dUsage = D3DDECLUSAGE_TEXCOORD; + usageIndex = RENDERER_INSTANCE_NORMALY_CHANNEL; + break; + case RendererInstanceBuffer::SEMANTIC_NORMALZ: + d3dUsage = D3DDECLUSAGE_TEXCOORD; + usageIndex = RENDERER_INSTANCE_NORMALZ_CHANNEL; + break; + case RendererInstanceBuffer::SEMANTIC_VELOCITY_LIFE: + d3dUsage = D3DDECLUSAGE_TEXCOORD; + usageIndex = RENDERER_INSTANCE_VEL_LIFE_CHANNEL; + break; + case RendererInstanceBuffer::SEMANTIC_DENSITY: + d3dUsage = D3DDECLUSAGE_TEXCOORD; + usageIndex = RENDERER_INSTANCE_DENSITY_CHANNEL; + break; + case RendererInstanceBuffer::SEMANTIC_UV_OFFSET: + d3dUsage = D3DDECLUSAGE_TEXCOORD; + usageIndex = RENDERER_INSTANCE_UV_CHANNEL; + break; + case RendererInstanceBuffer::SEMANTIC_LOCAL_OFFSET: + d3dUsage = D3DDECLUSAGE_TEXCOORD; + usageIndex = RENDERER_INSTANCE_LOCAL_CHANNEL; + break; + } + RENDERER_ASSERT(d3dUsage != D3DDECLUSAGE_FOG, "Invalid Direct3D9 vertex usage."); + return d3dUsage; +} + +D3D9RendererInstanceBuffer::D3D9RendererInstanceBuffer(IDirect3DDevice9 &d3dDevice, D3D9Renderer& renderer, const RendererInstanceBufferDesc &desc) : +RendererInstanceBuffer(desc) +#if RENDERER_INSTANCING + ,m_d3dDevice(d3dDevice) +#endif +{ +#if RENDERER_INSTANCING + m_d3dVertexBuffer = 0; +#endif + + m_usage = D3DUSAGE_WRITEONLY; + m_pool = renderer.canUseManagedResources() ? D3DPOOL_MANAGED : D3DPOOL_DEFAULT; + m_bufferSize = (UINT)(desc.maxInstances * m_stride); + +#if RENDERER_ENABLE_DYNAMIC_VB_POOLS + if(desc.hint==RendererInstanceBuffer::HINT_DYNAMIC ) + { + m_usage = desc.registerInCUDA ? 0 : D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY; + m_pool = D3DPOOL_DEFAULT; + } +#endif + + onDeviceReset(); + +#if RENDERER_INSTANCING + if(m_d3dVertexBuffer) + { + m_maxInstances = desc.maxInstances; + } +#else + m_maxInstances = desc.maxInstances; + mInstanceBuffer = malloc(m_maxInstances*m_stride); // PX_ALLOC(m_maxInstances*m_stride); +#endif +} + +D3D9RendererInstanceBuffer::~D3D9RendererInstanceBuffer(void) +{ +#if RENDERER_INSTANCING +#if PX_WINDOWS && PX_SUPPORT_GPU_PHYSX + if(m_interopContext && m_registeredInCUDA) + { + PX_ASSERT(m_d3dVertexBuffer); + m_registeredInCUDA = !m_interopContext->unregisterResourceInCuda(m_InteropHandle); + } +#endif + if(m_d3dVertexBuffer) m_d3dVertexBuffer->Release(); +#else + free(mInstanceBuffer); // PX_FREE(mInstanceBuffer); +#endif +} + +void D3D9RendererInstanceBuffer::addVertexElements(PxU32 streamIndex, std::vector<D3DVERTEXELEMENT9> &vertexElements) const +{ + for(PxU32 i=0; i<NUM_SEMANTICS; i++) + { + Semantic semantic = (Semantic)i; + const SemanticDesc &sm = m_semanticDescs[semantic]; + if(sm.format < NUM_FORMATS) + { + PxU8 d3dUsageIndex = 0; + D3DDECLUSAGE d3dUsage = getD3DUsage(semantic, d3dUsageIndex); + vertexElements.push_back(buildVertexElement((WORD)streamIndex, (WORD)sm.offset, getD3DType(sm.format), D3DDECLMETHOD_DEFAULT, (BYTE)d3dUsage, d3dUsageIndex)); + } + } +} + +void *D3D9RendererInstanceBuffer::lock(void) +{ + PX_PROFILE_ZONE("D3D9RenderIBlock",0); + + void *lockedBuffer = 0; +#if RENDERER_INSTANCING + if(m_d3dVertexBuffer) + { + const PxU32 bufferSize = m_maxInstances * m_stride; + m_d3dVertexBuffer->Lock(0, (UINT)bufferSize, &lockedBuffer, 0); + RENDERER_ASSERT(lockedBuffer, "Failed to lock Direct3D9 Vertex Buffer."); + } +#else + lockedBuffer = mInstanceBuffer; +#endif + return lockedBuffer; +} + +void D3D9RendererInstanceBuffer::unlock(void) +{ + PX_PROFILE_ZONE("D3D9RenderIBunlock",0); +#if RENDERER_INSTANCING + if(m_d3dVertexBuffer) + { + m_d3dVertexBuffer->Unlock(); + } +#endif +} + +void D3D9RendererInstanceBuffer::bind(PxU32 streamID, PxU32 firstInstance) const +{ +#if RENDERER_INSTANCING + if(m_d3dVertexBuffer) + { + m_d3dDevice.SetStreamSourceFreq((UINT)streamID, (UINT)(D3DSTREAMSOURCE_INSTANCEDATA | 1)); + m_d3dDevice.SetStreamSource( (UINT)streamID, m_d3dVertexBuffer, firstInstance*m_stride, m_stride); + } +#endif +} + +void D3D9RendererInstanceBuffer::unbind(PxU32 streamID) const +{ +#if RENDERER_INSTANCING + m_d3dDevice.SetStreamSource((UINT)streamID, 0, 0, 0); +#endif +} + +void D3D9RendererInstanceBuffer::onDeviceLost(void) +{ +#if RENDERER_INSTANCING + +#if PX_WINDOWS && PX_SUPPORT_GPU_PHYSX + if(m_interopContext && m_registeredInCUDA) + { + PX_ASSERT(m_d3dVertexBuffer); + m_interopContext->unregisterResourceInCuda(m_InteropHandle); + } +#endif + + m_registeredInCUDA = false; + + if(m_pool != D3DPOOL_MANAGED && m_d3dVertexBuffer) + { + m_d3dVertexBuffer->Release(); + m_d3dVertexBuffer = 0; + } +#endif +} + +void D3D9RendererInstanceBuffer::onDeviceReset(void) +{ +#if RENDERER_INSTANCING + if(!m_d3dVertexBuffer) + { + m_d3dDevice.CreateVertexBuffer(m_bufferSize, m_usage, 0, m_pool, &m_d3dVertexBuffer, 0); + RENDERER_ASSERT(m_d3dVertexBuffer, "Failed to create Direct3D9 Vertex Buffer."); + +#if PX_WINDOWS && PX_SUPPORT_GPU_PHYSX + if(m_interopContext && m_d3dVertexBuffer && m_mustBeRegisteredInCUDA) + { + m_registeredInCUDA = m_interopContext->registerResourceInCudaD3D(m_InteropHandle, m_d3dVertexBuffer); + } +#endif + } +#endif +} + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D9) diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererInstanceBuffer.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererInstanceBuffer.h new file mode 100644 index 00000000..bc32d885 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererInstanceBuffer.h @@ -0,0 +1,74 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +#ifndef D3D9_RENDERER_INSTANCEBUFFER_H +#define D3D9_RENDERER_INSTANCEBUFFER_H + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D9) + +#include <RendererInstanceBuffer.h> +#include "D3D9Renderer.h" + +namespace SampleRenderer +{ + + class D3D9RendererInstanceBuffer : public RendererInstanceBuffer, public D3D9RendererResource + { + public: + D3D9RendererInstanceBuffer(IDirect3DDevice9 &d3dDevice, D3D9Renderer& renderer, const RendererInstanceBufferDesc &desc); + virtual ~D3D9RendererInstanceBuffer(void); + + void addVertexElements(PxU32 streamIndex, std::vector<D3DVERTEXELEMENT9> &vertexElements) const; + + protected: + virtual void *lock(void); + virtual void unlock(void); + + virtual void bind(PxU32 streamID, PxU32 firstInstance) const; + virtual void unbind(PxU32 streamID) const; + + private: + virtual void onDeviceLost(void); + virtual void onDeviceReset(void); + + private: +#if RENDERER_INSTANCING + IDirect3DDevice9 &m_d3dDevice; + IDirect3DVertexBuffer9 *m_d3dVertexBuffer; +#else + void *mInstanceBuffer; +#endif + DWORD m_usage; + D3DPOOL m_pool; + UINT m_bufferSize; + }; + +} // namespace SampleRenderer + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D9) +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererMaterial.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererMaterial.cpp new file mode 100644 index 00000000..247e4665 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererMaterial.cpp @@ -0,0 +1,950 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D9) + +#include "D3D9RendererMaterial.h" +#include <RendererMaterialDesc.h> + +#include "D3D9RendererTexture2D.h" + +#include <stdio.h> + +// for PsString.h +#include <PsString.h> +#include <PxTkFile.h> +#include "SampleDirManager.h" + +namespace Ps = physx::shdfnd; + +using namespace SampleRenderer; + +void D3D9RendererMaterial::setModelMatrix(const float* matrix) +{ + if (m_instancedVertexConstants.table && m_instancedVertexConstants.modelMatrix) + { + m_instancedVertexConstants.table->SetMatrix(m_renderer.getD3DDevice(), m_instancedVertexConstants.modelMatrix, (const D3DXMATRIX*)matrix); + } +} + +D3D9RendererMaterial::ShaderConstants::ShaderConstants(void) +{ + memset(this, 0, sizeof(*this)); +} + +D3D9RendererMaterial::ShaderConstants::~ShaderConstants(void) +{ + if (table) + { + table->Release(); + } +} + +static D3DXHANDLE getShaderConstantByName(ID3DXConstantTable& table, const char* name) +{ + D3DXHANDLE found = 0; + D3DXCONSTANTTABLE_DESC desc; + table.GetDesc(&desc); + for (UINT i = 0; i < desc.Constants; i++) + { + D3DXHANDLE constant = table.GetConstant(0, i); + RENDERER_ASSERT(constant, "Unable to find constant"); + if (constant) + { + D3DXCONSTANT_DESC cdesc; + UINT count = 1; + table.GetConstantDesc(constant, &cdesc, &count); + RENDERER_ASSERT(count == 1, "Unable to obtain Constant Descriptor."); + if (count == 1 && !strcmp(cdesc.Name, name)) + { + found = constant; + break; + } + } + } + return found; +} + +static D3DBLEND getD3DBlendFunc(RendererMaterial::BlendFunc func) +{ + D3DBLEND d3dfunc = D3DBLEND_FORCE_DWORD; + switch (func) + { + case RendererMaterial::BLEND_ZERO: + d3dfunc = D3DBLEND_ZERO; + break; + case RendererMaterial::BLEND_ONE: + d3dfunc = D3DBLEND_ONE; + break; + case RendererMaterial::BLEND_SRC_COLOR: + d3dfunc = D3DBLEND_SRCCOLOR; + break; + case RendererMaterial::BLEND_ONE_MINUS_SRC_COLOR: + d3dfunc = D3DBLEND_INVSRCCOLOR; + break; + case RendererMaterial::BLEND_SRC_ALPHA: + d3dfunc = D3DBLEND_SRCALPHA; + break; + case RendererMaterial::BLEND_ONE_MINUS_SRC_ALPHA: + d3dfunc = D3DBLEND_INVSRCALPHA; + break; + case RendererMaterial::BLEND_DST_ALPHA: + d3dfunc = D3DBLEND_DESTALPHA; + break; + case RendererMaterial::BLEND_ONE_MINUS_DST_ALPHA: + d3dfunc = D3DBLEND_INVDESTALPHA; + break; + case RendererMaterial::BLEND_DST_COLOR: + d3dfunc = D3DBLEND_DESTCOLOR; + break; + case RendererMaterial::BLEND_ONE_MINUS_DST_COLOR: + d3dfunc = D3DBLEND_INVDESTCOLOR; + break; + case RendererMaterial::BLEND_SRC_ALPHA_SATURATE: + d3dfunc = D3DBLEND_SRCALPHASAT; + break; + } + RENDERER_ASSERT(d3dfunc != D3DBLEND_FORCE_DWORD, "Failed to look up D3D Blend Func."); + return d3dfunc; +} + +void D3D9RendererMaterial::ShaderConstants::loadConstants(void) +{ + if (table) + { + modelMatrix = table->GetConstantByName(0, "g_" "modelMatrix"); + viewMatrix = table->GetConstantByName(0, "g_" "viewMatrix"); + projMatrix = table->GetConstantByName(0, "g_" "projMatrix"); + modelViewMatrix = table->GetConstantByName(0, "g_" "modelViewMatrix"); + modelViewProjMatrix = table->GetConstantByName(0, "g_" "modelViewProjMatrix"); + + boneMatrices = getShaderConstantByName(*table, "g_" "boneMatrices"); + + fogColorAndDistance = table->GetConstantByName(0, "g_" "fogColorAndDistance"); + + eyePosition = table->GetConstantByName(0, "g_" "eyePosition"); + eyeDirection = table->GetConstantByName(0, "g_" "eyeDirection"); + + ambientColor = table->GetConstantByName(0, "g_" "ambientColor"); + + lightColor = table->GetConstantByName(0, "g_" "lightColor"); + lightIntensity = table->GetConstantByName(0, "g_" "lightIntensity"); + lightDirection = table->GetConstantByName(0, "g_" "lightDirection"); + lightPosition = table->GetConstantByName(0, "g_" "lightPosition"); + lightInnerRadius = table->GetConstantByName(0, "g_" "lightInnerRadius"); + lightOuterRadius = table->GetConstantByName(0, "g_" "lightOuterRadius"); + lightInnerCone = table->GetConstantByName(0, "g_" "lightInnerCone"); + lightOuterCone = table->GetConstantByName(0, "g_" "lightOuterCone"); + + lightShadowMap = table->GetConstantByName(0, "g_" "lightShadowMap"); + lightShadowMatrix = table->GetConstantByName(0, "g_" "lightShadowMatrix"); + + vfaceScale = table->GetConstantByName(0, "g_" "vfaceScale"); + } +} + +void D3D9RendererMaterial::ShaderConstants::bindEnvironment(IDirect3DDevice9& d3dDevice, const D3D9Renderer::ShaderEnvironment& shaderEnv) const +{ + if (table) + { +#define SET_MATRIX(_name) \ + if(_name) \ + { \ + const D3DXMATRIX xm(shaderEnv._name); \ + table->SetMatrix(&d3dDevice, _name, &xm); \ + } + +#define SET_FLOAT3(_name) \ + if(_name) \ + { \ + const D3DXVECTOR4 xv(shaderEnv._name[0], \ + shaderEnv._name[1], \ + shaderEnv._name[2], 1); \ + table->SetVector(&d3dDevice, _name, &xv); \ + } + +#define SET_FLOAT4(_name) \ + if(_name) \ + { \ + const D3DXVECTOR4 xv(shaderEnv._name[0], \ + shaderEnv._name[1], \ + shaderEnv._name[2], \ + shaderEnv._name[3]); \ + table->SetVector(&d3dDevice, _name, &xv); \ + } + +#define SET_COLOR(_name) \ + if(_name) \ + { \ + const D3DXCOLOR xc(shaderEnv._name); \ + const D3DXVECTOR4 xv(xc.r, xc.g, xc.b, xc.a); \ + table->SetVector(&d3dDevice, _name, &xv); \ + } + +#define SET_FLOAT(_name) \ + if(_name) table->SetFloat(&d3dDevice, _name, shaderEnv._name); + + SET_MATRIX(modelMatrix) + SET_MATRIX(viewMatrix) + SET_MATRIX(projMatrix) + SET_MATRIX(modelViewMatrix) + SET_MATRIX(modelViewProjMatrix) + + if (boneMatrices && shaderEnv.numBones > 0) + { + table->SetMatrixArray(&d3dDevice, boneMatrices, shaderEnv.boneMatrices, shaderEnv.numBones); + } + + SET_FLOAT4(fogColorAndDistance) + + + SET_FLOAT3(eyePosition) + SET_FLOAT3(eyeDirection) + + SET_COLOR(ambientColor) + + SET_COLOR(lightColor) + SET_FLOAT(lightIntensity) + SET_FLOAT3(lightDirection) + SET_FLOAT3(lightPosition) + SET_FLOAT(lightInnerRadius) + SET_FLOAT(lightOuterRadius) + SET_FLOAT(lightInnerCone) + SET_FLOAT(lightOuterCone) + if (lightShadowMap) + { + UINT index = table->GetSamplerIndex(lightShadowMap); + d3dDevice.SetSamplerState((DWORD)index, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + d3dDevice.SetSamplerState((DWORD)index, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); + d3dDevice.SetSamplerState((DWORD)index, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); + d3dDevice.SetSamplerState((DWORD)index, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); + d3dDevice.SetSamplerState((DWORD)index, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); + d3dDevice.SetTexture(index, shaderEnv.lightShadowMap); + } + SET_MATRIX(lightShadowMatrix) + + if (vfaceScale) + { + float vfs = 1.0f; + DWORD cullmode = 0; + d3dDevice.GetRenderState(D3DRS_CULLMODE, &cullmode); + if (cullmode == D3DCULL_CW) + { + vfs = -1.0f; + } +#if defined(RENDERER_XBOX360) + else if (cullmode == D3DCULL_NONE) + { + vfs = -1.0f; + } +#endif + table->SetFloat(&d3dDevice, vfaceScale, vfs); + } + +#undef SET_MATRIX +#undef SET_FLOAT3 +#undef SET_FLOAT4 +#undef SET_COLOR +#undef SET_FLOAT + } +} + +/************************************** +* D3D9RendererMaterial::D3D9Variable * +**************************************/ + +D3D9RendererMaterial::D3D9Variable::D3D9Variable(const char* name, VariableType type, PxU32 offset) : + Variable(name, type, offset) +{ + m_vertexHandle = 0; + memset(m_fragmentHandles, 0, sizeof(m_fragmentHandles)); +} + +D3D9RendererMaterial::D3D9Variable::~D3D9Variable(void) +{ + +} + +void D3D9RendererMaterial::D3D9Variable::addVertexHandle(ID3DXConstantTable& table, D3DXHANDLE handle) +{ + m_vertexHandle = handle; + D3DXCONSTANT_DESC cdesc; + UINT count = 1; + table.GetConstantDesc(handle, &cdesc, &count); + m_vertexRegister = cdesc.RegisterIndex; +} + +void D3D9RendererMaterial::D3D9Variable::addFragmentHandle(ID3DXConstantTable& table, D3DXHANDLE handle, Pass pass) +{ + m_fragmentHandles[pass] = handle; + D3DXCONSTANT_DESC cdesc; + UINT count = 1; + table.GetConstantDesc(handle, &cdesc, &count); + m_fragmentRegisters[pass] = cdesc.RegisterIndex; +} + +/********************************* +* D3D Shader Compiler Callbacks * +*********************************/ + +static void processCompileErrors(LPD3DXBUFFER errors) +{ +#if defined(RENDERER_WINDOWS) + if (errors) + { + const char* errorStr = (const char*)errors->GetBufferPointer(); + if (errorStr) + { + static bool ignoreErrors = false; + if (!ignoreErrors) + { + int ret = MessageBoxA(0, errorStr, "D3DXCompileShaderFromFile Error", MB_ABORTRETRYIGNORE); + if (ret == IDABORT) + { + exit(0); + } + else if (ret == IDIGNORE) + { + ignoreErrors = true; + } + } + } + } +#elif defined(RENDERER_XBOX360) + // this allows to watch errors in the debugger + if(errors) + { + const char *errorStr = (const char*)errors->GetBufferPointer(); + PX_UNUSED(errorStr); + } +#endif +} + +class D3D9ShaderIncluder : public ID3DXInclude +{ +public: + D3D9ShaderIncluder(const char* assetDir) : m_assetDir(assetDir) {} + +private: +#if defined(RENDERER_XBOX360) + STDMETHOD(Open)(THIS_ D3DXINCLUDE_TYPE includeType, LPCSTR fileName, LPCVOID parentData, LPCVOID* data, UINT* dataSize, LPSTR pFullPath, DWORD cbFullPath) +#else + STDMETHOD(Open)(THIS_ D3DXINCLUDE_TYPE includeType, LPCSTR fileName, LPCVOID parentData, LPCVOID* data, UINT* dataSize) +#endif + { + HRESULT result = D3DERR_NOTFOUND; + + char fullpath[1024]; + Ps::strlcpy(fullpath, 1024, m_assetDir); + Ps::strlcat(fullpath, 1024, "shaders/"); + if (includeType == D3DXINC_SYSTEM) + { + Ps::strlcat(fullpath, 1024, "include/"); + } + Ps::strlcat(fullpath, 1024, fileName); + + FILE* file = 0; + PxToolkit::fopen_s(&file, fullpath, "r"); + if (file) + { + fseek(file, 0, SEEK_END); + size_t fileLen = ftell(file); + if (fileLen > 1) + { + fseek(file, 0, SEEK_SET); + char* fileData = new char[fileLen + 1]; + fileLen = fread(fileData, 1, fileLen, file); + fileData[fileLen] = 0; + *data = fileData; + *dataSize = (UINT)fileLen; + } + fclose(file); + result = D3D_OK; + } + RENDERER_ASSERT(result == D3D_OK, "Failed to include shader header."); + return result; + } + + STDMETHOD(Close)(THIS_ LPCVOID data) + { + delete []((char*)data); + return D3D_OK; + } + + const char* m_assetDir; +}; + +D3D9RendererMaterial::D3D9RendererMaterial(D3D9Renderer& renderer, const RendererMaterialDesc& desc) : + RendererMaterial(desc, renderer.getEnableMaterialCaching()), + m_renderer(renderer) +{ + m_d3dAlphaTestFunc = D3DCMP_ALWAYS; + m_vertexShader = 0; + m_instancedVertexShader = 0; + memset(m_fragmentPrograms, 0, sizeof(m_fragmentPrograms)); + + AlphaTestFunc alphaTestFunc = getAlphaTestFunc(); + switch (alphaTestFunc) + { + case ALPHA_TEST_ALWAYS: + m_d3dAlphaTestFunc = D3DCMP_ALWAYS; + break; + case ALPHA_TEST_EQUAL: + m_d3dAlphaTestFunc = D3DCMP_EQUAL; + break; + case ALPHA_TEST_NOT_EQUAL: + m_d3dAlphaTestFunc = D3DCMP_NOTEQUAL; + break; + case ALPHA_TEST_LESS: + m_d3dAlphaTestFunc = D3DCMP_LESS; + break; + case ALPHA_TEST_LESS_EQUAL: + m_d3dAlphaTestFunc = D3DCMP_LESSEQUAL; + break; + case ALPHA_TEST_GREATER: + m_d3dAlphaTestFunc = D3DCMP_GREATER; + break; + case ALPHA_TEST_GREATER_EQUAL: + m_d3dAlphaTestFunc = D3DCMP_GREATEREQUAL; + break; + default: + RENDERER_ASSERT(0, "Unknown Alpha Test Func."); + } + + m_d3dSrcBlendFunc = getD3DBlendFunc(getSrcBlendFunc()); + m_d3dDstBlendFunc = getD3DBlendFunc(getDstBlendFunc()); + + D3D9Renderer::D3DXInterface& d3dx = m_renderer.getD3DX(); + IDirect3DDevice9* d3dDevice = m_renderer.getD3DDevice(); + if (d3dDevice) + { + D3D9ShaderIncluder shaderIncluder(m_renderer.getAssetDir()); + + const char* vertexEntry = "vmain"; + const char* vertexProfile = d3dx.GetVertexShaderProfile(d3dDevice); + const char* vertexShaderPath = desc.vertexShaderPath; + const DWORD vertexFlags = D3DXSHADER_PACKMATRIX_COLUMNMAJOR; + const D3DXMACRO vertexDefines[] = + { + {"RENDERER_VERTEX", "1"}, + {"RENDERER_D3D", "1"}, + {"SEMANTIC_TANGENT", "TANGENT"}, // This will prevent mapping tangent to texcoord5 and instead to the proper TANGENT semantic + {0, 0} + }; + + LPD3DXBUFFER vshader = 0; + + HRESULT result = loadCacheShader(vertexShaderPath, ".cache", vertexDefines, &shaderIncluder, vertexEntry, vertexProfile, vertexFlags, vshader, &m_vertexConstants.table); + + if (result == D3D_OK && vshader) + { + result = d3dDevice->CreateVertexShader((const DWORD*)vshader->GetBufferPointer(), &m_vertexShader); + RENDERER_ASSERT(result == D3D_OK && m_vertexShader, "Failed to load Vertex Shader."); + if (result == D3D_OK && m_vertexShader) + { + m_vertexConstants.loadConstants(); + if (m_vertexConstants.table) + { + loadCustomConstants(*m_vertexConstants.table, NUM_PASSES); + } + } + } + + if(vshader) + { + vshader->Release(); + } + +#if RENDERER_INSTANCING + const D3DXMACRO vertexDefinesInstanced[] = + { + {"RENDERER_VERTEX", "1"}, + {"RENDERER_D3D", "1"}, + {"RENDERER_INSTANCED", "1"}, + {"SEMANTIC_TANGENT", "TANGENT"}, +#if PX_WINDOWS + {"PX_WINDOWS", "1"}, +#endif + {0, 0} + }; +#else + const D3DXMACRO vertexDefinesInstanced[] = + { + {"RENDERER_VERTEX", "1"}, + {"RENDERER_INSTANCED", "0"}, + {"SEMANTIC_TANGENT", "TANGENT"}, +#if PX_WINDOWS + {"PX_WINDOWS", "1"}, +#endif + {0, 0} + }; +#endif + vshader = 0; + result = loadCacheShader(vertexShaderPath, ".instcache", vertexDefinesInstanced, &shaderIncluder, vertexEntry, vertexProfile, vertexFlags, vshader, &m_instancedVertexConstants.table); + + if (result == D3D_OK && vshader) + { + result = d3dDevice->CreateVertexShader((const DWORD*)vshader->GetBufferPointer(), &m_instancedVertexShader); + RENDERER_ASSERT(result == D3D_OK && m_vertexShader, "Failed to load Vertex Shader."); + if (result == D3D_OK && m_vertexShader) + { + m_instancedVertexConstants.loadConstants(); + if (m_instancedVertexConstants.table) + { + loadCustomConstants(*m_instancedVertexConstants.table, NUM_PASSES); + } + } + } + if (vshader) + { + vshader->Release(); + } + + const char* fragmentEntry = "fmain"; + const char* fragmentProfile = d3dx.GetPixelShaderProfile(d3dDevice); + const char* fragmentShaderPath = desc.fragmentShaderPath; + const DWORD fragmentFlags = D3DXSHADER_PACKMATRIX_COLUMNMAJOR; + + // profile string in the format "ps_x_x" + int majorVersion = fragmentProfile[3]-'0'; + + // vface is sm3.0 and up + bool vFaceSupported = majorVersion > 2; + // shadow shader pushes fragment prog registers > 32 which limits support to sm 3.0 as well + bool shadowsSupported = majorVersion > 2; + PX_UNUSED(shadowsSupported); + + for (PxU32 i = 0; i < NUM_PASSES; i++) + { + const D3DXMACRO fragmentDefines[] = + { + {"RENDERER_FRAGMENT", "1"}, + {getPassName((Pass)i), "1"}, + {"ENABLE_VFACE", vFaceSupported?"1":"0"}, + {"ENABLE_VFACE_SCALE", vFaceSupported?"1":"0"}, +#if PX_WINDOWS + {"PX_WINDOWS", "1"}, + {"ENABLE_SHADOWS", shadowsSupported?"1":"0"}, +#endif + {0, 0} + }; + LPD3DXBUFFER fshader = 0; + char suffix[32]; + Ps::snprintf(suffix, 32, ".cache%d", i); + result = loadCacheShader(fragmentShaderPath, suffix, fragmentDefines, &shaderIncluder, fragmentEntry, fragmentProfile, fragmentFlags, fshader, &m_fragmentConstants[i].table); + if (result == D3D_OK && fshader) + { + result = d3dDevice->CreatePixelShader((const DWORD*)fshader->GetBufferPointer(), &m_fragmentPrograms[i]); + RENDERER_ASSERT(result == D3D_OK && m_fragmentPrograms[i], "Failed to load Fragment Shader."); + if (result == D3D_OK && m_fragmentPrograms[i]) + { + m_fragmentConstants[i].loadConstants(); + if (m_fragmentConstants[i].table) + { + loadCustomConstants(*m_fragmentConstants[i].table, (Pass)i); + } + } + } + if (fshader) + { + fshader->Release(); + } + } + } +} + +D3D9RendererMaterial::~D3D9RendererMaterial(void) +{ + if (m_vertexShader) + { + m_vertexShader->Release(); + } + if (m_instancedVertexShader) + { + m_instancedVertexShader->Release(); + } + for (PxU32 i = 0; i < NUM_PASSES; i++) + { + IDirect3DPixelShader9* fp = m_fragmentPrograms[i]; + if (fp) + { + fp->Release(); + } + } +} + +void D3D9RendererMaterial::bind(RendererMaterial::Pass pass, RendererMaterialInstance* materialInstance, bool instanced) const +{ + IDirect3DDevice9* d3dDevice = m_renderer.getD3DDevice(); + RENDERER_ASSERT(pass < NUM_PASSES, "Invalid Material Pass."); + if (d3dDevice && pass < NUM_PASSES) + { + const D3D9Renderer::ShaderEnvironment& shaderEnv = m_renderer.getShaderEnvironment(); + + if (m_d3dAlphaTestFunc == D3DCMP_ALWAYS) + { + d3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, 0); + } + else + { + PxU8 alphaTestRef = (PxU8)(PxClamp(getAlphaTestRef(), 0.0f, 1.0f) * 255.0f); + d3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, 1); + d3dDevice->SetRenderState(D3DRS_ALPHAFUNC, (DWORD)m_d3dAlphaTestFunc); + d3dDevice->SetRenderState(D3DRS_ALPHAREF , (DWORD)alphaTestRef); + } + + if (getBlending()) + { + d3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, 1); + d3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, 0); + d3dDevice->SetRenderState(D3DRS_SRCBLEND, (DWORD)m_d3dSrcBlendFunc); + d3dDevice->SetRenderState(D3DRS_DESTBLEND, (DWORD)m_d3dDstBlendFunc); + } + + if (instanced) + { + d3dDevice->SetVertexShader(m_instancedVertexShader); + } + else + { + d3dDevice->SetVertexShader(m_vertexShader); + } + + m_fragmentConstants[pass].bindEnvironment(*d3dDevice, shaderEnv); + d3dDevice->SetPixelShader(m_fragmentPrograms[pass]); + + RendererMaterial::bind(pass, materialInstance, instanced); + } +} + +void D3D9RendererMaterial::bindMeshState(bool instanced) const +{ + IDirect3DDevice9* d3dDevice = m_renderer.getD3DDevice(); + if (d3dDevice) + { + const D3D9Renderer::ShaderEnvironment& shaderEnv = m_renderer.getShaderEnvironment(); + + if (instanced) + { + m_instancedVertexConstants.bindEnvironment(*d3dDevice, shaderEnv); + } + else + { + m_vertexConstants.bindEnvironment(*d3dDevice, shaderEnv); + } + } +} + +void D3D9RendererMaterial::unbind(void) const +{ + IDirect3DDevice9* d3dDevice = m_renderer.getD3DDevice(); + if (d3dDevice) + { + if (getBlending()) + { + d3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, 0); + d3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, 1); + } + + d3dDevice->SetVertexShader(0); + d3dDevice->SetPixelShader(0); + } +} + +template<class TextureType, class D3DTextureType> +static void bindSamplerVariable(IDirect3DDevice9& d3dDevice, ID3DXConstantTable& table, D3DXHANDLE handle, TextureType& texture) +{ + if (handle) + { + UINT samplerIndex = table.GetSamplerIndex(handle); + static_cast<D3DTextureType*>(&texture)->bind(samplerIndex); + } +} + +void D3D9RendererMaterial::bindVariable(Pass pass, const Variable& variable, const void* data) const +{ + D3D9Variable& var = *(D3D9Variable*)&variable; + IDirect3DDevice9* d3dDevice = m_renderer.getD3DDevice(); + if (d3dDevice) + { + switch (var.getType()) + { + case VARIABLE_FLOAT: + { + const float fdata[4] = {*(const float*)data, 0, 0, 0}; + if (var.m_vertexHandle) + { + d3dDevice->SetVertexShaderConstantF(var.m_vertexRegister, fdata, 1); + } + else if (var.m_fragmentHandles[pass]) + { + d3dDevice->SetPixelShaderConstantF(var.m_fragmentRegisters[pass], fdata, 1); + } + break; + } + case VARIABLE_FLOAT2: + { + const float fdata[4] = {((const float*)data)[0], ((const float*)data)[1], 0, 0}; + if (var.m_vertexHandle) + { + d3dDevice->SetVertexShaderConstantF(var.m_vertexRegister, fdata, 1); + } + else if (var.m_fragmentHandles[pass]) + { + d3dDevice->SetPixelShaderConstantF(var.m_fragmentRegisters[pass], fdata, 1); + } + break; + } + case VARIABLE_FLOAT3: + { + const float fdata[4] = {((const float*)data)[0], ((const float*)data)[1], ((const float*)data)[2], 0}; + if (var.m_vertexHandle) + { + d3dDevice->SetVertexShaderConstantF(var.m_vertexRegister, fdata, 1); + } + else if (var.m_fragmentHandles[pass]) + { + d3dDevice->SetPixelShaderConstantF(var.m_fragmentRegisters[pass], fdata, 1); + } + break; + } + case VARIABLE_FLOAT4: + { + const float fdata[4] = {((const float*)data)[0], ((const float*)data)[1], ((const float*)data)[2], ((const float*)data)[3]}; + if (var.m_vertexHandle) + { + d3dDevice->SetVertexShaderConstantF(var.m_vertexRegister, fdata, 1); + } + else if (var.m_fragmentHandles[pass]) + { + d3dDevice->SetPixelShaderConstantF(var.m_fragmentRegisters[pass], fdata, 1); + } + break; + } + case VARIABLE_SAMPLER2D: + data = *(void**)data; + RENDERER_ASSERT(data, "NULL Sampler."); + if (data) + { + bindSamplerVariable<RendererTexture2D, D3D9RendererTexture2D>(*m_renderer.getD3DDevice(), *m_vertexConstants.table, var.m_vertexHandle, *(RendererTexture2D*)data); + bindSamplerVariable<RendererTexture2D, D3D9RendererTexture2D>(*m_renderer.getD3DDevice(), *m_fragmentConstants[pass].table, var.m_fragmentHandles[pass], *(RendererTexture2D*)data); + } + break; + case VARIABLE_SAMPLER3D: + RENDERER_ASSERT(0, "3D D3D9 Textures Not Implemented."); + /* + data = *(void**)data; + RENDERER_ASSERT(data, "NULL Sampler."); + if (data) + { + bindSamplerVariable<RendererTexture3D, D3D9RendererTexture3D>(*m_renderer.getD3DDevice(), *m_vertexConstants.table, var.m_vertexHandle, *(RendererTexture2D*)data); + bindSamplerVariable<RendererTexture3D, D3D9RendererTexture3D>(*m_renderer.getD3DDevice(), *m_fragmentConstants[pass].table, var.m_fragmentHandles[pass], *(RendererTexture2D*)data); + } + */ + break; + } + } +} + +static RendererMaterial::VariableType getVariableType(const D3DXCONSTANT_DESC& desc) +{ + RendererMaterial::VariableType vt = RendererMaterial::NUM_VARIABLE_TYPES; + switch (desc.Type) + { + case D3DXPT_FLOAT: + if (desc.Rows == 4 && desc.Columns == 4) + { + vt = RendererMaterial::VARIABLE_FLOAT4x4; + } + else if (desc.Rows == 1 && desc.Columns == 1) + { + vt = RendererMaterial::VARIABLE_FLOAT; + } + else if (desc.Rows == 1 && desc.Columns == 2) + { + vt = RendererMaterial::VARIABLE_FLOAT2; + } + else if (desc.Rows == 1 && desc.Columns == 3) + { + vt = RendererMaterial::VARIABLE_FLOAT3; + } + else if (desc.Rows == 1 && desc.Columns == 4) + { + vt = RendererMaterial::VARIABLE_FLOAT4; + } + break; + case D3DXPT_SAMPLER2D: + vt = RendererMaterial::VARIABLE_SAMPLER2D; + break; + } + RENDERER_ASSERT(vt < RendererMaterial::NUM_VARIABLE_TYPES, "Unable to convert shader variable type."); + return vt; +} + +void D3D9RendererMaterial::loadCustomConstants(ID3DXConstantTable& table, Pass pass) +{ + D3DXCONSTANTTABLE_DESC desc; + table.GetDesc(&desc); + for (UINT i = 0; i < desc.Constants; i++) + { + D3DXHANDLE constant = table.GetConstant(0, i); + RENDERER_ASSERT(constant, "Unable to find constant"); + if (constant) + { + D3DXCONSTANT_DESC cdesc; + UINT count = 1; + table.GetConstantDesc(constant, &cdesc, &count); + PX_ASSERT(count == 1); + if (count == 1 && strncmp(cdesc.Name, "g_", 2)) + { + VariableType type = getVariableType(cdesc); + if (type < NUM_VARIABLE_TYPES) + { + D3D9Variable* var = 0; + // search to see if the variable already exists... + PxU32 numVariables = (PxU32)m_variables.size(); + for (PxU32 j = 0; j < numVariables; j++) + { + if (!strcmp(m_variables[j]->getName(), cdesc.Name)) + { + var = static_cast<D3D9Variable*>(m_variables[j]); + break; + } + } + // check to see if the variable is of the same type. + if (var) + { + RENDERER_ASSERT(var->getType() == type, "Variable changes type!"); + } + // if we couldn't find the variable... create a new variable... + if (!var) + { + var = new D3D9Variable(cdesc.Name, type, m_variableBufferSize); + m_variables.push_back(var); + m_variableBufferSize += var->getDataSize(); + } + // add the handle to the variable... + if (pass < NUM_PASSES) + { + var->addFragmentHandle(table, constant, pass); + } + else + { + var->addVertexHandle(table, constant); + } + } + } + } + } +} + +HRESULT D3D9RendererMaterial::loadCacheShader(LPCSTR shaderFilePath, const char* suffix, CONST D3DXMACRO *defines, LPD3DXINCLUDE shaderIncluder, LPCSTR functionName, LPCSTR profile, DWORD flags, LPD3DXBUFFER &shader, LPD3DXCONSTANTTABLE *constantTable) +{ + const char* cacheDir = m_renderer.getCacheShaderDir(); + D3D9Renderer::D3DXInterface &d3dx = m_renderer.getD3DX(); + char fullpath[1024]; + FILE* file = NULL; + WIN32_FIND_DATA FindFileData; + + if(cacheDir) + { + //get shader file time + char originpath[1024]; + Ps::strlcpy(originpath, 1024, m_renderer.getAssetDir()); + Ps::strlcat(originpath, 1024, "shaders/"); + Ps::strlcat(originpath, 1024, shaderFilePath); + + HANDLE hFind = FindFirstFile(originpath, &FindFileData); + if (hFind == INVALID_HANDLE_VALUE) + return D3DERR_NOTAVAILABLE; + FindClose(hFind); + + //read cached file + char relativepath[512]; + Ps::strlcpy(relativepath, 512, shaderFilePath); + Ps::strlcat(relativepath, 512, suffix); + + SampleFramework::SampleDirManager cacheOutputDirManager(cacheDir, false); + cacheOutputDirManager.getFilePath(relativepath, fullpath, false); + + PxToolkit::fopen_s(&file, fullpath, "rb"); + if(file) + { + FILETIME lastWriteTime1; + fread(&lastWriteTime1, 1, sizeof(FILETIME), file); + + if( CompareFileTime(&FindFileData.ftLastWriteTime, &lastWriteTime1) == 0) + { + PxU32 shaderSize; + size_t len = fread(&shaderSize, 1, sizeof(PxU32), file); + + HRESULT result = d3dx.CreateBuffer( shaderSize, &shader); + PX_ASSERT( result == D3D_OK); + if(result == D3D_OK) + { + len = fread(shader->GetBufferPointer(), 1, shader->GetBufferSize(), file); + PX_ASSERT(len == shaderSize); + result = d3dx.GetShaderConstantTable((const DWORD*)shader->GetBufferPointer(), constantTable); + } + fclose(file); + return result; + } + fclose(file); + } + } + + LPD3DXBUFFER errors = 0; + + HRESULT result = d3dx.CompileShaderFromFileA(shaderFilePath, defines, shaderIncluder, functionName, profile, flags, &shader, &errors, constantTable); + processCompileErrors(errors); + RENDERER_ASSERT(result == D3D_OK && shader, "Failed to compile shader."); + if(errors) + { + errors->Release(); + } + + //save compiled shader + if(cacheDir && result == D3D_OK && shader) + { + PxToolkit::fopen_s(&file, fullpath, "wb"); + if(file) + { + fwrite(&FindFileData.ftLastWriteTime, 1, sizeof(FILETIME), file); + + PxU32 shaderSize = shader->GetBufferSize(); + fwrite(&shaderSize, 1, sizeof(PxU32), file); + fwrite(shader->GetBufferPointer(), 1, shaderSize, file); + fclose(file); + } + } + + return result; +} + +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererMaterial.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererMaterial.h new file mode 100644 index 00000000..10ba4e64 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererMaterial.h @@ -0,0 +1,146 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +#ifndef D3D9_RENDERER_MATERIAL_H +#define D3D9_RENDERER_MATERIAL_H + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D9) + +#include <RendererMaterial.h> + +#include "D3D9Renderer.h" + +namespace SampleRenderer +{ + + class D3D9Renderer; + + class D3D9RendererMaterial : public RendererMaterial + { + public: + D3D9RendererMaterial(D3D9Renderer &renderer, const RendererMaterialDesc &desc); + virtual ~D3D9RendererMaterial(void); + virtual void setModelMatrix(const float *matrix); + + private: + virtual const Renderer& getRenderer() const { return m_renderer; } + virtual void bind(RendererMaterial::Pass pass, RendererMaterialInstance *materialInstance, bool instanced) const; + virtual void bindMeshState(bool instanced) const; + virtual void unbind(void) const; + virtual void bindVariable(Pass pass, const Variable &variable, const void *data) const; + + void loadCustomConstants(ID3DXConstantTable &table, Pass pass); + HRESULT loadCacheShader(LPCSTR shaderFilePath, const char* suffix, CONST D3DXMACRO *defines, LPD3DXINCLUDE shaderIncluder, + LPCSTR functionName, LPCSTR profile, DWORD flags, LPD3DXBUFFER &shader, LPD3DXCONSTANTTABLE *constantTable); + + private: + class ShaderConstants + { + public: + LPD3DXCONSTANTTABLE table; + + D3DXHANDLE modelMatrix; + D3DXHANDLE viewMatrix; + D3DXHANDLE projMatrix; + D3DXHANDLE modelViewMatrix; + D3DXHANDLE modelViewProjMatrix; + + D3DXHANDLE boneMatrices; + + D3DXHANDLE fogColorAndDistance; + + D3DXHANDLE eyePosition; + D3DXHANDLE eyeDirection; + + D3DXHANDLE ambientColor; + + D3DXHANDLE lightColor; + D3DXHANDLE lightIntensity; + D3DXHANDLE lightDirection; + D3DXHANDLE lightPosition; + D3DXHANDLE lightInnerRadius; + D3DXHANDLE lightOuterRadius; + D3DXHANDLE lightInnerCone; + D3DXHANDLE lightOuterCone; + D3DXHANDLE lightShadowMap; + D3DXHANDLE lightShadowMatrix; + + D3DXHANDLE vfaceScale; + + public: + ShaderConstants(void); + ~ShaderConstants(void); + + void loadConstants(void); + + void bindEnvironment(IDirect3DDevice9 &d3dDevice, const D3D9Renderer::ShaderEnvironment &shaderEnv) const; + }; + + class D3D9Variable : public Variable + { + friend class D3D9RendererMaterial; + public: + D3D9Variable(const char *name, VariableType type, PxU32 offset); + virtual ~D3D9Variable(void); + + void addVertexHandle(ID3DXConstantTable &table, D3DXHANDLE handle); + void addFragmentHandle(ID3DXConstantTable &table, D3DXHANDLE handle, Pass pass); + + private: + D3D9Variable &operator=(const D3D9Variable&) { return *this; } + + private: + D3DXHANDLE m_vertexHandle; + UINT m_vertexRegister; + D3DXHANDLE m_fragmentHandles[NUM_PASSES]; + UINT m_fragmentRegisters[NUM_PASSES]; + }; + + private: + D3D9RendererMaterial &operator=(const D3D9RendererMaterial&) { return *this; } + + private: + D3D9Renderer &m_renderer; + + D3DCMPFUNC m_d3dAlphaTestFunc; + D3DBLEND m_d3dSrcBlendFunc; + D3DBLEND m_d3dDstBlendFunc; + + IDirect3DVertexShader9 *m_vertexShader; + IDirect3DVertexShader9 *m_instancedVertexShader; + IDirect3DPixelShader9 *m_fragmentPrograms[NUM_PASSES]; + + ShaderConstants m_vertexConstants; + ShaderConstants m_instancedVertexConstants; + ShaderConstants m_fragmentConstants[NUM_PASSES]; + }; + +} // namespace SampleRenderer + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D9) +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererMesh.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererMesh.cpp new file mode 100644 index 00000000..f403c7f0 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererMesh.cpp @@ -0,0 +1,333 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D9) + +#include "D3D9RendererMesh.h" +#include "D3D9RendererVertexBuffer.h" +#include "D3D9RendererInstanceBuffer.h" + +#include <RendererMeshDesc.h> + +#include <SamplePlatform.h> + +#pragma warning(disable:4702 4189) + +using namespace SampleRenderer; + +static D3DVERTEXELEMENT9 buildVertexElement(WORD stream, WORD offset, D3DDECLTYPE type, BYTE method, BYTE usage, BYTE usageIndex) +{ + D3DVERTEXELEMENT9 element; + element.Stream = stream; + element.Offset = offset; +#if defined(RENDERER_WINDOWS) + element.Type = (BYTE)type; +#else + element.Type = type; +#endif + element.Method = method; + element.Usage = usage; + element.UsageIndex = usageIndex; + return element; +} + +D3D9RendererMesh::D3D9RendererMesh(D3D9Renderer &renderer, const RendererMeshDesc &desc) : +RendererMesh(desc), + m_renderer(renderer) +{ + m_d3dVertexDecl = 0; + + IDirect3DDevice9 *d3dDevice = m_renderer.getD3DDevice(); + RENDERER_ASSERT(d3dDevice, "Renderer's D3D Device not found!"); + if(d3dDevice) + { + PxU32 numVertexBuffers = getNumVertexBuffers(); + const RendererVertexBuffer *const*vertexBuffers = getVertexBuffers(); + std::vector<D3DVERTEXELEMENT9> vertexElements; + for(PxU32 i=0; i<numVertexBuffers; i++) + { + const RendererVertexBuffer *vb = vertexBuffers[i]; + if(vb) + { + const D3D9RendererVertexBuffer &d3dVb = *static_cast<const D3D9RendererVertexBuffer*>(vb); + d3dVb.addVertexElements(i, vertexElements); + } + } +#if RENDERER_INSTANCING + if(m_instanceBuffer) + { + static_cast<const D3D9RendererInstanceBuffer*>(m_instanceBuffer)->addVertexElements(numVertexBuffers, vertexElements); + } +#endif + vertexElements.push_back(buildVertexElement(0xFF, 0, D3DDECLTYPE_UNUSED, 0, 0, 0)); + + d3dDevice->CreateVertexDeclaration(&vertexElements[0], &m_d3dVertexDecl); + RENDERER_ASSERT(m_d3dVertexDecl, "Failed to create Direct3D9 Vertex Declaration."); + } +} + +D3D9RendererMesh::~D3D9RendererMesh(void) +{ + if(m_d3dVertexDecl) + { + SampleFramework::SamplePlatform::platform()->D3D9BlockUntilNotBusy(m_d3dVertexDecl); + m_d3dVertexDecl->Release(); + m_d3dVertexDecl = 0; + } +} + +static D3DPRIMITIVETYPE getD3DPrimitive(RendererMesh::Primitive primitive) +{ + D3DPRIMITIVETYPE d3dPrimitive = D3DPT_FORCE_DWORD; + switch(primitive) + { + case RendererMesh::PRIMITIVE_POINTS: d3dPrimitive = D3DPT_POINTLIST; break; + case RendererMesh::PRIMITIVE_LINES: d3dPrimitive = D3DPT_LINELIST; break; + case RendererMesh::PRIMITIVE_LINE_STRIP: d3dPrimitive = D3DPT_LINESTRIP; break; + case RendererMesh::PRIMITIVE_TRIANGLES: d3dPrimitive = D3DPT_TRIANGLELIST; break; + case RendererMesh::PRIMITIVE_TRIANGLE_STRIP: d3dPrimitive = D3DPT_TRIANGLESTRIP; break; + case RendererMesh::PRIMITIVE_POINT_SPRITES: d3dPrimitive = D3DPT_POINTLIST; break; + } + RENDERER_ASSERT(d3dPrimitive != D3DPT_FORCE_DWORD, "Unable to find Direct3D9 Primitive."); + return d3dPrimitive; +} + +static PxU32 computePrimitiveCount(RendererMesh::Primitive primitive, PxU32 vertexCount) +{ + PxU32 numPrimitives = 0; + switch(primitive) + { + case RendererMesh::PRIMITIVE_POINTS: numPrimitives = vertexCount; break; + case RendererMesh::PRIMITIVE_LINES: numPrimitives = vertexCount / 2; break; + case RendererMesh::PRIMITIVE_LINE_STRIP: numPrimitives = vertexCount>=2 ? vertexCount - 1 : 0; break; + case RendererMesh::PRIMITIVE_TRIANGLES: numPrimitives = vertexCount / 3; break; + case RendererMesh::PRIMITIVE_TRIANGLE_STRIP: numPrimitives = vertexCount>=3 ? vertexCount - 2 : 0; break; + case RendererMesh::PRIMITIVE_POINT_SPRITES: numPrimitives = vertexCount; break; + } + RENDERER_ASSERT(numPrimitives, "Unable to compute the number of Primitives."); + return numPrimitives; +} + +void D3D9RendererMesh::renderIndices(PxU32 numVertices, PxU32 firstIndex, PxU32 numIndices, RendererIndexBuffer::Format indexFormat, RendererMaterial *material) const +{ + PX_PROFILE_ZONE("D3D9RendererMesh_renderIndices",0); + IDirect3DDevice9 *d3dDevice = m_renderer.getD3DDevice(); + if(d3dDevice && m_d3dVertexDecl) + { + d3dDevice->SetVertexDeclaration(m_d3dVertexDecl); + Primitive primitive = getPrimitives(); +#if RENDERER_INSTANCING + PxU32 numVertexBuffers = getNumVertexBuffers(); + // Only reset stream source when multiple vertex buffers are given + // This fixes issues with several GPU vendors when rendering a given indexed mesh multiple times + static const physx::PxU32 minVertexBuffersForStreamSourceReset = 2; + if (numVertexBuffers >= minVertexBuffersForStreamSourceReset) + { + for(PxU32 i=0; i<numVertexBuffers; i++) + { + d3dDevice->SetStreamSourceFreq((UINT)i, D3DSTREAMSOURCE_INDEXEDDATA | 1); + } + } +#endif + if(primitive == RendererMesh::PRIMITIVE_POINT_SPRITES) d3dDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, 1); + + d3dDevice->DrawIndexedPrimitive(getD3DPrimitive(primitive), 0, 0, numVertices, firstIndex, computePrimitiveCount(primitive, numIndices)); + + if(primitive == RendererMesh::PRIMITIVE_POINT_SPRITES) d3dDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, 0); + } +} + +void D3D9RendererMesh::renderVertices(PxU32 numVertices, RendererMaterial *material) const +{ + PX_PROFILE_ZONE("D3D9RendererMesh_renderVertices",0); + IDirect3DDevice9 *d3dDevice = m_renderer.getD3DDevice(); + if(d3dDevice && m_d3dVertexDecl) + { + d3dDevice->SetVertexDeclaration(m_d3dVertexDecl); + Primitive primitive = getPrimitives(); +#if RENDERER_INSTANCING + PxU32 numVertexBuffers = getNumVertexBuffers(); + for(PxU32 i=0; i<numVertexBuffers; i++) + { + d3dDevice->SetStreamSourceFreq((UINT)i, 1); + } +#endif + if(primitive == RendererMesh::PRIMITIVE_POINT_SPRITES) d3dDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, 1); + + D3DPRIMITIVETYPE d3dPrimitive = getD3DPrimitive(primitive); + PxU32 numPrimitives = computePrimitiveCount(primitive, numVertices); + PX_ASSERT(d3dPrimitive != D3DPT_LINELIST || (numVertices&1)==0); // can't have an odd number of verts when drawing lines...! + d3dDevice->DrawPrimitive(d3dPrimitive, 0, numPrimitives); + + if(primitive == RendererMesh::PRIMITIVE_POINT_SPRITES) d3dDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, 0); + } +} + +void D3D9RendererMesh::renderIndicesInstanced(PxU32 numVertices, PxU32 firstIndex, PxU32 numIndices, RendererIndexBuffer::Format indexFormat,RendererMaterial *material) const +{ + PX_PROFILE_ZONE("D3D9RendererMesh_renderIndicesInstanced",0); + IDirect3DDevice9 *d3dDevice = m_renderer.getD3DDevice(); + if(d3dDevice && m_d3dVertexDecl) + { +#if RENDERER_INSTANCING + PxU32 numVertexBuffers = getNumVertexBuffers(); + for(PxU32 i=0; i<numVertexBuffers; i++) + { + d3dDevice->SetStreamSourceFreq((UINT)i, D3DSTREAMSOURCE_INDEXEDDATA | m_numInstances); + } +#endif + + d3dDevice->SetVertexDeclaration(m_d3dVertexDecl); + + Primitive primitive = getPrimitives(); + + if(primitive == RendererMesh::PRIMITIVE_POINT_SPRITES) + { + d3dDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, 1); + } + +#if RENDERER_INSTANCING + d3dDevice->DrawIndexedPrimitive(getD3DPrimitive(primitive), 0, 0, numVertices, firstIndex, computePrimitiveCount(primitive, numIndices)); +#else + const PxU8 *ibuffer = (const PxU8 *)m_instanceBuffer->lock(); + ibuffer+=m_instanceBuffer->getStride()*m_firstInstance; + D3DXMATRIX m; + D3DXMatrixIdentity(&m); + for (PxU32 i=0; i<m_numInstances; i++) + { + PxF32 *dest = (PxF32 *)&m; + + const PxF32 *src = (const PxF32 *)ibuffer; + + dest[0] = src[3]; + dest[1] = src[6]; + dest[2] = src[9]; + dest[3] = src[0]; + + dest[4] = src[4]; + dest[5] = src[7]; + dest[6] = src[10]; + dest[7] = src[1]; + + dest[8] = src[5]; + dest[9] = src[8]; + dest[10] = src[11]; + dest[11] = src[2]; + + dest[12] = 0; + dest[13] = 0; + dest[14] = 0; + dest[15] = 1; + + material->setModelMatrix(dest); + d3dDevice->DrawIndexedPrimitive(getD3DPrimitive(primitive), 0, 0, numVertices, firstIndex, computePrimitiveCount(primitive, numIndices)); + ibuffer+=m_instanceBuffer->getStride(); + } +#endif + + if(primitive == RendererMesh::PRIMITIVE_POINT_SPRITES) + { + d3dDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, 0); + } + } +} + +void D3D9RendererMesh::renderVerticesInstanced(PxU32 numVertices,RendererMaterial *material) const +{ + PX_PROFILE_ZONE("D3D9RendererMesh_renderVerticesInstanced",0); + IDirect3DDevice9 *d3dDevice = m_renderer.getD3DDevice(); + if(d3dDevice && m_d3dVertexDecl) + { +#if RENDERER_INSTANCING + PxU32 numVertexBuffers = getNumVertexBuffers(); + for(PxU32 i=0; i<numVertexBuffers; i++) + { + d3dDevice->SetStreamSourceFreq((UINT)i, m_numInstances); + } +#endif + + d3dDevice->SetVertexDeclaration(m_d3dVertexDecl); + + Primitive primitive = getPrimitives(); + + if(primitive == RendererMesh::PRIMITIVE_POINT_SPRITES) + { + d3dDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, 1); + } + + +#if RENDERER_INSTANCING + d3dDevice->DrawPrimitive(getD3DPrimitive(primitive), 0, computePrimitiveCount(primitive, numVertices)); +#else + const PxU8 *ibuffer = (const PxU8 *)m_instanceBuffer->lock(); + D3DXMATRIX m; + D3DXMatrixIdentity(&m); + for (PxU32 i=0; i<m_numInstances; i++) + { + PxF32 *dest = (PxF32 *)&m; + + const PxF32 *src = (const PxF32 *)ibuffer; + + dest[0] = src[3]; + dest[1] = src[6]; + dest[2] = src[9]; + dest[3] = src[0]; + + dest[4] = src[4]; + dest[5] = src[7]; + dest[6] = src[10]; + dest[7] = src[1]; + + dest[8] = src[5]; + dest[9] = src[8]; + dest[10] = src[11]; + dest[11] = src[2]; + + dest[12] = 0; + dest[13] = 0; + dest[14] = 0; + dest[15] = 1; + + + material->setModelMatrix(dest); + + d3dDevice->DrawPrimitive(getD3DPrimitive(primitive), 0, computePrimitiveCount(primitive, numVertices)); + + ibuffer+=m_instanceBuffer->getStride(); + } +#endif + + if(primitive == RendererMesh::PRIMITIVE_POINT_SPRITES) + { + d3dDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, 0); + } + } +} + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D9) diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererMesh.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererMesh.h new file mode 100644 index 00000000..d0e8f0b0 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererMesh.h @@ -0,0 +1,66 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +#ifndef D3D9_RENDERER_MESH_H +#define D3D9_RENDERER_MESH_H + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D9) + +#include <RendererMesh.h> +#include "D3D9Renderer.h" + +namespace SampleRenderer +{ + + class D3D9RendererMesh : public RendererMesh + { + public: + D3D9RendererMesh(D3D9Renderer &renderer, const RendererMeshDesc &desc); + virtual ~D3D9RendererMesh(void); + + public: + virtual void renderIndices(PxU32 numVertices, PxU32 firstIndex, PxU32 numIndices, RendererIndexBuffer::Format indexFormat,RendererMaterial *material) const; + virtual void renderVertices(PxU32 numVertices,RendererMaterial *material) const; + + virtual void renderIndicesInstanced(PxU32 numVertices, PxU32 firstIndex, PxU32 numIndices, RendererIndexBuffer::Format indexFormat,RendererMaterial *material) const; + virtual void renderVerticesInstanced(PxU32 numVertices,RendererMaterial *material) const; + + protected: + D3D9RendererMesh &operator=(const D3D9RendererMesh &) { return *this; } + + Renderer& renderer() { return m_renderer; } + + private: + D3D9Renderer &m_renderer; + IDirect3DVertexDeclaration9 *m_d3dVertexDecl; + }; + +} // namespace SampleRenderer + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D9) +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererSpotLight.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererSpotLight.cpp new file mode 100644 index 00000000..4be8e978 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererSpotLight.cpp @@ -0,0 +1,64 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D9) + +#include "D3D9RendererSpotLight.h" +#include "D3D9RendererTexture2D.h" + +using namespace SampleRenderer; + +D3D9RendererSpotLight::D3D9RendererSpotLight(D3D9Renderer &renderer, const RendererSpotLightDesc &desc) : + RendererSpotLight(desc), +m_renderer(renderer) +{ + +} + +D3D9RendererSpotLight::~D3D9RendererSpotLight(void) +{ + +} + +void D3D9RendererSpotLight::bind(void) const +{ + D3D9Renderer::ShaderEnvironment &shaderEnv = m_renderer.getShaderEnvironment(); + convertToD3D9(shaderEnv.lightColor, m_color); + shaderEnv.lightIntensity = m_intensity; + convertToD3D9(shaderEnv.lightPosition, m_position); + convertToD3D9(shaderEnv.lightDirection, m_direction); + shaderEnv.lightInnerRadius = m_innerRadius; + shaderEnv.lightOuterRadius = m_outerRadius; + shaderEnv.lightInnerCone = m_innerCone; + shaderEnv.lightOuterCone = m_outerCone; + shaderEnv.lightShadowMap = m_shadowMap ? static_cast<D3D9RendererTexture2D*>(m_shadowMap)->m_d3dTexture : 0; + buildProjectMatrix(shaderEnv.lightShadowMatrix, m_shadowProjection, m_shadowTransform); +} + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D9) diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererSpotLight.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererSpotLight.h new file mode 100644 index 00000000..cbeb668b --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererSpotLight.h @@ -0,0 +1,56 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +#ifndef D3D9_RENDERER_SPOT_LIGHT_H +#define D3D9_RENDERER_SPOT_LIGHT_H + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D9) + +#include <RendererSpotLight.h> + +#include "D3D9Renderer.h" + +namespace SampleRenderer +{ + + class D3D9RendererSpotLight : public RendererSpotLight + { + public: + D3D9RendererSpotLight(D3D9Renderer &renderer, const RendererSpotLightDesc &desc); + virtual ~D3D9RendererSpotLight(void); + + virtual void bind(void) const; + + private: + D3D9Renderer &m_renderer; + }; + +} // namespace SampleRenderer + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D9) +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererTarget.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererTarget.cpp new file mode 100644 index 00000000..0428ad04 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererTarget.cpp @@ -0,0 +1,143 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. + +// suppress LNK4221 on Xbox +namespace {char dummySymbol; } + +#include <RendererConfig.h> +#include "D3D9RendererTarget.h" + +#if defined(RENDERER_ENABLE_DIRECT3D9) && defined(RENDERER_ENABLE_DIRECT3D9_TARGET) + +#include <RendererTargetDesc.h> +#include "D3D9RendererTexture2D.h" + +using namespace SampleRenderer; + +D3D9RendererTarget::D3D9RendererTarget(IDirect3DDevice9 &d3dDevice, const RendererTargetDesc &desc) : + m_d3dDevice(d3dDevice) +{ + m_d3dLastSurface = 0; + m_d3dLastDepthStencilSurface = 0; + m_d3dDepthStencilSurface = 0; + for(PxU32 i=0; i<desc.numTextures; i++) + { + D3D9RendererTexture2D &texture = *static_cast<D3D9RendererTexture2D*>(desc.textures[i]); + m_textures.push_back(&texture); + } + m_depthStencilSurface = static_cast<D3D9RendererTexture2D*>(desc.depthStencilSurface); + RENDERER_ASSERT(m_depthStencilSurface && m_depthStencilSurface->m_d3dTexture, "Invalid Target Depth Stencil Surface!"); + onDeviceReset(); +} + +D3D9RendererTarget::~D3D9RendererTarget(void) +{ + if(m_d3dDepthStencilSurface) m_d3dDepthStencilSurface->Release(); +} + +void D3D9RendererTarget::bind(void) +{ + RENDERER_ASSERT(m_d3dLastSurface==0 && m_d3dLastDepthStencilSurface==0, "Render Target in bad state!"); + if(m_d3dDepthStencilSurface && !m_d3dLastSurface && !m_d3dLastDepthStencilSurface) + { + m_d3dDevice.GetRenderTarget(0, &m_d3dLastSurface); + m_d3dDevice.GetDepthStencilSurface(&m_d3dLastDepthStencilSurface); + const PxU32 numTextures = (PxU32)m_textures.size(); + for(PxU32 i=0; i<numTextures; i++) + { + IDirect3DSurface9 *d3dSurcace = 0; + D3D9RendererTexture2D &texture = *m_textures[i]; + /* HRESULT result = */ texture.m_d3dTexture->GetSurfaceLevel(0, &d3dSurcace); + RENDERER_ASSERT(d3dSurcace, "Cannot get Texture Surface!"); + if(d3dSurcace) + { + m_d3dDevice.SetRenderTarget(i, d3dSurcace); + d3dSurcace->Release(); + } + } + m_d3dDevice.SetDepthStencilSurface(m_d3dDepthStencilSurface); + const DWORD flags = D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER; + m_d3dDevice.Clear(0, 0, flags, 0x00000000, 1.0f, 0); + } + float depthBias = 0.0001f; + float biasSlope = 1.58f; +#if RENDERER_ENABLE_DRESSCODE + depthBias = dcParam("depthBias", depthBias, 0.0f, 0.01f); + biasSlope = dcParam("biasSlope", biasSlope, 0.0f, 5.0f); +#endif + m_d3dDevice.SetRenderState(D3DRS_DEPTHBIAS, *(DWORD*)&depthBias); + m_d3dDevice.SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, *(DWORD*)&biasSlope); +} + +void D3D9RendererTarget::unbind(void) +{ + RENDERER_ASSERT(m_d3dLastSurface && m_d3dLastDepthStencilSurface, "Render Target in bad state!"); + if(m_d3dDepthStencilSurface && m_d3dLastSurface && m_d3dLastDepthStencilSurface) + { + m_d3dDevice.SetDepthStencilSurface(m_d3dLastDepthStencilSurface); + m_d3dDevice.SetRenderTarget(0, m_d3dLastSurface); + const PxU32 numTextures = (PxU32)m_textures.size(); + for(PxU32 i=1; i<numTextures; i++) + { + m_d3dDevice.SetRenderTarget(i, 0); + } + m_d3dLastSurface->Release(); + m_d3dLastSurface = 0; + m_d3dLastDepthStencilSurface->Release(); + m_d3dLastDepthStencilSurface = 0; + } + float depthBias = 0; + float biasSlope = 0; + m_d3dDevice.SetRenderState(D3DRS_DEPTHBIAS, *(DWORD*)&depthBias); + m_d3dDevice.SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, *(DWORD*)&biasSlope); +} + +void D3D9RendererTarget::onDeviceLost(void) +{ + RENDERER_ASSERT(m_d3dLastDepthStencilSurface==0, "Render Target in bad state!"); + RENDERER_ASSERT(m_d3dDepthStencilSurface, "Render Target in bad state!"); + if(m_d3dDepthStencilSurface) + { + m_d3dDepthStencilSurface->Release(); + m_d3dDepthStencilSurface = 0; + } +} + +void D3D9RendererTarget::onDeviceReset(void) +{ + RENDERER_ASSERT(m_d3dDepthStencilSurface==0, "Render Target in bad state!"); + if(!m_d3dDepthStencilSurface && m_depthStencilSurface && m_depthStencilSurface->m_d3dTexture) + { + bool ok = m_depthStencilSurface->m_d3dTexture->GetSurfaceLevel(0, &m_d3dDepthStencilSurface) == D3D_OK; + if(!ok) + { + RENDERER_ASSERT(ok, "Failed to create Render Target Depth Stencil Surface."); + } + } +} + +#endif //#if defined(RENDERER_ENABLE_DIRECT3D9) && defined(RENDERER_ENABLE_DIRECT3D9_TARGET) diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererTarget.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererTarget.h new file mode 100644 index 00000000..495f9cd2 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererTarget.h @@ -0,0 +1,76 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +#ifndef D3D9_RENDERER_TARGET_H +#define D3D9_RENDERER_TARGET_H + +#include <RendererConfig.h> + +// TODO: 360 can't render directly into texture memory, so we need to create a pool of +// surfaces to share internally and then "resolve" them into the textures inside of +// the 'unbind' call. +#if defined(RENDERER_WINDOWS) + #define RENDERER_ENABLE_DIRECT3D9_TARGET +#endif + +#if defined(RENDERER_ENABLE_DIRECT3D9) && defined(RENDERER_ENABLE_DIRECT3D9_TARGET) + +#include <RendererTarget.h> +#include "D3D9Renderer.h" + +namespace SampleRenderer +{ + + class D3D9RendererTexture2D; + + class D3D9RendererTarget : public RendererTarget, public D3D9RendererResource + { + public: + D3D9RendererTarget(IDirect3DDevice9 &d3dDevice, const RendererTargetDesc &desc); + virtual ~D3D9RendererTarget(void); + + private: + D3D9RendererTarget& operator=( const D3D9RendererTarget& ) {} + virtual void bind(void); + virtual void unbind(void); + + private: + virtual void onDeviceLost(void); + virtual void onDeviceReset(void); + + private: + IDirect3DDevice9 &m_d3dDevice; + IDirect3DSurface9 *m_d3dLastSurface; + IDirect3DSurface9 *m_d3dLastDepthStencilSurface; + IDirect3DSurface9 *m_d3dDepthStencilSurface; + std::vector<D3D9RendererTexture2D*> m_textures; + D3D9RendererTexture2D *m_depthStencilSurface; + }; + +} // namespace SampleRenderer + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D9) && defined(RENDERER_ENABLE_DIRECT3D9_TARGET) +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererTexture2D.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererTexture2D.cpp new file mode 100644 index 00000000..a1c4e09f --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererTexture2D.cpp @@ -0,0 +1,190 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D9) + +#include "D3D9RendererTexture2D.h" +#include <RendererTexture2DDesc.h> + +#include <SamplePlatform.h> + +using namespace SampleRenderer; + +static void supportsAnisotropic(IDirect3DDevice9& device, bool& min, bool& mag, bool& mip) +{ + D3DCAPS9 caps; + device.GetDeviceCaps(&caps); + min = (caps.TextureFilterCaps & D3DPTFILTERCAPS_MINFANISOTROPIC) != 0; + mag = (caps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFANISOTROPIC) != 0; + mip = false; +} + +static D3DFORMAT getD3D9TextureFormat(RendererTexture2D::Format format) +{ + D3DFORMAT d3dFormat = static_cast<D3DFORMAT>(SampleFramework::SamplePlatform::platform()->getD3D9TextureFormat(format)); + RENDERER_ASSERT(d3dFormat != D3DFMT_UNKNOWN, "Unable to convert to D3D9 Texture Format."); + return d3dFormat; +} + +static D3DTEXTUREFILTERTYPE getD3D9TextureFilter(RendererTexture2D::Filter filter, bool anisoSupport) +{ + D3DTEXTUREFILTERTYPE d3dFilter = D3DTEXF_FORCE_DWORD; + switch(filter) + { + case RendererTexture2D::FILTER_NEAREST: d3dFilter = D3DTEXF_POINT; break; + case RendererTexture2D::FILTER_LINEAR: d3dFilter = D3DTEXF_LINEAR; break; + case RendererTexture2D::FILTER_ANISOTROPIC: d3dFilter = anisoSupport ? D3DTEXF_ANISOTROPIC : D3DTEXF_LINEAR; break; + } + RENDERER_ASSERT(d3dFilter != D3DTEXF_FORCE_DWORD, "Unable to convert to D3D9 Filter mode."); + return d3dFilter; +} + +static D3DTEXTUREADDRESS getD3D9TextureAddressing(RendererTexture2D::Addressing addressing) +{ + D3DTEXTUREADDRESS d3dAddressing = D3DTADDRESS_FORCE_DWORD; + switch(addressing) + { + case RendererTexture2D::ADDRESSING_WRAP: d3dAddressing = D3DTADDRESS_WRAP; break; + case RendererTexture2D::ADDRESSING_CLAMP: d3dAddressing = D3DTADDRESS_CLAMP; break; + case RendererTexture2D::ADDRESSING_MIRROR: d3dAddressing = D3DTADDRESS_MIRROR; break; + } + RENDERER_ASSERT(d3dAddressing != D3DTADDRESS_FORCE_DWORD, "Unable to convert to D3D9 Addressing mode."); + return d3dAddressing; +} + +D3D9RendererTexture2D::D3D9RendererTexture2D(IDirect3DDevice9 &d3dDevice, D3D9Renderer& renderer, const RendererTexture2DDesc &desc) + : RendererTexture2D(desc) + , m_d3dDevice(d3dDevice) +{ + RENDERER_ASSERT(desc.depth == 1, "Invalid depth for 2D Texture!"); + + m_d3dTexture = 0; + //managed textures can't be locked. +#ifdef DIRECT3D9_SUPPORT_D3DUSAGE_DYNAMIC + m_usage = renderer.canUseManagedResources() ? 0 : D3DUSAGE_DYNAMIC; +#else + m_usage = 0; +#endif + m_pool = renderer.canUseManagedResources() ? D3DPOOL_MANAGED : D3DPOOL_DEFAULT; + m_format = getD3D9TextureFormat(desc.format); + + bool minAniso, magAniso, mipAniso; + supportsAnisotropic(d3dDevice, minAniso, magAniso, mipAniso); + m_d3dMinFilter = getD3D9TextureFilter(desc.filter, minAniso); + m_d3dMagFilter = getD3D9TextureFilter(desc.filter, magAniso); + m_d3dMipFilter = getD3D9TextureFilter(desc.filter, mipAniso); + m_d3dAddressingU = getD3D9TextureAddressing(desc.addressingU); + m_d3dAddressingV = getD3D9TextureAddressing(desc.addressingV); + if(desc.renderTarget) + { + m_usage = D3DUSAGE_RENDERTARGET; + m_pool = D3DPOOL_DEFAULT; + } + if(isDepthStencilFormat(desc.format)) + { + m_usage = D3DUSAGE_DEPTHSTENCIL; + m_pool = D3DPOOL_DEFAULT; + } + onDeviceReset(); +} + +D3D9RendererTexture2D::~D3D9RendererTexture2D(void) +{ + if(m_d3dTexture) + { + D3DCAPS9 pCaps; + m_d3dDevice.GetDeviceCaps(&pCaps); + DWORD i = pCaps.MaxTextureBlendStages; + while(i--) m_d3dDevice.SetTexture(i, NULL); + SampleFramework::SamplePlatform::platform()->D3D9BlockUntilNotBusy(m_d3dTexture); + m_d3dTexture->Release(); + } +} + +void *D3D9RendererTexture2D::lockLevel(PxU32 level, PxU32 &pitch) +{ + void *buffer = 0; + if(m_d3dTexture) + { + D3DLOCKED_RECT lockedRect; + HRESULT result = m_d3dTexture->LockRect((DWORD)level, &lockedRect, 0, D3DLOCK_NOSYSLOCK); + RENDERER_ASSERT(result == D3D_OK, "Unable to lock Texture 2D."); + if(result == D3D_OK) + { + buffer = lockedRect.pBits; + pitch = (PxU32)lockedRect.Pitch; + } + } + return buffer; +} + +void D3D9RendererTexture2D::unlockLevel(PxU32 level) +{ + if(m_d3dTexture) + { + m_d3dTexture->UnlockRect(level); + } +} + +void D3D9RendererTexture2D::bind(PxU32 samplerIndex) +{ + m_d3dDevice.SetTexture( (DWORD)samplerIndex, m_d3dTexture); + m_d3dDevice.SetSamplerState((DWORD)samplerIndex, D3DSAMP_MINFILTER, m_d3dMinFilter); + m_d3dDevice.SetSamplerState((DWORD)samplerIndex, D3DSAMP_MAGFILTER, m_d3dMagFilter); + m_d3dDevice.SetSamplerState((DWORD)samplerIndex, D3DSAMP_MIPFILTER, m_d3dMipFilter); + m_d3dDevice.SetSamplerState((DWORD)samplerIndex, D3DSAMP_ADDRESSU, m_d3dAddressingU); + m_d3dDevice.SetSamplerState((DWORD)samplerIndex, D3DSAMP_ADDRESSV, m_d3dAddressingV); +} + +void D3D9RendererTexture2D::onDeviceLost(void) +{ + if(m_pool != D3DPOOL_MANAGED) + { + if(m_d3dTexture) + { + m_d3dTexture->Release(); + m_d3dTexture = 0; + } + } +} + +void D3D9RendererTexture2D::onDeviceReset(void) +{ + if(!m_d3dTexture) + { + HRESULT result = m_d3dDevice.CreateTexture((UINT)getWidth(), (UINT)getHeight(), (UINT)getNumLevels(), m_usage, m_format, m_pool, &m_d3dTexture, 0); + RENDERER_ASSERT(result == D3D_OK, "Unable to create D3D9 Texture."); + if(result == D3D_OK) + { + + } + } +} + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D9) diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererTexture2D.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererTexture2D.h new file mode 100644 index 00000000..29166103 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererTexture2D.h @@ -0,0 +1,82 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +#ifndef D3D9_RENDERER_TEXTURE_2D_H +#define D3D9_RENDERER_TEXTURE_2D_H + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D9) + +#include <RendererTexture2D.h> +#include "D3D9Renderer.h" + +namespace SampleRenderer +{ + class D3D9Renderer; + class D3D9RendererTexture2D : public RendererTexture2D, public D3D9RendererResource + { + friend class D3D9RendererTarget; + friend class D3D9RendererSpotLight; + public: + D3D9RendererTexture2D(IDirect3DDevice9 &d3dDevice, D3D9Renderer& renderer, const RendererTexture2DDesc &desc); + virtual ~D3D9RendererTexture2D(void); + + public: + virtual void *lockLevel(PxU32 level, PxU32 &pitch); + virtual void unlockLevel(PxU32 level); + + void bind(PxU32 samplerIndex); + + virtual void select(PxU32 stageIndex) + { + bind(stageIndex); + } + + private: + + virtual void onDeviceLost(void); + virtual void onDeviceReset(void); + + private: + IDirect3DDevice9 &m_d3dDevice; + IDirect3DTexture9 *m_d3dTexture; + + DWORD m_usage; + D3DPOOL m_pool; + D3DFORMAT m_format; + + D3DTEXTUREFILTERTYPE m_d3dMinFilter; + D3DTEXTUREFILTERTYPE m_d3dMagFilter; + D3DTEXTUREFILTERTYPE m_d3dMipFilter; + D3DTEXTUREADDRESS m_d3dAddressingU; + D3DTEXTUREADDRESS m_d3dAddressingV; + }; + +} // namespace SampleRenderer + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D9) +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererVertexBuffer.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererVertexBuffer.cpp new file mode 100644 index 00000000..383154a2 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererVertexBuffer.cpp @@ -0,0 +1,299 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D9) + +#include "D3D9RendererVertexBuffer.h" +#include <RendererVertexBufferDesc.h> + +#if PX_WINDOWS +#include <task/PxTask.h> +#endif + +using namespace SampleRenderer; + +static D3DVERTEXELEMENT9 buildVertexElement(WORD stream, WORD offset, D3DDECLTYPE type, BYTE method, BYTE usage, BYTE usageIndex) +{ + D3DVERTEXELEMENT9 element; + element.Stream = stream; + element.Offset = offset; +#if defined(RENDERER_WINDOWS) + element.Type = (BYTE)type; +#else + element.Type = type; +#endif + element.Method = method; + element.Usage = usage; + element.UsageIndex = usageIndex; + return element; +} + +static D3DDECLTYPE getD3DType(RendererVertexBuffer::Format format) +{ + D3DDECLTYPE d3dType = D3DDECLTYPE_UNUSED; + switch(format) + { + case RendererVertexBuffer::FORMAT_FLOAT1: d3dType = D3DDECLTYPE_FLOAT1; break; + case RendererVertexBuffer::FORMAT_FLOAT2: d3dType = D3DDECLTYPE_FLOAT2; break; + case RendererVertexBuffer::FORMAT_FLOAT3: d3dType = D3DDECLTYPE_FLOAT3; break; + case RendererVertexBuffer::FORMAT_FLOAT4: d3dType = D3DDECLTYPE_FLOAT4; break; + case RendererVertexBuffer::FORMAT_UBYTE4: d3dType = D3DDECLTYPE_UBYTE4; break; + case RendererVertexBuffer::FORMAT_USHORT4: d3dType = D3DDECLTYPE_SHORT4; break; + case RendererVertexBuffer::FORMAT_COLOR_BGRA: d3dType = D3DDECLTYPE_D3DCOLOR; break; + case RendererVertexBuffer::FORMAT_COLOR_RGBA: d3dType = D3DDECLTYPE_D3DCOLOR; break; + case RendererVertexBuffer::FORMAT_COLOR_NATIVE: d3dType = D3DDECLTYPE_D3DCOLOR; break; + } + RENDERER_ASSERT(d3dType != D3DDECLTYPE_UNUSED, "Invalid Direct3D9 vertex type."); + return d3dType; +} + +static D3DDECLUSAGE getD3DUsage(RendererVertexBuffer::Semantic semantic, PxU8 &usageIndex) +{ + D3DDECLUSAGE d3dUsage = D3DDECLUSAGE_FOG; + usageIndex = 0; + if(semantic >= RendererVertexBuffer::SEMANTIC_TEXCOORD0 && semantic <= RendererVertexBuffer::SEMANTIC_TEXCOORDMAX) + { + d3dUsage = D3DDECLUSAGE_TEXCOORD; + usageIndex = (PxU8)(semantic - RendererVertexBuffer::SEMANTIC_TEXCOORD0); + } + else + { + switch(semantic) + { + case RendererVertexBuffer::SEMANTIC_POSITION: d3dUsage = D3DDECLUSAGE_POSITION; break; + case RendererVertexBuffer::SEMANTIC_NORMAL: d3dUsage = D3DDECLUSAGE_NORMAL; break; + case RendererVertexBuffer::SEMANTIC_TANGENT: d3dUsage = D3DDECLUSAGE_TANGENT; break; + case RendererVertexBuffer::SEMANTIC_COLOR: d3dUsage = D3DDECLUSAGE_COLOR; break; + case RendererVertexBuffer::SEMANTIC_BONEINDEX: + d3dUsage = D3DDECLUSAGE_TEXCOORD; + usageIndex = RENDERER_BONEINDEX_CHANNEL; + break; + case RendererVertexBuffer::SEMANTIC_BONEWEIGHT: + d3dUsage = D3DDECLUSAGE_TEXCOORD; + usageIndex = RENDERER_BONEWEIGHT_CHANNEL; + break; + } + } + // There's absolutely no reason why there can't be semantics for which Direct3D9 has no support + //RENDERER_ASSERT(d3dUsage != D3DDECLUSAGE_FOG, "Invalid Direct3D9 vertex usage."); + return d3dUsage; +} + +D3D9RendererVertexBuffer::D3D9RendererVertexBuffer(IDirect3DDevice9 &d3dDevice, D3D9Renderer& renderer, const RendererVertexBufferDesc &desc) : +RendererVertexBuffer(desc), + m_d3dDevice(d3dDevice), + m_savedData(NULL) +{ + m_d3dVertexBuffer = 0; + + m_usage = D3DUSAGE_WRITEONLY; + m_lockFlags = 0; + m_pool = renderer.canUseManagedResources() ? D3DPOOL_MANAGED : D3DPOOL_DEFAULT; + m_bufferSize = (UINT)(desc.maxVertices * m_stride); + + m_bufferWritten = false; + +#if RENDERER_ENABLE_DYNAMIC_VB_POOLS + if(desc.hint==RendererVertexBuffer::HINT_DYNAMIC ) + { + if (!desc.registerInCUDA) + { + m_usage = D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY; + // discard all that data if we are going to overwrite it again (saves some time waiting to copy everything back) + m_lockFlags = D3DLOCK_DISCARD; + } + else + { + m_usage = 0; + } + + m_pool = D3DPOOL_DEFAULT; + } +#endif + + onDeviceReset(); + + if(m_d3dVertexBuffer) + { + m_maxVertices = desc.maxVertices; + } +} + +D3D9RendererVertexBuffer::~D3D9RendererVertexBuffer(void) +{ + if(m_d3dVertexBuffer) + { +#if PX_WINDOWS && PX_SUPPORT_GPU_PHYSX + if(m_interopContext && m_registeredInCUDA) + { + m_registeredInCUDA = !m_interopContext->unregisterResourceInCuda(m_InteropHandle); + } +#endif + + m_d3dVertexBuffer->Release(); + } + + delete[] m_savedData; +} + +void D3D9RendererVertexBuffer::addVertexElements(PxU32 streamIndex, std::vector<D3DVERTEXELEMENT9> &vertexElements) const +{ + for(PxU32 i=0; i<NUM_SEMANTICS; i++) + { + Semantic semantic = (Semantic)i; + const SemanticDesc &sm = m_semanticDescs[semantic]; + if(sm.format < NUM_FORMATS) + { + PxU8 d3dUsageIndex = 0; + D3DDECLUSAGE d3dUsage = getD3DUsage(semantic, d3dUsageIndex); + if (D3DDECLUSAGE_FOG != d3dUsage) + { + vertexElements.push_back(buildVertexElement((WORD)streamIndex, (WORD)sm.offset, getD3DType(sm.format), D3DDECLMETHOD_DEFAULT, (BYTE)d3dUsage, d3dUsageIndex)); + } + } + } +} + +void D3D9RendererVertexBuffer::swizzleColor(void *colors, PxU32 stride, PxU32 numColors, RendererVertexBuffer::Format inFormat) +{ + if (inFormat == RendererVertexBuffer::FORMAT_COLOR_RGBA) + { + const void *end = ((PxU8*)colors)+(stride*numColors); + for(PxU8* iterator = (PxU8*)colors; iterator < end; iterator+=stride) + { + std::swap(((PxU8*)iterator)[0], ((PxU8*)iterator)[2]); + } + } +} + +void *D3D9RendererVertexBuffer::lock(void) +{ + PX_PROFILE_ZONE("D3D9RenderVBlock",0); + void *lockedBuffer = 0; + if(m_d3dVertexBuffer) + { + const PxU32 bufferSize = m_maxVertices * m_stride; + HRESULT res = m_d3dVertexBuffer->Lock(0, (UINT)bufferSize, &lockedBuffer, m_lockFlags); + if(res != S_OK) + lockedBuffer = NULL; + RENDERER_ASSERT(lockedBuffer, "Failed to lock Direct3D9 Vertex Buffer."); + } + m_bufferWritten = true; + return lockedBuffer; +} + +void D3D9RendererVertexBuffer::unlock(void) +{ + PX_PROFILE_ZONE("D3D9RenderVBunlock",0); + if(m_d3dVertexBuffer) + { + m_d3dVertexBuffer->Unlock(); + } +} + +void D3D9RendererVertexBuffer::bind(PxU32 streamID, PxU32 firstVertex) +{ + prepareForRender(); + if(m_d3dVertexBuffer) + { + m_d3dDevice.SetStreamSource((UINT)streamID, m_d3dVertexBuffer, firstVertex*m_stride, m_stride); + } +} + +void D3D9RendererVertexBuffer::unbind(PxU32 streamID) +{ + m_d3dDevice.SetStreamSource((UINT)streamID, 0, 0, 0); +} + +void D3D9RendererVertexBuffer::onDeviceLost(void) +{ +#if PX_WINDOWS && PX_SUPPORT_GPU_PHYSX + if(m_interopContext && m_registeredInCUDA) + { + m_interopContext->unregisterResourceInCuda(m_InteropHandle); + } +#endif + m_registeredInCUDA = false; + + if(m_pool != D3DPOOL_MANAGED && m_d3dVertexBuffer) + { + if (m_bufferWritten) + { + if (NULL == m_savedData) + m_savedData = new char[m_bufferSize]; + + void* lockedBuffer = 0; + m_d3dVertexBuffer->Lock(0, m_bufferSize, &lockedBuffer, m_lockFlags); + RENDERER_ASSERT(lockedBuffer, "Failed to lock Direct3D9 Vertex Buffer."); + + memcpy(m_savedData, lockedBuffer, m_bufferSize); + m_d3dVertexBuffer->Unlock(); + } + + m_d3dVertexBuffer->Release(); + m_d3dVertexBuffer = 0; + } +} + +void D3D9RendererVertexBuffer::onDeviceReset(void) +{ + if(!m_d3dVertexBuffer) + { + m_d3dDevice.CreateVertexBuffer(m_bufferSize, m_usage, 0, m_pool, &m_d3dVertexBuffer, 0); + RENDERER_ASSERT(m_d3dVertexBuffer, "Failed to create Direct3D9 Vertex Buffer."); +#if PX_WINDOWS && PX_SUPPORT_GPU_PHYSX + if(m_interopContext && m_d3dVertexBuffer && m_mustBeRegisteredInCUDA) + { + RENDERER_ASSERT(m_deferredUnlock == false, "Deferred VB Unlock must be disabled when CUDA Interop is in use.") + m_registeredInCUDA = m_interopContext->registerResourceInCudaD3D(m_InteropHandle, m_d3dVertexBuffer); + } +#endif + + if (m_bufferWritten) + { + void* lockedBuffer = 0; + m_d3dVertexBuffer->Lock(0, m_bufferSize, &lockedBuffer, m_lockFlags); + RENDERER_ASSERT(lockedBuffer, "Failed to lock Direct3D9 Vertex Buffer."); + + RENDERER_ASSERT(m_savedData != NULL, "Data buffer must have been allocated."); + memcpy(lockedBuffer, m_savedData, m_bufferSize); + m_d3dVertexBuffer->Unlock(); + } + } +} + +bool D3D9RendererVertexBuffer::checkBufferWritten(void) +{ + if(m_InteropHandle) + return true; + else + return m_bufferWritten; +} + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D9) diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererVertexBuffer.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererVertexBuffer.h new file mode 100644 index 00000000..7f95f6d7 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9RendererVertexBuffer.h @@ -0,0 +1,79 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +#ifndef D3D9_RENDERER_VERTEXBUFFER_H +#define D3D9_RENDERER_VERTEXBUFFER_H + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D9) + +#include <RendererVertexBuffer.h> +#include "D3D9Renderer.h" + +namespace SampleRenderer +{ + + class D3D9RendererVertexBuffer : public RendererVertexBuffer, public D3D9RendererResource + { + public: + D3D9RendererVertexBuffer(IDirect3DDevice9 &d3dDevice, D3D9Renderer& renderer, const RendererVertexBufferDesc &desc); + virtual ~D3D9RendererVertexBuffer(void); + + void addVertexElements(PxU32 streamIndex, std::vector<D3DVERTEXELEMENT9> &vertexElements) const; + + virtual bool checkBufferWritten(void); + + protected: + virtual void swizzleColor(void *colors, PxU32 stride, PxU32 numColors, RendererVertexBuffer::Format inFormat); + + virtual void *lock(void); + virtual void unlock(void); + + virtual void bind(PxU32 streamID, PxU32 firstVertex); + virtual void unbind(PxU32 streamID); + + private: + virtual void onDeviceLost(void); + virtual void onDeviceReset(void); + + private: + IDirect3DDevice9 &m_d3dDevice; + IDirect3DVertexBuffer9 *m_d3dVertexBuffer; + + DWORD m_usage; + DWORD m_lockFlags; + D3DPOOL m_pool; + UINT m_bufferSize; + + bool m_bufferWritten; + void* m_savedData; + }; + +} // namespace SampleRenderer + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D9) +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9WPFRenderer.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9WPFRenderer.cpp new file mode 100644 index 00000000..41426bb6 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9WPFRenderer.cpp @@ -0,0 +1,350 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +#ifdef WIN32 // win32 only + +#include "D3D9WPFRenderer.h" +#include "SamplePlatform.h" + +#define APP_NAME "D3D9WPFRenderer" + +namespace SampleRenderer +{ + + + static volatile LONG classRefCount = 0; + + static LONG incrementClassReference() + { + return InterlockedIncrement( &classRefCount ); + } + static LONG decrementClassReference() + { + return InterlockedDecrement( &classRefCount ); + } + + D3D9WPFRenderer::D3D9WPFRenderer( HWND hWnd + , IDirect3D9* inDirect3d + , IDirect3DDevice9* inDevice + , const char* devName + , PxU32 dispWidth + , PxU32 dispHeight + , const char* assetDir + , bool lockable + , bool isDeviceEx ) + : D3D9Renderer( inDirect3d, devName, 0, 0, inDevice, isDeviceEx, assetDir ) + , mHwnd( hWnd ) + , mDesiredWidth( dispWidth ) + , mDesiredHeight( dispHeight ) + , mCanonicalSurface( NULL ) + , mLockable( lockable ) + , mListener( NULL ) + { + SampleFramework::createPlatform(NULL); + } + + D3D9WPFRenderer::~D3D9WPFRenderer() + { + releaseSurface(); + DestroyWindow(mHwnd); + if ( mListener ) mListener->release(); mListener = NULL; + if ( decrementClassReference() == 0 ) + UnregisterClass(TEXT(APP_NAME), NULL); + } + + WPFRendererListener* D3D9WPFRenderer::getListener() { return mListener; } + void D3D9WPFRenderer::setListener( WPFRendererListener* listener ) + { + if ( mListener != listener ) + { + if ( mListener ) mListener->release(); mListener = NULL; + mListener = listener; + if ( mCanonicalSurface && mListener ) mListener->afterSurfaceCreated( mCanonicalSurface ); + } + } + + void D3D9WPFRenderer::onResize( PxU32 newWidth, PxU32 newHeight ) + { + mDesiredWidth = newWidth; + mDesiredHeight = newHeight; + checkResize( false ); + } + + bool D3D9WPFRenderer::swapBuffers() + { + return true; //does nothing, that is up for the parent context to do. + } + + bool D3D9WPFRenderer::isOk() const + { + return true;} + + void D3D9WPFRenderer::onDeviceLost() + { + releaseSurface(); + D3D9Renderer::onDeviceLost(); + } + + void D3D9WPFRenderer::onDeviceReset() + { + allocateSurface(); + D3D9Renderer::onDeviceReset(); + } + + void D3D9WPFRenderer::releaseSurface() + { + if( mListener ) mListener->beforeSurfaceRelease( mCanonicalSurface ); + if ( mCanonicalSurface ) mCanonicalSurface->Release(); + mCanonicalSurface = NULL; + } + + void D3D9WPFRenderer::allocateSurface() + { + PX_ASSERT( mCanonicalSurface == NULL ); + + HRESULT result = m_d3dDevice->CreateRenderTarget( + m_displayWidth + , m_displayHeight + , D3DFMT_X8R8G8B8 + , D3DMULTISAMPLE_NONE + , 0 + , mLockable + , &mCanonicalSurface + , NULL ); + PX_ASSERT( mCanonicalSurface ); + PX_ASSERT( result == D3D_OK ); + + if ( mCanonicalSurface != NULL ) + m_d3dDevice->SetRenderTarget(0, mCanonicalSurface); + + if ( mListener ) mListener->afterSurfaceCreated( mCanonicalSurface ); + } + + bool D3D9WPFRenderer::checkResize( bool isDeviceLost ) + { + bool isDeviceReset = false; + //resize the system if the desired width or height is more than we can support. + if ( mDesiredWidth > m_displayWidth + || mDesiredHeight > m_displayHeight + || isDeviceLost ) + { + m_displayWidth = PxMax( mDesiredWidth, m_displayWidth ); + m_displayHeight = PxMax( mDesiredHeight, m_displayHeight ); + if ( isDeviceLost ) + { + physx::PxU64 res = m_d3dDevice->TestCooperativeLevel(); + if(res == D3D_OK || res == D3DERR_DEVICENOTRESET) //if device is lost, device has to be ready for reset + { + isDeviceReset = true; + onDeviceLost(); + onDeviceReset(); + } + } + else + { + releaseSurface(); + releaseDepthStencilSurface(); + allocateSurface(); + buildDepthStencilSurface(); + // set out initial states... + m_d3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); + m_d3dDevice->SetRenderState(D3DRS_LIGHTING, 0); + m_d3dDevice->SetRenderState(D3DRS_ZENABLE, 1); + } + } + //else just mess with the viewport so we only render pixel-by-pixel + D3DVIEWPORT9 viewport = {0}; + m_d3dDevice->GetViewport(&viewport); + if ( viewport.Width != mDesiredWidth + || viewport.Height != mDesiredHeight ) + { + viewport.X = 0; + viewport.Y = 0; + viewport.Width = (DWORD)mDesiredWidth; + viewport.Height = (DWORD)mDesiredHeight; + viewport.MinZ = 0.0f; + viewport.MaxZ = 1.0f; + m_d3dDevice->SetViewport(&viewport); + } + return isDeviceReset; + } + + void D3D9WPFRenderer::setupAlphaBlendState() + { + m_d3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, 1); + m_d3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE); + m_d3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + } + + void D3D9WPFRenderer::restoreAlphaBlendState() + { + m_d3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, 0); + } + + void D3D9WPFRenderer::disableZWrite() + { + m_d3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, 0); + } + void D3D9WPFRenderer::enableZWrite() + { + m_d3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, 1); + } + + static DWORD GetVertexProcessingCaps(IDirect3D9* d3d) + { + D3DCAPS9 caps; + DWORD dwVertexProcessing = D3DCREATE_SOFTWARE_VERTEXPROCESSING; + if (SUCCEEDED(d3d->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps))) + { + if ((caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == D3DDEVCAPS_HWTRANSFORMANDLIGHT) + { + dwVertexProcessing = D3DCREATE_HARDWARE_VERTEXPROCESSING; + } + } + return dwVertexProcessing; + } + + + HRESULT InitializeD3D(HWND hWnd, D3DPRESENT_PARAMETERS d3dpp, IDirect3D9*& d3d, IDirect3DDevice9*& d3dDevice ) + { + d3d = NULL; + d3dDevice = NULL; + // initialize Direct3D + d3d = Direct3DCreate9(D3D_SDK_VERSION); + if ( d3d != NULL ) + { + // determine what type of vertex processing to use based on the device capabilities + DWORD dwVertexProcessing = GetVertexProcessingCaps(d3d); + // create the D3D device + return d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, + dwVertexProcessing | D3DCREATE_MULTITHREADED | D3DCREATE_FPU_PRESERVE, + &d3dpp, &d3dDevice); + } + return -1; + } + + typedef HRESULT (WINAPI *D3DEXCreateFn)( DWORD version, IDirect3D9Ex** result ); + + + HRESULT InitializeD3DEx(HWND hWnd, D3DPRESENT_PARAMETERS d3dpp, IDirect3D9*& d3d, IDirect3DDevice9*& d3dDevice, D3DEXCreateFn createFn ) + { + d3d = NULL; + d3dDevice = NULL; + IDirect3D9Ex* d3dEx = NULL; + // initialize Direct3D using the Ex function + HRESULT result = createFn( D3D_SDK_VERSION, &d3dEx ); + if ( FAILED( result ) ) return result; + + result = d3dEx->QueryInterface(__uuidof(IDirect3D9), reinterpret_cast<void **>(&d3d) ); + if ( FAILED( result ) ) { d3dEx->Release(); return result; } + + // determine what type of vertex processing to use based on the device capabilities + DWORD dwVertexProcessing = GetVertexProcessingCaps(d3d); + + // create the D3D device using the Ex function + IDirect3DDevice9Ex* deviceEx = NULL; + result = d3dEx->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, + dwVertexProcessing | D3DCREATE_MULTITHREADED | D3DCREATE_FPU_PRESERVE, + &d3dpp, NULL, &deviceEx); + + if ( FAILED(result) ) { d3dEx->Release(); d3d->Release(); return result; } + + // obtain the standard D3D device interface + deviceEx->QueryInterface(__uuidof(IDirect3DDevice9), reinterpret_cast<void **>(&d3dDevice) ); + + deviceEx->Release(); + d3dEx->Release(); + + return 0; + } + + D3D9WPFRenderer* D3D9WPFRenderer::createWPFRenderer( const char* inAssetDir, PxU32 initialWidth, PxU32 initialHeight ) + { + if ( incrementClassReference() == 1 ) + { + WNDCLASS wndclass; + memset( &wndclass, 0, sizeof( WNDCLASS ) ); + + wndclass.style = CS_HREDRAW | CS_VREDRAW; + wndclass.lpfnWndProc = DefWindowProc; + wndclass.lpszClassName = TEXT(APP_NAME); + + RegisterClass(&wndclass); + } + + HWND hWnd = CreateWindow(TEXT(APP_NAME), + TEXT(APP_NAME), + WS_OVERLAPPEDWINDOW, + 0, // Initial X + 0, // Initial Y + 0, // Width + 0, // Height + NULL, + NULL, + NULL, + NULL); + if ( hWnd == 0 ) return NULL; + + HMODULE hD3D9 = LoadLibrary(TEXT("d3d9.dll")); + D3DEXCreateFn exCreateFn = reinterpret_cast<D3DEXCreateFn>( GetProcAddress(hD3D9, "Direct3DCreate9Ex") ); + bool is9x = exCreateFn != NULL; + IDirect3D9* d3d = NULL; + IDirect3DDevice9* d3dDevice = NULL; + D3DPRESENT_PARAMETERS d3dpp; + ZeroMemory(&d3dpp, sizeof(d3dpp)); + d3dpp.Windowed = TRUE; + d3dpp.BackBufferHeight = 1; + d3dpp.BackBufferWidth = 1; + d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8; + d3dpp.hDeviceWindow = hWnd; + HRESULT result; + + if (is9x) + { + result = InitializeD3DEx(NULL, d3dpp, d3d, d3dDevice, exCreateFn); + } + else + { + result = InitializeD3D(NULL, d3dpp, d3d, d3dDevice); + } + PX_ASSERT( result >= 0 ); + if ( result >= 0 ) + { + bool lockable = !is9x; + //We only lock earlier interface, not later ones because the later ones use a hardware transfer mechanism + //where you seem to not need to lock according to some... + D3D9WPFRenderer* retval = new D3D9WPFRenderer( hWnd, d3d, d3dDevice, "Direct3d", initialWidth, initialHeight, inAssetDir, !is9x, is9x ); + retval->checkResize( false ); //setup viewport. + //Can we create a vertex buffer here? + PX_ASSERT( result == D3D_OK ); + return retval; + } + return NULL; + } +} + +#endif
\ No newline at end of file diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9WPFRenderer.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9WPFRenderer.h new file mode 100644 index 00000000..b21b815c --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d9/D3D9WPFRenderer.h @@ -0,0 +1,100 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +#ifndef D3D9_WPF_RENDERER_H +#define D3D9_WPF_RENDERER_H +#include "D3D9Renderer.h" + +namespace SampleRenderer +{ + class WPFRendererListener + { + protected: + virtual ~WPFRendererListener(){} + public: + + virtual void beforeSurfaceRelease( IDirect3DSurface9* surface ) = 0; + virtual void afterSurfaceCreated( IDirect3DSurface9* surface ) = 0; + virtual void release() = 0; + }; + + //This renderer has special interop needs with WFP so it needs to use a slightly slowing + //device specification. Also it uses some special creation mechanisms so we get as much + //performance as we can on various platforms taking the interop considerations into account. + + //One component is that SamplePlatform isn't initialized nor available thus forcing us to override + //details on some functions + class D3D9WPFRenderer : public D3D9Renderer + { + HWND mHwnd; + IDirect3DSurface9* mCanonicalSurface; + PxU32 mDesiredWidth; + PxU32 mDesiredHeight; + const bool mLockable; + WPFRendererListener* mListener; + + protected: + + D3D9WPFRenderer( HWND hWnd + , IDirect3D9* inDirect3d + , IDirect3DDevice9* inDevice + , const char* devName + , PxU32 dispWidth + , PxU32 dispHeight + , const char* assetDir + , bool lockable + , bool isDeviceEx ); + + public: + static D3D9WPFRenderer* createWPFRenderer(const char* inAssetDir, PxU32 initialWidth = 1024, PxU32 initialHeight = 768 ); + + virtual ~D3D9WPFRenderer(); + + virtual IDirect3DSurface9* getSurface() { return mCanonicalSurface; } + virtual WPFRendererListener* getListener(); + virtual void setListener( WPFRendererListener* listener ); + + virtual void onResize( PxU32 newWidth, PxU32 newHeight ); + virtual bool swapBuffers(); + virtual bool isOk() const; + virtual void onDeviceLost(); + virtual void onDeviceReset(); + + virtual PxU32 getWidth() { return mDesiredWidth; } + virtual PxU32 getHeight() { return mDesiredHeight; } + virtual void render() { beginRender(); endRender(); } + virtual void setupAlphaBlendState(); + virtual void restoreAlphaBlendState(); + virtual void disableZWrite(); + virtual void enableZWrite(); + protected: + virtual bool checkResize( bool isDeviceLost ); + void releaseSurface(); + void allocateSurface(); + }; +} + +#endif
\ No newline at end of file |