Added GPU SoftBody constraint solvers for DirectX 11 (Direct Compute) and OpenCL, thanks to AMD.
See also http://code.google.com/p/bullet/issues/detail?id=390 Added Demos/DX11ClothDemo (an OpenCL cloth demo will follow soon)
This commit is contained in:
@@ -38,6 +38,16 @@ SET (VECTOR_MATH_INCLUDE ${BULLET_PHYSICS_SOURCE_DIR}/src/BulletMultiThreaded/ve
|
||||
ENDIF(WIN32)
|
||||
|
||||
|
||||
IF (WIN32)
|
||||
FIND_PATH(DIRECTX_SDK_BASE_DIR Include/D3D11.h PATH $ENV{DXSDK_DIR} )
|
||||
IF(DIRECTX_SDK_BASE_DIR)
|
||||
OPTION(USE_DX11 "Use DirectX 11" ON)
|
||||
ELSE()
|
||||
OPTION(USE_DX11 "Use DirectX 11" OFF)
|
||||
ENDIF()
|
||||
ENDIF(WIN32)
|
||||
|
||||
|
||||
#SET(CMAKE_EXE_LINKER_FLAGS_INIT "/STACK:10000000 /INCREMENTAL:NO")
|
||||
#SET(CMAKE_EXE_LINKER_FLAGS "/STACK:10000000 /INCREMENTAL:NO")
|
||||
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
|
||||
IF (USE_DX11)
|
||||
SUBDIRS(DX11ClothDemo)
|
||||
ENDIF()
|
||||
|
||||
IF (USE_GLUT)
|
||||
|
||||
IF(BUILD_CPU_DEMOS)
|
||||
|
||||
152
Demos/DX11ClothDemo/CMakeLists.txt
Normal file
152
Demos/DX11ClothDemo/CMakeLists.txt
Normal file
@@ -0,0 +1,152 @@
|
||||
cmake_minimum_required(VERSION 2.4)
|
||||
|
||||
|
||||
#this line has to appear before 'PROJECT' in order to be able to disable incremental linking
|
||||
SET(MSVC_INCREMENTAL_DEFAULT ON)
|
||||
|
||||
PROJECT(AppDX11ClothDemo)
|
||||
SET(BULLET_VERSION 2.76)
|
||||
|
||||
IF (NOT CMAKE_BUILD_TYPE)
|
||||
# SET(CMAKE_BUILD_TYPE "Debug")
|
||||
SET(CMAKE_BUILD_TYPE "Release")
|
||||
ENDIF (NOT CMAKE_BUILD_TYPE)
|
||||
|
||||
|
||||
OPTION(USE_MSVC_RUNTIME_LIBRARY_DLL "Use MSVC Runtime Library DLL (/MD or /MDd)" ON)
|
||||
OPTION(USE_MSVC_INCREMENTAL_LINKING "Use MSVC Incremental Linking" OFF)
|
||||
|
||||
|
||||
IF(MSVC)
|
||||
IF (NOT USE_MSVC_INCREMENTAL_LINKING)
|
||||
#MESSAGE("MSVC_INCREMENTAL_DEFAULT"+${MSVC_INCREMENTAL_DEFAULT})
|
||||
SET( MSVC_INCREMENTAL_YES_FLAG "/INCREMENTAL:NO")
|
||||
|
||||
STRING(REPLACE "INCREMENTAL:YES" "INCREMENTAL:NO" replacementFlags ${CMAKE_EXE_LINKER_FLAGS_DEBUG})
|
||||
SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "/INCREMENTAL:NO ${replacementFlags}" )
|
||||
MESSAGE("CMAKE_EXE_LINKER_FLAGS_DEBUG=${CMAKE_EXE_LINKER_FLAGS_DEBUG}")
|
||||
|
||||
STRING(REPLACE "INCREMENTAL:YES" "INCREMENTAL:NO" replacementFlags3 ${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO})
|
||||
SET(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO ${replacementFlags3})
|
||||
SET(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "/INCREMENTAL:NO ${replacementFlags3}" )
|
||||
ENDIF (NOT USE_MSVC_INCREMENTAL_LINKING)
|
||||
|
||||
IF (NOT USE_MSVC_RUNTIME_LIBRARY_DLL)
|
||||
#We statically link to reduce dependancies
|
||||
FOREACH(flag_var CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
|
||||
IF(${flag_var} MATCHES "/MD")
|
||||
STRING(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
|
||||
ENDIF(${flag_var} MATCHES "/MD")
|
||||
IF(${flag_var} MATCHES "/MDd")
|
||||
STRING(REGEX REPLACE "/MDd" "/MTd" ${flag_var} "${${flag_var}}")
|
||||
ENDIF(${flag_var} MATCHES "/MDd")
|
||||
ENDFOREACH(flag_var)
|
||||
ENDIF (NOT USE_MSVC_RUNTIME_LIBRARY_DLL)
|
||||
|
||||
OPTION(USE_MSVC_SSE "Use MSVC /arch:sse option" ON)
|
||||
IF (USE_MSVC_SSE)
|
||||
ADD_DEFINITIONS(/arch:SSE)
|
||||
ENDIF()
|
||||
OPTION(USE_MSVC_FAST_FLOATINGPOINT "Use MSVC /fp:fast option" ON)
|
||||
IF (USE_MSVC_FAST_FLOATINGPOINT)
|
||||
ADD_DEFINITIONS(/fp:fast)
|
||||
ENDIF()
|
||||
ENDIF(MSVC)
|
||||
|
||||
|
||||
IF(COMMAND cmake_policy)
|
||||
cmake_policy(SET CMP0003 NEW)
|
||||
ENDIF(COMMAND cmake_policy)
|
||||
|
||||
|
||||
|
||||
|
||||
SET(DXSDK_DIR $ENV{DXSDK_DIR})
|
||||
SET(DX11_INCLUDE_PATH "${DXSDK_DIR}Include" CACHE DOCSTRING "Microsoft directX SDK include path")
|
||||
SET(DX11_LIB_PATH "${DXSDK_DIR}Lib/x86" CACHE DOCSTRING "Microsoft DirectX SDK library path")
|
||||
|
||||
SET(BulletClothExample_SRCS
|
||||
DXUT/Core/DXUT.cpp
|
||||
DXUT/Optional/DXUTcamera.cpp
|
||||
DXUT/Core/DXUTDevice11.cpp
|
||||
DXUT/Core/DXUTDevice9.cpp
|
||||
DXUT/Optional/DXUTgui.cpp
|
||||
DXUT/Core/DXUTmisc.cpp
|
||||
DXUT/Optional/DXUTres.cpp
|
||||
DXUT/Optional/DXUTsettingsdlg.cpp
|
||||
DXUT/Optional/SDKmesh.cpp
|
||||
DXUT/Optional/SDKmisc.cpp
|
||||
|
||||
cloth_renderer.cpp
|
||||
)
|
||||
|
||||
|
||||
SET(BulletClothExample_HDRS
|
||||
DXUT/Core/DXUT.h
|
||||
DXUT/Optional/DXUTcamera.h
|
||||
DXUT/Core/DXUTDevice11.h
|
||||
DXUT/Core/DXUTDevice9.h
|
||||
DXUT/Optional/DXUTgui.h
|
||||
DXUT/Core/DXUTmisc.h
|
||||
DXUT/Optional/DXUTres.h
|
||||
DXUT/Optional/DXUTsettingsdlg.h
|
||||
DXUT/Optional/SDKmesh.h
|
||||
DXUT/Optional/SDKmisc.h
|
||||
|
||||
btDirectComputeSupport.h
|
||||
cap.h
|
||||
cloth.h
|
||||
cylinder.h
|
||||
# FreeImage.h
|
||||
resource.h
|
||||
)
|
||||
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
${DX11_INCLUDE_PATH}
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/src
|
||||
"DXUT/Core" "DXUT/Optional"
|
||||
${VECTOR_MATH_INCLUDE}
|
||||
)
|
||||
LINK_DIRECTORIES(${DX11_LIB_PATH})
|
||||
|
||||
ADD_DEFINITIONS(-DUNICODE)
|
||||
ADD_DEFINITIONS(-D_UNICODE)
|
||||
|
||||
ADD_EXECUTABLE(AppDX11ClothDemo WIN32
|
||||
${BulletClothExample_SRCS}
|
||||
${BulletClothExample_HDRS}
|
||||
)
|
||||
TARGET_LINK_LIBRARIES(AppDX11ClothDemo
|
||||
d3dcompiler
|
||||
dxerr
|
||||
dxguid
|
||||
d3dx9
|
||||
d3d9
|
||||
winmm
|
||||
comctl32
|
||||
d3dx11
|
||||
BulletDynamics
|
||||
BulletCollision
|
||||
LinearMath
|
||||
BulletSoftBody
|
||||
BulletSoftBodySolvers_CPU
|
||||
BulletSoftBodySolvers_DX11
|
||||
)
|
||||
|
||||
IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES)
|
||||
ADD_CUSTOM_COMMAND(
|
||||
TARGET AppDX11ClothDemo
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/Demos/DX11ClothDemo/cloth_renderer_PS.hlsl ${CMAKE_CURRENT_BINARY_DIR}/cloth_renderer_PS.hlsl
|
||||
COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/Demos/DX11ClothDemo/cloth_renderer_VS.hlsl ${CMAKE_CURRENT_BINARY_DIR}/cloth_renderer_VS.hlsl
|
||||
COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/Demos/DX11ClothDemo/texture.bmp ${CMAKE_CURRENT_BINARY_DIR}/texture.bmp
|
||||
COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/Demos/DX11ClothDemo/amdFlag.bmp ${CMAKE_CURRENT_BINARY_DIR}/amdFlag.bmp
|
||||
COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/Demos/DX11ClothDemo/atiFlag.bmp ${CMAKE_CURRENT_BINARY_DIR}/atiFlag.bmp
|
||||
COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/Demos/DX11ClothDemo/texture.png ${CMAKE_CURRENT_BINARY_DIR}/texture.png
|
||||
COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/Demos/DX11ClothDemo/Media/UI/Font.dds ${CMAKE_CURRENT_BINARY_DIR}/Media/UI/Font.dds
|
||||
COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/Demos/DX11ClothDemo/Media/Tiny/tiny.sdkmesh ${CMAKE_CURRENT_BINARY_DIR}/Media/Tiny/tiny.sdkmesh
|
||||
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
5846
Demos/DX11ClothDemo/DXUT/Core/DXUT.cpp
Normal file
5846
Demos/DX11ClothDemo/DXUT/Core/DXUT.cpp
Normal file
File diff suppressed because it is too large
Load Diff
378
Demos/DX11ClothDemo/DXUT/Core/DXUT.h
Normal file
378
Demos/DX11ClothDemo/DXUT/Core/DXUT.h
Normal file
@@ -0,0 +1,378 @@
|
||||
//--------------------------------------------------------------------------------------
|
||||
// File: DXUT.h
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//--------------------------------------------------------------------------------------
|
||||
#pragma once
|
||||
#ifndef DXUT_H
|
||||
#define DXUT_H
|
||||
|
||||
#ifndef UNICODE
|
||||
#error "DXUT requires a Unicode build. See the nearby comments for details"
|
||||
//
|
||||
// If you are using Microsoft Visual C++ .NET, under the General tab of the project
|
||||
// properties change the Character Set to 'Use Unicode Character Set'.
|
||||
//
|
||||
// Windows XP and later are native Unicode so Unicode applications will perform better.
|
||||
// For Windows 98 and Windows Me support, consider using the Microsoft Layer for Unicode (MSLU).
|
||||
//
|
||||
// To use MSLU, link against a set of libraries similar to this
|
||||
// /nod:kernel32.lib /nod:advapi32.lib /nod:user32.lib /nod:gdi32.lib /nod:shell32.lib /nod:comdlg32.lib /nod:version.lib /nod:mpr.lib /nod:rasapi32.lib /nod:winmm.lib /nod:winspool.lib /nod:vfw32.lib /nod:secur32.lib /nod:oleacc.lib /nod:oledlg.lib /nod:sensapi.lib UnicoWS.lib kernel32.lib advapi32.lib user32.lib gdi32.lib shell32.lib comdlg32.lib version.lib mpr.lib rasapi32.lib winmm.lib winspool.lib vfw32.lib secur32.lib oleacc.lib oledlg.lib sensapi.lib dxerr.lib dxguid.lib d3dx9d.lib d3d9.lib comctl32.lib
|
||||
// and put the unicows.dll (available for download from msdn.microsoft.com) in the exe's folder.
|
||||
//
|
||||
// For more details see the MSDN article titled:
|
||||
// "MSLU: Develop Unicode Applications for Windows 9x Platforms with the Microsoft Layer for Unicode"
|
||||
// at http://msdn.microsoft.com/msdnmag/issues/01/10/MSLU/default.aspx
|
||||
//
|
||||
#endif
|
||||
|
||||
#include "dxsdkver.h"
|
||||
#if ( _DXSDK_PRODUCT_MAJOR < 9 || _DXSDK_BUILD_MAJOR < 1455 )
|
||||
#error The installed DXSDK is out of date.
|
||||
#endif
|
||||
|
||||
#ifndef STRICT
|
||||
#define STRICT
|
||||
#endif
|
||||
|
||||
// If app hasn't choosen, set to work with Windows 98, Windows Me, Windows 2000, Windows XP and beyond
|
||||
#ifndef WINVER
|
||||
#define WINVER 0x0500
|
||||
#endif
|
||||
#ifndef _WIN32_WINDOWS
|
||||
#define _WIN32_WINDOWS 0x0500
|
||||
#endif
|
||||
#ifndef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0600
|
||||
#endif
|
||||
|
||||
// #define DXUT_AUTOLIB to automatically include the libs needed for DXUT
|
||||
#ifdef DXUT_AUTOLIB
|
||||
#pragma comment( lib, "dxerr.lib" )
|
||||
#pragma comment( lib, "dxguid.lib" )
|
||||
#pragma comment( lib, "d3d9.lib" )
|
||||
#if defined(DEBUG) || defined(_DEBUG)
|
||||
#pragma comment( lib, "d3dx9d.lib" )
|
||||
#else
|
||||
#pragma comment( lib, "d3dx9.lib" )
|
||||
#endif
|
||||
#pragma comment( lib, "winmm.lib" )
|
||||
#pragma comment( lib, "comctl32.lib" )
|
||||
#endif
|
||||
|
||||
#pragma warning( disable : 4100 ) // disable unreference formal parameter warnings for /W4 builds
|
||||
|
||||
// Enable extra D3D debugging in debug builds if using the debug DirectX runtime.
|
||||
// This makes D3D objects work well in the debugger watch window, but slows down
|
||||
// performance slightly.
|
||||
#if defined(DEBUG) || defined(_DEBUG)
|
||||
#ifndef D3D_DEBUG_INFO
|
||||
#define D3D_DEBUG_INFO
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Standard Windows includes
|
||||
#include <windows.h>
|
||||
#include <initguid.h>
|
||||
#include <assert.h>
|
||||
#include <wchar.h>
|
||||
#include <mmsystem.h>
|
||||
#include <commctrl.h> // for InitCommonControls()
|
||||
#include <shellapi.h> // for ExtractIcon()
|
||||
#include <new.h> // for placement new
|
||||
#include <shlobj.h>
|
||||
#include <math.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// CRT's memory leak detection
|
||||
#if defined(DEBUG) || defined(_DEBUG)
|
||||
#include <crtdbg.h>
|
||||
#endif
|
||||
|
||||
// Direct3D9 includes
|
||||
#include <d3d9.h>
|
||||
#include <d3dx9.h>
|
||||
|
||||
|
||||
// Direct3D11 includes
|
||||
#include <dxgi.h>
|
||||
#include <d3d11.h>
|
||||
#include <d3dCompiler.h>
|
||||
#include <d3dx11.h>
|
||||
|
||||
// XInput includes
|
||||
#include <xinput.h>
|
||||
|
||||
// HRESULT translation for Direct3D10 and other APIs
|
||||
#include <dxerr.h>
|
||||
|
||||
|
||||
#if defined(DEBUG) || defined(_DEBUG)
|
||||
#ifndef V
|
||||
#define V(x) { hr = (x); if( FAILED(hr) ) { DXUTTrace( __FILE__, (DWORD)__LINE__, hr, L#x, true ); } }
|
||||
#endif
|
||||
#ifndef V_RETURN
|
||||
#define V_RETURN(x) { hr = (x); if( FAILED(hr) ) { return DXUTTrace( __FILE__, (DWORD)__LINE__, hr, L#x, true ); } }
|
||||
#endif
|
||||
#else
|
||||
#ifndef V
|
||||
#define V(x) { hr = (x); }
|
||||
#endif
|
||||
#ifndef V_RETURN
|
||||
#define V_RETURN(x) { hr = (x); if( FAILED(hr) ) { return hr; } }
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef SAFE_DELETE
|
||||
#define SAFE_DELETE(p) { if (p) { delete (p); (p)=NULL; } }
|
||||
#endif
|
||||
#ifndef SAFE_DELETE_ARRAY
|
||||
#define SAFE_DELETE_ARRAY(p) { if (p) { delete[] (p); (p)=NULL; } }
|
||||
#endif
|
||||
#ifndef SAFE_RELEASE
|
||||
#define SAFE_RELEASE(p) { if (p) { (p)->Release(); (p)=NULL; } }
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Structs
|
||||
//--------------------------------------------------------------------------------------
|
||||
struct DXUTD3D9DeviceSettings
|
||||
{
|
||||
UINT AdapterOrdinal;
|
||||
D3DDEVTYPE DeviceType;
|
||||
D3DFORMAT AdapterFormat;
|
||||
DWORD BehaviorFlags;
|
||||
D3DPRESENT_PARAMETERS pp;
|
||||
};
|
||||
|
||||
struct DXUTD3D11DeviceSettings
|
||||
{
|
||||
UINT AdapterOrdinal;
|
||||
D3D_DRIVER_TYPE DriverType;
|
||||
UINT Output;
|
||||
DXGI_SWAP_CHAIN_DESC sd;
|
||||
UINT32 CreateFlags;
|
||||
UINT32 SyncInterval;
|
||||
DWORD PresentFlags;
|
||||
bool AutoCreateDepthStencil; // DXUT will create the depth stencil resource and view if true
|
||||
DXGI_FORMAT AutoDepthStencilFormat;
|
||||
D3D_FEATURE_LEVEL DeviceFeatureLevel;
|
||||
};
|
||||
|
||||
enum DXUTDeviceVersion
|
||||
{
|
||||
DXUT_D3D9_DEVICE,
|
||||
DXUT_D3D11_DEVICE
|
||||
};
|
||||
|
||||
struct DXUTDeviceSettings
|
||||
{
|
||||
DXUTDeviceVersion ver;
|
||||
D3D_FEATURE_LEVEL MinimumFeatureLevel;
|
||||
DXUTD3D9DeviceSettings d3d9; // only valid if ver == DXUT_D3D9_DEVICE
|
||||
DXUTD3D11DeviceSettings d3d11; // only valid if ver == DXUT_D3D11_DEVICE
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Error codes
|
||||
//--------------------------------------------------------------------------------------
|
||||
#define DXUTERR_NODIRECT3D MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0901)
|
||||
#define DXUTERR_NOCOMPATIBLEDEVICES MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0902)
|
||||
#define DXUTERR_MEDIANOTFOUND MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0903)
|
||||
#define DXUTERR_NONZEROREFCOUNT MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0904)
|
||||
#define DXUTERR_CREATINGDEVICE MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0905)
|
||||
#define DXUTERR_RESETTINGDEVICE MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0906)
|
||||
#define DXUTERR_CREATINGDEVICEOBJECTS MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0907)
|
||||
#define DXUTERR_RESETTINGDEVICEOBJECTS MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0908)
|
||||
#define DXUTERR_DEVICEREMOVED MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x090A)
|
||||
#define DXUTERR_NODIRECT3D11 MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x090)
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Callback registration
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// General callbacks
|
||||
typedef void (CALLBACK *LPDXUTCALLBACKFRAMEMOVE)( double fTime, float fElapsedTime, void* pUserContext );
|
||||
typedef void (CALLBACK *LPDXUTCALLBACKKEYBOARD)( UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext );
|
||||
typedef void (CALLBACK *LPDXUTCALLBACKMOUSE)( bool bLeftButtonDown, bool bRightButtonDown, bool bMiddleButtonDown, bool bSideButton1Down, bool bSideButton2Down, int nMouseWheelDelta, int xPos, int yPos, void* pUserContext );
|
||||
typedef LRESULT (CALLBACK *LPDXUTCALLBACKMSGPROC)( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing, void* pUserContext );
|
||||
typedef void (CALLBACK *LPDXUTCALLBACKTIMER)( UINT idEvent, void* pUserContext );
|
||||
typedef bool (CALLBACK *LPDXUTCALLBACKMODIFYDEVICESETTINGS)( DXUTDeviceSettings* pDeviceSettings, void* pUserContext );
|
||||
typedef bool (CALLBACK *LPDXUTCALLBACKDEVICEREMOVED)( void* pUserContext );
|
||||
|
||||
// Direct3D 9 callbacks
|
||||
typedef bool (CALLBACK *LPDXUTCALLBACKISD3D9DEVICEACCEPTABLE)( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext );
|
||||
typedef HRESULT (CALLBACK *LPDXUTCALLBACKD3D9DEVICECREATED)( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext );
|
||||
typedef HRESULT (CALLBACK *LPDXUTCALLBACKD3D9DEVICERESET)( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext );
|
||||
typedef void (CALLBACK *LPDXUTCALLBACKD3D9FRAMERENDER)( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext );
|
||||
typedef void (CALLBACK *LPDXUTCALLBACKD3D9DEVICELOST)( void* pUserContext );
|
||||
typedef void (CALLBACK *LPDXUTCALLBACKD3D9DEVICEDESTROYED)( void* pUserContext );
|
||||
|
||||
class CD3D11EnumAdapterInfo;
|
||||
class CD3D11EnumDeviceInfo;
|
||||
// Direct3D 11 callbacks
|
||||
typedef bool (CALLBACK *LPDXUTCALLBACKISD3D11DEVICEACCEPTABLE)( const CD3D11EnumAdapterInfo *AdapterInfo, UINT Output, const CD3D11EnumDeviceInfo *DeviceInfo, DXGI_FORMAT BackBufferFormat, bool bWindowed, void* pUserContext );
|
||||
typedef HRESULT (CALLBACK *LPDXUTCALLBACKD3D11DEVICECREATED)( ID3D11Device* pd3dDevice, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext );
|
||||
typedef HRESULT (CALLBACK *LPDXUTCALLBACKD3D11SWAPCHAINRESIZED)( ID3D11Device* pd3dDevice, IDXGISwapChain *pSwapChain, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext );
|
||||
typedef void (CALLBACK *LPDXUTCALLBACKD3D11FRAMERENDER)( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3dImmediateContext, double fTime, float fElapsedTime, void* pUserContext );
|
||||
typedef void (CALLBACK *LPDXUTCALLBACKD3D11SWAPCHAINRELEASING)( void* pUserContext );
|
||||
typedef void (CALLBACK *LPDXUTCALLBACKD3D11DEVICEDESTROYED)( void* pUserContext );
|
||||
|
||||
// General callbacks
|
||||
void WINAPI DXUTSetCallbackFrameMove( LPDXUTCALLBACKFRAMEMOVE pCallback, void* pUserContext = NULL );
|
||||
void WINAPI DXUTSetCallbackKeyboard( LPDXUTCALLBACKKEYBOARD pCallback, void* pUserContext = NULL );
|
||||
void WINAPI DXUTSetCallbackMouse( LPDXUTCALLBACKMOUSE pCallback, bool bIncludeMouseMove = false, void* pUserContext = NULL );
|
||||
void WINAPI DXUTSetCallbackMsgProc( LPDXUTCALLBACKMSGPROC pCallback, void* pUserContext = NULL );
|
||||
void WINAPI DXUTSetCallbackDeviceChanging( LPDXUTCALLBACKMODIFYDEVICESETTINGS pCallback, void* pUserContext = NULL );
|
||||
void WINAPI DXUTSetCallbackDeviceRemoved( LPDXUTCALLBACKDEVICEREMOVED pCallback, void* pUserContext = NULL );
|
||||
|
||||
// Direct3D 9 callbacks
|
||||
void WINAPI DXUTSetCallbackD3D9DeviceAcceptable( LPDXUTCALLBACKISD3D9DEVICEACCEPTABLE pCallback, void* pUserContext = NULL );
|
||||
void WINAPI DXUTSetCallbackD3D9DeviceCreated( LPDXUTCALLBACKD3D9DEVICECREATED pCallback, void* pUserContext = NULL );
|
||||
void WINAPI DXUTSetCallbackD3D9DeviceReset( LPDXUTCALLBACKD3D9DEVICERESET pCallback, void* pUserContext = NULL );
|
||||
void WINAPI DXUTSetCallbackD3D9FrameRender( LPDXUTCALLBACKD3D9FRAMERENDER pCallback, void* pUserContext = NULL );
|
||||
void WINAPI DXUTSetCallbackD3D9DeviceLost( LPDXUTCALLBACKD3D9DEVICELOST pCallback, void* pUserContext = NULL );
|
||||
void WINAPI DXUTSetCallbackD3D9DeviceDestroyed( LPDXUTCALLBACKD3D9DEVICEDESTROYED pCallback, void* pUserContext = NULL );
|
||||
|
||||
// Direct3D 11 callbacks
|
||||
void WINAPI DXUTSetCallbackD3D11DeviceAcceptable( LPDXUTCALLBACKISD3D11DEVICEACCEPTABLE pCallback, void* pUserContext = NULL );
|
||||
void WINAPI DXUTSetCallbackD3D11DeviceCreated( LPDXUTCALLBACKD3D11DEVICECREATED pCallback, void* pUserContext = NULL );
|
||||
void WINAPI DXUTSetCallbackD3D11SwapChainResized( LPDXUTCALLBACKD3D11SWAPCHAINRESIZED pCallback, void* pUserContext = NULL );
|
||||
void WINAPI DXUTSetCallbackD3D11FrameRender( LPDXUTCALLBACKD3D11FRAMERENDER pCallback, void* pUserContext = NULL );
|
||||
void WINAPI DXUTSetCallbackD3D11SwapChainReleasing( LPDXUTCALLBACKD3D11SWAPCHAINRELEASING pCallback, void* pUserContext = NULL );
|
||||
void WINAPI DXUTSetCallbackD3D11DeviceDestroyed( LPDXUTCALLBACKD3D11DEVICEDESTROYED pCallback, void* pUserContext = NULL );
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
HRESULT WINAPI DXUTInit( bool bParseCommandLine = true,
|
||||
bool bShowMsgBoxOnError = true,
|
||||
__in_opt WCHAR* strExtraCommandLineParams = NULL,
|
||||
bool bThreadSafeDXUT = false );
|
||||
|
||||
// Choose either DXUTCreateWindow or DXUTSetWindow. If using DXUTSetWindow, consider using DXUTStaticWndProc
|
||||
HRESULT WINAPI DXUTCreateWindow( const WCHAR* strWindowTitle = L"Direct3D Window",
|
||||
HINSTANCE hInstance = NULL, HICON hIcon = NULL, HMENU hMenu = NULL,
|
||||
int x = CW_USEDEFAULT, int y = CW_USEDEFAULT );
|
||||
HRESULT WINAPI DXUTSetWindow( HWND hWndFocus, HWND hWndDeviceFullScreen, HWND hWndDeviceWindowed, bool bHandleMessages = true );
|
||||
LRESULT CALLBACK DXUTStaticWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
|
||||
|
||||
// Choose either DXUTCreateDevice or DXUTSetD3D*Device or DXUTCreateD3DDeviceFromSettings
|
||||
|
||||
HRESULT WINAPI DXUTCreateDevice(D3D_FEATURE_LEVEL reqFL, bool bWindowed= true, int nSuggestedWidth =0, int nSuggestedHeight =0 );
|
||||
HRESULT WINAPI DXUTCreateDeviceFromSettings( DXUTDeviceSettings* pDeviceSettings, bool bPreserveInput = false, bool bClipWindowToSingleAdapter = true );
|
||||
HRESULT WINAPI DXUTSetD3D9Device( IDirect3DDevice9* pd3dDevice );
|
||||
HRESULT WINAPI DXUTSetD3D11Device( ID3D11Device* pd3dDevice, IDXGISwapChain* pSwapChain );
|
||||
|
||||
// Choose either DXUTMainLoop or implement your own main loop
|
||||
HRESULT WINAPI DXUTMainLoop( HACCEL hAccel = NULL );
|
||||
|
||||
// If not using DXUTMainLoop consider using DXUTRender3DEnvironment
|
||||
void WINAPI DXUTRender3DEnvironment();
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Common Tasks
|
||||
//--------------------------------------------------------------------------------------
|
||||
HRESULT WINAPI DXUTToggleFullScreen();
|
||||
HRESULT WINAPI DXUTToggleREF();
|
||||
HRESULT WINAPI DXUTToggleWARP();
|
||||
void WINAPI DXUTPause( bool bPauseTime, bool bPauseRendering );
|
||||
void WINAPI DXUTSetConstantFrameTime( bool bConstantFrameTime, float fTimePerFrame = 0.0333f );
|
||||
void WINAPI DXUTSetCursorSettings( bool bShowCursorWhenFullScreen = false, bool bClipCursorWhenFullScreen = false );
|
||||
void WINAPI DXUTSetD3DVersionSupport( bool bAppCanUseD3D9 = true, bool bAppCanUseD3D11 = true );
|
||||
void WINAPI DXUTSetHotkeyHandling( bool bAltEnterToToggleFullscreen = true, bool bEscapeToQuit = true, bool bPauseToToggleTimePause = true );
|
||||
void WINAPI DXUTSetMultimonSettings( bool bAutoChangeAdapter = true );
|
||||
void WINAPI DXUTSetShortcutKeySettings( bool bAllowWhenFullscreen = false, bool bAllowWhenWindowed = true ); // Controls the Windows key, and accessibility shortcut keys
|
||||
void WINAPI DXUTSetWindowSettings( bool bCallDefWindowProc = true );
|
||||
HRESULT WINAPI DXUTSetTimer( LPDXUTCALLBACKTIMER pCallbackTimer, float fTimeoutInSecs = 1.0f, UINT* pnIDEvent = NULL, void* pCallbackUserContext = NULL );
|
||||
HRESULT WINAPI DXUTKillTimer( UINT nIDEvent );
|
||||
void WINAPI DXUTResetFrameworkState();
|
||||
void WINAPI DXUTShutdown( int nExitCode = 0 );
|
||||
void WINAPI DXUTSetIsInGammaCorrectMode( bool bGammaCorrect );
|
||||
BOOL WINAPI DXUTGetMSAASwapChainCreated();
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// State Retrieval
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Direct3D 9
|
||||
IDirect3D9* WINAPI DXUTGetD3D9Object(); // Does not addref unlike typical Get* APIs
|
||||
IDirect3DDevice9* WINAPI DXUTGetD3D9Device(); // Does not addref unlike typical Get* APIs
|
||||
D3DPRESENT_PARAMETERS WINAPI DXUTGetD3D9PresentParameters();
|
||||
const D3DSURFACE_DESC* WINAPI DXUTGetD3D9BackBufferSurfaceDesc();
|
||||
const D3DCAPS9* WINAPI DXUTGetD3D9DeviceCaps();
|
||||
HRESULT WINAPI DXUTGetD3D9DeviceCaps( DXUTDeviceSettings* pDeviceSettings, D3DCAPS9* pCaps );
|
||||
bool WINAPI DXUTDoesAppSupportD3D9();
|
||||
bool WINAPI DXUTIsAppRenderingWithD3D9();
|
||||
|
||||
|
||||
// Direct3D 11
|
||||
IDXGIFactory1* WINAPI DXUTGetDXGIFactory(); // Does not addref unlike typical Get* APIs
|
||||
IDXGISwapChain* WINAPI DXUTGetDXGISwapChain(); // Does not addref unlike typical Get* APIs
|
||||
const DXGI_SURFACE_DESC* WINAPI DXUTGetDXGIBackBufferSurfaceDesc();
|
||||
bool WINAPI DXUTIsD3D11Available(); // If D3D11 APIs are availible
|
||||
ID3D11Device* WINAPI DXUTGetD3D11Device(); // Does not addref unlike typical Get* APIs
|
||||
ID3D11DeviceContext* WINAPI DXUTGetD3D11DeviceContext(); // Does not addref unlike typical Get* APIs
|
||||
HRESULT WINAPI DXUTSetupD3D11Views( ID3D11DeviceContext* pd3dDeviceContext ); // Supports immediate or deferred context
|
||||
D3D_FEATURE_LEVEL WINAPI DXUTGetD3D11DeviceFeatureLevel(); // Returns the D3D11 devices current feature level
|
||||
ID3D11RenderTargetView* WINAPI DXUTGetD3D11RenderTargetView(); // Does not addref unlike typical Get* APIs
|
||||
ID3D11DepthStencilView* WINAPI DXUTGetD3D11DepthStencilView(); // Does not addref unlike typical Get* APIs
|
||||
bool WINAPI DXUTDoesAppSupportD3D11();
|
||||
bool WINAPI DXUTIsAppRenderingWithD3D11();
|
||||
|
||||
|
||||
// General
|
||||
DXUTDeviceSettings WINAPI DXUTGetDeviceSettings();
|
||||
HINSTANCE WINAPI DXUTGetHINSTANCE();
|
||||
HWND WINAPI DXUTGetHWND();
|
||||
HWND WINAPI DXUTGetHWNDFocus();
|
||||
HWND WINAPI DXUTGetHWNDDeviceFullScreen();
|
||||
HWND WINAPI DXUTGetHWNDDeviceWindowed();
|
||||
RECT WINAPI DXUTGetWindowClientRect();
|
||||
LONG WINAPI DXUTGetWindowWidth();
|
||||
LONG WINAPI DXUTGetWindowHeight();
|
||||
RECT WINAPI DXUTGetWindowClientRectAtModeChange(); // Useful for returning to windowed mode with the same resolution as before toggle to full screen mode
|
||||
RECT WINAPI DXUTGetFullsceenClientRectAtModeChange(); // Useful for returning to full screen mode with the same resolution as before toggle to windowed mode
|
||||
double WINAPI DXUTGetTime();
|
||||
float WINAPI DXUTGetElapsedTime();
|
||||
bool WINAPI DXUTIsWindowed();
|
||||
bool WINAPI DXUTIsInGammaCorrectMode();
|
||||
float WINAPI DXUTGetFPS();
|
||||
LPCWSTR WINAPI DXUTGetWindowTitle();
|
||||
LPCWSTR WINAPI DXUTGetFrameStats( bool bIncludeFPS = false );
|
||||
LPCWSTR WINAPI DXUTGetDeviceStats();
|
||||
|
||||
bool WINAPI DXUTIsVsyncEnabled();
|
||||
bool WINAPI DXUTIsRenderingPaused();
|
||||
bool WINAPI DXUTIsTimePaused();
|
||||
bool WINAPI DXUTIsActive();
|
||||
int WINAPI DXUTGetExitCode();
|
||||
bool WINAPI DXUTGetShowMsgBoxOnError();
|
||||
bool WINAPI DXUTGetAutomation(); // Returns true if -automation parameter is used to launch the app
|
||||
bool WINAPI DXUTIsKeyDown( BYTE vKey ); // Pass a virtual-key code, ex. VK_F1, 'A', VK_RETURN, VK_LSHIFT, etc
|
||||
bool WINAPI DXUTWasKeyPressed( BYTE vKey ); // Like DXUTIsKeyDown() but return true only if the key was just pressed
|
||||
bool WINAPI DXUTIsMouseButtonDown( BYTE vButton ); // Pass a virtual-key code: VK_LBUTTON, VK_RBUTTON, VK_MBUTTON, VK_XBUTTON1, VK_XBUTTON2
|
||||
HRESULT WINAPI DXUTCreateState(); // Optional method to create DXUT's memory. If its not called by the application it will be automatically called when needed
|
||||
void WINAPI DXUTDestroyState(); // Optional method to destroy DXUT's memory. If its not called by the application it will be automatically called after the application exits WinMain
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// DXUT core layer includes
|
||||
//--------------------------------------------------------------------------------------
|
||||
#include "DXUTmisc.h"
|
||||
#include "DXUTDevice9.h"
|
||||
#include "DXUTDevice11.h"
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
1154
Demos/DX11ClothDemo/DXUT/Core/DXUTDevice11.cpp
Normal file
1154
Demos/DX11ClothDemo/DXUT/Core/DXUTDevice11.cpp
Normal file
File diff suppressed because it is too large
Load Diff
210
Demos/DX11ClothDemo/DXUT/Core/DXUTDevice11.h
Normal file
210
Demos/DX11ClothDemo/DXUT/Core/DXUTDevice11.h
Normal file
@@ -0,0 +1,210 @@
|
||||
//--------------------------------------------------------------------------------------
|
||||
// File: DXUTDevice11.h
|
||||
//
|
||||
// Enumerates D3D adapters, devices, modes, etc.
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//--------------------------------------------------------------------------------------
|
||||
#pragma once
|
||||
#ifndef DXUT_DEVICE11_H
|
||||
#define DXUT_DEVICE11_H
|
||||
|
||||
void DXUTApplyDefaultDeviceSettings(DXUTDeviceSettings *modifySettings);
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Functions to get bit depth from formats
|
||||
//--------------------------------------------------------------------------------------
|
||||
HRESULT WINAPI DXUTGetD3D11AdapterDisplayMode( UINT AdapterOrdinal, UINT Output, DXGI_MODE_DESC* pModeDesc );
|
||||
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Optional memory create/destory functions. If not call, these will be called automatically
|
||||
//--------------------------------------------------------------------------------------
|
||||
HRESULT WINAPI DXUTCreateD3D11Enumeration();
|
||||
void WINAPI DXUTDestroyD3D11Enumeration();
|
||||
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Forward declarations
|
||||
//--------------------------------------------------------------------------------------
|
||||
class CD3D11EnumAdapterInfo;
|
||||
class CD3D11EnumDeviceInfo;
|
||||
class CD3D11EnumOutputInfo;
|
||||
struct CD3D11EnumDeviceSettingsCombo;
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Enumerates available Direct3D10 adapters, devices, modes, etc.
|
||||
// Use DXUTGetD3D9Enumeration() to access global instance
|
||||
//--------------------------------------------------------------------------------------
|
||||
class CD3D11Enumeration
|
||||
{
|
||||
public:
|
||||
// These should be called before Enumerate().
|
||||
//
|
||||
// Use these calls and the IsDeviceAcceptable to control the contents of
|
||||
// the enumeration object, which affects the device selection and the device settings dialog.
|
||||
void SetResolutionMinMax( UINT nMinWidth, UINT nMinHeight, UINT nMaxWidth, UINT nMaxHeight );
|
||||
void SetRefreshMinMax( UINT nMin, UINT nMax );
|
||||
void SetForceFeatureLevel( D3D_FEATURE_LEVEL forceFL) {
|
||||
g_forceFL = forceFL;
|
||||
};
|
||||
void SetMultisampleQualityMax( UINT nMax );
|
||||
CGrowableArray<D3DFORMAT>* GetPossibleDepthStencilFormatList();
|
||||
void ResetPossibleDepthStencilFormats();
|
||||
void SetEnumerateAllAdapterFormats( bool bEnumerateAllAdapterFormats );
|
||||
|
||||
// Call Enumerate() to enumerate available D3D11 adapters, devices, modes, etc.
|
||||
bool HasEnumerated() { return m_bHasEnumerated; }
|
||||
HRESULT Enumerate( LPDXUTCALLBACKISD3D11DEVICEACCEPTABLE IsD3D11DeviceAcceptableFunc,
|
||||
void* pIsD3D11DeviceAcceptableFuncUserContext );
|
||||
|
||||
// These should be called after Enumerate() is called
|
||||
CGrowableArray<CD3D11EnumAdapterInfo*>* GetAdapterInfoList();
|
||||
CD3D11EnumAdapterInfo* GetAdapterInfo( UINT AdapterOrdinal );
|
||||
CD3D11EnumDeviceInfo* GetDeviceInfo( UINT AdapterOrdinal, D3D_DRIVER_TYPE DeviceType );
|
||||
CD3D11EnumOutputInfo* GetOutputInfo( UINT AdapterOrdinal, UINT Output );
|
||||
CD3D11EnumDeviceSettingsCombo* GetDeviceSettingsCombo( DXUTD3D11DeviceSettings* pDeviceSettings ) { return GetDeviceSettingsCombo( pDeviceSettings->AdapterOrdinal, pDeviceSettings->DriverType, pDeviceSettings->Output, pDeviceSettings->sd.BufferDesc.Format, pDeviceSettings->sd.Windowed ); }
|
||||
CD3D11EnumDeviceSettingsCombo* GetDeviceSettingsCombo( UINT AdapterOrdinal, D3D_DRIVER_TYPE DeviceType, UINT Output, DXGI_FORMAT BackBufferFormat, BOOL Windowed );
|
||||
|
||||
~CD3D11Enumeration();
|
||||
|
||||
private:
|
||||
friend HRESULT WINAPI DXUTCreateD3D11Enumeration();
|
||||
|
||||
// Use DXUTGetD3D11Enumeration() to access global instance
|
||||
CD3D11Enumeration();
|
||||
|
||||
bool m_bHasEnumerated;
|
||||
LPDXUTCALLBACKISD3D11DEVICEACCEPTABLE m_IsD3D11DeviceAcceptableFunc;
|
||||
void* m_pIsD3D11DeviceAcceptableFuncUserContext;
|
||||
|
||||
CGrowableArray<DXGI_FORMAT> m_DepthStencilPossibleList;
|
||||
|
||||
UINT m_nMinWidth;
|
||||
UINT m_nMaxWidth;
|
||||
UINT m_nMinHeight;
|
||||
UINT m_nMaxHeight;
|
||||
UINT m_nRefreshMin;
|
||||
UINT m_nRefreshMax;
|
||||
UINT m_nMultisampleQualityMax;
|
||||
bool m_bEnumerateAllAdapterFormats;
|
||||
D3D_FEATURE_LEVEL g_forceFL;
|
||||
|
||||
// Array of CD3D9EnumAdapterInfo* with unique AdapterOrdinals
|
||||
CGrowableArray<CD3D11EnumAdapterInfo*> m_AdapterInfoList;
|
||||
|
||||
HRESULT EnumerateOutputs( CD3D11EnumAdapterInfo *pAdapterInfo );
|
||||
HRESULT EnumerateDevices( CD3D11EnumAdapterInfo *pAdapterInfo );
|
||||
HRESULT EnumerateDeviceCombos( IDXGIFactory1 *pFactory, CD3D11EnumAdapterInfo* pAdapterInfo );
|
||||
HRESULT EnumerateDeviceCombosNoAdapter( CD3D11EnumAdapterInfo* pAdapterInfo );
|
||||
|
||||
HRESULT EnumerateDisplayModes( CD3D11EnumOutputInfo *pOutputInfo );
|
||||
void BuildMultiSampleQualityList( DXGI_FORMAT fmt, CD3D11EnumDeviceSettingsCombo* pDeviceCombo );
|
||||
void ClearAdapterInfoList();
|
||||
};
|
||||
|
||||
CD3D11Enumeration* WINAPI DXUTGetD3D11Enumeration(bool bForceEnumerate = false, bool EnumerateAllAdapterFormats = false, D3D_FEATURE_LEVEL forceFL = ((D3D_FEATURE_LEVEL )0) );
|
||||
|
||||
|
||||
#define DXGI_MAX_DEVICE_IDENTIFIER_STRING 128
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// A class describing an adapter which contains a unique adapter ordinal
|
||||
// that is installed on the system
|
||||
//--------------------------------------------------------------------------------------
|
||||
class CD3D11EnumAdapterInfo
|
||||
{
|
||||
const CD3D11EnumAdapterInfo &operator = ( const CD3D11EnumAdapterInfo &rhs );
|
||||
|
||||
public:
|
||||
~CD3D11EnumAdapterInfo();
|
||||
|
||||
UINT AdapterOrdinal;
|
||||
DXGI_ADAPTER_DESC AdapterDesc;
|
||||
WCHAR szUniqueDescription[DXGI_MAX_DEVICE_IDENTIFIER_STRING];
|
||||
IDXGIAdapter *m_pAdapter;
|
||||
bool bAdapterUnavailable;
|
||||
|
||||
CGrowableArray<CD3D11EnumOutputInfo*> outputInfoList; // Array of CD3D11EnumOutputInfo*
|
||||
CGrowableArray<CD3D11EnumDeviceInfo*> deviceInfoList; // Array of CD3D11EnumDeviceInfo*
|
||||
// List of CD3D11EnumDeviceSettingsCombo* with a unique set
|
||||
// of BackBufferFormat, and Windowed
|
||||
CGrowableArray<CD3D11EnumDeviceSettingsCombo*> deviceSettingsComboList;
|
||||
};
|
||||
|
||||
|
||||
class CD3D11EnumOutputInfo
|
||||
{
|
||||
const CD3D11EnumOutputInfo &operator = ( const CD3D11EnumOutputInfo &rhs );
|
||||
|
||||
public:
|
||||
~CD3D11EnumOutputInfo();
|
||||
|
||||
UINT AdapterOrdinal;
|
||||
UINT Output;
|
||||
IDXGIOutput* m_pOutput;
|
||||
DXGI_OUTPUT_DESC Desc;
|
||||
|
||||
CGrowableArray <DXGI_MODE_DESC> displayModeList; // Array of supported D3DDISPLAYMODEs
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// A class describing a Direct3D10 device that contains a
|
||||
// unique supported driver type
|
||||
//--------------------------------------------------------------------------------------
|
||||
class CD3D11EnumDeviceInfo
|
||||
{
|
||||
const CD3D11EnumDeviceInfo& operator =( const CD3D11EnumDeviceInfo& rhs );
|
||||
|
||||
public:
|
||||
~CD3D11EnumDeviceInfo();
|
||||
|
||||
UINT AdapterOrdinal;
|
||||
D3D_DRIVER_TYPE DeviceType;
|
||||
D3D_FEATURE_LEVEL SelectedLevel;
|
||||
D3D_FEATURE_LEVEL MaxLevel;
|
||||
BOOL ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x;
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// A struct describing device settings that contains a unique combination of
|
||||
// adapter format, back buffer format, and windowed that is compatible with a
|
||||
// particular Direct3D device and the app.
|
||||
//--------------------------------------------------------------------------------------
|
||||
struct CD3D11EnumDeviceSettingsCombo
|
||||
{
|
||||
UINT AdapterOrdinal;
|
||||
D3D_DRIVER_TYPE DeviceType;
|
||||
DXGI_FORMAT BackBufferFormat;
|
||||
BOOL Windowed;
|
||||
UINT Output;
|
||||
|
||||
CGrowableArray <UINT> multiSampleCountList; // List of valid sampling counts (multisampling)
|
||||
CGrowableArray <UINT> multiSampleQualityList; // List of number of quality levels for each multisample count
|
||||
|
||||
CD3D11EnumAdapterInfo* pAdapterInfo;
|
||||
CD3D11EnumDeviceInfo* pDeviceInfo;
|
||||
CD3D11EnumOutputInfo* pOutputInfo;
|
||||
};
|
||||
|
||||
float DXUTRankD3D11DeviceCombo( CD3D11EnumDeviceSettingsCombo* pDeviceSettingsCombo,
|
||||
DXUTD3D11DeviceSettings* pOptimalDeviceSettings,
|
||||
DXGI_MODE_DESC* pAdapterDisplayMode,
|
||||
int &bestModeIndex,
|
||||
int &bestMSAAIndex
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
1177
Demos/DX11ClothDemo/DXUT/Core/DXUTDevice9.cpp
Normal file
1177
Demos/DX11ClothDemo/DXUT/Core/DXUTDevice9.cpp
Normal file
File diff suppressed because it is too large
Load Diff
207
Demos/DX11ClothDemo/DXUT/Core/DXUTDevice9.h
Normal file
207
Demos/DX11ClothDemo/DXUT/Core/DXUTDevice9.h
Normal file
@@ -0,0 +1,207 @@
|
||||
//--------------------------------------------------------------------------------------
|
||||
// File: DXUTDevice9.h
|
||||
//
|
||||
// Enumerates D3D adapters, devices, modes, etc.
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//--------------------------------------------------------------------------------------
|
||||
#pragma once
|
||||
#ifndef DXUT_DEVICE9_H
|
||||
#define DXUT_DEVICE9_H
|
||||
|
||||
//void DXUTApplyDefaultDeviceSettings(DXUTDeviceSettings *modifySettings);
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Functions to get bit depth from formats
|
||||
//--------------------------------------------------------------------------------------
|
||||
UINT WINAPI DXUTGetD3D9ColorChannelBits( D3DFORMAT fmt );
|
||||
UINT WINAPI DXUTGetAlphaChannelBits( D3DFORMAT fmt );
|
||||
UINT WINAPI DXUTGetStencilBits( D3DFORMAT fmt );
|
||||
UINT WINAPI DXUTGetDepthBits( D3DFORMAT fmt );
|
||||
UINT WINAPI DXUTGetDXGIColorChannelBits( DXGI_FORMAT fmt );
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Forward declarations
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
class CD3D9EnumAdapterInfo;
|
||||
class CD3D9EnumDeviceInfo;
|
||||
struct CD3D9EnumDeviceSettingsCombo;
|
||||
struct CD3D9EnumDSMSConflict;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Optional memory create/destory functions. If not call, these will be called automatically
|
||||
//--------------------------------------------------------------------------------------
|
||||
HRESULT WINAPI DXUTCreateD3D9Enumeration();
|
||||
void WINAPI DXUTDestroyD3D9Enumeration();
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Enumerates available Direct3D9 adapters, devices, modes, etc.
|
||||
// Use DXUTGetD3D9Enumeration() to access global instance
|
||||
//--------------------------------------------------------------------------------------
|
||||
class CD3D9Enumeration
|
||||
{
|
||||
public:
|
||||
// These should be called before Enumerate().
|
||||
//
|
||||
// Use these calls and the IsDeviceAcceptable to control the contents of
|
||||
// the enumeration object, which affects the device selection and the device settings dialog.
|
||||
void SetRequirePostPixelShaderBlending( bool bRequire ) { m_bRequirePostPixelShaderBlending = bRequire; }
|
||||
void SetResolutionMinMax( UINT nMinWidth, UINT nMinHeight, UINT nMaxWidth, UINT nMaxHeight );
|
||||
void SetRefreshMinMax( UINT nMin, UINT nMax );
|
||||
void SetMultisampleQualityMax( UINT nMax );
|
||||
void GetPossibleVertexProcessingList( bool* pbSoftwareVP, bool* pbHardwareVP, bool* pbPureHarewareVP, bool* pbMixedVP );
|
||||
void SetPossibleVertexProcessingList( bool bSoftwareVP, bool bHardwareVP, bool bPureHarewareVP, bool bMixedVP );
|
||||
CGrowableArray<D3DFORMAT>* GetPossibleDepthStencilFormatList();
|
||||
CGrowableArray<D3DMULTISAMPLE_TYPE>* GetPossibleMultisampleTypeList();
|
||||
CGrowableArray<UINT>* GetPossiblePresentIntervalList();
|
||||
void ResetPossibleDepthStencilFormats();
|
||||
void ResetPossibleMultisampleTypeList();
|
||||
void ResetPossiblePresentIntervalList();
|
||||
|
||||
// Call Enumerate() to enumerate available D3D adapters, devices, modes, etc.
|
||||
bool HasEnumerated() { return m_bHasEnumerated; }
|
||||
HRESULT Enumerate( LPDXUTCALLBACKISD3D9DEVICEACCEPTABLE IsD3D9DeviceAcceptableFunc = NULL,
|
||||
void* pIsD3D9DeviceAcceptableFuncUserContext = NULL );
|
||||
|
||||
// These should be called after Enumerate() is called
|
||||
CGrowableArray<CD3D9EnumAdapterInfo*>* GetAdapterInfoList();
|
||||
CD3D9EnumAdapterInfo* GetAdapterInfo( UINT AdapterOrdinal );
|
||||
CD3D9EnumDeviceInfo* GetDeviceInfo( UINT AdapterOrdinal, D3DDEVTYPE DeviceType );
|
||||
CD3D9EnumDeviceSettingsCombo* GetDeviceSettingsCombo( DXUTD3D9DeviceSettings* pD3D9DeviceSettings ) { return GetDeviceSettingsCombo( pD3D9DeviceSettings->AdapterOrdinal, pD3D9DeviceSettings->DeviceType, pD3D9DeviceSettings->AdapterFormat, pD3D9DeviceSettings->pp.BackBufferFormat, pD3D9DeviceSettings->pp.Windowed ); }
|
||||
CD3D9EnumDeviceSettingsCombo* GetDeviceSettingsCombo( UINT AdapterOrdinal, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, BOOL Windowed );
|
||||
|
||||
~CD3D9Enumeration();
|
||||
|
||||
private:
|
||||
friend HRESULT WINAPI DXUTCreateD3D9Enumeration();
|
||||
|
||||
// Use DXUTGetD3D9Enumeration() to access global instance
|
||||
CD3D9Enumeration();
|
||||
|
||||
bool m_bHasEnumerated;
|
||||
IDirect3D9* m_pD3D;
|
||||
LPDXUTCALLBACKISD3D9DEVICEACCEPTABLE m_IsD3D9DeviceAcceptableFunc;
|
||||
void* m_pIsD3D9DeviceAcceptableFuncUserContext;
|
||||
bool m_bRequirePostPixelShaderBlending;
|
||||
CGrowableArray<D3DFORMAT> m_DepthStencilPossibleList;
|
||||
CGrowableArray<D3DMULTISAMPLE_TYPE> m_MultiSampleTypeList;
|
||||
CGrowableArray<UINT> m_PresentIntervalList;
|
||||
|
||||
bool m_bSoftwareVP;
|
||||
bool m_bHardwareVP;
|
||||
bool m_bPureHarewareVP;
|
||||
bool m_bMixedVP;
|
||||
|
||||
UINT m_nMinWidth;
|
||||
UINT m_nMaxWidth;
|
||||
UINT m_nMinHeight;
|
||||
UINT m_nMaxHeight;
|
||||
UINT m_nRefreshMin;
|
||||
UINT m_nRefreshMax;
|
||||
UINT m_nMultisampleQualityMax;
|
||||
|
||||
// Array of CD3D9EnumAdapterInfo* with unique AdapterOrdinals
|
||||
CGrowableArray<CD3D9EnumAdapterInfo*> m_AdapterInfoList;
|
||||
|
||||
HRESULT EnumerateDevices( CD3D9EnumAdapterInfo* pAdapterInfo, CGrowableArray<D3DFORMAT>* pAdapterFormatList );
|
||||
HRESULT EnumerateDeviceCombos( CD3D9EnumAdapterInfo* pAdapterInfo, CD3D9EnumDeviceInfo* pDeviceInfo, CGrowableArray<D3DFORMAT>* pAdapterFormatList );
|
||||
void BuildDepthStencilFormatList( CD3D9EnumDeviceSettingsCombo* pDeviceCombo );
|
||||
void BuildMultiSampleTypeList( CD3D9EnumDeviceSettingsCombo* pDeviceCombo );
|
||||
void BuildDSMSConflictList( CD3D9EnumDeviceSettingsCombo* pDeviceCombo );
|
||||
void BuildPresentIntervalList( CD3D9EnumDeviceInfo* pDeviceInfo, CD3D9EnumDeviceSettingsCombo* pDeviceCombo );
|
||||
void ClearAdapterInfoList();
|
||||
};
|
||||
|
||||
CD3D9Enumeration* WINAPI DXUTGetD3D9Enumeration( bool bForceEnumerate = false );
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// A class describing an adapter which contains a unique adapter ordinal
|
||||
// that is installed on the system
|
||||
//--------------------------------------------------------------------------------------
|
||||
class CD3D9EnumAdapterInfo
|
||||
{
|
||||
public:
|
||||
~CD3D9EnumAdapterInfo();
|
||||
|
||||
UINT AdapterOrdinal;
|
||||
D3DADAPTER_IDENTIFIER9 AdapterIdentifier;
|
||||
WCHAR szUniqueDescription[256];
|
||||
|
||||
CGrowableArray <D3DDISPLAYMODE> displayModeList; // Array of supported D3DDISPLAYMODEs
|
||||
CGrowableArray <CD3D9EnumDeviceInfo*> deviceInfoList; // Array of CD3D9EnumDeviceInfo* with unique supported DeviceTypes
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// A class describing a Direct3D device that contains a
|
||||
// unique supported device type
|
||||
//--------------------------------------------------------------------------------------
|
||||
class CD3D9EnumDeviceInfo
|
||||
{
|
||||
public:
|
||||
~CD3D9EnumDeviceInfo();
|
||||
|
||||
UINT AdapterOrdinal;
|
||||
D3DDEVTYPE DeviceType;
|
||||
D3DCAPS9 Caps;
|
||||
|
||||
// List of CD3D9EnumDeviceSettingsCombo* with a unique set
|
||||
// of AdapterFormat, BackBufferFormat, and Windowed
|
||||
CGrowableArray <CD3D9EnumDeviceSettingsCombo*> deviceSettingsComboList;
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// A struct describing device settings that contains a unique combination of
|
||||
// adapter format, back buffer format, and windowed that is compatible with a
|
||||
// particular Direct3D device and the app.
|
||||
//--------------------------------------------------------------------------------------
|
||||
struct CD3D9EnumDeviceSettingsCombo
|
||||
{
|
||||
UINT AdapterOrdinal;
|
||||
D3DDEVTYPE DeviceType;
|
||||
D3DFORMAT AdapterFormat;
|
||||
D3DFORMAT BackBufferFormat;
|
||||
BOOL Windowed;
|
||||
|
||||
CGrowableArray <D3DFORMAT> depthStencilFormatList; // List of D3DFORMATs
|
||||
CGrowableArray <D3DMULTISAMPLE_TYPE> multiSampleTypeList; // List of D3DMULTISAMPLE_TYPEs
|
||||
CGrowableArray <DWORD> multiSampleQualityList; // List of number of quality levels for each multisample type
|
||||
CGrowableArray <UINT> presentIntervalList; // List of D3DPRESENT flags
|
||||
CGrowableArray <CD3D9EnumDSMSConflict> DSMSConflictList; // List of CD3D9EnumDSMSConflict
|
||||
|
||||
CD3D9EnumAdapterInfo* pAdapterInfo;
|
||||
CD3D9EnumDeviceInfo* pDeviceInfo;
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// A depth/stencil buffer format that is incompatible with a
|
||||
// multisample type.
|
||||
//--------------------------------------------------------------------------------------
|
||||
struct CD3D9EnumDSMSConflict
|
||||
{
|
||||
D3DFORMAT DSFormat;
|
||||
D3DMULTISAMPLE_TYPE MSType;
|
||||
};
|
||||
|
||||
|
||||
|
||||
float DXUTRankD3D9DeviceCombo( CD3D9EnumDeviceSettingsCombo* pDeviceSettingsCombo,
|
||||
DXUTD3D9DeviceSettings* pOptimalDeviceSettings,
|
||||
D3DDISPLAYMODE* pAdapterDesktopDisplayMode,
|
||||
int &bestModeIndex,
|
||||
int &bestMSAAIndex
|
||||
);
|
||||
|
||||
|
||||
#endif
|
||||
1785
Demos/DX11ClothDemo/DXUT/Core/DXUTmisc.cpp
Normal file
1785
Demos/DX11ClothDemo/DXUT/Core/DXUTmisc.cpp
Normal file
File diff suppressed because it is too large
Load Diff
594
Demos/DX11ClothDemo/DXUT/Core/DXUTmisc.h
Normal file
594
Demos/DX11ClothDemo/DXUT/Core/DXUTmisc.h
Normal file
@@ -0,0 +1,594 @@
|
||||
//--------------------------------------------------------------------------------------
|
||||
// File: DXUTMisc.h
|
||||
//
|
||||
// Helper functions for Direct3D programming.
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved
|
||||
//--------------------------------------------------------------------------------------
|
||||
#pragma once
|
||||
#ifndef DXUT_MISC_H
|
||||
#define DXUT_MISC_H
|
||||
|
||||
#ifndef MAX_FVF_DECL_SIZE
|
||||
#define MAX_FVF_DECL_SIZE MAXD3DDECLLENGTH + 1 // +1 for END
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// XInput helper state/function
|
||||
// This performs extra processing on XInput gamepad data to make it slightly more convenient to use
|
||||
//
|
||||
// Example usage:
|
||||
//
|
||||
// DXUT_GAMEPAD gamepad[4];
|
||||
// for( DWORD iPort=0; iPort<DXUT_MAX_CONTROLLERS; iPort++ )
|
||||
// DXUTGetGamepadState( iPort, gamepad[iPort] );
|
||||
//
|
||||
//--------------------------------------------------------------------------------------
|
||||
#define DXUT_MAX_CONTROLLERS 4 // XInput handles up to 4 controllers
|
||||
|
||||
struct DXUT_GAMEPAD
|
||||
{
|
||||
// From XINPUT_GAMEPAD
|
||||
WORD wButtons;
|
||||
BYTE bLeftTrigger;
|
||||
BYTE bRightTrigger;
|
||||
SHORT sThumbLX;
|
||||
SHORT sThumbLY;
|
||||
SHORT sThumbRX;
|
||||
SHORT sThumbRY;
|
||||
|
||||
// Device properties
|
||||
XINPUT_CAPABILITIES caps;
|
||||
bool bConnected; // If the controller is currently connected
|
||||
bool bInserted; // If the controller was inserted this frame
|
||||
bool bRemoved; // If the controller was removed this frame
|
||||
|
||||
// Thumb stick values converted to range [-1,+1]
|
||||
float fThumbRX;
|
||||
float fThumbRY;
|
||||
float fThumbLX;
|
||||
float fThumbLY;
|
||||
|
||||
// Records which buttons were pressed this frame.
|
||||
// These are only set on the first frame that the button is pressed
|
||||
WORD wPressedButtons;
|
||||
bool bPressedLeftTrigger;
|
||||
bool bPressedRightTrigger;
|
||||
|
||||
// Last state of the buttons
|
||||
WORD wLastButtons;
|
||||
bool bLastLeftTrigger;
|
||||
bool bLastRightTrigger;
|
||||
};
|
||||
|
||||
HRESULT DXUTGetGamepadState( DWORD dwPort, DXUT_GAMEPAD* pGamePad, bool bThumbstickDeadZone = true,
|
||||
bool bSnapThumbstickToCardinals = true );
|
||||
HRESULT DXUTStopRumbleOnAllControllers();
|
||||
void DXUTEnableXInput( bool bEnable );
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Takes a screen shot of a 32bit D3D9 back buffer and saves the images to a BMP file
|
||||
//--------------------------------------------------------------------------------------
|
||||
HRESULT DXUTSnapD3D9Screenshot( LPCTSTR szFileName );
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Takes a screen shot of a 32bit D3D11 back buffer and saves the images to a BMP file
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
HRESULT DXUTSnapD3D11Screenshot( LPCTSTR szFileName, D3DX11_IMAGE_FILE_FORMAT iff = D3DX11_IFF_DDS );
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// A growable array
|
||||
//--------------------------------------------------------------------------------------
|
||||
template<typename TYPE> class CGrowableArray
|
||||
{
|
||||
public:
|
||||
CGrowableArray() { m_pData = NULL; m_nSize = 0; m_nMaxSize = 0; }
|
||||
CGrowableArray( const CGrowableArray<TYPE>& a ) { for( int i=0; i < a.m_nSize; i++ ) Add( a.m_pData[i] ); }
|
||||
~CGrowableArray() { RemoveAll(); }
|
||||
|
||||
const TYPE& operator[]( int nIndex ) const { return GetAt( nIndex ); }
|
||||
TYPE& operator[]( int nIndex ) { return GetAt( nIndex ); }
|
||||
|
||||
CGrowableArray& operator=( const CGrowableArray<TYPE>& a ) { if( this == &a ) return *this; RemoveAll(); for( int i=0; i < a.m_nSize; i++ ) Add( a.m_pData[i] ); return *this; }
|
||||
|
||||
HRESULT SetSize( int nNewMaxSize );
|
||||
HRESULT Add( const TYPE& value );
|
||||
HRESULT Insert( int nIndex, const TYPE& value );
|
||||
HRESULT SetAt( int nIndex, const TYPE& value );
|
||||
TYPE& GetAt( int nIndex ) const { assert( nIndex >= 0 && nIndex < m_nSize ); return m_pData[nIndex]; }
|
||||
int GetSize() const { return m_nSize; }
|
||||
TYPE* GetData() { return m_pData; }
|
||||
bool Contains( const TYPE& value ){ return ( -1 != IndexOf( value ) ); }
|
||||
|
||||
int IndexOf( const TYPE& value ) { return ( m_nSize > 0 ) ? IndexOf( value, 0, m_nSize ) : -1; }
|
||||
int IndexOf( const TYPE& value, int iStart ) { return IndexOf( value, iStart, m_nSize - iStart ); }
|
||||
int IndexOf( const TYPE& value, int nIndex, int nNumElements );
|
||||
|
||||
int LastIndexOf( const TYPE& value ) { return ( m_nSize > 0 ) ? LastIndexOf( value, m_nSize-1, m_nSize ) : -1; }
|
||||
int LastIndexOf( const TYPE& value, int nIndex ) { return LastIndexOf( value, nIndex, nIndex+1 ); }
|
||||
int LastIndexOf( const TYPE& value, int nIndex, int nNumElements );
|
||||
|
||||
HRESULT Remove( int nIndex );
|
||||
void RemoveAll() { SetSize(0); }
|
||||
void Reset() { m_nSize = 0; }
|
||||
|
||||
protected:
|
||||
TYPE* m_pData; // the actual array of data
|
||||
int m_nSize; // # of elements (upperBound - 1)
|
||||
int m_nMaxSize; // max allocated
|
||||
|
||||
HRESULT SetSizeInternal( int nNewMaxSize ); // This version doesn't call ctor or dtor.
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Performs timer operations
|
||||
// Use DXUTGetGlobalTimer() to get the global instance
|
||||
//--------------------------------------------------------------------------------------
|
||||
class CDXUTTimer
|
||||
{
|
||||
public:
|
||||
CDXUTTimer();
|
||||
|
||||
void Reset(); // resets the timer
|
||||
void Start(); // starts the timer
|
||||
void Stop(); // stop (or pause) the timer
|
||||
void Advance(); // advance the timer by 0.1 seconds
|
||||
double GetAbsoluteTime(); // get the absolute system time
|
||||
double GetTime(); // get the current time
|
||||
float GetElapsedTime(); // get the time that elapsed between Get*ElapsedTime() calls
|
||||
void GetTimeValues( double* pfTime, double* pfAbsoluteTime, float* pfElapsedTime ); // get all time values at once
|
||||
bool IsStopped(); // returns true if timer stopped
|
||||
|
||||
// Limit the current thread to one processor (the current one). This ensures that timing code runs
|
||||
// on only one processor, and will not suffer any ill effects from power management.
|
||||
void LimitThreadAffinityToCurrentProc();
|
||||
|
||||
protected:
|
||||
LARGE_INTEGER GetAdjustedCurrentTime();
|
||||
|
||||
bool m_bUsingQPF;
|
||||
bool m_bTimerStopped;
|
||||
LONGLONG m_llQPFTicksPerSec;
|
||||
|
||||
LONGLONG m_llStopTime;
|
||||
LONGLONG m_llLastElapsedTime;
|
||||
LONGLONG m_llBaseTime;
|
||||
};
|
||||
|
||||
CDXUTTimer* WINAPI DXUTGetGlobalTimer();
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Returns the string for the given D3DFORMAT.
|
||||
// bWithPrefix determines whether the string should include the "D3DFMT_"
|
||||
//--------------------------------------------------------------------------------------
|
||||
LPCWSTR WINAPI DXUTD3DFormatToString( D3DFORMAT format, bool bWithPrefix );
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Returns the string for the given DXGI_FORMAT.
|
||||
// bWithPrefix determines whether the string should include the "DXGI_FORMAT_"
|
||||
//--------------------------------------------------------------------------------------
|
||||
LPCWSTR WINAPI DXUTDXGIFormatToString( DXGI_FORMAT format, bool bWithPrefix );
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Device settings conversion
|
||||
//--------------------------------------------------------------------------------------
|
||||
void WINAPI DXUTConvertDeviceSettings11to9( DXUTD3D11DeviceSettings* pIn, DXUTD3D9DeviceSettings* pOut );
|
||||
void WINAPI DXUTConvertDeviceSettings9to11( DXUTD3D9DeviceSettings* pIn, DXUTD3D11DeviceSettings* pOut );
|
||||
|
||||
DXGI_FORMAT WINAPI ConvertFormatD3D9ToDXGI( D3DFORMAT fmt );
|
||||
D3DFORMAT WINAPI ConvertFormatDXGIToD3D9( DXGI_FORMAT fmt );
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Debug printing support
|
||||
// See dxerr.h for more debug printing support
|
||||
//--------------------------------------------------------------------------------------
|
||||
void WINAPI DXUTOutputDebugStringW( LPCWSTR strMsg, ... );
|
||||
void WINAPI DXUTOutputDebugStringA( LPCSTR strMsg, ... );
|
||||
HRESULT WINAPI DXUTTrace( const CHAR* strFile, DWORD dwLine, HRESULT hr, const WCHAR* strMsg, bool bPopMsgBox );
|
||||
void WINAPI DXUTTraceDecl( D3DVERTEXELEMENT9 decl[MAX_FVF_DECL_SIZE] );
|
||||
WCHAR* WINAPI DXUTTraceD3DDECLUSAGEtoString( BYTE u );
|
||||
WCHAR* WINAPI DXUTTraceD3DDECLMETHODtoString( BYTE m );
|
||||
WCHAR* WINAPI DXUTTraceD3DDECLTYPEtoString( BYTE t );
|
||||
WCHAR* WINAPI DXUTTraceWindowsMessage( UINT uMsg );
|
||||
|
||||
#ifdef UNICODE
|
||||
#define DXUTOutputDebugString DXUTOutputDebugStringW
|
||||
#else
|
||||
#define DXUTOutputDebugString DXUTOutputDebugStringA
|
||||
#endif
|
||||
|
||||
// These macros are very similar to dxerr's but it special cases the HRESULT defined
|
||||
// by DXUT to pop better message boxes.
|
||||
#if defined(DEBUG) || defined(_DEBUG)
|
||||
#define DXUT_ERR(str,hr) DXUTTrace( __FILE__, (DWORD)__LINE__, hr, str, false )
|
||||
#define DXUT_ERR_MSGBOX(str,hr) DXUTTrace( __FILE__, (DWORD)__LINE__, hr, str, true )
|
||||
#define DXUTTRACE DXUTOutputDebugString
|
||||
#else
|
||||
#define DXUT_ERR(str,hr) (hr)
|
||||
#define DXUT_ERR_MSGBOX(str,hr) (hr)
|
||||
#define DXUTTRACE (__noop)
|
||||
#endif
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Direct3D9 dynamic linking support -- calls top-level D3D9 APIs with graceful
|
||||
// failure if APIs are not present.
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
IDirect3D9 * WINAPI DXUT_Dynamic_Direct3DCreate9(UINT SDKVersion);
|
||||
int WINAPI DXUT_Dynamic_D3DPERF_BeginEvent( D3DCOLOR col, LPCWSTR wszName );
|
||||
int WINAPI DXUT_Dynamic_D3DPERF_EndEvent( void );
|
||||
void WINAPI DXUT_Dynamic_D3DPERF_SetMarker( D3DCOLOR col, LPCWSTR wszName );
|
||||
void WINAPI DXUT_Dynamic_D3DPERF_SetRegion( D3DCOLOR col, LPCWSTR wszName );
|
||||
BOOL WINAPI DXUT_Dynamic_D3DPERF_QueryRepeatFrame( void );
|
||||
void WINAPI DXUT_Dynamic_D3DPERF_SetOptions( DWORD dwOptions );
|
||||
DWORD WINAPI DXUT_Dynamic_D3DPERF_GetStatus( void );
|
||||
HRESULT WINAPI DXUT_Dynamic_CreateDXGIFactory1( REFIID rInterface, void** ppOut );
|
||||
|
||||
HRESULT WINAPI DXUT_Dynamic_D3D11CreateDevice( IDXGIAdapter* pAdapter,
|
||||
D3D_DRIVER_TYPE DriverType,
|
||||
HMODULE Software,
|
||||
UINT32 Flags,
|
||||
D3D_FEATURE_LEVEL* pFeatureLevels,
|
||||
UINT FeatureLevels,
|
||||
UINT32 SDKVersion,
|
||||
ID3D11Device** ppDevice,
|
||||
D3D_FEATURE_LEVEL* pFeatureLevel,
|
||||
ID3D11DeviceContext** ppImmediateContext );
|
||||
|
||||
bool DXUT_EnsureD3D11APIs( void );
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Profiling/instrumentation support
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Some D3DPERF APIs take a color that can be used when displaying user events in
|
||||
// performance analysis tools. The following constants are provided for your
|
||||
// convenience, but you can use any colors you like.
|
||||
//--------------------------------------------------------------------------------------
|
||||
const D3DCOLOR DXUT_PERFEVENTCOLOR = D3DCOLOR_XRGB( 200, 100, 100 );
|
||||
const D3DCOLOR DXUT_PERFEVENTCOLOR2 = D3DCOLOR_XRGB( 100, 200, 100 );
|
||||
const D3DCOLOR DXUT_PERFEVENTCOLOR3 = D3DCOLOR_XRGB( 100, 100, 200 );
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// The following macros provide a convenient way for your code to call the D3DPERF
|
||||
// functions only when PROFILE is defined. If PROFILE is not defined (as for the final
|
||||
// release version of a program), these macros evaluate to nothing, so no detailed event
|
||||
// information is embedded in your shipping program. It is recommended that you create
|
||||
// and use three build configurations for your projects:
|
||||
// Debug (nonoptimized code, asserts active, PROFILE defined to assist debugging)
|
||||
// Profile (optimized code, asserts disabled, PROFILE defined to assist optimization)
|
||||
// Release (optimized code, asserts disabled, PROFILE not defined)
|
||||
//--------------------------------------------------------------------------------------
|
||||
#ifdef PROFILE
|
||||
// PROFILE is defined, so these macros call the D3DPERF functions
|
||||
#define DXUT_BeginPerfEvent( color, pstrMessage ) DXUT_Dynamic_D3DPERF_BeginEvent( color, pstrMessage )
|
||||
#define DXUT_EndPerfEvent() DXUT_Dynamic_D3DPERF_EndEvent()
|
||||
#define DXUT_SetPerfMarker( color, pstrMessage ) DXUT_Dynamic_D3DPERF_SetMarker( color, pstrMessage )
|
||||
#else
|
||||
// PROFILE is not defined, so these macros do nothing
|
||||
#define DXUT_BeginPerfEvent( color, pstrMessage ) (__noop)
|
||||
#define DXUT_EndPerfEvent() (__noop)
|
||||
#define DXUT_SetPerfMarker( color, pstrMessage ) (__noop)
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// CDXUTPerfEventGenerator is a helper class that makes it easy to attach begin and end
|
||||
// events to a block of code. Simply define a CDXUTPerfEventGenerator variable anywhere
|
||||
// in a block of code, and the class's constructor will call DXUT_BeginPerfEvent when
|
||||
// the block of code begins, and the class's destructor will call DXUT_EndPerfEvent when
|
||||
// the block ends.
|
||||
//--------------------------------------------------------------------------------------
|
||||
class CDXUTPerfEventGenerator
|
||||
{
|
||||
public:
|
||||
CDXUTPerfEventGenerator( D3DCOLOR color, LPCWSTR pstrMessage )
|
||||
{
|
||||
DXUT_BeginPerfEvent( color, pstrMessage );
|
||||
}
|
||||
~CDXUTPerfEventGenerator( void )
|
||||
{
|
||||
DXUT_EndPerfEvent();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Multimon handling to support OSes with or without multimon API support.
|
||||
// Purposely avoiding the use of multimon.h so DXUT.lib doesn't require
|
||||
// COMPILE_MULTIMON_STUBS and cause complication with MFC or other users of multimon.h
|
||||
//--------------------------------------------------------------------------------------
|
||||
#ifndef MONITOR_DEFAULTTOPRIMARY
|
||||
#define MONITORINFOF_PRIMARY 0x00000001
|
||||
#define MONITOR_DEFAULTTONULL 0x00000000
|
||||
#define MONITOR_DEFAULTTOPRIMARY 0x00000001
|
||||
#define MONITOR_DEFAULTTONEAREST 0x00000002
|
||||
typedef struct tagMONITORINFO
|
||||
{
|
||||
DWORD cbSize;
|
||||
RECT rcMonitor;
|
||||
RECT rcWork;
|
||||
DWORD dwFlags;
|
||||
} MONITORINFO, *LPMONITORINFO;
|
||||
typedef struct tagMONITORINFOEXW : public tagMONITORINFO
|
||||
{
|
||||
WCHAR szDevice[CCHDEVICENAME];
|
||||
} MONITORINFOEXW, *LPMONITORINFOEXW;
|
||||
typedef MONITORINFOEXW MONITORINFOEX;
|
||||
typedef LPMONITORINFOEXW LPMONITORINFOEX;
|
||||
#endif
|
||||
|
||||
HMONITOR WINAPI DXUTMonitorFromWindow( HWND hWnd, DWORD dwFlags );
|
||||
HMONITOR WINAPI DXUTMonitorFromRect( LPCRECT lprcScreenCoords, DWORD dwFlags );
|
||||
BOOL WINAPI DXUTGetMonitorInfo( HMONITOR hMonitor, LPMONITORINFO lpMonitorInfo );
|
||||
void WINAPI DXUTGetDesktopResolution( UINT AdapterOrdinal, UINT* pWidth, UINT* pHeight );
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Implementation of CGrowableArray
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// This version doesn't call ctor or dtor.
|
||||
template<typename TYPE> HRESULT CGrowableArray <TYPE>::SetSizeInternal( int nNewMaxSize )
|
||||
{
|
||||
if( nNewMaxSize < 0 || ( nNewMaxSize > INT_MAX / sizeof( TYPE ) ) )
|
||||
{
|
||||
assert( false );
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
if( nNewMaxSize == 0 )
|
||||
{
|
||||
// Shrink to 0 size & cleanup
|
||||
if( m_pData )
|
||||
{
|
||||
free( m_pData );
|
||||
m_pData = NULL;
|
||||
}
|
||||
|
||||
m_nMaxSize = 0;
|
||||
m_nSize = 0;
|
||||
}
|
||||
else if( m_pData == NULL || nNewMaxSize > m_nMaxSize )
|
||||
{
|
||||
// Grow array
|
||||
int nGrowBy = ( m_nMaxSize == 0 ) ? 16 : m_nMaxSize;
|
||||
|
||||
// Limit nGrowBy to keep m_nMaxSize less than INT_MAX
|
||||
if( ( UINT )m_nMaxSize + ( UINT )nGrowBy > ( UINT )INT_MAX )
|
||||
nGrowBy = INT_MAX - m_nMaxSize;
|
||||
|
||||
nNewMaxSize = __max( nNewMaxSize, m_nMaxSize + nGrowBy );
|
||||
|
||||
// Verify that (nNewMaxSize * sizeof(TYPE)) is not greater than UINT_MAX or the realloc will overrun
|
||||
if( sizeof( TYPE ) > UINT_MAX / ( UINT )nNewMaxSize )
|
||||
return E_INVALIDARG;
|
||||
|
||||
TYPE* pDataNew = ( TYPE* )realloc( m_pData, nNewMaxSize * sizeof( TYPE ) );
|
||||
if( pDataNew == NULL )
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
m_pData = pDataNew;
|
||||
m_nMaxSize = nNewMaxSize;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
template<typename TYPE> HRESULT CGrowableArray <TYPE>::SetSize( int nNewMaxSize )
|
||||
{
|
||||
int nOldSize = m_nSize;
|
||||
|
||||
if( nOldSize > nNewMaxSize )
|
||||
{
|
||||
assert( m_pData );
|
||||
if( m_pData )
|
||||
{
|
||||
// Removing elements. Call dtor.
|
||||
|
||||
for( int i = nNewMaxSize; i < nOldSize; ++i )
|
||||
m_pData[i].~TYPE();
|
||||
}
|
||||
}
|
||||
|
||||
// Adjust buffer. Note that there's no need to check for error
|
||||
// since if it happens, nOldSize == nNewMaxSize will be true.)
|
||||
HRESULT hr = SetSizeInternal( nNewMaxSize );
|
||||
|
||||
if( nOldSize < nNewMaxSize )
|
||||
{
|
||||
assert( m_pData );
|
||||
if( m_pData )
|
||||
{
|
||||
// Adding elements. Call ctor.
|
||||
|
||||
for( int i = nOldSize; i < nNewMaxSize; ++i )
|
||||
::new ( &m_pData[i] ) TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
template<typename TYPE> HRESULT CGrowableArray <TYPE>::Add( const TYPE& value )
|
||||
{
|
||||
HRESULT hr;
|
||||
if( FAILED( hr = SetSizeInternal( m_nSize + 1 ) ) )
|
||||
return hr;
|
||||
|
||||
// Construct the new element
|
||||
::new ( &m_pData[m_nSize] ) TYPE;
|
||||
|
||||
// Assign
|
||||
m_pData[m_nSize] = value;
|
||||
++m_nSize;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
template<typename TYPE> HRESULT CGrowableArray <TYPE>::Insert( int nIndex, const TYPE& value )
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
// Validate index
|
||||
if( nIndex < 0 ||
|
||||
nIndex > m_nSize )
|
||||
{
|
||||
assert( false );
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
// Prepare the buffer
|
||||
if( FAILED( hr = SetSizeInternal( m_nSize + 1 ) ) )
|
||||
return hr;
|
||||
|
||||
// Shift the array
|
||||
MoveMemory( &m_pData[nIndex + 1], &m_pData[nIndex], sizeof( TYPE ) * ( m_nSize - nIndex ) );
|
||||
|
||||
// Construct the new element
|
||||
::new ( &m_pData[nIndex] ) TYPE;
|
||||
|
||||
// Set the value and increase the size
|
||||
m_pData[nIndex] = value;
|
||||
++m_nSize;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
template<typename TYPE> HRESULT CGrowableArray <TYPE>::SetAt( int nIndex, const TYPE& value )
|
||||
{
|
||||
// Validate arguments
|
||||
if( nIndex < 0 ||
|
||||
nIndex >= m_nSize )
|
||||
{
|
||||
assert( false );
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
m_pData[nIndex] = value;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Searches for the specified value and returns the index of the first occurrence
|
||||
// within the section of the data array that extends from iStart and contains the
|
||||
// specified number of elements. Returns -1 if value is not found within the given
|
||||
// section.
|
||||
//--------------------------------------------------------------------------------------
|
||||
template<typename TYPE> int CGrowableArray <TYPE>::IndexOf( const TYPE& value, int iStart, int nNumElements )
|
||||
{
|
||||
// Validate arguments
|
||||
if( iStart < 0 ||
|
||||
iStart >= m_nSize ||
|
||||
nNumElements < 0 ||
|
||||
iStart + nNumElements > m_nSize )
|
||||
{
|
||||
assert( false );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Search
|
||||
for( int i = iStart; i < ( iStart + nNumElements ); i++ )
|
||||
{
|
||||
if( value == m_pData[i] )
|
||||
return i;
|
||||
}
|
||||
|
||||
// Not found
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Searches for the specified value and returns the index of the last occurrence
|
||||
// within the section of the data array that contains the specified number of elements
|
||||
// and ends at iEnd. Returns -1 if value is not found within the given section.
|
||||
//--------------------------------------------------------------------------------------
|
||||
template<typename TYPE> int CGrowableArray <TYPE>::LastIndexOf( const TYPE& value, int iEnd, int nNumElements )
|
||||
{
|
||||
// Validate arguments
|
||||
if( iEnd < 0 ||
|
||||
iEnd >= m_nSize ||
|
||||
nNumElements < 0 ||
|
||||
iEnd - nNumElements < 0 )
|
||||
{
|
||||
assert( false );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Search
|
||||
for( int i = iEnd; i > ( iEnd - nNumElements ); i-- )
|
||||
{
|
||||
if( value == m_pData[i] )
|
||||
return i;
|
||||
}
|
||||
|
||||
// Not found
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
template<typename TYPE> HRESULT CGrowableArray <TYPE>::Remove( int nIndex )
|
||||
{
|
||||
if( nIndex < 0 ||
|
||||
nIndex >= m_nSize )
|
||||
{
|
||||
assert( false );
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
// Destruct the element to be removed
|
||||
m_pData[nIndex].~TYPE();
|
||||
|
||||
// Compact the array and decrease the size
|
||||
MoveMemory( &m_pData[nIndex], &m_pData[nIndex + 1], sizeof( TYPE ) * ( m_nSize - ( nIndex + 1 ) ) );
|
||||
--m_nSize;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Creates a REF or NULLREF D3D9 device and returns that device. The caller should call
|
||||
// Release() when done with the device.
|
||||
//--------------------------------------------------------------------------------------
|
||||
IDirect3DDevice9* WINAPI DXUTCreateRefDevice9( HWND hWnd, bool bNullRef = true );
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Creates a REF or NULLREF D3D10 device and returns the device. The caller should call
|
||||
// Release() when done with the device.
|
||||
//--------------------------------------------------------------------------------------
|
||||
//test d3d10 version ID3D10Device* WINAPI DXUTCreateRefDevice10( bool bNullRef = true );
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Helper function to launch the Media Center UI after the program terminates
|
||||
//--------------------------------------------------------------------------------------
|
||||
bool DXUTReLaunchMediaCenter();
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Helper functions to create SRGB formats from typeless formats and vice versa
|
||||
//--------------------------------------------------------------------------------------
|
||||
DXGI_FORMAT MAKE_SRGB( DXGI_FORMAT format );
|
||||
DXGI_FORMAT MAKE_TYPELESS( DXGI_FORMAT format );
|
||||
|
||||
#endif
|
||||
7
Demos/DX11ClothDemo/DXUT/Core/dpiaware.manifest
Normal file
7
Demos/DX11ClothDemo/DXUT/Core/dpiaware.manifest
Normal file
@@ -0,0 +1,7 @@
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
|
||||
<asmv3:application>
|
||||
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
|
||||
<dpiAware>true</dpiAware>
|
||||
</asmv3:windowsSettings>
|
||||
</asmv3:application>
|
||||
</assembly>
|
||||
227
Demos/DX11ClothDemo/DXUT/Optional/DXUTLockFreePipe.h
Normal file
227
Demos/DX11ClothDemo/DXUT/Optional/DXUTLockFreePipe.h
Normal file
@@ -0,0 +1,227 @@
|
||||
//--------------------------------------------------------------------------------------
|
||||
// DXUTLockFreePipe.h
|
||||
//
|
||||
// See the "Lockless Programming Considerations for Xbox 360 and Microsoft Windows"
|
||||
// article in the DirectX SDK for more details.
|
||||
//
|
||||
// http://msdn2.microsoft.com/en-us/library/bb310595.aspx
|
||||
//
|
||||
// XNA Developer Connection
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
//--------------------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
#include <sal.h>
|
||||
|
||||
#ifdef _XBOX_VER
|
||||
// Prevent the CPU from rearranging loads
|
||||
// and stores, sufficiently for read-acquire
|
||||
// and write-release.
|
||||
#define DXUTImportBarrier __lwsync
|
||||
#define DXUTExportBarrier __lwsync
|
||||
#else
|
||||
#pragma pack(push)
|
||||
#pragma pack(8)
|
||||
#include <windows.h>
|
||||
#pragma pack (pop)
|
||||
|
||||
extern "C"
|
||||
void _ReadWriteBarrier();
|
||||
#pragma intrinsic(_ReadWriteBarrier)
|
||||
|
||||
// Prevent the compiler from rearranging loads
|
||||
// and stores, sufficiently for read-acquire
|
||||
// and write-release. This is sufficient on
|
||||
// x86 and x64.
|
||||
#define DXUTImportBarrier _ReadWriteBarrier
|
||||
#define DXUTExportBarrier _ReadWriteBarrier
|
||||
#endif
|
||||
|
||||
//
|
||||
// Pipe class designed for use by at most two threads: one reader, one writer.
|
||||
// Access by more than two threads isn't guaranteed to be safe.
|
||||
//
|
||||
// In order to provide efficient access the size of the buffer is passed
|
||||
// as a template parameter and restricted to powers of two less than 31.
|
||||
//
|
||||
|
||||
template <BYTE cbBufferSizeLog2> class DXUTLockFreePipe
|
||||
{
|
||||
public:
|
||||
DXUTLockFreePipe() : m_readOffset( 0 ),
|
||||
m_writeOffset( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
DWORD GetBufferSize() const
|
||||
{
|
||||
return c_cbBufferSize;
|
||||
}
|
||||
|
||||
__forceinline unsigned long BytesAvailable() const
|
||||
{
|
||||
return m_writeOffset - m_readOffset;
|
||||
}
|
||||
|
||||
bool __forceinline Read( void* pvDest, unsigned long cbDest )
|
||||
{
|
||||
// Store the read and write offsets into local variables--this is
|
||||
// essentially a snapshot of their values so that they stay constant
|
||||
// for the duration of the function (and so we don't end up with cache
|
||||
// misses due to false sharing).
|
||||
DWORD readOffset = m_readOffset;
|
||||
DWORD writeOffset = m_writeOffset;
|
||||
|
||||
// Compare the two offsets to see if we have anything to read.
|
||||
// Note that we don't do anything to synchronize the offsets here.
|
||||
// Really there's not much we *can* do unless we're willing to completely
|
||||
// synchronize access to the entire object. We have to assume that as we
|
||||
// read, someone else may be writing, and the write offset we have now
|
||||
// may be out of date by the time we read it. Fortunately that's not a
|
||||
// very big deal. We might miss reading some data that was just written.
|
||||
// But the assumption is that we'll be back before long to grab more data
|
||||
// anyway.
|
||||
//
|
||||
// Note that this comparison works because we're careful to constrain
|
||||
// the total buffer size to be a power of 2, which means it will divide
|
||||
// evenly into ULONG_MAX+1. That, and the fact that the offsets are
|
||||
// unsigned, means that the calculation returns correct results even
|
||||
// when the values wrap around.
|
||||
DWORD cbAvailable = writeOffset - readOffset;
|
||||
if( cbDest > cbAvailable )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// The data has been made available, but we need to make sure
|
||||
// that our view on the data is up to date -- at least as up to
|
||||
// date as the control values we just read. We need to prevent
|
||||
// the compiler or CPU from moving any of the data reads before
|
||||
// the control value reads. This import barrier serves this
|
||||
// purpose, on Xbox 360 and on Windows.
|
||||
|
||||
// Reading a control value and then having a barrier is known
|
||||
// as a "read-acquire."
|
||||
DXUTImportBarrier();
|
||||
|
||||
unsigned char* pbDest = ( unsigned char* )pvDest;
|
||||
|
||||
unsigned long actualReadOffset = readOffset & c_sizeMask;
|
||||
unsigned long bytesLeft = cbDest;
|
||||
|
||||
//
|
||||
// Copy from the tail, then the head. Note that there's no explicit
|
||||
// check to see if the write offset comes between the read offset
|
||||
// and the end of the buffer--that particular condition is implicitly
|
||||
// checked by the comparison with AvailableToRead(), above. If copying
|
||||
// cbDest bytes off the tail would cause us to cross the write offset,
|
||||
// then the previous comparison would have failed since that would imply
|
||||
// that there were less than cbDest bytes available to read.
|
||||
//
|
||||
unsigned long cbTailBytes = min( bytesLeft, c_cbBufferSize - actualReadOffset );
|
||||
memcpy( pbDest, m_pbBuffer + actualReadOffset, cbTailBytes );
|
||||
bytesLeft -= cbTailBytes;
|
||||
|
||||
if( bytesLeft )
|
||||
{
|
||||
memcpy( pbDest + cbTailBytes, m_pbBuffer, bytesLeft );
|
||||
}
|
||||
|
||||
// When we update the read offset we are, effectively, 'freeing' buffer
|
||||
// memory so that the writing thread can use it. We need to make sure that
|
||||
// we don't free the memory before we have finished reading it. That is,
|
||||
// we need to make sure that the write to m_readOffset can't get reordered
|
||||
// above the reads of the buffer data. The only way to guarantee this is to
|
||||
// have an export barrier to prevent both compiler and CPU rearrangements.
|
||||
DXUTExportBarrier();
|
||||
|
||||
// Advance the read offset. From the CPUs point of view this is several
|
||||
// operations--read, modify, store--and we'd normally want to make sure that
|
||||
// all of the operations happened atomically. But in the case of a single
|
||||
// reader, only one thread updates this value and so the only operation that
|
||||
// must be atomic is the store. That's lucky, because 32-bit aligned stores are
|
||||
// atomic on all modern processors.
|
||||
//
|
||||
readOffset += cbDest;
|
||||
m_readOffset = readOffset;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool __forceinline Write( const void* pvSrc, unsigned long cbSrc )
|
||||
{
|
||||
// Reading the read offset here has the same caveats as reading
|
||||
// the write offset had in the Read() function above.
|
||||
DWORD readOffset = m_readOffset;
|
||||
DWORD writeOffset = m_writeOffset;
|
||||
|
||||
// Compute the available write size. This comparison relies on
|
||||
// the fact that the buffer size is always a power of 2, and the
|
||||
// offsets are unsigned integers, so that when the write pointer
|
||||
// wraps around the subtraction still yields a value (assuming
|
||||
// we haven't messed up somewhere else) between 0 and c_cbBufferSize - 1.
|
||||
DWORD cbAvailable = c_cbBufferSize - ( writeOffset - readOffset );
|
||||
if( cbSrc > cbAvailable )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// It is theoretically possible for writes of the data to be reordered
|
||||
// above the reads to see if the data is available. Improbable perhaps,
|
||||
// but possible. This barrier guarantees that the reordering will not
|
||||
// happen.
|
||||
DXUTImportBarrier();
|
||||
|
||||
// Write the data
|
||||
const unsigned char* pbSrc = ( const unsigned char* )pvSrc;
|
||||
unsigned long actualWriteOffset = writeOffset & c_sizeMask;
|
||||
unsigned long bytesLeft = cbSrc;
|
||||
|
||||
// See the explanation in the Read() function as to why we don't
|
||||
// explicitly check against the read offset here.
|
||||
unsigned long cbTailBytes = min( bytesLeft, c_cbBufferSize - actualWriteOffset );
|
||||
memcpy( m_pbBuffer + actualWriteOffset, pbSrc, cbTailBytes );
|
||||
bytesLeft -= cbTailBytes;
|
||||
|
||||
if( bytesLeft )
|
||||
{
|
||||
memcpy( m_pbBuffer, pbSrc + cbTailBytes, bytesLeft );
|
||||
}
|
||||
|
||||
// Now it's time to update the write offset, but since the updated position
|
||||
// of the write offset will imply that there's data to be read, we need to
|
||||
// make sure that the data all actually gets written before the update to
|
||||
// the write offset. The writes could be reordered by the compiler (on any
|
||||
// platform) or by the CPU (on Xbox 360). We need a barrier which prevents
|
||||
// the writes from being reordered past each other.
|
||||
//
|
||||
// Having a barrier and then writing a control value is called "write-release."
|
||||
DXUTExportBarrier();
|
||||
|
||||
// See comments in Read() as to why this operation isn't interlocked.
|
||||
writeOffset += cbSrc;
|
||||
m_writeOffset = writeOffset;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
// Values derived from the buffer size template parameter
|
||||
//
|
||||
const static BYTE c_cbBufferSizeLog2 = min( cbBufferSizeLog2, 31 );
|
||||
const static DWORD c_cbBufferSize = ( 1 << c_cbBufferSizeLog2 );
|
||||
const static DWORD c_sizeMask = c_cbBufferSize - 1;
|
||||
|
||||
// Leave these private and undefined to prevent their use
|
||||
DXUTLockFreePipe( const DXUTLockFreePipe& );
|
||||
DXUTLockFreePipe& operator =( const DXUTLockFreePipe& );
|
||||
|
||||
// Member data
|
||||
//
|
||||
BYTE m_pbBuffer[c_cbBufferSize];
|
||||
// Note that these offsets are not clamped to the buffer size.
|
||||
// Instead the calculations rely on wrapping at ULONG_MAX+1.
|
||||
// See the comments in Read() for details.
|
||||
volatile DWORD __declspec( align( 4 ) ) m_readOffset;
|
||||
volatile DWORD __declspec( align( 4 ) ) m_writeOffset;
|
||||
};
|
||||
5663
Demos/DX11ClothDemo/DXUT/Optional/DXUTShapes.cpp
Normal file
5663
Demos/DX11ClothDemo/DXUT/Optional/DXUTShapes.cpp
Normal file
File diff suppressed because it is too large
Load Diff
24
Demos/DX11ClothDemo/DXUT/Optional/DXUTShapes.h
Normal file
24
Demos/DX11ClothDemo/DXUT/Optional/DXUTShapes.h
Normal file
@@ -0,0 +1,24 @@
|
||||
//--------------------------------------------------------------------------------------
|
||||
// File: DXUTShapes.h
|
||||
//
|
||||
// Shape creation functions for DXUT
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved
|
||||
//--------------------------------------------------------------------------------------
|
||||
#pragma once
|
||||
#ifndef DXUT_SHAPES_H
|
||||
#define DXUT_SHAPES_H
|
||||
#include <d3d10.h>
|
||||
#include <d3dx10.h>
|
||||
|
||||
HRESULT WINAPI DXUTCreateBox( ID3D10Device* pDevice, float fWidth, float fHeight, float fDepth, ID3DX10Mesh** ppMesh );
|
||||
HRESULT WINAPI DXUTCreateCylinder( ID3D10Device* pDevice, float fRadius1, float fRadius2, float fLength, UINT uSlices,
|
||||
UINT uStacks, ID3DX10Mesh** ppMesh );
|
||||
HRESULT WINAPI DXUTCreatePolygon( ID3D10Device* pDevice, float fLength, UINT uSides, ID3DX10Mesh** ppMesh );
|
||||
HRESULT WINAPI DXUTCreateSphere( ID3D10Device* pDevice, float fRadius, UINT uSlices, UINT uStacks,
|
||||
ID3DX10Mesh** ppMesh );
|
||||
HRESULT WINAPI DXUTCreateTorus( ID3D10Device* pDevice, float fInnerRadius, float fOuterRadius, UINT uSides,
|
||||
UINT uRings, ID3DX10Mesh** ppMesh );
|
||||
HRESULT WINAPI DXUTCreateTeapot( ID3D10Device* pDevice, ID3DX10Mesh** ppMesh );
|
||||
|
||||
#endif
|
||||
1525
Demos/DX11ClothDemo/DXUT/Optional/DXUTcamera.cpp
Normal file
1525
Demos/DX11ClothDemo/DXUT/Optional/DXUTcamera.cpp
Normal file
File diff suppressed because it is too large
Load Diff
517
Demos/DX11ClothDemo/DXUT/Optional/DXUTcamera.h
Normal file
517
Demos/DX11ClothDemo/DXUT/Optional/DXUTcamera.h
Normal file
@@ -0,0 +1,517 @@
|
||||
//--------------------------------------------------------------------------------------
|
||||
// File: Camera.h
|
||||
//
|
||||
// Helper functions for Direct3D programming.
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved
|
||||
//--------------------------------------------------------------------------------------
|
||||
#pragma once
|
||||
#ifndef CAMERA_H
|
||||
#define CAMERA_H
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
class CD3DArcBall
|
||||
{
|
||||
public:
|
||||
CD3DArcBall();
|
||||
|
||||
// Functions to change behavior
|
||||
void Reset();
|
||||
void SetTranslationRadius( FLOAT fRadiusTranslation )
|
||||
{
|
||||
m_fRadiusTranslation = fRadiusTranslation;
|
||||
}
|
||||
void SetWindow( INT nWidth, INT nHeight, FLOAT fRadius = 0.9f )
|
||||
{
|
||||
m_nWidth = nWidth; m_nHeight = nHeight; m_fRadius = fRadius;
|
||||
m_vCenter = D3DXVECTOR2( m_nWidth / 2.0f, m_nHeight / 2.0f );
|
||||
}
|
||||
void SetOffset( INT nX, INT nY )
|
||||
{
|
||||
m_Offset.x = nX; m_Offset.y = nY;
|
||||
}
|
||||
|
||||
// Call these from client and use GetRotationMatrix() to read new rotation matrix
|
||||
void OnBegin( int nX, int nY ); // start the rotation (pass current mouse position)
|
||||
void OnMove( int nX, int nY ); // continue the rotation (pass current mouse position)
|
||||
void OnEnd(); // end the rotation
|
||||
|
||||
// Or call this to automatically handle left, middle, right buttons
|
||||
LRESULT HandleMessages( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
|
||||
|
||||
// Functions to get/set state
|
||||
const D3DXMATRIX* GetRotationMatrix()
|
||||
{
|
||||
return D3DXMatrixRotationQuaternion( &m_mRotation, &m_qNow );
|
||||
};
|
||||
const D3DXMATRIX* GetTranslationMatrix() const
|
||||
{
|
||||
return &m_mTranslation;
|
||||
}
|
||||
const D3DXMATRIX* GetTranslationDeltaMatrix() const
|
||||
{
|
||||
return &m_mTranslationDelta;
|
||||
}
|
||||
bool IsBeingDragged() const
|
||||
{
|
||||
return m_bDrag;
|
||||
}
|
||||
D3DXQUATERNION GetQuatNow() const
|
||||
{
|
||||
return m_qNow;
|
||||
}
|
||||
void SetQuatNow( D3DXQUATERNION q )
|
||||
{
|
||||
m_qNow = q;
|
||||
}
|
||||
|
||||
static D3DXQUATERNION WINAPI QuatFromBallPoints( const D3DXVECTOR3& vFrom, const D3DXVECTOR3& vTo );
|
||||
|
||||
|
||||
protected:
|
||||
D3DXMATRIXA16 m_mRotation; // Matrix for arc ball's orientation
|
||||
D3DXMATRIXA16 m_mTranslation; // Matrix for arc ball's position
|
||||
D3DXMATRIXA16 m_mTranslationDelta; // Matrix for arc ball's position
|
||||
|
||||
POINT m_Offset; // window offset, or upper-left corner of window
|
||||
INT m_nWidth; // arc ball's window width
|
||||
INT m_nHeight; // arc ball's window height
|
||||
D3DXVECTOR2 m_vCenter; // center of arc ball
|
||||
FLOAT m_fRadius; // arc ball's radius in screen coords
|
||||
FLOAT m_fRadiusTranslation; // arc ball's radius for translating the target
|
||||
|
||||
D3DXQUATERNION m_qDown; // Quaternion before button down
|
||||
D3DXQUATERNION m_qNow; // Composite quaternion for current drag
|
||||
bool m_bDrag; // Whether user is dragging arc ball
|
||||
|
||||
POINT m_ptLastMouse; // position of last mouse point
|
||||
D3DXVECTOR3 m_vDownPt; // starting point of rotation arc
|
||||
D3DXVECTOR3 m_vCurrentPt; // current point of rotation arc
|
||||
|
||||
D3DXVECTOR3 ScreenToVector( float fScreenPtX, float fScreenPtY );
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// used by CCamera to map WM_KEYDOWN keys
|
||||
//--------------------------------------------------------------------------------------
|
||||
enum D3DUtil_CameraKeys
|
||||
{
|
||||
CAM_STRAFE_LEFT = 0,
|
||||
CAM_STRAFE_RIGHT,
|
||||
CAM_MOVE_FORWARD,
|
||||
CAM_MOVE_BACKWARD,
|
||||
CAM_MOVE_UP,
|
||||
CAM_MOVE_DOWN,
|
||||
CAM_RESET,
|
||||
CAM_CONTROLDOWN,
|
||||
CAM_MAX_KEYS,
|
||||
CAM_UNKNOWN = 0xFF
|
||||
};
|
||||
|
||||
#define KEY_WAS_DOWN_MASK 0x80
|
||||
#define KEY_IS_DOWN_MASK 0x01
|
||||
|
||||
#define MOUSE_LEFT_BUTTON 0x01
|
||||
#define MOUSE_MIDDLE_BUTTON 0x02
|
||||
#define MOUSE_RIGHT_BUTTON 0x04
|
||||
#define MOUSE_WHEEL 0x08
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Simple base camera class that moves and rotates. The base class
|
||||
// records mouse and keyboard input for use by a derived class, and
|
||||
// keeps common state.
|
||||
//--------------------------------------------------------------------------------------
|
||||
class CBaseCamera
|
||||
{
|
||||
public:
|
||||
CBaseCamera();
|
||||
|
||||
// Call these from client and use Get*Matrix() to read new matrices
|
||||
virtual LRESULT HandleMessages( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
|
||||
virtual void FrameMove( FLOAT fElapsedTime ) = 0;
|
||||
|
||||
// Functions to change camera matrices
|
||||
virtual void Reset();
|
||||
virtual void SetViewParams( D3DXVECTOR3* pvEyePt, D3DXVECTOR3* pvLookatPt );
|
||||
virtual void SetProjParams( FLOAT fFOV, FLOAT fAspect, FLOAT fNearPlane, FLOAT fFarPlane );
|
||||
|
||||
// Functions to change behavior
|
||||
virtual void SetDragRect( RECT& rc )
|
||||
{
|
||||
m_rcDrag = rc;
|
||||
}
|
||||
void SetInvertPitch( bool bInvertPitch )
|
||||
{
|
||||
m_bInvertPitch = bInvertPitch;
|
||||
}
|
||||
void SetDrag( bool bMovementDrag, FLOAT fTotalDragTimeToZero = 0.25f )
|
||||
{
|
||||
m_bMovementDrag = bMovementDrag; m_fTotalDragTimeToZero = fTotalDragTimeToZero;
|
||||
}
|
||||
void SetEnableYAxisMovement( bool bEnableYAxisMovement )
|
||||
{
|
||||
m_bEnableYAxisMovement = bEnableYAxisMovement;
|
||||
}
|
||||
void SetEnablePositionMovement( bool bEnablePositionMovement )
|
||||
{
|
||||
m_bEnablePositionMovement = bEnablePositionMovement;
|
||||
}
|
||||
void SetClipToBoundary( bool bClipToBoundary, D3DXVECTOR3* pvMinBoundary,
|
||||
D3DXVECTOR3* pvMaxBoundary )
|
||||
{
|
||||
m_bClipToBoundary = bClipToBoundary; if( pvMinBoundary ) m_vMinBoundary = *pvMinBoundary;
|
||||
if( pvMaxBoundary ) m_vMaxBoundary = *pvMaxBoundary;
|
||||
}
|
||||
void SetScalers( FLOAT fRotationScaler = 0.01f, FLOAT fMoveScaler = 5.0f )
|
||||
{
|
||||
m_fRotationScaler = fRotationScaler; m_fMoveScaler = fMoveScaler;
|
||||
}
|
||||
void SetNumberOfFramesToSmoothMouseData( int nFrames )
|
||||
{
|
||||
if( nFrames > 0 ) m_fFramesToSmoothMouseData = ( float )nFrames;
|
||||
}
|
||||
void SetResetCursorAfterMove( bool bResetCursorAfterMove )
|
||||
{
|
||||
m_bResetCursorAfterMove = bResetCursorAfterMove;
|
||||
}
|
||||
|
||||
// Functions to get state
|
||||
const D3DXMATRIX* GetViewMatrix() const
|
||||
{
|
||||
return &m_mView;
|
||||
}
|
||||
const D3DXMATRIX* GetProjMatrix() const
|
||||
{
|
||||
return &m_mProj;
|
||||
}
|
||||
const D3DXVECTOR3* GetEyePt() const
|
||||
{
|
||||
return &m_vEye;
|
||||
}
|
||||
const D3DXVECTOR3* GetLookAtPt() const
|
||||
{
|
||||
return &m_vLookAt;
|
||||
}
|
||||
float GetNearClip() const
|
||||
{
|
||||
return m_fNearPlane;
|
||||
}
|
||||
float GetFarClip() const
|
||||
{
|
||||
return m_fFarPlane;
|
||||
}
|
||||
|
||||
bool IsBeingDragged() const
|
||||
{
|
||||
return ( m_bMouseLButtonDown || m_bMouseMButtonDown || m_bMouseRButtonDown );
|
||||
}
|
||||
bool IsMouseLButtonDown() const
|
||||
{
|
||||
return m_bMouseLButtonDown;
|
||||
}
|
||||
bool IsMouseMButtonDown() const
|
||||
{
|
||||
return m_bMouseMButtonDown;
|
||||
}
|
||||
bool IsMouseRButtonDown() const
|
||||
{
|
||||
return m_bMouseRButtonDown;
|
||||
}
|
||||
|
||||
protected:
|
||||
// Functions to map a WM_KEYDOWN key to a D3DUtil_CameraKeys enum
|
||||
virtual D3DUtil_CameraKeys MapKey( UINT nKey );
|
||||
bool IsKeyDown( BYTE key ) const
|
||||
{
|
||||
return( ( key & KEY_IS_DOWN_MASK ) == KEY_IS_DOWN_MASK );
|
||||
}
|
||||
bool WasKeyDown( BYTE key ) const
|
||||
{
|
||||
return( ( key & KEY_WAS_DOWN_MASK ) == KEY_WAS_DOWN_MASK );
|
||||
}
|
||||
|
||||
void ConstrainToBoundary( D3DXVECTOR3* pV );
|
||||
void UpdateMouseDelta();
|
||||
void UpdateVelocity( float fElapsedTime );
|
||||
void GetInput( bool bGetKeyboardInput, bool bGetMouseInput, bool bGetGamepadInput,
|
||||
bool bResetCursorAfterMove );
|
||||
|
||||
D3DXMATRIX m_mView; // View matrix
|
||||
D3DXMATRIX m_mProj; // Projection matrix
|
||||
|
||||
DXUT_GAMEPAD m_GamePad[DXUT_MAX_CONTROLLERS]; // XInput controller state
|
||||
D3DXVECTOR3 m_vGamePadLeftThumb;
|
||||
D3DXVECTOR3 m_vGamePadRightThumb;
|
||||
double m_GamePadLastActive[DXUT_MAX_CONTROLLERS];
|
||||
|
||||
int m_cKeysDown; // Number of camera keys that are down.
|
||||
BYTE m_aKeys[CAM_MAX_KEYS]; // State of input - KEY_WAS_DOWN_MASK|KEY_IS_DOWN_MASK
|
||||
D3DXVECTOR3 m_vKeyboardDirection; // Direction vector of keyboard input
|
||||
POINT m_ptLastMousePosition; // Last absolute position of mouse cursor
|
||||
bool m_bMouseLButtonDown; // True if left button is down
|
||||
bool m_bMouseMButtonDown; // True if middle button is down
|
||||
bool m_bMouseRButtonDown; // True if right button is down
|
||||
int m_nCurrentButtonMask; // mask of which buttons are down
|
||||
int m_nMouseWheelDelta; // Amount of middle wheel scroll (+/-)
|
||||
D3DXVECTOR2 m_vMouseDelta; // Mouse relative delta smoothed over a few frames
|
||||
float m_fFramesToSmoothMouseData; // Number of frames to smooth mouse data over
|
||||
|
||||
D3DXVECTOR3 m_vDefaultEye; // Default camera eye position
|
||||
D3DXVECTOR3 m_vDefaultLookAt; // Default LookAt position
|
||||
D3DXVECTOR3 m_vEye; // Camera eye position
|
||||
D3DXVECTOR3 m_vLookAt; // LookAt position
|
||||
float m_fCameraYawAngle; // Yaw angle of camera
|
||||
float m_fCameraPitchAngle; // Pitch angle of camera
|
||||
|
||||
RECT m_rcDrag; // Rectangle within which a drag can be initiated.
|
||||
D3DXVECTOR3 m_vVelocity; // Velocity of camera
|
||||
bool m_bMovementDrag; // If true, then camera movement will slow to a stop otherwise movement is instant
|
||||
D3DXVECTOR3 m_vVelocityDrag; // Velocity drag force
|
||||
FLOAT m_fDragTimer; // Countdown timer to apply drag
|
||||
FLOAT m_fTotalDragTimeToZero; // Time it takes for velocity to go from full to 0
|
||||
D3DXVECTOR2 m_vRotVelocity; // Velocity of camera
|
||||
|
||||
float m_fFOV; // Field of view
|
||||
float m_fAspect; // Aspect ratio
|
||||
float m_fNearPlane; // Near plane
|
||||
float m_fFarPlane; // Far plane
|
||||
|
||||
float m_fRotationScaler; // Scaler for rotation
|
||||
float m_fMoveScaler; // Scaler for movement
|
||||
|
||||
bool m_bInvertPitch; // Invert the pitch axis
|
||||
bool m_bEnablePositionMovement; // If true, then the user can translate the camera/model
|
||||
bool m_bEnableYAxisMovement; // If true, then camera can move in the y-axis
|
||||
|
||||
bool m_bClipToBoundary; // If true, then the camera will be clipped to the boundary
|
||||
D3DXVECTOR3 m_vMinBoundary; // Min point in clip boundary
|
||||
D3DXVECTOR3 m_vMaxBoundary; // Max point in clip boundary
|
||||
|
||||
bool m_bResetCursorAfterMove;// If true, the class will reset the cursor position so that the cursor always has space to move
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Simple first person camera class that moves and rotates.
|
||||
// It allows yaw and pitch but not roll. It uses WM_KEYDOWN and
|
||||
// GetCursorPos() to respond to keyboard and mouse input and updates the
|
||||
// view matrix based on input.
|
||||
//--------------------------------------------------------------------------------------
|
||||
class CFirstPersonCamera : public CBaseCamera
|
||||
{
|
||||
public:
|
||||
CFirstPersonCamera();
|
||||
|
||||
// Call these from client and use Get*Matrix() to read new matrices
|
||||
virtual void FrameMove( FLOAT fElapsedTime );
|
||||
|
||||
// Functions to change behavior
|
||||
void SetRotateButtons( bool bLeft, bool bMiddle, bool bRight, bool bRotateWithoutButtonDown = false );
|
||||
|
||||
// Functions to get state
|
||||
D3DXMATRIX* GetWorldMatrix()
|
||||
{
|
||||
return &m_mCameraWorld;
|
||||
}
|
||||
|
||||
const D3DXVECTOR3* GetWorldRight() const
|
||||
{
|
||||
return ( D3DXVECTOR3* )&m_mCameraWorld._11;
|
||||
}
|
||||
const D3DXVECTOR3* GetWorldUp() const
|
||||
{
|
||||
return ( D3DXVECTOR3* )&m_mCameraWorld._21;
|
||||
}
|
||||
const D3DXVECTOR3* GetWorldAhead() const
|
||||
{
|
||||
return ( D3DXVECTOR3* )&m_mCameraWorld._31;
|
||||
}
|
||||
const D3DXVECTOR3* GetEyePt() const
|
||||
{
|
||||
return ( D3DXVECTOR3* )&m_mCameraWorld._41;
|
||||
}
|
||||
|
||||
protected:
|
||||
D3DXMATRIX m_mCameraWorld; // World matrix of the camera (inverse of the view matrix)
|
||||
|
||||
int m_nActiveButtonMask; // Mask to determine which button to enable for rotation
|
||||
bool m_bRotateWithoutButtonDown;
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Simple model viewing camera class that rotates around the object.
|
||||
//--------------------------------------------------------------------------------------
|
||||
class CModelViewerCamera : public CBaseCamera
|
||||
{
|
||||
public:
|
||||
CModelViewerCamera();
|
||||
|
||||
// Call these from client and use Get*Matrix() to read new matrices
|
||||
virtual LRESULT HandleMessages( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
|
||||
virtual void FrameMove( FLOAT fElapsedTime );
|
||||
|
||||
|
||||
// Functions to change behavior
|
||||
virtual void SetDragRect( RECT& rc );
|
||||
void Reset();
|
||||
void SetViewParams( D3DXVECTOR3* pvEyePt, D3DXVECTOR3* pvLookatPt );
|
||||
void SetButtonMasks( int nRotateModelButtonMask = MOUSE_LEFT_BUTTON, int nZoomButtonMask = MOUSE_WHEEL,
|
||||
int nRotateCameraButtonMask = MOUSE_RIGHT_BUTTON )
|
||||
{
|
||||
m_nRotateModelButtonMask = nRotateModelButtonMask, m_nZoomButtonMask = nZoomButtonMask;
|
||||
m_nRotateCameraButtonMask = nRotateCameraButtonMask;
|
||||
}
|
||||
void SetAttachCameraToModel( bool bEnable = false )
|
||||
{
|
||||
m_bAttachCameraToModel = bEnable;
|
||||
}
|
||||
void SetWindow( int nWidth, int nHeight, float fArcballRadius=0.9f )
|
||||
{
|
||||
m_WorldArcBall.SetWindow( nWidth, nHeight, fArcballRadius );
|
||||
m_ViewArcBall.SetWindow( nWidth, nHeight, fArcballRadius );
|
||||
}
|
||||
void SetRadius( float fDefaultRadius=5.0f, float fMinRadius=1.0f, float fMaxRadius=FLT_MAX )
|
||||
{
|
||||
m_fDefaultRadius = m_fRadius = fDefaultRadius; m_fMinRadius = fMinRadius; m_fMaxRadius = fMaxRadius;
|
||||
m_bDragSinceLastUpdate = true;
|
||||
}
|
||||
void SetModelCenter( D3DXVECTOR3 vModelCenter )
|
||||
{
|
||||
m_vModelCenter = vModelCenter;
|
||||
}
|
||||
void SetLimitPitch( bool bLimitPitch )
|
||||
{
|
||||
m_bLimitPitch = bLimitPitch;
|
||||
}
|
||||
void SetViewQuat( D3DXQUATERNION q )
|
||||
{
|
||||
m_ViewArcBall.SetQuatNow( q ); m_bDragSinceLastUpdate = true;
|
||||
}
|
||||
void SetWorldQuat( D3DXQUATERNION q )
|
||||
{
|
||||
m_WorldArcBall.SetQuatNow( q ); m_bDragSinceLastUpdate = true;
|
||||
}
|
||||
|
||||
// Functions to get state
|
||||
const D3DXMATRIX* GetWorldMatrix() const
|
||||
{
|
||||
return &m_mWorld;
|
||||
}
|
||||
void SetWorldMatrix( D3DXMATRIX& mWorld )
|
||||
{
|
||||
m_mWorld = mWorld; m_bDragSinceLastUpdate = true;
|
||||
}
|
||||
|
||||
protected:
|
||||
CD3DArcBall m_WorldArcBall;
|
||||
CD3DArcBall m_ViewArcBall;
|
||||
D3DXVECTOR3 m_vModelCenter;
|
||||
D3DXMATRIX m_mModelLastRot; // Last arcball rotation matrix for model
|
||||
D3DXMATRIX m_mModelRot; // Rotation matrix of model
|
||||
D3DXMATRIX m_mWorld; // World matrix of model
|
||||
|
||||
int m_nRotateModelButtonMask;
|
||||
int m_nZoomButtonMask;
|
||||
int m_nRotateCameraButtonMask;
|
||||
|
||||
bool m_bAttachCameraToModel;
|
||||
bool m_bLimitPitch;
|
||||
float m_fRadius; // Distance from the camera to model
|
||||
float m_fDefaultRadius; // Distance from the camera to model
|
||||
float m_fMinRadius; // Min radius
|
||||
float m_fMaxRadius; // Max radius
|
||||
bool m_bDragSinceLastUpdate; // True if mouse drag has happened since last time FrameMove is called.
|
||||
|
||||
D3DXMATRIX m_mCameraRotLast;
|
||||
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Manages the mesh, direction, mouse events of a directional arrow that
|
||||
// rotates around a radius controlled by an arcball
|
||||
//--------------------------------------------------------------------------------------
|
||||
class CDXUTDirectionWidget
|
||||
{
|
||||
public:
|
||||
CDXUTDirectionWidget();
|
||||
|
||||
static HRESULT WINAPI StaticOnD3D9CreateDevice( IDirect3DDevice9* pd3dDevice );
|
||||
HRESULT OnD3D9ResetDevice( const D3DSURFACE_DESC* pBackBufferSurfaceDesc );
|
||||
HRESULT OnRender9( D3DXCOLOR color, const D3DXMATRIX* pmView, const D3DXMATRIX* pmProj,
|
||||
const D3DXVECTOR3* pEyePt );
|
||||
LRESULT HandleMessages( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
|
||||
static void WINAPI StaticOnD3D9LostDevice();
|
||||
static void WINAPI StaticOnD3D9DestroyDevice();
|
||||
|
||||
static HRESULT WINAPI StaticOnD3D11CreateDevice( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3dImmediateContext );
|
||||
HRESULT OnRender11( D3DXCOLOR color, const D3DXMATRIX* pmView, const D3DXMATRIX* pmProj,
|
||||
const D3DXVECTOR3* pEyePt );
|
||||
static void WINAPI StaticOnD3D11DestroyDevice();
|
||||
|
||||
D3DXVECTOR3 GetLightDirection()
|
||||
{
|
||||
return m_vCurrentDir;
|
||||
};
|
||||
void SetLightDirection( D3DXVECTOR3 vDir )
|
||||
{
|
||||
m_vDefaultDir = m_vCurrentDir = vDir;
|
||||
};
|
||||
void SetButtonMask( int nRotate = MOUSE_RIGHT_BUTTON )
|
||||
{
|
||||
m_nRotateMask = nRotate;
|
||||
}
|
||||
|
||||
float GetRadius()
|
||||
{
|
||||
return m_fRadius;
|
||||
};
|
||||
void SetRadius( float fRadius )
|
||||
{
|
||||
m_fRadius = fRadius;
|
||||
};
|
||||
|
||||
bool IsBeingDragged()
|
||||
{
|
||||
return m_ArcBall.IsBeingDragged();
|
||||
};
|
||||
|
||||
protected:
|
||||
HRESULT UpdateLightDir();
|
||||
|
||||
// D3D9 objects
|
||||
static IDirect3DDevice9* s_pd3d9Device;
|
||||
static ID3DXEffect* s_pD3D9Effect;
|
||||
static ID3DXMesh* s_pD3D9Mesh;
|
||||
static D3DXHANDLE s_hRenderWith1LightNoTexture;
|
||||
static D3DXHANDLE s_hMaterialDiffuseColor;
|
||||
static D3DXHANDLE s_hLightDir;
|
||||
static D3DXHANDLE s_hWorldViewProjection;
|
||||
static D3DXHANDLE s_hWorld;
|
||||
|
||||
// D3D10 objects
|
||||
//static ID3D10Device* s_pd3d10Device;
|
||||
//static ID3D10Effect* s_pD3D10Effect;
|
||||
//TODO: add some sort of d3d10 mesh object here
|
||||
//static ID3D10InputLayout* s_pVertexLayout;
|
||||
//static ID3D10EffectTechnique* s_pRenderTech;
|
||||
//static ID3D10EffectVectorVariable* g_pMaterialDiffuseColor;
|
||||
//static ID3D10EffectVectorVariable* g_pLightDir;
|
||||
//static ID3D10EffectMatrixVariable* g_pmWorld;
|
||||
//static ID3D10EffectMatrixVariable* g_pmWorldViewProjection;
|
||||
|
||||
D3DXMATRIXA16 m_mRot;
|
||||
D3DXMATRIXA16 m_mRotSnapshot;
|
||||
float m_fRadius;
|
||||
int m_nRotateMask;
|
||||
CD3DArcBall m_ArcBall;
|
||||
D3DXVECTOR3 m_vDefaultDir;
|
||||
D3DXVECTOR3 m_vCurrentDir;
|
||||
D3DXMATRIX m_mView;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
7241
Demos/DX11ClothDemo/DXUT/Optional/DXUTgui.cpp
Normal file
7241
Demos/DX11ClothDemo/DXUT/Optional/DXUTgui.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1383
Demos/DX11ClothDemo/DXUT/Optional/DXUTgui.h
Normal file
1383
Demos/DX11ClothDemo/DXUT/Optional/DXUTgui.h
Normal file
File diff suppressed because it is too large
Load Diff
990
Demos/DX11ClothDemo/DXUT/Optional/DXUTguiIME.cpp
Normal file
990
Demos/DX11ClothDemo/DXUT/Optional/DXUTguiIME.cpp
Normal file
@@ -0,0 +1,990 @@
|
||||
//--------------------------------------------------------------------------------------
|
||||
// File: DXUTguiIME.cpp
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//--------------------------------------------------------------------------------------
|
||||
#include "DXUT.h"
|
||||
#include "DXUTgui.h"
|
||||
#include "DXUTsettingsDlg.h"
|
||||
#include "DXUTres.h"
|
||||
#include "DXUTgui.h"
|
||||
#include "DXUTguiIME.h"
|
||||
|
||||
#undef min // use __min instead
|
||||
#undef max // use __max instead
|
||||
#define DXUT_NEAR_BUTTON_DEPTH 0.6f
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// CDXUTIMEEditBox class
|
||||
//--------------------------------------------------------------------------------------
|
||||
// IME constants
|
||||
|
||||
POINT CDXUTIMEEditBox::s_ptCompString; // Composition string position. Updated every frame.
|
||||
int CDXUTIMEEditBox::s_nFirstTargetConv; // Index of the first target converted char in comp string. If none, -1.
|
||||
CUniBuffer CDXUTIMEEditBox::s_CompString = CUniBuffer( 0 );
|
||||
DWORD CDXUTIMEEditBox::s_adwCompStringClause[MAX_COMPSTRING_SIZE];
|
||||
WCHAR CDXUTIMEEditBox::s_wszReadingString[32];
|
||||
CDXUTIMEEditBox::CCandList CDXUTIMEEditBox::s_CandList; // Data relevant to the candidate list
|
||||
bool CDXUTIMEEditBox::s_bImeFlag = true;
|
||||
|
||||
|
||||
#if defined(DEBUG) || defined(_DEBUG)
|
||||
bool CDXUTIMEEditBox::m_bIMEStaticMsgProcCalled = false;
|
||||
#endif
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
HRESULT CDXUTIMEEditBox::CreateIMEEditBox( CDXUTDialog* pDialog, int ID, LPCWSTR strText, int x, int y, int width,
|
||||
int height, bool bIsDefault, CDXUTIMEEditBox** ppCreated )
|
||||
{
|
||||
CDXUTIMEEditBox* pEditBox = new CDXUTIMEEditBox( pDialog );
|
||||
|
||||
if( ppCreated != NULL )
|
||||
*ppCreated = pEditBox;
|
||||
|
||||
if( pEditBox == NULL )
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
// Set the ID and position
|
||||
pEditBox->SetID( ID );
|
||||
pEditBox->SetLocation( x, y );
|
||||
pEditBox->SetSize( width, height );
|
||||
pEditBox->m_bIsDefault = bIsDefault;
|
||||
|
||||
if( strText )
|
||||
pEditBox->SetText( strText );
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
void CDXUTIMEEditBox::InitDefaultElements( CDXUTDialog* pDialog )
|
||||
{
|
||||
//-------------------------------------
|
||||
// CDXUTIMEEditBox
|
||||
//-------------------------------------
|
||||
|
||||
CDXUTElement Element;
|
||||
RECT rcTexture;
|
||||
|
||||
Element.SetFont( 0, D3DCOLOR_ARGB( 255, 0, 0, 0 ), DT_LEFT | DT_TOP );
|
||||
|
||||
// Assign the style
|
||||
SetRect( &rcTexture, 14, 90, 241, 113 );
|
||||
Element.SetTexture( 0, &rcTexture );
|
||||
pDialog->SetDefaultElement( DXUT_CONTROL_IMEEDITBOX, 0, &Element );
|
||||
SetRect( &rcTexture, 8, 82, 14, 90 );
|
||||
Element.SetTexture( 0, &rcTexture );
|
||||
pDialog->SetDefaultElement( DXUT_CONTROL_IMEEDITBOX, 1, &Element );
|
||||
SetRect( &rcTexture, 14, 82, 241, 90 );
|
||||
Element.SetTexture( 0, &rcTexture );
|
||||
pDialog->SetDefaultElement( DXUT_CONTROL_IMEEDITBOX, 2, &Element );
|
||||
SetRect( &rcTexture, 241, 82, 246, 90 );
|
||||
Element.SetTexture( 0, &rcTexture );
|
||||
pDialog->SetDefaultElement( DXUT_CONTROL_IMEEDITBOX, 3, &Element );
|
||||
SetRect( &rcTexture, 8, 90, 14, 113 );
|
||||
Element.SetTexture( 0, &rcTexture );
|
||||
pDialog->SetDefaultElement( DXUT_CONTROL_IMEEDITBOX, 4, &Element );
|
||||
SetRect( &rcTexture, 241, 90, 246, 113 );
|
||||
Element.SetTexture( 0, &rcTexture );
|
||||
pDialog->SetDefaultElement( DXUT_CONTROL_IMEEDITBOX, 5, &Element );
|
||||
SetRect( &rcTexture, 8, 113, 14, 121 );
|
||||
Element.SetTexture( 0, &rcTexture );
|
||||
pDialog->SetDefaultElement( DXUT_CONTROL_IMEEDITBOX, 6, &Element );
|
||||
SetRect( &rcTexture, 14, 113, 241, 121 );
|
||||
Element.SetTexture( 0, &rcTexture );
|
||||
pDialog->SetDefaultElement( DXUT_CONTROL_IMEEDITBOX, 7, &Element );
|
||||
SetRect( &rcTexture, 241, 113, 246, 121 );
|
||||
Element.SetTexture( 0, &rcTexture );
|
||||
pDialog->SetDefaultElement( DXUT_CONTROL_IMEEDITBOX, 8, &Element );
|
||||
// Element 9 for IME text, and indicator button
|
||||
SetRect( &rcTexture, 0, 0, 136, 54 );
|
||||
Element.SetTexture( 0, &rcTexture );
|
||||
Element.SetFont( 0, D3DCOLOR_ARGB( 255, 0, 0, 0 ), DT_CENTER | DT_VCENTER );
|
||||
pDialog->SetDefaultElement( DXUT_CONTROL_IMEEDITBOX, 9, &Element );
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
CDXUTIMEEditBox::CDXUTIMEEditBox( CDXUTDialog* pDialog )
|
||||
{
|
||||
m_Type = DXUT_CONTROL_IMEEDITBOX;
|
||||
m_pDialog = pDialog;
|
||||
|
||||
m_nIndicatorWidth = 0;
|
||||
m_ReadingColor = D3DCOLOR_ARGB( 188, 255, 255, 255 );
|
||||
m_ReadingWinColor = D3DCOLOR_ARGB( 128, 0, 0, 0 );
|
||||
m_ReadingSelColor = D3DCOLOR_ARGB( 255, 255, 0, 0 );
|
||||
m_ReadingSelBkColor = D3DCOLOR_ARGB( 128, 80, 80, 80 );
|
||||
m_CandidateColor = D3DCOLOR_ARGB( 255, 200, 200, 200 );
|
||||
m_CandidateWinColor = D3DCOLOR_ARGB( 128, 0, 0, 0 );
|
||||
m_CandidateSelColor = D3DCOLOR_ARGB( 255, 255, 255, 255 );
|
||||
m_CandidateSelBkColor = D3DCOLOR_ARGB( 128, 158, 158, 158 );
|
||||
m_CompColor = D3DCOLOR_ARGB( 255, 200, 200, 255 );
|
||||
m_CompWinColor = D3DCOLOR_ARGB( 198, 0, 0, 0 );
|
||||
m_CompCaretColor = D3DCOLOR_ARGB( 255, 255, 255, 255 );
|
||||
m_CompTargetColor = D3DCOLOR_ARGB( 255, 255, 255, 255 );
|
||||
m_CompTargetBkColor = D3DCOLOR_ARGB( 255, 150, 150, 150 );
|
||||
m_CompTargetNonColor = D3DCOLOR_ARGB( 255, 255, 255, 0 );
|
||||
m_CompTargetNonBkColor = D3DCOLOR_ARGB( 255, 150, 150, 150 );
|
||||
m_IndicatorImeColor = D3DCOLOR_ARGB( 255, 255, 255, 255 );
|
||||
m_IndicatorEngColor = D3DCOLOR_ARGB( 255, 0, 0, 0 );
|
||||
m_IndicatorBkColor = D3DCOLOR_ARGB( 255, 128, 128, 128 );
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
CDXUTIMEEditBox::~CDXUTIMEEditBox()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
void CDXUTIMEEditBox::SendKey( BYTE nVirtKey )
|
||||
{
|
||||
keybd_event( nVirtKey, 0, 0, 0 );
|
||||
keybd_event( nVirtKey, 0, KEYEVENTF_KEYUP, 0 );
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
void CDXUTIMEEditBox::UpdateRects()
|
||||
{
|
||||
// Temporary adjust m_width so that CDXUTEditBox can compute
|
||||
// the correct rects for its rendering since we need to make space
|
||||
// for the indicator button
|
||||
int nWidth = m_width;
|
||||
m_width -= m_nIndicatorWidth + m_nBorder * 2; // Make room for the indicator button
|
||||
CDXUTEditBox::UpdateRects();
|
||||
m_width = nWidth; // Restore
|
||||
|
||||
// Compute the indicator button rectangle
|
||||
SetRect( &m_rcIndicator, m_rcBoundingBox.right, m_rcBoundingBox.top, m_x + m_width, m_rcBoundingBox.bottom );
|
||||
// InflateRect( &m_rcIndicator, -m_nBorder, -m_nBorder );
|
||||
m_rcBoundingBox.right = m_rcBoundingBox.left + m_width;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// GetImeId( UINT uIndex )
|
||||
// returns
|
||||
// returned value:
|
||||
// 0: In the following cases
|
||||
// - Non Chinese IME input locale
|
||||
// - Older Chinese IME
|
||||
// - Other error cases
|
||||
//
|
||||
// Othewise:
|
||||
// When uIndex is 0 (default)
|
||||
// bit 31-24: Major version
|
||||
// bit 23-16: Minor version
|
||||
// bit 15-0: Language ID
|
||||
// When uIndex is 1
|
||||
// pVerFixedInfo->dwFileVersionLS
|
||||
//
|
||||
// Use IMEID_VER and IMEID_LANG macro to extract version and language information.
|
||||
//
|
||||
|
||||
// We define the locale-invariant ID ourselves since it doesn't exist prior to WinXP
|
||||
// For more information, see the CompareString() reference.
|
||||
#define LCID_INVARIANT MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT)
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Enable/disable the entire IME system. When disabled, the default IME handling
|
||||
// kicks in.
|
||||
void CDXUTIMEEditBox::EnableImeSystem( bool bEnable )
|
||||
{
|
||||
ImeUi_EnableIme( bEnable );
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Resets the composition string.
|
||||
void CDXUTIMEEditBox::ResetCompositionString()
|
||||
{
|
||||
s_CompString.SetText( L"" );
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// This function is used only briefly in CHT IME handling,
|
||||
// so accelerator isn't processed.
|
||||
void CDXUTIMEEditBox::PumpMessage()
|
||||
{
|
||||
MSG msg;
|
||||
|
||||
while( PeekMessageW( &msg, NULL, 0, 0, PM_NOREMOVE ) )
|
||||
{
|
||||
if( !GetMessageW( &msg, NULL, 0, 0 ) )
|
||||
{
|
||||
PostQuitMessage( ( int )msg.wParam );
|
||||
return;
|
||||
}
|
||||
TranslateMessage( &msg );
|
||||
DispatchMessageA( &msg );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
void CDXUTIMEEditBox::OnFocusIn()
|
||||
{
|
||||
ImeUi_EnableIme( s_bImeFlag );
|
||||
CDXUTEditBox::OnFocusIn();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
void CDXUTIMEEditBox::OnFocusOut()
|
||||
{
|
||||
ImeUi_FinalizeString();
|
||||
ImeUi_EnableIme( false );
|
||||
CDXUTEditBox::OnFocusOut();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
bool CDXUTIMEEditBox::StaticMsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
|
||||
{
|
||||
|
||||
if( !ImeUi_IsEnabled() )
|
||||
return false;
|
||||
|
||||
#if defined(DEBUG) || defined(_DEBUG)
|
||||
m_bIMEStaticMsgProcCalled = true;
|
||||
#endif
|
||||
|
||||
switch( uMsg )
|
||||
{
|
||||
case WM_INPUTLANGCHANGE:
|
||||
DXUTTRACE( L"WM_INPUTLANGCHANGE\n" );
|
||||
{
|
||||
}
|
||||
return true;
|
||||
|
||||
case WM_IME_SETCONTEXT:
|
||||
DXUTTRACE( L"WM_IME_SETCONTEXT\n" );
|
||||
//
|
||||
// We don't want anything to display, so we have to clear this
|
||||
//
|
||||
lParam = 0;
|
||||
return false;
|
||||
|
||||
// Handle WM_IME_STARTCOMPOSITION here since
|
||||
// we do not want the default IME handler to see
|
||||
// this when our fullscreen app is running.
|
||||
case WM_IME_STARTCOMPOSITION:
|
||||
DXUTTRACE( L"WM_IME_STARTCOMPOSITION\n" );
|
||||
ResetCompositionString();
|
||||
// Since the composition string has its own caret, we don't render
|
||||
// the edit control's own caret to avoid double carets on screen.
|
||||
s_bHideCaret = true;
|
||||
return true;
|
||||
case WM_IME_ENDCOMPOSITION:
|
||||
DXUTTRACE( L"WM_IME_ENDCOMPOSITION\n" );
|
||||
s_bHideCaret = false;
|
||||
return false;
|
||||
case WM_IME_COMPOSITION:
|
||||
DXUTTRACE( L"WM_IME_COMPOSITION\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
bool CDXUTIMEEditBox::HandleMouse( UINT uMsg, POINT pt, WPARAM wParam, LPARAM lParam )
|
||||
{
|
||||
if( !m_bEnabled || !m_bVisible )
|
||||
return false;
|
||||
|
||||
switch( uMsg )
|
||||
{
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_LBUTTONDBLCLK:
|
||||
{
|
||||
DXUTFontNode* pFont = m_pDialog->GetFont( m_Elements.GetAt( 9 )->iFont );
|
||||
|
||||
// Check if this click is on top of the composition string
|
||||
int nCompStrWidth;
|
||||
s_CompString.CPtoX( s_CompString.GetTextSize(), FALSE, &nCompStrWidth );
|
||||
|
||||
if( s_ptCompString.x <= pt.x &&
|
||||
s_ptCompString.y <= pt.y &&
|
||||
s_ptCompString.x + nCompStrWidth > pt.x &&
|
||||
s_ptCompString.y + pFont->nHeight > pt.y )
|
||||
{
|
||||
int nCharBodyHit, nCharHit;
|
||||
int nTrail;
|
||||
|
||||
// Determine the character clicked on.
|
||||
s_CompString.XtoCP( pt.x - s_ptCompString.x, &nCharBodyHit, &nTrail );
|
||||
if( nTrail && nCharBodyHit < s_CompString.GetTextSize() )
|
||||
nCharHit = nCharBodyHit + 1;
|
||||
else
|
||||
nCharHit = nCharBodyHit;
|
||||
|
||||
|
||||
switch( GetPrimaryLanguage() )
|
||||
{
|
||||
case LANG_JAPANESE:
|
||||
// For Japanese, there are two cases. If s_nFirstTargetConv is
|
||||
// -1, the comp string hasn't been converted yet, and we use
|
||||
// s_nCompCaret. For any other value of s_nFirstTargetConv,
|
||||
// the string has been converted, so we use clause information.
|
||||
|
||||
if( s_nFirstTargetConv != -1 )
|
||||
{
|
||||
int nClauseClicked = 0;
|
||||
while( ( int )s_adwCompStringClause[nClauseClicked + 1] <= nCharBodyHit )
|
||||
++nClauseClicked;
|
||||
|
||||
int nClauseSelected = 0;
|
||||
while( ( int )s_adwCompStringClause[nClauseSelected + 1] <= s_nFirstTargetConv )
|
||||
++nClauseSelected;
|
||||
|
||||
BYTE nVirtKey = nClauseClicked > nClauseSelected ? VK_RIGHT : VK_LEFT;
|
||||
int nSendCount = abs( nClauseClicked - nClauseSelected );
|
||||
while( nSendCount-- > 0 )
|
||||
SendKey( nVirtKey );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Not converted case. Fall thru to Chinese case.
|
||||
|
||||
case LANG_CHINESE:
|
||||
{
|
||||
// For Chinese, use s_nCompCaret.
|
||||
BYTE nVirtKey = nCharHit > ( int )ImeUi_GetImeCursorChars() ? VK_RIGHT : VK_LEFT;
|
||||
int nSendCount = abs( nCharHit - ( int )ImeUi_GetImeCursorChars() );
|
||||
while( nSendCount-- > 0 )
|
||||
SendKey( nVirtKey );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if the click is on top of the candidate window
|
||||
if( ImeUi_IsShowCandListWindow() && PtInRect( &s_CandList.rcCandidate, pt ) )
|
||||
{
|
||||
if( ImeUi_IsVerticalCand() )
|
||||
{
|
||||
// Vertical candidate window
|
||||
|
||||
// Compute the row the click is on
|
||||
int nRow = ( pt.y - s_CandList.rcCandidate.top ) / pFont->nHeight;
|
||||
|
||||
if( nRow < ( int )ImeUi_GetCandidateCount() )
|
||||
{
|
||||
// nRow is a valid entry.
|
||||
// Now emulate keystrokes to select the candidate at this row.
|
||||
switch( GetPrimaryLanguage() )
|
||||
{
|
||||
case LANG_CHINESE:
|
||||
case LANG_KOREAN:
|
||||
// For Chinese and Korean, simply send the number keystroke.
|
||||
SendKey( ( BYTE )( '0' + nRow + 1 ) );
|
||||
break;
|
||||
|
||||
case LANG_JAPANESE:
|
||||
// For Japanese, move the selection to the target row,
|
||||
// then send Right, then send Left.
|
||||
|
||||
BYTE nVirtKey;
|
||||
if( nRow > ( int )ImeUi_GetCandidateSelection() )
|
||||
nVirtKey = VK_DOWN;
|
||||
else
|
||||
nVirtKey = VK_UP;
|
||||
int nNumToHit = abs( int( nRow - ImeUi_GetCandidateSelection() ) );
|
||||
for( int nStrike = 0; nStrike < nNumToHit; ++nStrike )
|
||||
SendKey( nVirtKey );
|
||||
|
||||
// Do this to close the candidate window without ending composition.
|
||||
SendKey( VK_RIGHT );
|
||||
SendKey( VK_LEFT );
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Horizontal candidate window
|
||||
|
||||
// Determine which the character the click has hit.
|
||||
int nCharHit;
|
||||
int nTrail;
|
||||
s_CandList.HoriCand.XtoCP( pt.x - s_CandList.rcCandidate.left, &nCharHit, &nTrail );
|
||||
|
||||
// Determine which candidate string the character belongs to.
|
||||
int nCandidate = ImeUi_GetCandidateCount() - 1;
|
||||
|
||||
int nEntryStart = 0;
|
||||
for( UINT i = 0; i < ImeUi_GetCandidateCount(); ++i )
|
||||
{
|
||||
if( nCharHit >= nEntryStart )
|
||||
{
|
||||
// Haven't found it.
|
||||
nEntryStart += lstrlenW( ImeUi_GetCandidate( i ) ) + 1; // plus space separator
|
||||
}
|
||||
else
|
||||
{
|
||||
// Found it. This entry starts at the right side of the click point,
|
||||
// so the char belongs to the previous entry.
|
||||
nCandidate = i - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Now emulate keystrokes to select the candidate entry.
|
||||
switch( GetPrimaryLanguage() )
|
||||
{
|
||||
case LANG_CHINESE:
|
||||
case LANG_KOREAN:
|
||||
// For Chinese and Korean, simply send the number keystroke.
|
||||
SendKey( ( BYTE )( '0' + nCandidate + 1 ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we didn't care for the msg, let the parent process it.
|
||||
return CDXUTEditBox::HandleMouse( uMsg, pt, wParam, lParam );
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
bool CDXUTIMEEditBox::MsgProc( UINT uMsg, WPARAM wParam, LPARAM lParam )
|
||||
{
|
||||
if( !m_bEnabled || !m_bVisible )
|
||||
return false;
|
||||
|
||||
#if defined(DEBUG) || defined(_DEBUG)
|
||||
// DXUT.cpp used to call CDXUTIMEEditBox::StaticMsgProc() so that, but now
|
||||
// this is the application's responsiblity. To do this, call
|
||||
// CDXUTDialogResourceManager::MsgProc() before calling this function.
|
||||
assert( m_bIMEStaticMsgProcCalled && L"To fix, call CDXUTDialogResourceManager::MsgProc() first" );
|
||||
#endif
|
||||
switch( uMsg )
|
||||
{
|
||||
case WM_DESTROY:
|
||||
ImeUi_Uninitialize();
|
||||
break;
|
||||
}
|
||||
|
||||
bool trappedData;
|
||||
bool* trapped = &trappedData;
|
||||
|
||||
*trapped = false;
|
||||
if( !ImeUi_IsEnabled() )
|
||||
return CDXUTEditBox::MsgProc( uMsg, wParam, lParam );
|
||||
|
||||
ImeUi_ProcessMessage( DXUTGetHWND(), uMsg, wParam, lParam, trapped );
|
||||
if( *trapped == false )
|
||||
CDXUTEditBox::MsgProc( uMsg, wParam, lParam );
|
||||
|
||||
return *trapped;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
void CDXUTIMEEditBox::RenderCandidateReadingWindow( float fElapsedTime, bool bReading )
|
||||
{
|
||||
RECT rc;
|
||||
UINT nNumEntries = bReading ? 4 : MAX_CANDLIST;
|
||||
D3DCOLOR TextColor, TextBkColor, SelTextColor, SelBkColor;
|
||||
int nX, nXFirst, nXComp;
|
||||
m_Buffer.CPtoX( m_nCaret, FALSE, &nX );
|
||||
m_Buffer.CPtoX( m_nFirstVisible, FALSE, &nXFirst );
|
||||
|
||||
if( bReading )
|
||||
{
|
||||
TextColor = m_ReadingColor;
|
||||
TextBkColor = m_ReadingWinColor;
|
||||
SelTextColor = m_ReadingSelColor;
|
||||
SelBkColor = m_ReadingSelBkColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
TextColor = m_CandidateColor;
|
||||
TextBkColor = m_CandidateWinColor;
|
||||
SelTextColor = m_CandidateSelColor;
|
||||
SelBkColor = m_CandidateSelBkColor;
|
||||
}
|
||||
|
||||
// For Japanese IME, align the window with the first target converted character.
|
||||
// For all other IMEs, align with the caret. This is because the caret
|
||||
// does not move for Japanese IME.
|
||||
if( GetLanguage() == MAKELANGID( LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL ) && !GetImeId() )
|
||||
nXComp = 0;
|
||||
else if( GetPrimaryLanguage() == LANG_JAPANESE )
|
||||
s_CompString.CPtoX( s_nFirstTargetConv, FALSE, &nXComp );
|
||||
else
|
||||
s_CompString.CPtoX( ImeUi_GetImeCursorChars(), FALSE, &nXComp );
|
||||
|
||||
// Compute the size of the candidate window
|
||||
int nWidthRequired = 0;
|
||||
int nHeightRequired = 0;
|
||||
int nSingleLineHeight = 0;
|
||||
|
||||
if( ( ImeUi_IsVerticalCand() && !bReading ) ||
|
||||
( !ImeUi_IsHorizontalReading() && bReading ) )
|
||||
{
|
||||
// Vertical window
|
||||
for( UINT i = 0; i < nNumEntries; ++i )
|
||||
{
|
||||
if( *( ImeUi_GetCandidate( i ) ) == L'\0' )
|
||||
break;
|
||||
SetRect( &rc, 0, 0, 0, 0 );
|
||||
m_pDialog->CalcTextRect( ImeUi_GetCandidate( i ), m_Elements.GetAt( 1 ), &rc );
|
||||
nWidthRequired = __max( nWidthRequired, rc.right - rc.left );
|
||||
nSingleLineHeight = __max( nSingleLineHeight, rc.bottom - rc.top );
|
||||
}
|
||||
nHeightRequired = nSingleLineHeight * nNumEntries;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Horizontal window
|
||||
SetRect( &rc, 0, 0, 0, 0 );
|
||||
if( bReading )
|
||||
m_pDialog->CalcTextRect( s_wszReadingString, m_Elements.GetAt( 1 ), &rc );
|
||||
else
|
||||
{
|
||||
|
||||
WCHAR wszCand[256] = L"";
|
||||
|
||||
s_CandList.nFirstSelected = 0;
|
||||
s_CandList.nHoriSelectedLen = 0;
|
||||
for( UINT i = 0; i < MAX_CANDLIST; ++i )
|
||||
{
|
||||
if( *ImeUi_GetCandidate( i ) == L'\0' )
|
||||
break;
|
||||
|
||||
WCHAR wszEntry[32];
|
||||
swprintf_s( wszEntry, 32, L"%s ", ImeUi_GetCandidate( i ) );
|
||||
// If this is the selected entry, mark its char position.
|
||||
if( ImeUi_GetCandidateSelection() == i )
|
||||
{
|
||||
s_CandList.nFirstSelected = lstrlen( wszCand );
|
||||
s_CandList.nHoriSelectedLen = lstrlen( wszEntry ) - 1; // Minus space
|
||||
}
|
||||
wcscat_s( wszCand, 256, wszEntry );
|
||||
}
|
||||
wszCand[lstrlen( wszCand ) - 1] = L'\0'; // Remove the last space
|
||||
s_CandList.HoriCand.SetText( wszCand );
|
||||
|
||||
m_pDialog->CalcTextRect( s_CandList.HoriCand.GetBuffer(), m_Elements.GetAt( 1 ), &rc );
|
||||
}
|
||||
nWidthRequired = rc.right - rc.left;
|
||||
nSingleLineHeight = nHeightRequired = rc.bottom - rc.top;
|
||||
}
|
||||
|
||||
// Now that we have the dimension, calculate the location for the candidate window.
|
||||
// We attempt to fit the window in this order:
|
||||
// bottom, top, right, left.
|
||||
|
||||
bool bHasPosition = false;
|
||||
|
||||
// Bottom
|
||||
SetRect( &rc, s_ptCompString.x + nXComp, s_ptCompString.y + m_rcText.bottom - m_rcText.top,
|
||||
s_ptCompString.x + nXComp + nWidthRequired, s_ptCompString.y + m_rcText.bottom - m_rcText.top +
|
||||
nHeightRequired );
|
||||
// if the right edge is cut off, move it left.
|
||||
if( rc.right > m_pDialog->GetWidth() )
|
||||
{
|
||||
rc.left -= rc.right - m_pDialog->GetWidth();
|
||||
rc.right = m_pDialog->GetWidth();
|
||||
}
|
||||
if( rc.bottom <= m_pDialog->GetHeight() )
|
||||
bHasPosition = true;
|
||||
|
||||
// Top
|
||||
if( !bHasPosition )
|
||||
{
|
||||
SetRect( &rc, s_ptCompString.x + nXComp, s_ptCompString.y - nHeightRequired,
|
||||
s_ptCompString.x + nXComp + nWidthRequired, s_ptCompString.y );
|
||||
// if the right edge is cut off, move it left.
|
||||
if( rc.right > m_pDialog->GetWidth() )
|
||||
{
|
||||
rc.left -= rc.right - m_pDialog->GetWidth();
|
||||
rc.right = m_pDialog->GetWidth();
|
||||
}
|
||||
if( rc.top >= 0 )
|
||||
bHasPosition = true;
|
||||
}
|
||||
|
||||
// Right
|
||||
if( !bHasPosition )
|
||||
{
|
||||
int nXCompTrail;
|
||||
s_CompString.CPtoX( ImeUi_GetImeCursorChars(), TRUE, &nXCompTrail );
|
||||
SetRect( &rc, s_ptCompString.x + nXCompTrail, 0,
|
||||
s_ptCompString.x + nXCompTrail + nWidthRequired, nHeightRequired );
|
||||
if( rc.right <= m_pDialog->GetWidth() )
|
||||
bHasPosition = true;
|
||||
}
|
||||
|
||||
// Left
|
||||
if( !bHasPosition )
|
||||
{
|
||||
SetRect( &rc, s_ptCompString.x + nXComp - nWidthRequired, 0,
|
||||
s_ptCompString.x + nXComp, nHeightRequired );
|
||||
if( rc.right >= 0 )
|
||||
bHasPosition = true;
|
||||
}
|
||||
|
||||
if( !bHasPosition )
|
||||
{
|
||||
// The dialog is too small for the candidate window.
|
||||
// Fall back to render at 0, 0. Some part of the window
|
||||
// will be cut off.
|
||||
rc.left = 0;
|
||||
rc.right = nWidthRequired;
|
||||
}
|
||||
|
||||
// If we are rendering the candidate window, save the position
|
||||
// so that mouse clicks are checked properly.
|
||||
if( !bReading )
|
||||
s_CandList.rcCandidate = rc;
|
||||
|
||||
// Render the elements
|
||||
m_pDialog->DrawRect( &rc, TextBkColor );
|
||||
if( ( ImeUi_IsVerticalCand() && !bReading ) ||
|
||||
( !ImeUi_IsHorizontalReading() && bReading ) )
|
||||
{
|
||||
// Vertical candidate window
|
||||
for( UINT i = 0; i < nNumEntries; ++i )
|
||||
{
|
||||
// Here we are rendering one line at a time
|
||||
rc.bottom = rc.top + nSingleLineHeight;
|
||||
// Use a different color for the selected string
|
||||
if( ImeUi_GetCandidateSelection() == i )
|
||||
{
|
||||
m_pDialog->DrawRect( &rc, SelBkColor );
|
||||
m_Elements.GetAt( 1 )->FontColor.Current = SelTextColor;
|
||||
}
|
||||
else
|
||||
m_Elements.GetAt( 1 )->FontColor.Current = TextColor;
|
||||
|
||||
m_pDialog->DrawText( ImeUi_GetCandidate( i ), m_Elements.GetAt( 1 ), &rc );
|
||||
|
||||
rc.top += nSingleLineHeight;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Horizontal candidate window
|
||||
m_Elements.GetAt( 1 )->FontColor.Current = TextColor;
|
||||
if( bReading )
|
||||
m_pDialog->DrawText( s_wszReadingString, m_Elements.GetAt( 1 ), &rc );
|
||||
else
|
||||
m_pDialog->DrawText( s_CandList.HoriCand.GetBuffer(), m_Elements.GetAt( 1 ), &rc );
|
||||
|
||||
// Render the selected entry differently
|
||||
if( !bReading )
|
||||
{
|
||||
int nXLeft, nXRight;
|
||||
s_CandList.HoriCand.CPtoX( s_CandList.nFirstSelected, FALSE, &nXLeft );
|
||||
s_CandList.HoriCand.CPtoX( s_CandList.nFirstSelected + s_CandList.nHoriSelectedLen, FALSE, &nXRight );
|
||||
|
||||
rc.right = rc.left + nXRight;
|
||||
rc.left += nXLeft;
|
||||
m_pDialog->DrawRect( &rc, SelBkColor );
|
||||
m_Elements.GetAt( 1 )->FontColor.Current = SelTextColor;
|
||||
m_pDialog->DrawText( s_CandList.HoriCand.GetBuffer() + s_CandList.nFirstSelected,
|
||||
m_Elements.GetAt( 1 ), &rc, false, s_CandList.nHoriSelectedLen );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
void CDXUTIMEEditBox::RenderComposition( float fElapsedTime )
|
||||
{
|
||||
|
||||
s_CompString.SetText( ImeUi_GetCompositionString() );
|
||||
|
||||
RECT rcCaret =
|
||||
{
|
||||
0, 0, 0, 0
|
||||
};
|
||||
int nX, nXFirst;
|
||||
m_Buffer.CPtoX( m_nCaret, FALSE, &nX );
|
||||
m_Buffer.CPtoX( m_nFirstVisible, FALSE, &nXFirst );
|
||||
CDXUTElement* pElement = m_Elements.GetAt( 1 );
|
||||
|
||||
// Get the required width
|
||||
RECT rc =
|
||||
{
|
||||
m_rcText.left + nX - nXFirst, m_rcText.top,
|
||||
m_rcText.left + nX - nXFirst, m_rcText.bottom
|
||||
};
|
||||
m_pDialog->CalcTextRect( s_CompString.GetBuffer(), pElement, &rc );
|
||||
|
||||
// If the composition string is too long to fit within
|
||||
// the text area, move it to below the current line.
|
||||
// This matches the behavior of the default IME.
|
||||
if( rc.right > m_rcText.right )
|
||||
OffsetRect( &rc, m_rcText.left - rc.left, rc.bottom - rc.top );
|
||||
|
||||
// Save the rectangle position for processing highlighted text.
|
||||
RECT rcFirst = rc;
|
||||
|
||||
// Update s_ptCompString for RenderCandidateReadingWindow().
|
||||
s_ptCompString.x = rc.left; s_ptCompString.y = rc.top;
|
||||
|
||||
|
||||
D3DCOLOR TextColor = m_CompColor;
|
||||
// Render the window and string.
|
||||
// If the string is too long, we must wrap the line.
|
||||
pElement->FontColor.Current = TextColor;
|
||||
const WCHAR* pwszComp = s_CompString.GetBuffer();
|
||||
int nCharLeft = s_CompString.GetTextSize();
|
||||
for(; ; )
|
||||
{
|
||||
// Find the last character that can be drawn on the same line.
|
||||
int nLastInLine;
|
||||
int bTrail;
|
||||
s_CompString.XtoCP( m_rcText.right - rc.left, &nLastInLine, &bTrail );
|
||||
int nNumCharToDraw = __min( nCharLeft, nLastInLine );
|
||||
m_pDialog->CalcTextRect( pwszComp, pElement, &rc, nNumCharToDraw );
|
||||
|
||||
// Draw the background
|
||||
// For Korean IME, blink the composition window background as if it
|
||||
// is a cursor.
|
||||
if( GetPrimaryLanguage() == LANG_KOREAN )
|
||||
{
|
||||
if( m_bCaretOn )
|
||||
{
|
||||
m_pDialog->DrawRect( &rc, m_CompWinColor );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not drawing composition string background. We
|
||||
// use the editbox's text color for composition
|
||||
// string text.
|
||||
TextColor = m_Elements.GetAt( 0 )->FontColor.States[DXUT_STATE_NORMAL];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Non-Korean IME. Always draw composition background.
|
||||
m_pDialog->DrawRect( &rc, m_CompWinColor );
|
||||
}
|
||||
|
||||
// Draw the text
|
||||
pElement->FontColor.Current = TextColor;
|
||||
m_pDialog->DrawText( pwszComp, pElement, &rc, false, nNumCharToDraw );
|
||||
|
||||
// Advance pointer and counter
|
||||
nCharLeft -= nNumCharToDraw;
|
||||
pwszComp += nNumCharToDraw;
|
||||
if( nCharLeft <= 0 )
|
||||
break;
|
||||
|
||||
// Advance rectangle coordinates to beginning of next line
|
||||
OffsetRect( &rc, m_rcText.left - rc.left, rc.bottom - rc.top );
|
||||
}
|
||||
|
||||
// Load the rect for the first line again.
|
||||
rc = rcFirst;
|
||||
|
||||
// Inspect each character in the comp string.
|
||||
// For target-converted and target-non-converted characters,
|
||||
// we display a different background color so they appear highlighted.
|
||||
int nCharFirst = 0;
|
||||
nXFirst = 0;
|
||||
s_nFirstTargetConv = -1;
|
||||
BYTE* pAttr;
|
||||
const WCHAR* pcComp;
|
||||
for( pcComp = s_CompString.GetBuffer(), pAttr = ImeUi_GetCompStringAttr();
|
||||
*pcComp != L'\0'; ++pcComp, ++pAttr )
|
||||
{
|
||||
D3DCOLOR bkColor;
|
||||
|
||||
// Render a different background for this character
|
||||
int nXLeft, nXRight;
|
||||
s_CompString.CPtoX( int( pcComp - s_CompString.GetBuffer() ), FALSE, &nXLeft );
|
||||
s_CompString.CPtoX( int( pcComp - s_CompString.GetBuffer() ), TRUE, &nXRight );
|
||||
|
||||
// Check if this character is off the right edge and should
|
||||
// be wrapped to the next line.
|
||||
if( nXRight - nXFirst > m_rcText.right - rc.left )
|
||||
{
|
||||
// Advance rectangle coordinates to beginning of next line
|
||||
OffsetRect( &rc, m_rcText.left - rc.left, rc.bottom - rc.top );
|
||||
|
||||
// Update the line's first character information
|
||||
nCharFirst = int( pcComp - s_CompString.GetBuffer() );
|
||||
s_CompString.CPtoX( nCharFirst, FALSE, &nXFirst );
|
||||
}
|
||||
|
||||
// If the caret is on this character, save the coordinates
|
||||
// for drawing the caret later.
|
||||
if( ImeUi_GetImeCursorChars() == ( DWORD )( pcComp - s_CompString.GetBuffer() ) )
|
||||
{
|
||||
rcCaret = rc;
|
||||
rcCaret.left += nXLeft - nXFirst - 1;
|
||||
rcCaret.right = rcCaret.left + 2;
|
||||
}
|
||||
|
||||
// Set up color based on the character attribute
|
||||
if( *pAttr == ATTR_TARGET_CONVERTED )
|
||||
{
|
||||
pElement->FontColor.Current = m_CompTargetColor;
|
||||
bkColor = m_CompTargetBkColor;
|
||||
}
|
||||
else if( *pAttr == ATTR_TARGET_NOTCONVERTED )
|
||||
{
|
||||
pElement->FontColor.Current = m_CompTargetNonColor;
|
||||
bkColor = m_CompTargetNonBkColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
RECT rcTarget =
|
||||
{
|
||||
rc.left + nXLeft - nXFirst, rc.top, rc.left + nXRight - nXFirst, rc.bottom
|
||||
};
|
||||
m_pDialog->DrawRect( &rcTarget, bkColor );
|
||||
m_pDialog->DrawText( pcComp, pElement, &rcTarget, false, 1 );
|
||||
|
||||
// Record the first target converted character's index
|
||||
if( -1 == s_nFirstTargetConv )
|
||||
s_nFirstTargetConv = int( pAttr - ImeUi_GetCompStringAttr() );
|
||||
}
|
||||
|
||||
// Render the composition caret
|
||||
if( m_bCaretOn )
|
||||
{
|
||||
// If the caret is at the very end, its position would not have
|
||||
// been computed in the above loop. We compute it here.
|
||||
if( ImeUi_GetImeCursorChars() == ( DWORD )s_CompString.GetTextSize() )
|
||||
{
|
||||
s_CompString.CPtoX( ImeUi_GetImeCursorChars(), FALSE, &nX );
|
||||
rcCaret = rc;
|
||||
rcCaret.left += nX - nXFirst - 1;
|
||||
rcCaret.right = rcCaret.left + 2;
|
||||
}
|
||||
|
||||
m_pDialog->DrawRect( &rcCaret, m_CompCaretColor );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
void CDXUTIMEEditBox::RenderIndicator( float fElapsedTime )
|
||||
{
|
||||
CDXUTElement* pElement = m_Elements.GetAt( 9 );
|
||||
pElement->TextureColor.Blend( DXUT_STATE_NORMAL, fElapsedTime );
|
||||
|
||||
m_pDialog->DrawSprite( pElement, &m_rcIndicator, DXUT_NEAR_BUTTON_DEPTH );
|
||||
RECT rc = m_rcIndicator;
|
||||
InflateRect( &rc, -m_nSpacing, -m_nSpacing );
|
||||
|
||||
pElement->FontColor.Current = m_IndicatorImeColor;
|
||||
RECT rcCalc =
|
||||
{
|
||||
0, 0, 0, 0
|
||||
};
|
||||
// If IME system is off, draw English indicator.
|
||||
WCHAR* pwszIndicator = ImeUi_IsEnabled() ? ImeUi_GetIndicatior() : L"En";
|
||||
|
||||
m_pDialog->CalcTextRect( pwszIndicator, pElement, &rcCalc );
|
||||
m_pDialog->DrawText( pwszIndicator, pElement, &rc );
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
void CDXUTIMEEditBox::Render( float fElapsedTime )
|
||||
{
|
||||
if( m_bVisible == false )
|
||||
return;
|
||||
|
||||
// If we have not computed the indicator symbol width,
|
||||
// do it.
|
||||
if( !m_nIndicatorWidth )
|
||||
{
|
||||
RECT rc =
|
||||
{
|
||||
0, 0, 0, 0
|
||||
};
|
||||
m_pDialog->CalcTextRect( L"En", m_Elements.GetAt( 9 ), &rc );
|
||||
m_nIndicatorWidth = rc.right - rc.left;
|
||||
|
||||
// Update the rectangles now that we have the indicator's width
|
||||
UpdateRects();
|
||||
}
|
||||
|
||||
// Let the parent render first (edit control)
|
||||
CDXUTEditBox::Render( fElapsedTime );
|
||||
|
||||
CDXUTElement* pElement = GetElement( 1 );
|
||||
if( pElement )
|
||||
{
|
||||
s_CompString.SetFontNode( m_pDialog->GetFont( pElement->iFont ) );
|
||||
s_CandList.HoriCand.SetFontNode( m_pDialog->GetFont( pElement->iFont ) );
|
||||
}
|
||||
|
||||
//
|
||||
// Now render the IME elements
|
||||
//
|
||||
|
||||
ImeUi_RenderUI();
|
||||
|
||||
if( m_bHasFocus )
|
||||
{
|
||||
// Render the input locale indicator
|
||||
RenderIndicator( fElapsedTime );
|
||||
|
||||
// Display the composition string.
|
||||
// This method should also update s_ptCompString
|
||||
// for RenderCandidateReadingWindow.
|
||||
RenderComposition( fElapsedTime );
|
||||
|
||||
// Display the reading/candidate window. RenderCandidateReadingWindow()
|
||||
// uses s_ptCompString to position itself. s_ptCompString must have
|
||||
// been filled in by RenderComposition().
|
||||
if( ImeUi_IsShowReadingWindow() )
|
||||
// Reading window
|
||||
RenderCandidateReadingWindow( fElapsedTime, true );
|
||||
else if( ImeUi_IsShowCandListWindow() )
|
||||
// Candidate list window
|
||||
RenderCandidateReadingWindow( fElapsedTime, false );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
void CDXUTIMEEditBox::SetImeEnableFlag( bool bFlag )
|
||||
{
|
||||
s_bImeFlag = bFlag;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
void CDXUTIMEEditBox::Initialize( HWND hWnd )
|
||||
{
|
||||
ImeUiCallback_DrawRect = NULL;
|
||||
ImeUiCallback_Malloc = malloc;
|
||||
ImeUiCallback_Free = free;
|
||||
ImeUiCallback_DrawFans = NULL;
|
||||
|
||||
ImeUi_Initialize( hWnd );
|
||||
|
||||
s_CompString.SetBufferSize( MAX_COMPSTRING_SIZE );
|
||||
ImeUi_EnableIme( true );
|
||||
}
|
||||
|
||||
|
||||
141
Demos/DX11ClothDemo/DXUT/Optional/DXUTguiIME.h
Normal file
141
Demos/DX11ClothDemo/DXUT/Optional/DXUTguiIME.h
Normal file
@@ -0,0 +1,141 @@
|
||||
//--------------------------------------------------------------------------------------
|
||||
// File: DXUTguiIME.h
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//--------------------------------------------------------------------------------------
|
||||
#pragma once
|
||||
#ifndef DXUT_IME_H
|
||||
#define DXUT_IME_H
|
||||
|
||||
#include <usp10.h>
|
||||
#include <dimm.h>
|
||||
#include <ImeUi.h>
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Forward declarations
|
||||
//--------------------------------------------------------------------------------------
|
||||
class CDXUTIMEEditBox;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// IME-enabled EditBox control
|
||||
//-----------------------------------------------------------------------------
|
||||
#define MAX_COMPSTRING_SIZE 256
|
||||
|
||||
|
||||
class CDXUTIMEEditBox : public CDXUTEditBox
|
||||
{
|
||||
public:
|
||||
|
||||
static HRESULT CreateIMEEditBox( CDXUTDialog* pDialog, int ID, LPCWSTR strText, int x, int y, int width,
|
||||
int height, bool bIsDefault=false, CDXUTIMEEditBox** ppCreated=NULL );
|
||||
|
||||
CDXUTIMEEditBox( CDXUTDialog* pDialog = NULL );
|
||||
virtual ~CDXUTIMEEditBox();
|
||||
|
||||
static void InitDefaultElements( CDXUTDialog* pDialog );
|
||||
|
||||
static void WINAPI Initialize( HWND hWnd );
|
||||
static void WINAPI Uninitialize();
|
||||
|
||||
static HRESULT WINAPI StaticOnCreateDevice();
|
||||
static bool WINAPI StaticMsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
|
||||
|
||||
static void WINAPI SetImeEnableFlag( bool bFlag );
|
||||
|
||||
virtual void Render( float fElapsedTime );
|
||||
virtual bool MsgProc( UINT uMsg, WPARAM wParam, LPARAM lParam );
|
||||
virtual bool HandleMouse( UINT uMsg, POINT pt, WPARAM wParam, LPARAM lParam );
|
||||
virtual void UpdateRects();
|
||||
virtual void OnFocusIn();
|
||||
virtual void OnFocusOut();
|
||||
|
||||
void PumpMessage();
|
||||
|
||||
virtual void RenderCandidateReadingWindow( float fElapsedTime, bool bReading );
|
||||
virtual void RenderComposition( float fElapsedTime );
|
||||
virtual void RenderIndicator( float fElapsedTime );
|
||||
|
||||
protected:
|
||||
static void WINAPI EnableImeSystem( bool bEnable );
|
||||
|
||||
static WORD WINAPI GetLanguage()
|
||||
{
|
||||
return ImeUi_GetLanguage();
|
||||
}
|
||||
static WORD WINAPI GetPrimaryLanguage()
|
||||
{
|
||||
return ImeUi_GetPrimaryLanguage();
|
||||
}
|
||||
static void WINAPI SendKey( BYTE nVirtKey );
|
||||
static DWORD WINAPI GetImeId( UINT uIndex = 0 )
|
||||
{
|
||||
return ImeUi_GetImeId( uIndex );
|
||||
};
|
||||
static void WINAPI CheckInputLocale();
|
||||
static void WINAPI CheckToggleState();
|
||||
static void WINAPI SetupImeApi();
|
||||
static void WINAPI ResetCompositionString();
|
||||
|
||||
|
||||
static void SetupImeUiCallback();
|
||||
|
||||
protected:
|
||||
enum
|
||||
{
|
||||
INDICATOR_NON_IME,
|
||||
INDICATOR_CHS,
|
||||
INDICATOR_CHT,
|
||||
INDICATOR_KOREAN,
|
||||
INDICATOR_JAPANESE
|
||||
};
|
||||
|
||||
struct CCandList
|
||||
{
|
||||
CUniBuffer HoriCand; // Candidate list string (for horizontal candidate window)
|
||||
int nFirstSelected; // First character position of the selected string in HoriCand
|
||||
int nHoriSelectedLen; // Length of the selected string in HoriCand
|
||||
RECT rcCandidate; // Candidate rectangle computed and filled each time before rendered
|
||||
};
|
||||
|
||||
static POINT s_ptCompString; // Composition string position. Updated every frame.
|
||||
static int s_nFirstTargetConv; // Index of the first target converted char in comp string. If none, -1.
|
||||
static CUniBuffer s_CompString; // Buffer to hold the composition string (we fix its length)
|
||||
static DWORD s_adwCompStringClause[MAX_COMPSTRING_SIZE];
|
||||
static CCandList s_CandList; // Data relevant to the candidate list
|
||||
static WCHAR s_wszReadingString[32];// Used only with horizontal reading window (why?)
|
||||
static bool s_bImeFlag; // Is ime enabled
|
||||
|
||||
// Color of various IME elements
|
||||
D3DCOLOR m_ReadingColor; // Reading string color
|
||||
D3DCOLOR m_ReadingWinColor; // Reading window color
|
||||
D3DCOLOR m_ReadingSelColor; // Selected character in reading string
|
||||
D3DCOLOR m_ReadingSelBkColor; // Background color for selected char in reading str
|
||||
D3DCOLOR m_CandidateColor; // Candidate string color
|
||||
D3DCOLOR m_CandidateWinColor; // Candidate window color
|
||||
D3DCOLOR m_CandidateSelColor; // Selected candidate string color
|
||||
D3DCOLOR m_CandidateSelBkColor; // Selected candidate background color
|
||||
D3DCOLOR m_CompColor; // Composition string color
|
||||
D3DCOLOR m_CompWinColor; // Composition string window color
|
||||
D3DCOLOR m_CompCaretColor; // Composition string caret color
|
||||
D3DCOLOR m_CompTargetColor; // Composition string target converted color
|
||||
D3DCOLOR m_CompTargetBkColor; // Composition string target converted background
|
||||
D3DCOLOR m_CompTargetNonColor; // Composition string target non-converted color
|
||||
D3DCOLOR m_CompTargetNonBkColor;// Composition string target non-converted background
|
||||
D3DCOLOR m_IndicatorImeColor; // Indicator text color for IME
|
||||
D3DCOLOR m_IndicatorEngColor; // Indicator text color for English
|
||||
D3DCOLOR m_IndicatorBkColor; // Indicator text background color
|
||||
|
||||
// Edit-control-specific data
|
||||
int m_nIndicatorWidth; // Width of the indicator symbol
|
||||
RECT m_rcIndicator; // Rectangle for drawing the indicator button
|
||||
|
||||
#if defined(DEBUG) || defined(_DEBUG)
|
||||
static bool m_bIMEStaticMsgProcCalled;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // DXUT_IME_H
|
||||
8338
Demos/DX11ClothDemo/DXUT/Optional/DXUTres.cpp
Normal file
8338
Demos/DX11ClothDemo/DXUT/Optional/DXUTres.cpp
Normal file
File diff suppressed because it is too large
Load Diff
18
Demos/DX11ClothDemo/DXUT/Optional/DXUTres.h
Normal file
18
Demos/DX11ClothDemo/DXUT/Optional/DXUTres.h
Normal file
@@ -0,0 +1,18 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// File: dxutres.h
|
||||
//
|
||||
// Functions to create DXUT media from arrays in memory
|
||||
//
|
||||
// Copyright (c) Microsoft Corp. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
#pragma once
|
||||
#ifndef DXUT_RES_H
|
||||
#define DXUT_RES_H
|
||||
|
||||
HRESULT WINAPI DXUTCreateGUITextureFromInternalArray9( LPDIRECT3DDEVICE9 pd3dDevice, IDirect3DTexture9** ppTexture,
|
||||
D3DXIMAGE_INFO* pInfo );
|
||||
HRESULT WINAPI DXUTCreateGUITextureFromInternalArray11( ID3D11Device* pd3dDevice, ID3D11Texture2D** ppTexture,
|
||||
D3DX11_IMAGE_INFO* pInfo );
|
||||
HRESULT WINAPI DXUTCreateArrowMeshFromInternalArray( LPDIRECT3DDEVICE9 pd3dDevice, ID3DXMesh** ppMesh );
|
||||
|
||||
#endif
|
||||
2853
Demos/DX11ClothDemo/DXUT/Optional/DXUTsettingsdlg.cpp
Normal file
2853
Demos/DX11ClothDemo/DXUT/Optional/DXUTsettingsdlg.cpp
Normal file
File diff suppressed because it is too large
Load Diff
248
Demos/DX11ClothDemo/DXUT/Optional/DXUTsettingsdlg.h
Normal file
248
Demos/DX11ClothDemo/DXUT/Optional/DXUTsettingsdlg.h
Normal file
@@ -0,0 +1,248 @@
|
||||
//--------------------------------------------------------------------------------------
|
||||
// File: DXUTSettingsDlg.cpp
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved
|
||||
//--------------------------------------------------------------------------------------
|
||||
#pragma once
|
||||
#ifndef DXUT_SETTINGS_H
|
||||
#define DXUT_SETTINGS_H
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Header Includes
|
||||
//--------------------------------------------------------------------------------------
|
||||
#include "DXUTgui.h"
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Control IDs
|
||||
//--------------------------------------------------------------------------------------
|
||||
#define DXUTSETTINGSDLG_STATIC -1
|
||||
#define DXUTSETTINGSDLG_OK 1
|
||||
#define DXUTSETTINGSDLG_CANCEL 2
|
||||
#define DXUTSETTINGSDLG_ADAPTER 3
|
||||
#define DXUTSETTINGSDLG_DEVICE_TYPE 4
|
||||
#define DXUTSETTINGSDLG_WINDOWED 5
|
||||
#define DXUTSETTINGSDLG_FULLSCREEN 6
|
||||
#define DXUTSETTINGSDLG_ADAPTER_FORMAT 7
|
||||
#define DXUTSETTINGSDLG_ADAPTER_FORMAT_LABEL 8
|
||||
#define DXUTSETTINGSDLG_RESOLUTION 9
|
||||
#define DXUTSETTINGSDLG_RESOLUTION_LABEL 10
|
||||
#define DXUTSETTINGSDLG_REFRESH_RATE 11
|
||||
#define DXUTSETTINGSDLG_REFRESH_RATE_LABEL 12
|
||||
#define DXUTSETTINGSDLG_BACK_BUFFER_FORMAT 13
|
||||
#define DXUTSETTINGSDLG_BACK_BUFFER_FORMAT_LABEL 14
|
||||
#define DXUTSETTINGSDLG_DEPTH_STENCIL 15
|
||||
#define DXUTSETTINGSDLG_DEPTH_STENCIL_LABEL 16
|
||||
#define DXUTSETTINGSDLG_MULTISAMPLE_TYPE 17
|
||||
#define DXUTSETTINGSDLG_MULTISAMPLE_TYPE_LABEL 18
|
||||
#define DXUTSETTINGSDLG_MULTISAMPLE_QUALITY 19
|
||||
#define DXUTSETTINGSDLG_MULTISAMPLE_QUALITY_LABEL 20
|
||||
#define DXUTSETTINGSDLG_VERTEX_PROCESSING 21
|
||||
#define DXUTSETTINGSDLG_VERTEX_PROCESSING_LABEL 22
|
||||
#define DXUTSETTINGSDLG_PRESENT_INTERVAL 23
|
||||
#define DXUTSETTINGSDLG_PRESENT_INTERVAL_LABEL 24
|
||||
#define DXUTSETTINGSDLG_DEVICECLIP 25
|
||||
#define DXUTSETTINGSDLG_RESOLUTION_SHOW_ALL 26
|
||||
#define DXUTSETTINGSDLG_API_VERSION 27
|
||||
#define DXUTSETTINGSDLG_D3D11_ADAPTER_OUTPUT 28
|
||||
#define DXUTSETTINGSDLG_D3D11_ADAPTER_OUTPUT_LABEL 29
|
||||
#define DXUTSETTINGSDLG_D3D11_RESOLUTION 30
|
||||
#define DXUTSETTINGSDLG_D3D11_RESOLUTION_LABEL 31
|
||||
#define DXUTSETTINGSDLG_D3D11_REFRESH_RATE 32
|
||||
#define DXUTSETTINGSDLG_D3D11_REFRESH_RATE_LABEL 33
|
||||
#define DXUTSETTINGSDLG_D3D11_BACK_BUFFER_FORMAT 34
|
||||
#define DXUTSETTINGSDLG_D3D11_BACK_BUFFER_FORMAT_LABEL 35
|
||||
#define DXUTSETTINGSDLG_D3D11_MULTISAMPLE_COUNT 36
|
||||
#define DXUTSETTINGSDLG_D3D11_MULTISAMPLE_COUNT_LABEL 37
|
||||
#define DXUTSETTINGSDLG_D3D11_MULTISAMPLE_QUALITY 38
|
||||
#define DXUTSETTINGSDLG_D3D11_MULTISAMPLE_QUALITY_LABEL 39
|
||||
#define DXUTSETTINGSDLG_D3D11_PRESENT_INTERVAL 40
|
||||
#define DXUTSETTINGSDLG_D3D11_PRESENT_INTERVAL_LABEL 41
|
||||
#define DXUTSETTINGSDLG_D3D11_DEBUG_DEVICE 42
|
||||
#define DXUTSETTINGSDLG_D3D11_FEATURE_LEVEL 43
|
||||
#define DXUTSETTINGSDLG_D3D11_FEATURE_LEVEL_LABEL 44
|
||||
|
||||
#define DXUTSETTINGSDLG_MODE_CHANGE_ACCEPT 58
|
||||
#define DXUTSETTINGSDLG_MODE_CHANGE_REVERT 59
|
||||
#define DXUTSETTINGSDLG_STATIC_MODE_CHANGE_TIMEOUT 60
|
||||
#define DXUTSETTINGSDLG_WINDOWED_GROUP 0x0100
|
||||
|
||||
#define TOTAL_FEATURE_LEVLES 6
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Dialog for selection of device settings
|
||||
// Use DXUTGetD3DSettingsDialog() to access global instance
|
||||
// To control the contents of the dialog, use the CD3D9Enumeration class.
|
||||
//--------------------------------------------------------------------------------------
|
||||
class CD3DSettingsDlg
|
||||
{
|
||||
public:
|
||||
CD3DSettingsDlg();
|
||||
~CD3DSettingsDlg();
|
||||
|
||||
void Init( CDXUTDialogResourceManager* pManager );
|
||||
void Init( CDXUTDialogResourceManager* pManager, LPCWSTR szControlTextureFileName );
|
||||
void Init( CDXUTDialogResourceManager* pManager, LPCWSTR pszControlTextureResourcename,
|
||||
HMODULE hModule );
|
||||
|
||||
HRESULT Refresh();
|
||||
void OnRender( float fElapsedTime );
|
||||
void OnRender9( float fElapsedTime );
|
||||
void OnRender10( float fElapsedTime );
|
||||
void OnRender11( float fElapsedTime );
|
||||
|
||||
HRESULT OnD3D9CreateDevice( IDirect3DDevice9* pd3dDevice );
|
||||
HRESULT OnD3D9ResetDevice();
|
||||
void OnD3D9LostDevice();
|
||||
void OnD3D9DestroyDevice();
|
||||
|
||||
HRESULT OnD3D11CreateDevice( ID3D11Device* pd3dDevice );
|
||||
HRESULT OnD3D11ResizedSwapChain( ID3D11Device* pd3dDevice,
|
||||
const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc );
|
||||
void OnD3D11DestroyDevice();
|
||||
|
||||
CDXUTDialog* GetDialogControl()
|
||||
{
|
||||
return &m_Dialog;
|
||||
}
|
||||
bool IsActive()
|
||||
{
|
||||
return m_bActive;
|
||||
}
|
||||
void SetActive( bool bActive )
|
||||
{
|
||||
m_bActive = bActive; if( bActive ) Refresh();
|
||||
}
|
||||
void ShowControlSet( DXUTDeviceVersion ver );
|
||||
|
||||
LRESULT MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
|
||||
|
||||
protected:
|
||||
friend CD3DSettingsDlg* WINAPI DXUTGetD3DSettingsDialog();
|
||||
|
||||
void CreateControls();
|
||||
HRESULT SetDeviceSettingsFromUI();
|
||||
void SetSelectedD3D11RefreshRate( DXGI_RATIONAL RefreshRate );
|
||||
HRESULT UpdateD3D11Resolutions();
|
||||
|
||||
void OnEvent( UINT nEvent, int nControlID, CDXUTControl* pControl );
|
||||
static void WINAPI StaticOnEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserData );
|
||||
static void WINAPI StaticOnModeChangeTimer( UINT nIDEvent, void* pUserContext );
|
||||
|
||||
CD3D9EnumAdapterInfo* GetCurrentAdapterInfo();
|
||||
CD3D9EnumDeviceInfo* GetCurrentDeviceInfo();
|
||||
CD3D9EnumDeviceSettingsCombo* GetCurrentDeviceSettingsCombo();
|
||||
|
||||
CD3D11EnumAdapterInfo* GetCurrentD3D11AdapterInfo();
|
||||
CD3D11EnumDeviceInfo* GetCurrentD3D11DeviceInfo();
|
||||
CD3D11EnumOutputInfo* GetCurrentD3D11OutputInfo();
|
||||
CD3D11EnumDeviceSettingsCombo* GetCurrentD3D11DeviceSettingsCombo();
|
||||
|
||||
void AddAPIVersion( DXUTDeviceVersion version );
|
||||
DXUTDeviceVersion GetSelectedAPIVersion();
|
||||
|
||||
void AddAdapter( const WCHAR* strDescription, UINT iAdapter );
|
||||
UINT GetSelectedAdapter();
|
||||
|
||||
void AddDeviceType( D3DDEVTYPE devType );
|
||||
D3DDEVTYPE GetSelectedDeviceType();
|
||||
|
||||
void SetWindowed( bool bWindowed );
|
||||
bool IsWindowed();
|
||||
|
||||
void AddAdapterFormat( D3DFORMAT format );
|
||||
D3DFORMAT GetSelectedAdapterFormat();
|
||||
|
||||
void AddResolution( DWORD dwWidth, DWORD dwHeight );
|
||||
void GetSelectedResolution( DWORD* pdwWidth, DWORD* pdwHeight );
|
||||
|
||||
void AddRefreshRate( DWORD dwRate );
|
||||
DWORD GetSelectedRefreshRate();
|
||||
|
||||
void AddBackBufferFormat( D3DFORMAT format );
|
||||
D3DFORMAT GetSelectedBackBufferFormat();
|
||||
|
||||
void AddDepthStencilBufferFormat( D3DFORMAT format );
|
||||
D3DFORMAT GetSelectedDepthStencilBufferFormat();
|
||||
|
||||
void AddMultisampleType( D3DMULTISAMPLE_TYPE type );
|
||||
D3DMULTISAMPLE_TYPE GetSelectedMultisampleType();
|
||||
|
||||
void AddMultisampleQuality( DWORD dwQuality );
|
||||
DWORD GetSelectedMultisampleQuality();
|
||||
|
||||
void AddVertexProcessingType( DWORD dwType );
|
||||
DWORD GetSelectedVertexProcessingType();
|
||||
|
||||
DWORD GetSelectedPresentInterval();
|
||||
|
||||
void SetDeviceClip( bool bDeviceClip );
|
||||
bool IsDeviceClip();
|
||||
|
||||
// D3D11
|
||||
void AddD3D11DeviceType( D3D_DRIVER_TYPE devType );
|
||||
D3D_DRIVER_TYPE GetSelectedD3D11DeviceType();
|
||||
|
||||
void AddD3D11AdapterOutput( const WCHAR* strName, UINT nOutput );
|
||||
UINT GetSelectedD3D11AdapterOutput();
|
||||
|
||||
void AddD3D11Resolution( DWORD dwWidth, DWORD dwHeight );
|
||||
void GetSelectedD3D11Resolution( DWORD* pdwWidth, DWORD* pdwHeight );
|
||||
|
||||
void AddD3D11FeatureLevel(D3D_FEATURE_LEVEL);
|
||||
D3D_FEATURE_LEVEL GetSelectedFeatureLevel();
|
||||
|
||||
void AddD3D11RefreshRate( DXGI_RATIONAL RefreshRate );
|
||||
DXGI_RATIONAL GetSelectedD3D11RefreshRate();
|
||||
|
||||
void AddD3D11BackBufferFormat( DXGI_FORMAT format );
|
||||
DXGI_FORMAT GetSelectedD3D11BackBufferFormat();
|
||||
|
||||
void AddD3D11MultisampleCount( UINT count );
|
||||
UINT GetSelectedD3D11MultisampleCount();
|
||||
|
||||
void AddD3D11MultisampleQuality( UINT Quality );
|
||||
UINT GetSelectedD3D11MultisampleQuality();
|
||||
|
||||
DWORD GetSelectedD3D11PresentInterval();
|
||||
bool GetSelectedDebugDeviceValue();
|
||||
|
||||
|
||||
|
||||
HRESULT OnD3D11ResolutionChanged ();
|
||||
HRESULT OnAPIVersionChanged( bool bRefresh=false );
|
||||
HRESULT OnFeatureLevelChanged();
|
||||
HRESULT OnAdapterChanged();
|
||||
HRESULT OnDeviceTypeChanged();
|
||||
HRESULT OnWindowedFullScreenChanged();
|
||||
HRESULT OnAdapterOutputChanged();
|
||||
HRESULT OnAdapterFormatChanged();
|
||||
HRESULT OnResolutionChanged();
|
||||
HRESULT OnRefreshRateChanged();
|
||||
HRESULT OnBackBufferFormatChanged();
|
||||
HRESULT OnDepthStencilBufferFormatChanged();
|
||||
HRESULT OnMultisampleTypeChanged();
|
||||
HRESULT OnMultisampleQualityChanged();
|
||||
HRESULT OnVertexProcessingChanged();
|
||||
HRESULT OnPresentIntervalChanged();
|
||||
HRESULT OnDebugDeviceChanged();
|
||||
HRESULT OnDeviceClipChanged();
|
||||
|
||||
void UpdateModeChangeTimeoutText( int nSecRemaining );
|
||||
|
||||
IDirect3DStateBlock9* m_pStateBlock;
|
||||
CDXUTDialog* m_pActiveDialog;
|
||||
CDXUTDialog m_Dialog;
|
||||
CDXUTDialog m_RevertModeDialog;
|
||||
int m_nRevertModeTimeout;
|
||||
UINT m_nIDEvent;
|
||||
bool m_bActive;
|
||||
|
||||
D3D_FEATURE_LEVEL m_Levels[TOTAL_FEATURE_LEVLES];
|
||||
|
||||
};
|
||||
|
||||
|
||||
CD3DSettingsDlg* WINAPI DXUTGetD3DSettingsDialog();
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
3662
Demos/DX11ClothDemo/DXUT/Optional/ImeUi.cpp
Normal file
3662
Demos/DX11ClothDemo/DXUT/Optional/ImeUi.cpp
Normal file
File diff suppressed because it is too large
Load Diff
124
Demos/DX11ClothDemo/DXUT/Optional/ImeUi.h
Normal file
124
Demos/DX11ClothDemo/DXUT/Optional/ImeUi.h
Normal file
@@ -0,0 +1,124 @@
|
||||
//--------------------------------------------------------------------------------------
|
||||
// File: ImeUi.h
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//--------------------------------------------------------------------------------------
|
||||
#ifndef _IMEUI_H_
|
||||
#define _IMEUI_H_
|
||||
#if _WIN32_WINNT < 0x0400
|
||||
#error IMEUI requires _WIN32_WINNT to be 0x0400 or higher. Please add "_WIN32_WINNT=0x0400" to your project's preprocessor setting.
|
||||
#endif
|
||||
#include <windows.h>
|
||||
|
||||
class CImeUiFont_Base
|
||||
{
|
||||
public:
|
||||
virtual void SetHeight( UINT uHeight )
|
||||
{
|
||||
uHeight;
|
||||
}; // for backward compatibility
|
||||
virtual void SetColor( DWORD color ) = 0;
|
||||
virtual void SetPosition( int x, int y ) = 0;
|
||||
virtual void GetTextExtent( LPCTSTR szText, DWORD* puWidth, DWORD* puHeight ) = 0;
|
||||
virtual void DrawText( LPCTSTR pszText ) = 0;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// symbol (Henkan-kyu)
|
||||
DWORD symbolColor;
|
||||
DWORD symbolColorOff;
|
||||
DWORD symbolColorText;
|
||||
BYTE symbolHeight;
|
||||
BYTE symbolTranslucence;
|
||||
BYTE symbolPlacement;
|
||||
CImeUiFont_Base* symbolFont;
|
||||
|
||||
// candidate list
|
||||
DWORD candColorBase;
|
||||
DWORD candColorBorder;
|
||||
DWORD candColorText;
|
||||
|
||||
// composition string
|
||||
DWORD compColorInput;
|
||||
DWORD compColorTargetConv;
|
||||
DWORD compColorConverted;
|
||||
DWORD compColorTargetNotConv;
|
||||
DWORD compColorInputErr;
|
||||
BYTE compTranslucence;
|
||||
DWORD compColorText;
|
||||
|
||||
// caret
|
||||
BYTE caretWidth;
|
||||
BYTE caretYMargin;
|
||||
} IMEUI_APPEARANCE;
|
||||
|
||||
typedef struct // D3DTLVERTEX compatible
|
||||
{
|
||||
float sx;
|
||||
float sy;
|
||||
float sz;
|
||||
float rhw;
|
||||
DWORD color;
|
||||
DWORD specular;
|
||||
float tu;
|
||||
float tv;
|
||||
} IMEUI_VERTEX;
|
||||
|
||||
// IME States
|
||||
#define IMEUI_STATE_OFF 0
|
||||
#define IMEUI_STATE_ON 1
|
||||
#define IMEUI_STATE_ENGLISH 2
|
||||
|
||||
// IME const
|
||||
#define MAX_CANDLIST 10
|
||||
|
||||
// IME Flags
|
||||
#define IMEUI_FLAG_SUPPORT_CARET 0x00000001
|
||||
|
||||
bool ImeUi_Initialize( HWND hwnd, bool bDisable = false );
|
||||
void ImeUi_Uninitialize();
|
||||
void ImeUi_SetAppearance( const IMEUI_APPEARANCE* pia );
|
||||
void ImeUi_GetAppearance( IMEUI_APPEARANCE* pia );
|
||||
bool ImeUi_IgnoreHotKey( const MSG* pmsg );
|
||||
LPARAM ImeUi_ProcessMessage( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM& lParam, bool* trapped );
|
||||
void ImeUi_SetScreenDimension( UINT width, UINT height );
|
||||
void ImeUi_RenderUI( bool bDrawCompAttr = true, bool bDrawOtherUi = true );
|
||||
void ImeUi_SetCaretPosition( UINT x, UINT y );
|
||||
void ImeUi_SetCompStringAppearance( CImeUiFont_Base* pFont, DWORD color, const RECT* prc );
|
||||
bool ImeUi_GetCaretStatus();
|
||||
void ImeUi_SetInsertMode( bool bInsert );
|
||||
void ImeUi_SetState( DWORD dwState );
|
||||
DWORD ImeUi_GetState();
|
||||
void ImeUi_EnableIme( bool bEnable );
|
||||
bool ImeUi_IsEnabled( void );
|
||||
void ImeUi_FinalizeString( bool bSend = false );
|
||||
void ImeUi_ToggleLanguageBar( BOOL bRestore );
|
||||
bool ImeUi_IsSendingKeyMessage();
|
||||
void ImeUi_SetWindow( HWND hwnd );
|
||||
UINT ImeUi_GetInputCodePage();
|
||||
DWORD ImeUi_GetFlags();
|
||||
void ImeUi_SetFlags( DWORD dwFlags, bool bSet );
|
||||
|
||||
WORD ImeUi_GetPrimaryLanguage();
|
||||
DWORD ImeUi_GetImeId( UINT uIndex );
|
||||
WORD ImeUi_GetLanguage();
|
||||
LPTSTR ImeUi_GetIndicatior();
|
||||
bool ImeUi_IsShowReadingWindow();
|
||||
bool ImeUi_IsShowCandListWindow();
|
||||
bool ImeUi_IsVerticalCand();
|
||||
bool ImeUi_IsHorizontalReading();
|
||||
TCHAR* ImeUi_GetCandidate( UINT idx );
|
||||
TCHAR* ImeUi_GetCompositionString();
|
||||
DWORD ImeUi_GetCandidateSelection();
|
||||
DWORD ImeUi_GetCandidateCount();
|
||||
BYTE* ImeUi_GetCompStringAttr();
|
||||
DWORD ImeUi_GetImeCursorChars();
|
||||
|
||||
extern void ( CALLBACK*ImeUiCallback_DrawRect )( int x1, int y1, int x2, int y2, DWORD color );
|
||||
extern void* ( __cdecl*ImeUiCallback_Malloc )( size_t bytes );
|
||||
extern void ( __cdecl*ImeUiCallback_Free )( void* ptr );
|
||||
extern void ( CALLBACK*ImeUiCallback_DrawFans )( const IMEUI_VERTEX* paVertex, UINT uNum );
|
||||
extern void ( CALLBACK*ImeUiCallback_OnChar )( WCHAR wc );
|
||||
|
||||
#endif //_IMEUI_H_
|
||||
2348
Demos/DX11ClothDemo/DXUT/Optional/SDKmesh.cpp
Normal file
2348
Demos/DX11ClothDemo/DXUT/Optional/SDKmesh.cpp
Normal file
File diff suppressed because it is too large
Load Diff
589
Demos/DX11ClothDemo/DXUT/Optional/SDKmesh.h
Normal file
589
Demos/DX11ClothDemo/DXUT/Optional/SDKmesh.h
Normal file
@@ -0,0 +1,589 @@
|
||||
//--------------------------------------------------------------------------------------
|
||||
// File: SDKMesh.h
|
||||
//
|
||||
// Disclaimer:
|
||||
// The SDK Mesh format (.sdkmesh) is not a recommended file format for shipping titles.
|
||||
// It was designed to meet the specific needs of the SDK samples. Any real-world
|
||||
// applications should avoid this file format in favor of a destination format that
|
||||
// meets the specific needs of the application.
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//--------------------------------------------------------------------------------------
|
||||
#pragma once
|
||||
#ifndef _SDKMESH_
|
||||
#define _SDKMESH_
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Hard Defines for the various structures
|
||||
//--------------------------------------------------------------------------------------
|
||||
#define SDKMESH_FILE_VERSION 101
|
||||
#define MAX_VERTEX_ELEMENTS 32
|
||||
#define MAX_VERTEX_STREAMS 16
|
||||
#define MAX_FRAME_NAME 100
|
||||
#define MAX_MESH_NAME 100
|
||||
#define MAX_SUBSET_NAME 100
|
||||
#define MAX_MATERIAL_NAME 100
|
||||
#define MAX_TEXTURE_NAME MAX_PATH
|
||||
#define MAX_MATERIAL_PATH MAX_PATH
|
||||
#define INVALID_FRAME ((UINT)-1)
|
||||
#define INVALID_MESH ((UINT)-1)
|
||||
#define INVALID_MATERIAL ((UINT)-1)
|
||||
#define INVALID_SUBSET ((UINT)-1)
|
||||
#define INVALID_ANIMATION_DATA ((UINT)-1)
|
||||
#define INVALID_SAMPLER_SLOT ((UINT)-1)
|
||||
#define ERROR_RESOURCE_VALUE 1
|
||||
|
||||
template<typename TYPE> BOOL IsErrorResource( TYPE data )
|
||||
{
|
||||
if( ( TYPE )ERROR_RESOURCE_VALUE == data )
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Enumerated Types. These will have mirrors in both D3D9 and D3D11
|
||||
//--------------------------------------------------------------------------------------
|
||||
enum SDKMESH_PRIMITIVE_TYPE
|
||||
{
|
||||
PT_TRIANGLE_LIST = 0,
|
||||
PT_TRIANGLE_STRIP,
|
||||
PT_LINE_LIST,
|
||||
PT_LINE_STRIP,
|
||||
PT_POINT_LIST,
|
||||
PT_TRIANGLE_LIST_ADJ,
|
||||
PT_TRIANGLE_STRIP_ADJ,
|
||||
PT_LINE_LIST_ADJ,
|
||||
PT_LINE_STRIP_ADJ,
|
||||
PT_QUAD_PATCH_LIST,
|
||||
PT_TRIANGLE_PATCH_LIST,
|
||||
};
|
||||
|
||||
enum SDKMESH_INDEX_TYPE
|
||||
{
|
||||
IT_16BIT = 0,
|
||||
IT_32BIT,
|
||||
};
|
||||
|
||||
enum FRAME_TRANSFORM_TYPE
|
||||
{
|
||||
FTT_RELATIVE = 0,
|
||||
FTT_ABSOLUTE, //This is not currently used but is here to support absolute transformations in the future
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Structures. Unions with pointers are forced to 64bit.
|
||||
//--------------------------------------------------------------------------------------
|
||||
struct SDKMESH_HEADER
|
||||
{
|
||||
//Basic Info and sizes
|
||||
UINT Version;
|
||||
BYTE IsBigEndian;
|
||||
UINT64 HeaderSize;
|
||||
UINT64 NonBufferDataSize;
|
||||
UINT64 BufferDataSize;
|
||||
|
||||
//Stats
|
||||
UINT NumVertexBuffers;
|
||||
UINT NumIndexBuffers;
|
||||
UINT NumMeshes;
|
||||
UINT NumTotalSubsets;
|
||||
UINT NumFrames;
|
||||
UINT NumMaterials;
|
||||
|
||||
//Offsets to Data
|
||||
UINT64 VertexStreamHeadersOffset;
|
||||
UINT64 IndexStreamHeadersOffset;
|
||||
UINT64 MeshDataOffset;
|
||||
UINT64 SubsetDataOffset;
|
||||
UINT64 FrameDataOffset;
|
||||
UINT64 MaterialDataOffset;
|
||||
};
|
||||
|
||||
struct SDKMESH_VERTEX_BUFFER_HEADER
|
||||
{
|
||||
UINT64 NumVertices;
|
||||
UINT64 SizeBytes;
|
||||
UINT64 StrideBytes;
|
||||
D3DVERTEXELEMENT9 Decl[MAX_VERTEX_ELEMENTS];
|
||||
union
|
||||
{
|
||||
UINT64 DataOffset; //(This also forces the union to 64bits)
|
||||
IDirect3DVertexBuffer9* pVB9;
|
||||
ID3D11Buffer* pVB11;
|
||||
};
|
||||
};
|
||||
|
||||
struct SDKMESH_INDEX_BUFFER_HEADER
|
||||
{
|
||||
UINT64 NumIndices;
|
||||
UINT64 SizeBytes;
|
||||
UINT IndexType;
|
||||
union
|
||||
{
|
||||
UINT64 DataOffset; //(This also forces the union to 64bits)
|
||||
IDirect3DIndexBuffer9* pIB9;
|
||||
ID3D11Buffer* pIB11;
|
||||
};
|
||||
};
|
||||
|
||||
struct SDKMESH_MESH
|
||||
{
|
||||
char Name[MAX_MESH_NAME];
|
||||
BYTE NumVertexBuffers;
|
||||
UINT VertexBuffers[MAX_VERTEX_STREAMS];
|
||||
UINT IndexBuffer;
|
||||
UINT NumSubsets;
|
||||
UINT NumFrameInfluences; //aka bones
|
||||
|
||||
D3DXVECTOR3 BoundingBoxCenter;
|
||||
D3DXVECTOR3 BoundingBoxExtents;
|
||||
|
||||
union
|
||||
{
|
||||
UINT64 SubsetOffset; //Offset to list of subsets (This also forces the union to 64bits)
|
||||
UINT* pSubsets; //Pointer to list of subsets
|
||||
};
|
||||
union
|
||||
{
|
||||
UINT64 FrameInfluenceOffset; //Offset to list of frame influences (This also forces the union to 64bits)
|
||||
UINT* pFrameInfluences; //Pointer to list of frame influences
|
||||
};
|
||||
};
|
||||
|
||||
struct SDKMESH_SUBSET
|
||||
{
|
||||
char Name[MAX_SUBSET_NAME];
|
||||
UINT MaterialID;
|
||||
UINT PrimitiveType;
|
||||
UINT64 IndexStart;
|
||||
UINT64 IndexCount;
|
||||
UINT64 VertexStart;
|
||||
UINT64 VertexCount;
|
||||
};
|
||||
|
||||
struct SDKMESH_FRAME
|
||||
{
|
||||
char Name[MAX_FRAME_NAME];
|
||||
UINT Mesh;
|
||||
UINT ParentFrame;
|
||||
UINT ChildFrame;
|
||||
UINT SiblingFrame;
|
||||
D3DXMATRIX Matrix;
|
||||
UINT AnimationDataIndex; //Used to index which set of keyframes transforms this frame
|
||||
};
|
||||
|
||||
struct SDKMESH_MATERIAL
|
||||
{
|
||||
char Name[MAX_MATERIAL_NAME];
|
||||
|
||||
// Use MaterialInstancePath
|
||||
char MaterialInstancePath[MAX_MATERIAL_PATH];
|
||||
|
||||
// Or fall back to d3d8-type materials
|
||||
char DiffuseTexture[MAX_TEXTURE_NAME];
|
||||
char NormalTexture[MAX_TEXTURE_NAME];
|
||||
char SpecularTexture[MAX_TEXTURE_NAME];
|
||||
|
||||
D3DXVECTOR4 Diffuse;
|
||||
D3DXVECTOR4 Ambient;
|
||||
D3DXVECTOR4 Specular;
|
||||
D3DXVECTOR4 Emissive;
|
||||
FLOAT Power;
|
||||
|
||||
union
|
||||
{
|
||||
UINT64 Force64_1; //Force the union to 64bits
|
||||
IDirect3DTexture9* pDiffuseTexture9;
|
||||
ID3D11Texture2D* pDiffuseTexture11;
|
||||
};
|
||||
union
|
||||
{
|
||||
UINT64 Force64_2; //Force the union to 64bits
|
||||
IDirect3DTexture9* pNormalTexture9;
|
||||
ID3D11Texture2D* pNormalTexture11;
|
||||
};
|
||||
union
|
||||
{
|
||||
UINT64 Force64_3; //Force the union to 64bits
|
||||
IDirect3DTexture9* pSpecularTexture9;
|
||||
ID3D11Texture2D* pSpecularTexture11;
|
||||
};
|
||||
|
||||
union
|
||||
{
|
||||
UINT64 Force64_4; //Force the union to 64bits
|
||||
ID3D11ShaderResourceView* pDiffuseRV11;
|
||||
};
|
||||
union
|
||||
{
|
||||
UINT64 Force64_5; //Force the union to 64bits
|
||||
ID3D11ShaderResourceView* pNormalRV11;
|
||||
};
|
||||
union
|
||||
{
|
||||
UINT64 Force64_6; //Force the union to 64bits
|
||||
ID3D11ShaderResourceView* pSpecularRV11;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
struct SDKANIMATION_FILE_HEADER
|
||||
{
|
||||
UINT Version;
|
||||
BYTE IsBigEndian;
|
||||
UINT FrameTransformType;
|
||||
UINT NumFrames;
|
||||
UINT NumAnimationKeys;
|
||||
UINT AnimationFPS;
|
||||
UINT64 AnimationDataSize;
|
||||
UINT64 AnimationDataOffset;
|
||||
};
|
||||
|
||||
struct SDKANIMATION_DATA
|
||||
{
|
||||
D3DXVECTOR3 Translation;
|
||||
D3DXVECTOR4 Orientation;
|
||||
D3DXVECTOR3 Scaling;
|
||||
};
|
||||
|
||||
struct SDKANIMATION_FRAME_DATA
|
||||
{
|
||||
char FrameName[MAX_FRAME_NAME];
|
||||
union
|
||||
{
|
||||
UINT64 DataOffset;
|
||||
SDKANIMATION_DATA* pAnimationData;
|
||||
};
|
||||
};
|
||||
|
||||
#ifndef _CONVERTER_APP_
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// AsyncLoading callbacks
|
||||
//--------------------------------------------------------------------------------------
|
||||
typedef void ( CALLBACK*LPCREATETEXTUREFROMFILE9 )( IDirect3DDevice9* pDev, char* szFileName,
|
||||
IDirect3DTexture9** ppTexture, void* pContext );
|
||||
typedef void ( CALLBACK*LPCREATEVERTEXBUFFER9 )( IDirect3DDevice9* pDev, IDirect3DVertexBuffer9** ppBuffer,
|
||||
UINT iSizeBytes, DWORD Usage, DWORD FVF, D3DPOOL Pool, void* pData,
|
||||
void* pContext );
|
||||
typedef void ( CALLBACK*LPCREATEINDEXBUFFER9 )( IDirect3DDevice9* pDev, IDirect3DIndexBuffer9** ppBuffer,
|
||||
UINT iSizeBytes, DWORD Usage, D3DFORMAT ibFormat, D3DPOOL Pool,
|
||||
void* pData, void* pContext );
|
||||
struct SDKMESH_CALLBACKS9
|
||||
{
|
||||
LPCREATETEXTUREFROMFILE9 pCreateTextureFromFile;
|
||||
LPCREATEVERTEXBUFFER9 pCreateVertexBuffer;
|
||||
LPCREATEINDEXBUFFER9 pCreateIndexBuffer;
|
||||
void* pContext;
|
||||
};
|
||||
|
||||
|
||||
typedef void ( CALLBACK*LPCREATETEXTUREFROMFILE11 )( ID3D11Device* pDev, char* szFileName,
|
||||
ID3D11ShaderResourceView** ppRV, void* pContext );
|
||||
typedef void ( CALLBACK*LPCREATEVERTEXBUFFER11 )( ID3D11Device* pDev, ID3D11Buffer** ppBuffer,
|
||||
D3D11_BUFFER_DESC BufferDesc, void* pData, void* pContext );
|
||||
typedef void ( CALLBACK*LPCREATEINDEXBUFFER11 )( ID3D11Device* pDev, ID3D11Buffer** ppBuffer,
|
||||
D3D11_BUFFER_DESC BufferDesc, void* pData, void* pContext );
|
||||
struct SDKMESH_CALLBACKS11
|
||||
{
|
||||
LPCREATETEXTUREFROMFILE11 pCreateTextureFromFile;
|
||||
LPCREATEVERTEXBUFFER11 pCreateVertexBuffer;
|
||||
LPCREATEINDEXBUFFER11 pCreateIndexBuffer;
|
||||
void* pContext;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// CDXUTSDKMesh class. This class reads the sdkmesh file format for use by the samples
|
||||
//--------------------------------------------------------------------------------------
|
||||
class CDXUTSDKMesh
|
||||
{
|
||||
private:
|
||||
UINT m_NumOutstandingResources;
|
||||
bool m_bLoading;
|
||||
//BYTE* m_pBufferData;
|
||||
HANDLE m_hFile;
|
||||
HANDLE m_hFileMappingObject;
|
||||
CGrowableArray <BYTE*> m_MappedPointers;
|
||||
IDirect3DDevice9* m_pDev9;
|
||||
ID3D11Device* m_pDev11;
|
||||
ID3D11DeviceContext* m_pDevContext11;
|
||||
|
||||
protected:
|
||||
//These are the pointers to the two chunks of data loaded in from the mesh file
|
||||
BYTE* m_pStaticMeshData;
|
||||
BYTE* m_pHeapData;
|
||||
BYTE* m_pAnimationData;
|
||||
BYTE** m_ppVertices;
|
||||
BYTE** m_ppIndices;
|
||||
|
||||
//Keep track of the path
|
||||
WCHAR m_strPathW[MAX_PATH];
|
||||
char m_strPath[MAX_PATH];
|
||||
|
||||
//General mesh info
|
||||
SDKMESH_HEADER* m_pMeshHeader;
|
||||
SDKMESH_VERTEX_BUFFER_HEADER* m_pVertexBufferArray;
|
||||
SDKMESH_INDEX_BUFFER_HEADER* m_pIndexBufferArray;
|
||||
SDKMESH_MESH* m_pMeshArray;
|
||||
SDKMESH_SUBSET* m_pSubsetArray;
|
||||
SDKMESH_FRAME* m_pFrameArray;
|
||||
SDKMESH_MATERIAL* m_pMaterialArray;
|
||||
|
||||
// Adjacency information (not part of the m_pStaticMeshData, so it must be created and destroyed separately )
|
||||
SDKMESH_INDEX_BUFFER_HEADER* m_pAdjacencyIndexBufferArray;
|
||||
|
||||
//Animation (TODO: Add ability to load/track multiple animation sets)
|
||||
SDKANIMATION_FILE_HEADER* m_pAnimationHeader;
|
||||
SDKANIMATION_FRAME_DATA* m_pAnimationFrameData;
|
||||
D3DXMATRIX* m_pBindPoseFrameMatrices;
|
||||
D3DXMATRIX* m_pTransformedFrameMatrices;
|
||||
D3DXMATRIX* m_pWorldPoseFrameMatrices;
|
||||
|
||||
protected:
|
||||
void LoadMaterials( ID3D11Device* pd3dDevice, SDKMESH_MATERIAL* pMaterials,
|
||||
UINT NumMaterials, SDKMESH_CALLBACKS11* pLoaderCallbacks=NULL );
|
||||
|
||||
void LoadMaterials( IDirect3DDevice9* pd3dDevice, SDKMESH_MATERIAL* pMaterials,
|
||||
UINT NumMaterials, SDKMESH_CALLBACKS9* pLoaderCallbacks=NULL );
|
||||
|
||||
HRESULT CreateVertexBuffer( ID3D11Device* pd3dDevice,
|
||||
SDKMESH_VERTEX_BUFFER_HEADER* pHeader, void* pVertices,
|
||||
SDKMESH_CALLBACKS11* pLoaderCallbacks=NULL );
|
||||
HRESULT CreateVertexBuffer( IDirect3DDevice9* pd3dDevice,
|
||||
SDKMESH_VERTEX_BUFFER_HEADER* pHeader, void* pVertices,
|
||||
SDKMESH_CALLBACKS9* pLoaderCallbacks=NULL );
|
||||
|
||||
HRESULT CreateIndexBuffer( ID3D11Device* pd3dDevice, SDKMESH_INDEX_BUFFER_HEADER* pHeader,
|
||||
void* pIndices, SDKMESH_CALLBACKS11* pLoaderCallbacks=NULL );
|
||||
HRESULT CreateIndexBuffer( IDirect3DDevice9* pd3dDevice,
|
||||
SDKMESH_INDEX_BUFFER_HEADER* pHeader, void* pIndices,
|
||||
SDKMESH_CALLBACKS9* pLoaderCallbacks=NULL );
|
||||
|
||||
virtual HRESULT CreateFromFile( ID3D11Device* pDev11,
|
||||
IDirect3DDevice9* pDev9,
|
||||
LPCTSTR szFileName,
|
||||
bool bCreateAdjacencyIndices,
|
||||
SDKMESH_CALLBACKS11* pLoaderCallbacks11 = NULL,
|
||||
SDKMESH_CALLBACKS9* pLoaderCallbacks9 = NULL );
|
||||
|
||||
virtual HRESULT CreateFromMemory( ID3D11Device* pDev11,
|
||||
IDirect3DDevice9* pDev9,
|
||||
BYTE* pData,
|
||||
UINT DataBytes,
|
||||
bool bCreateAdjacencyIndices,
|
||||
bool bCopyStatic,
|
||||
SDKMESH_CALLBACKS11* pLoaderCallbacks11 = NULL,
|
||||
SDKMESH_CALLBACKS9* pLoaderCallbacks9 = NULL );
|
||||
|
||||
//frame manipulation
|
||||
void TransformBindPoseFrame( UINT iFrame, D3DXMATRIX* pParentWorld );
|
||||
void TransformFrame( UINT iFrame, D3DXMATRIX* pParentWorld, double fTime );
|
||||
void TransformFrameAbsolute( UINT iFrame, double fTime );
|
||||
|
||||
//Direct3D 11 rendering helpers
|
||||
void RenderMesh( UINT iMesh,
|
||||
bool bAdjacent,
|
||||
ID3D11DeviceContext* pd3dDeviceContext,
|
||||
UINT iDiffuseSlot,
|
||||
UINT iNormalSlot,
|
||||
UINT iSpecularSlot );
|
||||
void RenderFrame( UINT iFrame,
|
||||
bool bAdjacent,
|
||||
ID3D11DeviceContext* pd3dDeviceContext,
|
||||
UINT iDiffuseSlot,
|
||||
UINT iNormalSlot,
|
||||
UINT iSpecularSlot );
|
||||
|
||||
|
||||
//Direct3D 9 rendering helpers
|
||||
void RenderMesh( UINT iMesh,
|
||||
LPDIRECT3DDEVICE9 pd3dDevice,
|
||||
LPD3DXEFFECT pEffect,
|
||||
D3DXHANDLE hTechnique,
|
||||
D3DXHANDLE htxDiffuse,
|
||||
D3DXHANDLE htxNormal,
|
||||
D3DXHANDLE htxSpecular );
|
||||
void RenderFrame( UINT iFrame,
|
||||
LPDIRECT3DDEVICE9 pd3dDevice,
|
||||
LPD3DXEFFECT pEffect,
|
||||
D3DXHANDLE hTechnique,
|
||||
D3DXHANDLE htxDiffuse,
|
||||
D3DXHANDLE htxNormal,
|
||||
D3DXHANDLE htxSpecular );
|
||||
|
||||
public:
|
||||
CDXUTSDKMesh();
|
||||
virtual ~CDXUTSDKMesh();
|
||||
|
||||
virtual HRESULT Create( ID3D11Device* pDev11, LPCTSTR szFileName, bool bCreateAdjacencyIndices=
|
||||
false, SDKMESH_CALLBACKS11* pLoaderCallbacks=NULL );
|
||||
virtual HRESULT Create( IDirect3DDevice9* pDev9, LPCTSTR szFileName, bool bCreateAdjacencyIndices=
|
||||
false, SDKMESH_CALLBACKS9* pLoaderCallbacks=NULL );
|
||||
virtual HRESULT Create( ID3D11Device* pDev11, BYTE* pData, UINT DataBytes,
|
||||
bool bCreateAdjacencyIndices=false, bool bCopyStatic=false,
|
||||
SDKMESH_CALLBACKS11* pLoaderCallbacks=NULL );
|
||||
virtual HRESULT Create( IDirect3DDevice9* pDev9, BYTE* pData, UINT DataBytes,
|
||||
bool bCreateAdjacencyIndices=false, bool bCopyStatic=false,
|
||||
SDKMESH_CALLBACKS9* pLoaderCallbacks=NULL );
|
||||
virtual HRESULT LoadAnimation( WCHAR* szFileName );
|
||||
virtual void Destroy();
|
||||
|
||||
//Frame manipulation
|
||||
void TransformBindPose( D3DXMATRIX* pWorld );
|
||||
void TransformMesh( D3DXMATRIX* pWorld, double fTime );
|
||||
|
||||
|
||||
//Direct3D 11 Rendering
|
||||
virtual void Render( ID3D11DeviceContext* pd3dDeviceContext,
|
||||
UINT iDiffuseSlot = INVALID_SAMPLER_SLOT,
|
||||
UINT iNormalSlot = INVALID_SAMPLER_SLOT,
|
||||
UINT iSpecularSlot = INVALID_SAMPLER_SLOT );
|
||||
virtual void RenderAdjacent( ID3D11DeviceContext* pd3dDeviceContext,
|
||||
UINT iDiffuseSlot = INVALID_SAMPLER_SLOT,
|
||||
UINT iNormalSlot = INVALID_SAMPLER_SLOT,
|
||||
UINT iSpecularSlot = INVALID_SAMPLER_SLOT );
|
||||
|
||||
//Direct3D 9 Rendering
|
||||
virtual void Render( LPDIRECT3DDEVICE9 pd3dDevice,
|
||||
LPD3DXEFFECT pEffect,
|
||||
D3DXHANDLE hTechnique,
|
||||
D3DXHANDLE htxDiffuse = 0,
|
||||
D3DXHANDLE htxNormal = 0,
|
||||
D3DXHANDLE htxSpecular = 0 );
|
||||
|
||||
//Helpers (D3D11 specific)
|
||||
static D3D11_PRIMITIVE_TOPOLOGY GetPrimitiveType11( SDKMESH_PRIMITIVE_TYPE PrimType );
|
||||
DXGI_FORMAT GetIBFormat11( UINT iMesh );
|
||||
ID3D11Buffer* GetVB11( UINT iMesh, UINT iVB );
|
||||
ID3D11Buffer* GetIB11( UINT iMesh );
|
||||
SDKMESH_INDEX_TYPE GetIndexType( UINT iMesh );
|
||||
|
||||
ID3D11Buffer* GetAdjIB11( UINT iMesh );
|
||||
|
||||
//Helpers (D3D9 specific)
|
||||
static D3DPRIMITIVETYPE GetPrimitiveType9( SDKMESH_PRIMITIVE_TYPE PrimType );
|
||||
D3DFORMAT GetIBFormat9( UINT iMesh );
|
||||
IDirect3DVertexBuffer9* GetVB9( UINT iMesh, UINT iVB );
|
||||
IDirect3DIndexBuffer9* GetIB9( UINT iMesh );
|
||||
|
||||
//Helpers (general)
|
||||
char* GetMeshPathA();
|
||||
WCHAR* GetMeshPathW();
|
||||
UINT GetNumMeshes();
|
||||
UINT GetNumMaterials();
|
||||
UINT GetNumVBs();
|
||||
UINT GetNumIBs();
|
||||
|
||||
ID3D11Buffer* GetVB11At( UINT iVB );
|
||||
ID3D11Buffer* GetIB11At( UINT iIB );
|
||||
|
||||
IDirect3DVertexBuffer9* GetVB9At( UINT iVB );
|
||||
IDirect3DIndexBuffer9* GetIB9At( UINT iIB );
|
||||
|
||||
BYTE* GetRawVerticesAt( UINT iVB );
|
||||
BYTE* GetRawIndicesAt( UINT iIB );
|
||||
SDKMESH_MATERIAL* GetMaterial( UINT iMaterial );
|
||||
SDKMESH_MESH* GetMesh( UINT iMesh );
|
||||
UINT GetNumSubsets( UINT iMesh );
|
||||
SDKMESH_SUBSET* GetSubset( UINT iMesh, UINT iSubset );
|
||||
UINT GetVertexStride( UINT iMesh, UINT iVB );
|
||||
UINT GetNumFrames();
|
||||
SDKMESH_FRAME* GetFrame( UINT iFrame );
|
||||
SDKMESH_FRAME* FindFrame( char* pszName );
|
||||
UINT64 GetNumVertices( UINT iMesh, UINT iVB );
|
||||
UINT64 GetNumIndices( UINT iMesh );
|
||||
D3DXVECTOR3 GetMeshBBoxCenter( UINT iMesh );
|
||||
D3DXVECTOR3 GetMeshBBoxExtents( UINT iMesh );
|
||||
UINT GetOutstandingResources();
|
||||
UINT GetOutstandingBufferResources();
|
||||
bool CheckLoadDone();
|
||||
bool IsLoaded();
|
||||
bool IsLoading();
|
||||
void SetLoading( bool bLoading );
|
||||
BOOL HadLoadingError();
|
||||
|
||||
//Animation
|
||||
UINT GetNumInfluences( UINT iMesh );
|
||||
const D3DXMATRIX* GetMeshInfluenceMatrix( UINT iMesh, UINT iInfluence );
|
||||
UINT GetAnimationKeyFromTime( double fTime );
|
||||
const D3DXMATRIX* GetWorldMatrix( UINT iFrameIndex );
|
||||
const D3DXMATRIX* GetInfluenceMatrix( UINT iFrameIndex );
|
||||
bool GetAnimationProperties( UINT* pNumKeys, FLOAT* pFrameTime );
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: class CDXUTXFileMesh
|
||||
// Desc: Class for loading and rendering file-based meshes
|
||||
//-----------------------------------------------------------------------------
|
||||
class CDXUTXFileMesh
|
||||
{
|
||||
public:
|
||||
WCHAR m_strName[512];
|
||||
LPD3DXMESH m_pMesh; // Managed mesh
|
||||
|
||||
// Cache of data in m_pMesh for easy access
|
||||
IDirect3DVertexBuffer9* m_pVB;
|
||||
IDirect3DIndexBuffer9* m_pIB;
|
||||
IDirect3DVertexDeclaration9* m_pDecl;
|
||||
DWORD m_dwNumVertices;
|
||||
DWORD m_dwNumFaces;
|
||||
DWORD m_dwBytesPerVertex;
|
||||
|
||||
DWORD m_dwNumMaterials; // Materials for the mesh
|
||||
D3DMATERIAL9* m_pMaterials;
|
||||
CHAR (*m_strMaterials )[MAX_PATH];
|
||||
IDirect3DBaseTexture9** m_pTextures;
|
||||
bool m_bUseMaterials;
|
||||
|
||||
public:
|
||||
// Rendering
|
||||
HRESULT Render( LPDIRECT3DDEVICE9 pd3dDevice,
|
||||
bool bDrawOpaqueSubsets = true,
|
||||
bool bDrawAlphaSubsets = true );
|
||||
HRESULT Render( ID3DXEffect* pEffect,
|
||||
D3DXHANDLE hTexture = NULL,
|
||||
D3DXHANDLE hDiffuse = NULL,
|
||||
D3DXHANDLE hAmbient = NULL,
|
||||
D3DXHANDLE hSpecular = NULL,
|
||||
D3DXHANDLE hEmissive = NULL,
|
||||
D3DXHANDLE hPower = NULL,
|
||||
bool bDrawOpaqueSubsets = true,
|
||||
bool bDrawAlphaSubsets = true );
|
||||
|
||||
// Mesh access
|
||||
LPD3DXMESH GetMesh()
|
||||
{
|
||||
return m_pMesh;
|
||||
}
|
||||
|
||||
// Rendering options
|
||||
void UseMeshMaterials( bool bFlag )
|
||||
{
|
||||
m_bUseMaterials = bFlag;
|
||||
}
|
||||
HRESULT SetFVF( LPDIRECT3DDEVICE9 pd3dDevice, DWORD dwFVF );
|
||||
HRESULT SetVertexDecl( LPDIRECT3DDEVICE9 pd3dDevice, const D3DVERTEXELEMENT9* pDecl,
|
||||
bool bAutoComputeNormals = true, bool bAutoComputeTangents = true,
|
||||
bool bSplitVertexForOptimalTangents = false );
|
||||
|
||||
// Initializing
|
||||
HRESULT RestoreDeviceObjects( LPDIRECT3DDEVICE9 pd3dDevice );
|
||||
HRESULT InvalidateDeviceObjects();
|
||||
|
||||
// Creation/destruction
|
||||
HRESULT Create( LPDIRECT3DDEVICE9 pd3dDevice, LPCWSTR strFilename );
|
||||
HRESULT Create( LPDIRECT3DDEVICE9 pd3dDevice, LPD3DXFILEDATA pFileData );
|
||||
HRESULT Create( LPDIRECT3DDEVICE9 pd3dDevice, ID3DXMesh* pInMesh, D3DXMATERIAL* pd3dxMaterials,
|
||||
DWORD dwMaterials );
|
||||
HRESULT CreateMaterials( LPCWSTR strPath, IDirect3DDevice9* pd3dDevice, D3DXMATERIAL* d3dxMtrls,
|
||||
DWORD dwNumMaterials );
|
||||
HRESULT Destroy();
|
||||
|
||||
CDXUTXFileMesh( LPCWSTR strName = L"CDXUTXMeshFile_Mesh" );
|
||||
virtual ~CDXUTXFileMesh();
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
1684
Demos/DX11ClothDemo/DXUT/Optional/SDKmisc.cpp
Normal file
1684
Demos/DX11ClothDemo/DXUT/Optional/SDKmisc.cpp
Normal file
File diff suppressed because it is too large
Load Diff
368
Demos/DX11ClothDemo/DXUT/Optional/SDKmisc.h
Normal file
368
Demos/DX11ClothDemo/DXUT/Optional/SDKmisc.h
Normal file
@@ -0,0 +1,368 @@
|
||||
//--------------------------------------------------------------------------------------
|
||||
// File: SDKMisc.h
|
||||
//
|
||||
// Various helper functionality that is shared between SDK samples
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved
|
||||
//--------------------------------------------------------------------------------------
|
||||
#pragma once
|
||||
#ifndef SDKMISC_H
|
||||
#define SDKMISC_H
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Resource cache for textures, fonts, meshs, and effects.
|
||||
// Use DXUTGetGlobalResourceCache() to access the global cache
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
enum DXUTCACHE_SOURCELOCATION
|
||||
{
|
||||
DXUTCACHE_LOCATION_FILE,
|
||||
DXUTCACHE_LOCATION_RESOURCE
|
||||
};
|
||||
|
||||
struct DXUTCache_Texture
|
||||
{
|
||||
DXUTCACHE_SOURCELOCATION Location;
|
||||
WCHAR wszSource[MAX_PATH];
|
||||
HMODULE hSrcModule;
|
||||
UINT Width;
|
||||
UINT Height;
|
||||
UINT Depth;
|
||||
UINT MipLevels;
|
||||
UINT MiscFlags;
|
||||
union
|
||||
{
|
||||
DWORD Usage9;
|
||||
D3D11_USAGE Usage11;
|
||||
};
|
||||
union
|
||||
{
|
||||
D3DFORMAT Format9;
|
||||
DXGI_FORMAT Format;
|
||||
};
|
||||
union
|
||||
{
|
||||
D3DPOOL Pool9;
|
||||
UINT CpuAccessFlags;
|
||||
};
|
||||
union
|
||||
{
|
||||
D3DRESOURCETYPE Type9;
|
||||
UINT BindFlags;
|
||||
};
|
||||
IDirect3DBaseTexture9* pTexture9;
|
||||
ID3D11ShaderResourceView* pSRV11;
|
||||
|
||||
DXUTCache_Texture()
|
||||
{
|
||||
pTexture9 = NULL;
|
||||
pSRV11 = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
struct DXUTCache_Font : public D3DXFONT_DESC
|
||||
{
|
||||
ID3DXFont* pFont;
|
||||
};
|
||||
|
||||
struct DXUTCache_Effect
|
||||
{
|
||||
DXUTCACHE_SOURCELOCATION Location;
|
||||
WCHAR wszSource[MAX_PATH];
|
||||
HMODULE hSrcModule;
|
||||
DWORD dwFlags;
|
||||
ID3DXEffect* pEffect;
|
||||
};
|
||||
|
||||
|
||||
class CDXUTResourceCache
|
||||
{
|
||||
public:
|
||||
~CDXUTResourceCache();
|
||||
|
||||
HRESULT CreateTextureFromFile( LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile,
|
||||
LPDIRECT3DTEXTURE9* ppTexture );
|
||||
HRESULT CreateTextureFromFile( LPDIRECT3DDEVICE9 pDevice, LPCSTR pSrcFile,
|
||||
LPDIRECT3DTEXTURE9* ppTexture );
|
||||
HRESULT CreateTextureFromFile( ID3D11Device* pDevice, ID3D11DeviceContext *pContext, LPCTSTR pSrcFile,
|
||||
ID3D11ShaderResourceView** ppOutputRV, bool bSRGB=false );
|
||||
HRESULT CreateTextureFromFile( ID3D11Device* pDevice, ID3D11DeviceContext *pContext, LPCSTR pSrcFile,
|
||||
ID3D11ShaderResourceView** ppOutputRV, bool bSRGB=false );
|
||||
HRESULT CreateTextureFromFileEx( LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile, UINT Width,
|
||||
UINT Height, UINT MipLevels, DWORD Usage, D3DFORMAT Format,
|
||||
D3DPOOL Pool, DWORD Filter, DWORD MipFilter, D3DCOLOR ColorKey,
|
||||
D3DXIMAGE_INFO* pSrcInfo, PALETTEENTRY* pPalette,
|
||||
LPDIRECT3DTEXTURE9* ppTexture );
|
||||
HRESULT CreateTextureFromFileEx( ID3D11Device* pDevice, ID3D11DeviceContext* pContext, LPCTSTR pSrcFile,
|
||||
D3DX11_IMAGE_LOAD_INFO* pLoadInfo, ID3DX11ThreadPump* pPump,
|
||||
ID3D11ShaderResourceView** ppOutputRV, bool bSRGB );
|
||||
HRESULT CreateTextureFromResource( LPDIRECT3DDEVICE9 pDevice, HMODULE hSrcModule,
|
||||
LPCTSTR pSrcResource, LPDIRECT3DTEXTURE9* ppTexture );
|
||||
HRESULT CreateTextureFromResourceEx( LPDIRECT3DDEVICE9 pDevice, HMODULE hSrcModule,
|
||||
LPCTSTR pSrcResource, UINT Width, UINT Height, UINT MipLevels,
|
||||
DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, DWORD Filter,
|
||||
DWORD MipFilter, D3DCOLOR ColorKey, D3DXIMAGE_INFO* pSrcInfo,
|
||||
PALETTEENTRY* pPalette, LPDIRECT3DTEXTURE9* ppTexture );
|
||||
HRESULT CreateCubeTextureFromFile( LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile,
|
||||
LPDIRECT3DCUBETEXTURE9* ppCubeTexture );
|
||||
HRESULT CreateCubeTextureFromFileEx( LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile, UINT Size,
|
||||
UINT MipLevels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool,
|
||||
DWORD Filter, DWORD MipFilter, D3DCOLOR ColorKey,
|
||||
D3DXIMAGE_INFO* pSrcInfo, PALETTEENTRY* pPalette,
|
||||
LPDIRECT3DCUBETEXTURE9* ppCubeTexture );
|
||||
HRESULT CreateCubeTextureFromResource( LPDIRECT3DDEVICE9 pDevice, HMODULE hSrcModule,
|
||||
LPCTSTR pSrcResource,
|
||||
LPDIRECT3DCUBETEXTURE9* ppCubeTexture );
|
||||
HRESULT CreateCubeTextureFromResourceEx( LPDIRECT3DDEVICE9 pDevice, HMODULE hSrcModule,
|
||||
LPCTSTR pSrcResource, UINT Size, UINT MipLevels,
|
||||
DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, DWORD Filter,
|
||||
DWORD MipFilter, D3DCOLOR ColorKey,
|
||||
D3DXIMAGE_INFO* pSrcInfo, PALETTEENTRY* pPalette,
|
||||
LPDIRECT3DCUBETEXTURE9* ppCubeTexture );
|
||||
HRESULT CreateVolumeTextureFromFile( LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile,
|
||||
LPDIRECT3DVOLUMETEXTURE9* ppVolumeTexture );
|
||||
HRESULT CreateVolumeTextureFromFileEx( LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile, UINT Width,
|
||||
UINT Height, UINT Depth, UINT MipLevels, DWORD Usage,
|
||||
D3DFORMAT Format, D3DPOOL Pool, DWORD Filter,
|
||||
DWORD MipFilter, D3DCOLOR ColorKey,
|
||||
D3DXIMAGE_INFO* pSrcInfo, PALETTEENTRY* pPalette,
|
||||
LPDIRECT3DVOLUMETEXTURE9* ppTexture );
|
||||
HRESULT CreateVolumeTextureFromResource( LPDIRECT3DDEVICE9 pDevice, HMODULE hSrcModule,
|
||||
LPCTSTR pSrcResource,
|
||||
LPDIRECT3DVOLUMETEXTURE9* ppVolumeTexture );
|
||||
HRESULT CreateVolumeTextureFromResourceEx( LPDIRECT3DDEVICE9 pDevice, HMODULE hSrcModule,
|
||||
LPCTSTR pSrcResource, UINT Width, UINT Height,
|
||||
UINT Depth, UINT MipLevels, DWORD Usage,
|
||||
D3DFORMAT Format, D3DPOOL Pool, DWORD Filter,
|
||||
DWORD MipFilter, D3DCOLOR ColorKey,
|
||||
D3DXIMAGE_INFO* pSrcInfo, PALETTEENTRY* pPalette,
|
||||
LPDIRECT3DVOLUMETEXTURE9* ppVolumeTexture );
|
||||
HRESULT CreateFont( LPDIRECT3DDEVICE9 pDevice, UINT Height, UINT Width, UINT Weight,
|
||||
UINT MipLevels, BOOL Italic, DWORD CharSet, DWORD OutputPrecision,
|
||||
DWORD Quality, DWORD PitchAndFamily, LPCTSTR pFacename, LPD3DXFONT* ppFont );
|
||||
HRESULT CreateFontIndirect( LPDIRECT3DDEVICE9 pDevice, CONST D3DXFONT_DESC *pDesc, LPD3DXFONT *ppFont );
|
||||
HRESULT CreateEffectFromFile( LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile,
|
||||
const D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, DWORD Flags,
|
||||
LPD3DXEFFECTPOOL pPool, LPD3DXEFFECT* ppEffect,
|
||||
LPD3DXBUFFER* ppCompilationErrors );
|
||||
HRESULT CreateEffectFromResource( LPDIRECT3DDEVICE9 pDevice, HMODULE hSrcModule,
|
||||
LPCTSTR pSrcResource, const D3DXMACRO* pDefines,
|
||||
LPD3DXINCLUDE pInclude, DWORD Flags, LPD3DXEFFECTPOOL pPool,
|
||||
LPD3DXEFFECT* ppEffect, LPD3DXBUFFER* ppCompilationErrors );
|
||||
|
||||
public:
|
||||
HRESULT OnCreateDevice( IDirect3DDevice9* pd3dDevice );
|
||||
HRESULT OnResetDevice( IDirect3DDevice9* pd3dDevice );
|
||||
HRESULT OnLostDevice();
|
||||
HRESULT OnDestroyDevice();
|
||||
|
||||
protected:
|
||||
friend CDXUTResourceCache& WINAPI DXUTGetGlobalResourceCache();
|
||||
friend HRESULT WINAPI DXUTInitialize3DEnvironment();
|
||||
friend HRESULT WINAPI DXUTReset3DEnvironment();
|
||||
friend void WINAPI DXUTCleanup3DEnvironment( bool bReleaseSettings );
|
||||
|
||||
CDXUTResourceCache()
|
||||
{
|
||||
}
|
||||
|
||||
CGrowableArray <DXUTCache_Texture> m_TextureCache;
|
||||
CGrowableArray <DXUTCache_Effect> m_EffectCache;
|
||||
CGrowableArray <DXUTCache_Font> m_FontCache;
|
||||
};
|
||||
|
||||
CDXUTResourceCache& WINAPI DXUTGetGlobalResourceCache();
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Manages the insertion point when drawing text
|
||||
//--------------------------------------------------------------------------------------
|
||||
class CDXUTDialogResourceManager;
|
||||
class CDXUTTextHelper
|
||||
{
|
||||
public:
|
||||
CDXUTTextHelper( ID3DXFont* pFont9 = NULL, ID3DXSprite* pSprite9 = NULL,
|
||||
int nLineHeight = 15 );
|
||||
CDXUTTextHelper( ID3D11Device* pd3d11Device, ID3D11DeviceContext* pd3dDeviceContext, CDXUTDialogResourceManager* pManager, int nLineHeight );
|
||||
~CDXUTTextHelper();
|
||||
|
||||
void Init( ID3DXFont* pFont9 = NULL, ID3DXSprite* pSprite9 = NULL,
|
||||
int nLineHeight = 15 );
|
||||
|
||||
void SetInsertionPos( int x, int y )
|
||||
{
|
||||
m_pt.x = x; m_pt.y = y;
|
||||
}
|
||||
void SetForegroundColor( D3DXCOLOR clr )
|
||||
{
|
||||
m_clr = clr;
|
||||
}
|
||||
|
||||
void Begin();
|
||||
HRESULT DrawFormattedTextLine( const WCHAR* strMsg, ... );
|
||||
HRESULT DrawTextLine( const WCHAR* strMsg );
|
||||
HRESULT DrawFormattedTextLine( RECT& rc, DWORD dwFlags, const WCHAR* strMsg, ... );
|
||||
HRESULT DrawTextLine( RECT& rc, DWORD dwFlags, const WCHAR* strMsg );
|
||||
void End();
|
||||
|
||||
protected:
|
||||
ID3DXFont* m_pFont9;
|
||||
ID3DXSprite* m_pSprite9;
|
||||
D3DXCOLOR m_clr;
|
||||
POINT m_pt;
|
||||
int m_nLineHeight;
|
||||
|
||||
// D3D11 font
|
||||
ID3D11Device* m_pd3d11Device;
|
||||
ID3D11DeviceContext* m_pd3d11DeviceContext;
|
||||
CDXUTDialogResourceManager* m_pManager;
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Manages a persistent list of lines and draws them using ID3DXLine
|
||||
//--------------------------------------------------------------------------------------
|
||||
class CDXUTLineManager
|
||||
{
|
||||
public:
|
||||
CDXUTLineManager();
|
||||
~CDXUTLineManager();
|
||||
|
||||
HRESULT OnCreatedDevice( IDirect3DDevice9* pd3dDevice );
|
||||
HRESULT OnResetDevice();
|
||||
HRESULT OnRender();
|
||||
HRESULT OnLostDevice();
|
||||
HRESULT OnDeletedDevice();
|
||||
|
||||
HRESULT AddLine( int* pnLineID, D3DXVECTOR2* pVertexList, DWORD dwVertexListCount, D3DCOLOR Color, float fWidth,
|
||||
float fScaleRatio, bool bAntiAlias );
|
||||
HRESULT AddRect( int* pnLineID, RECT rc, D3DCOLOR Color, float fWidth, float fScaleRatio, bool bAntiAlias );
|
||||
HRESULT RemoveLine( int nLineID );
|
||||
HRESULT RemoveAllLines();
|
||||
|
||||
protected:
|
||||
struct LINE_NODE
|
||||
{
|
||||
int nLineID;
|
||||
D3DCOLOR Color;
|
||||
float fWidth;
|
||||
bool bAntiAlias;
|
||||
float fScaleRatio;
|
||||
D3DXVECTOR2* pVertexList;
|
||||
DWORD dwVertexListCount;
|
||||
};
|
||||
|
||||
CGrowableArray <LINE_NODE*> m_LinesList;
|
||||
IDirect3DDevice9* m_pd3dDevice;
|
||||
ID3DXLine* m_pD3DXLine;
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Shared code for samples to ask user if they want to use a REF device or quit
|
||||
//--------------------------------------------------------------------------------------
|
||||
void WINAPI DXUTDisplaySwitchingToREFWarning( DXUTDeviceVersion ver );
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Tries to finds a media file by searching in common locations
|
||||
//--------------------------------------------------------------------------------------
|
||||
HRESULT WINAPI DXUTFindDXSDKMediaFileCch( __in_ecount(cchDest) WCHAR* strDestPath,
|
||||
int cchDest,
|
||||
__in LPCWSTR strFilename );
|
||||
HRESULT WINAPI DXUTSetMediaSearchPath( LPCWSTR strPath );
|
||||
LPCWSTR WINAPI DXUTGetMediaSearchPath();
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Returns a view matrix for rendering to a face of a cubemap.
|
||||
//--------------------------------------------------------------------------------------
|
||||
D3DXMATRIX WINAPI DXUTGetCubeMapViewMatrix( DWORD dwFace );
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Simple helper stack class
|
||||
//--------------------------------------------------------------------------------------
|
||||
template <class T> class CDXUTStack
|
||||
{
|
||||
private:
|
||||
UINT m_MemorySize;
|
||||
UINT m_NumElements;
|
||||
T* m_pData;
|
||||
|
||||
bool EnsureStackSize( UINT64 iElements )
|
||||
{
|
||||
if( m_MemorySize > iElements )
|
||||
return true;
|
||||
|
||||
T* pTemp = new T[ ( size_t )( iElements * 2 + 256 ) ];
|
||||
if( !pTemp )
|
||||
return false;
|
||||
|
||||
if( m_NumElements )
|
||||
{
|
||||
CopyMemory( pTemp, m_pData, ( size_t )( m_NumElements * sizeof( T ) ) );
|
||||
}
|
||||
|
||||
if( m_pData ) delete []m_pData;
|
||||
m_pData = pTemp;
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
CDXUTStack()
|
||||
{
|
||||
m_pData = NULL; m_NumElements = 0; m_MemorySize = 0;
|
||||
}
|
||||
~CDXUTStack()
|
||||
{
|
||||
if( m_pData ) delete []m_pData;
|
||||
}
|
||||
|
||||
UINT GetCount()
|
||||
{
|
||||
return m_NumElements;
|
||||
}
|
||||
T GetAt( UINT i )
|
||||
{
|
||||
return m_pData[i];
|
||||
}
|
||||
T GetTop()
|
||||
{
|
||||
if( m_NumElements < 1 )
|
||||
return NULL;
|
||||
|
||||
return m_pData[ m_NumElements - 1 ];
|
||||
}
|
||||
|
||||
T GetRelative( INT i )
|
||||
{
|
||||
INT64 iVal = m_NumElements - 1 + i;
|
||||
if( iVal < 0 )
|
||||
return NULL;
|
||||
return m_pData[ iVal ];
|
||||
}
|
||||
|
||||
bool Push( T pElem )
|
||||
{
|
||||
if( !EnsureStackSize( m_NumElements + 1 ) )
|
||||
return false;
|
||||
|
||||
m_pData[m_NumElements] = pElem;
|
||||
m_NumElements++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
T Pop()
|
||||
{
|
||||
if( m_NumElements < 1 )
|
||||
return NULL;
|
||||
|
||||
m_NumElements --;
|
||||
return m_pData[m_NumElements];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
1053
Demos/DX11ClothDemo/DXUT/Optional/SDKsound.cpp
Normal file
1053
Demos/DX11ClothDemo/DXUT/Optional/SDKsound.cpp
Normal file
File diff suppressed because it is too large
Load Diff
124
Demos/DX11ClothDemo/DXUT/Optional/SDKsound.h
Normal file
124
Demos/DX11ClothDemo/DXUT/Optional/SDKsound.h
Normal file
@@ -0,0 +1,124 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// File: DXUTsound.h
|
||||
//
|
||||
// Copyright (c) Microsoft Corp. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef DXUTSOUND_H
|
||||
#define DXUTSOUND_H
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Header Includes
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <dsound.h>
|
||||
#include <ks.h>
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Classes used by this header
|
||||
//-----------------------------------------------------------------------------
|
||||
class CSoundManager;
|
||||
class CSound;
|
||||
class CStreamingSound;
|
||||
class CWaveFile;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Typing macros
|
||||
//-----------------------------------------------------------------------------
|
||||
#define DXUT_StopSound(s) { if(s) s->Stop(); }
|
||||
#define DXUT_PlaySound(s) { if(s) s->Play( 0, 0 ); }
|
||||
#define DXUT_PlaySoundLooping(s) { if(s) s->Play( 0, DSBPLAY_LOOPING ); }
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: class CSoundManager
|
||||
// Desc:
|
||||
//-----------------------------------------------------------------------------
|
||||
class CSoundManager
|
||||
{
|
||||
protected:
|
||||
IDirectSound8* m_pDS;
|
||||
|
||||
public:
|
||||
CSoundManager();
|
||||
~CSoundManager();
|
||||
|
||||
HRESULT Initialize( HWND hWnd, DWORD dwCoopLevel );
|
||||
inline LPDIRECTSOUND8 GetDirectSound()
|
||||
{
|
||||
return m_pDS;
|
||||
}
|
||||
HRESULT SetPrimaryBufferFormat( DWORD dwPrimaryChannels, DWORD dwPrimaryFreq,
|
||||
DWORD dwPrimaryBitRate );
|
||||
HRESULT Get3DListenerInterface( LPDIRECTSOUND3DLISTENER* ppDSListener );
|
||||
|
||||
HRESULT Create( CSound** ppSound, LPWSTR strWaveFileName, DWORD dwCreationFlags = 0,
|
||||
GUID guid3DAlgorithm = GUID_NULL, DWORD dwNumBuffers = 1 );
|
||||
HRESULT CreateFromMemory( CSound** ppSound, BYTE* pbData, ULONG ulDataSize, LPWAVEFORMATEX pwfx,
|
||||
DWORD dwCreationFlags = 0, GUID guid3DAlgorithm = GUID_NULL,
|
||||
DWORD dwNumBuffers = 1 );
|
||||
HRESULT CreateStreaming( CStreamingSound** ppStreamingSound, LPWSTR strWaveFileName,
|
||||
DWORD dwCreationFlags, GUID guid3DAlgorithm, DWORD dwNotifyCount,
|
||||
DWORD dwNotifySize, HANDLE hNotifyEvent );
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: class CSound
|
||||
// Desc: Encapsulates functionality of a DirectSound buffer.
|
||||
//-----------------------------------------------------------------------------
|
||||
class CSound
|
||||
{
|
||||
protected:
|
||||
LPDIRECTSOUNDBUFFER* m_apDSBuffer;
|
||||
DWORD m_dwDSBufferSize;
|
||||
CWaveFile* m_pWaveFile;
|
||||
DWORD m_dwNumBuffers;
|
||||
DWORD m_dwCreationFlags;
|
||||
|
||||
HRESULT RestoreBuffer( LPDIRECTSOUNDBUFFER pDSB, BOOL* pbWasRestored );
|
||||
|
||||
public:
|
||||
CSound( LPDIRECTSOUNDBUFFER* apDSBuffer, DWORD dwDSBufferSize, DWORD dwNumBuffers,
|
||||
CWaveFile* pWaveFile, DWORD dwCreationFlags );
|
||||
virtual ~CSound();
|
||||
|
||||
HRESULT Get3DBufferInterface( DWORD dwIndex, LPDIRECTSOUND3DBUFFER* ppDS3DBuffer );
|
||||
HRESULT FillBufferWithSound( LPDIRECTSOUNDBUFFER pDSB, BOOL bRepeatWavIfBufferLarger );
|
||||
LPDIRECTSOUNDBUFFER GetFreeBuffer();
|
||||
LPDIRECTSOUNDBUFFER GetBuffer( DWORD dwIndex );
|
||||
|
||||
HRESULT Play( DWORD dwPriority = 0, DWORD dwFlags = 0, LONG lVolume = 0, LONG lFrequency = -1,
|
||||
LONG lPan = 0 );
|
||||
HRESULT Play3D( LPDS3DBUFFER p3DBuffer, DWORD dwPriority = 0, DWORD dwFlags = 0, LONG lFrequency = 0 );
|
||||
HRESULT Stop();
|
||||
HRESULT Reset();
|
||||
BOOL IsSoundPlaying();
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: class CStreamingSound
|
||||
// Desc: Encapsulates functionality to play a wave file with DirectSound.
|
||||
// The Create() method loads a chunk of wave file into the buffer,
|
||||
// and as sound plays more is written to the buffer by calling
|
||||
// HandleWaveStreamNotification() whenever hNotifyEvent is signaled.
|
||||
//-----------------------------------------------------------------------------
|
||||
class CStreamingSound : public CSound
|
||||
{
|
||||
protected:
|
||||
DWORD m_dwLastPlayPos;
|
||||
DWORD m_dwPlayProgress;
|
||||
DWORD m_dwNotifySize;
|
||||
DWORD m_dwNextWriteOffset;
|
||||
BOOL m_bFillNextNotificationWithSilence;
|
||||
|
||||
public:
|
||||
CStreamingSound( LPDIRECTSOUNDBUFFER pDSBuffer, DWORD dwDSBufferSize, CWaveFile* pWaveFile,
|
||||
DWORD dwNotifySize );
|
||||
~CStreamingSound();
|
||||
|
||||
HRESULT HandleWaveStreamNotification( BOOL bLoopedPlay );
|
||||
HRESULT Reset();
|
||||
};
|
||||
|
||||
#endif // DXUTSOUND_H
|
||||
539
Demos/DX11ClothDemo/DXUT/Optional/SDKwavefile.cpp
Normal file
539
Demos/DX11ClothDemo/DXUT/Optional/SDKwavefile.cpp
Normal file
@@ -0,0 +1,539 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// File: SDKWaveFile.cpp
|
||||
//
|
||||
// Desc: Classes for reading and writing wav files. Feel free to use this class
|
||||
// as a starting point for adding extra functionality.
|
||||
//
|
||||
// XNA Developer Connection
|
||||
//
|
||||
// Copyright (c) Microsoft Corp. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
#define STRICT
|
||||
#include "DXUT.h"
|
||||
#include "SDKwavefile.h"
|
||||
#undef min // use __min instead
|
||||
#undef max // use __max instead
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: CWaveFile::CWaveFile()
|
||||
// Desc: Constructs the class. Call Open() to open a wave file for reading.
|
||||
// Then call Read() as needed. Calling the destructor or Close()
|
||||
// will close the file.
|
||||
//-----------------------------------------------------------------------------
|
||||
CWaveFile::CWaveFile()
|
||||
{
|
||||
m_pwfx = NULL;
|
||||
m_hmmio = NULL;
|
||||
m_pResourceBuffer = NULL;
|
||||
m_dwSize = 0;
|
||||
m_bIsReadingFromMemory = FALSE;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: CWaveFile::~CWaveFile()
|
||||
// Desc: Destructs the class
|
||||
//-----------------------------------------------------------------------------
|
||||
CWaveFile::~CWaveFile()
|
||||
{
|
||||
Close();
|
||||
|
||||
if( !m_bIsReadingFromMemory )
|
||||
SAFE_DELETE_ARRAY( m_pwfx );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: CWaveFile::Open()
|
||||
// Desc: Opens a wave file for reading
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT CWaveFile::Open( LPWSTR strFileName, WAVEFORMATEX* pwfx, DWORD dwFlags )
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
m_dwFlags = dwFlags;
|
||||
m_bIsReadingFromMemory = FALSE;
|
||||
|
||||
if( m_dwFlags == WAVEFILE_READ )
|
||||
{
|
||||
if( strFileName == NULL )
|
||||
return E_INVALIDARG;
|
||||
SAFE_DELETE_ARRAY( m_pwfx );
|
||||
|
||||
m_hmmio = mmioOpen( strFileName, NULL, MMIO_ALLOCBUF | MMIO_READ );
|
||||
|
||||
if( NULL == m_hmmio )
|
||||
{
|
||||
HRSRC hResInfo;
|
||||
HGLOBAL hResData;
|
||||
DWORD dwSize;
|
||||
VOID* pvRes;
|
||||
|
||||
// Loading it as a file failed, so try it as a resource
|
||||
if( NULL == ( hResInfo = FindResource( NULL, strFileName, L"WAVE" ) ) )
|
||||
{
|
||||
if( NULL == ( hResInfo = FindResource( NULL, strFileName, L"WAV" ) ) )
|
||||
return DXTRACE_ERR( L"FindResource", E_FAIL );
|
||||
}
|
||||
|
||||
if( NULL == ( hResData = LoadResource( GetModuleHandle( NULL ), hResInfo ) ) )
|
||||
return DXTRACE_ERR( L"LoadResource", E_FAIL );
|
||||
|
||||
if( 0 == ( dwSize = SizeofResource( GetModuleHandle( NULL ), hResInfo ) ) )
|
||||
return DXTRACE_ERR( L"SizeofResource", E_FAIL );
|
||||
|
||||
if( NULL == ( pvRes = LockResource( hResData ) ) )
|
||||
return DXTRACE_ERR( L"LockResource", E_FAIL );
|
||||
|
||||
m_pResourceBuffer = new CHAR[ dwSize ];
|
||||
if( m_pResourceBuffer == NULL )
|
||||
return DXTRACE_ERR( L"new", E_OUTOFMEMORY );
|
||||
memcpy( m_pResourceBuffer, pvRes, dwSize );
|
||||
|
||||
MMIOINFO mmioInfo;
|
||||
ZeroMemory( &mmioInfo, sizeof( mmioInfo ) );
|
||||
mmioInfo.fccIOProc = FOURCC_MEM;
|
||||
mmioInfo.cchBuffer = dwSize;
|
||||
mmioInfo.pchBuffer = ( CHAR* )m_pResourceBuffer;
|
||||
|
||||
m_hmmio = mmioOpen( NULL, &mmioInfo, MMIO_ALLOCBUF | MMIO_READ );
|
||||
}
|
||||
|
||||
if( FAILED( hr = ReadMMIO() ) )
|
||||
{
|
||||
// ReadMMIO will fail if its an not a wave file
|
||||
mmioClose( m_hmmio, 0 );
|
||||
return DXTRACE_ERR( L"ReadMMIO", hr );
|
||||
}
|
||||
|
||||
if( FAILED( hr = ResetFile() ) )
|
||||
return DXTRACE_ERR( L"ResetFile", hr );
|
||||
|
||||
// After the reset, the size of the wav file is m_ck.cksize so store it now
|
||||
m_dwSize = m_ck.cksize;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_hmmio = mmioOpen( strFileName, NULL, MMIO_ALLOCBUF |
|
||||
MMIO_READWRITE |
|
||||
MMIO_CREATE );
|
||||
if( NULL == m_hmmio )
|
||||
return DXTRACE_ERR( L"mmioOpen", E_FAIL );
|
||||
|
||||
if( FAILED( hr = WriteMMIO( pwfx ) ) )
|
||||
{
|
||||
mmioClose( m_hmmio, 0 );
|
||||
return DXTRACE_ERR( L"WriteMMIO", hr );
|
||||
}
|
||||
|
||||
if( FAILED( hr = ResetFile() ) )
|
||||
return DXTRACE_ERR( L"ResetFile", hr );
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: CWaveFile::OpenFromMemory()
|
||||
// Desc: copy data to CWaveFile member variable from memory
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT CWaveFile::OpenFromMemory( BYTE* pbData, ULONG ulDataSize,
|
||||
WAVEFORMATEX* pwfx, DWORD dwFlags )
|
||||
{
|
||||
m_pwfx = pwfx;
|
||||
m_ulDataSize = ulDataSize;
|
||||
m_pbData = pbData;
|
||||
m_pbDataCur = m_pbData;
|
||||
m_bIsReadingFromMemory = TRUE;
|
||||
|
||||
if( dwFlags != WAVEFILE_READ )
|
||||
return E_NOTIMPL;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: CWaveFile::ReadMMIO()
|
||||
// Desc: Support function for reading from a multimedia I/O stream.
|
||||
// m_hmmio must be valid before calling. This function uses it to
|
||||
// update m_ckRiff, and m_pwfx.
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT CWaveFile::ReadMMIO()
|
||||
{
|
||||
MMCKINFO ckIn; // chunk info. for general use.
|
||||
PCMWAVEFORMAT pcmWaveFormat; // Temp PCM structure to load in.
|
||||
|
||||
m_pwfx = NULL;
|
||||
|
||||
if( ( 0 != mmioDescend( m_hmmio, &m_ckRiff, NULL, 0 ) ) )
|
||||
return DXTRACE_ERR( L"mmioDescend", E_FAIL );
|
||||
|
||||
// Check to make sure this is a valid wave file
|
||||
if( ( m_ckRiff.ckid != FOURCC_RIFF ) ||
|
||||
( m_ckRiff.fccType != mmioFOURCC( 'W', 'A', 'V', 'E' ) ) )
|
||||
return DXTRACE_ERR( L"mmioFOURCC", E_FAIL );
|
||||
|
||||
// Search the input file for for the 'fmt ' chunk.
|
||||
ckIn.ckid = mmioFOURCC( 'f', 'm', 't', ' ' );
|
||||
if( 0 != mmioDescend( m_hmmio, &ckIn, &m_ckRiff, MMIO_FINDCHUNK ) )
|
||||
return DXTRACE_ERR( L"mmioDescend", E_FAIL );
|
||||
|
||||
// Expect the 'fmt' chunk to be at least as large as <PCMWAVEFORMAT>;
|
||||
// if there are extra parameters at the end, we'll ignore them
|
||||
if( ckIn.cksize < ( LONG )sizeof( PCMWAVEFORMAT ) )
|
||||
return DXTRACE_ERR( L"sizeof(PCMWAVEFORMAT)", E_FAIL );
|
||||
|
||||
// Read the 'fmt ' chunk into <pcmWaveFormat>.
|
||||
if( mmioRead( m_hmmio, ( HPSTR )&pcmWaveFormat,
|
||||
sizeof( pcmWaveFormat ) ) != sizeof( pcmWaveFormat ) )
|
||||
return DXTRACE_ERR( L"mmioRead", E_FAIL );
|
||||
|
||||
// Allocate the waveformatex, but if its not pcm format, read the next
|
||||
// word, and thats how many extra bytes to allocate.
|
||||
if( pcmWaveFormat.wf.wFormatTag == WAVE_FORMAT_PCM )
|
||||
{
|
||||
m_pwfx = ( WAVEFORMATEX* )new CHAR[ sizeof( WAVEFORMATEX ) ];
|
||||
if( NULL == m_pwfx )
|
||||
return DXTRACE_ERR( L"m_pwfx", E_FAIL );
|
||||
|
||||
// Copy the bytes from the pcm structure to the waveformatex structure
|
||||
memcpy( m_pwfx, &pcmWaveFormat, sizeof( pcmWaveFormat ) );
|
||||
m_pwfx->cbSize = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Read in length of extra bytes.
|
||||
WORD cbExtraBytes = 0L;
|
||||
if( mmioRead( m_hmmio, ( CHAR* )&cbExtraBytes, sizeof( WORD ) ) != sizeof( WORD ) )
|
||||
return DXTRACE_ERR( L"mmioRead", E_FAIL );
|
||||
|
||||
m_pwfx = ( WAVEFORMATEX* )new CHAR[ sizeof( WAVEFORMATEX ) + cbExtraBytes ];
|
||||
if( NULL == m_pwfx )
|
||||
return DXTRACE_ERR( L"new", E_FAIL );
|
||||
|
||||
// Copy the bytes from the pcm structure to the waveformatex structure
|
||||
memcpy( m_pwfx, &pcmWaveFormat, sizeof( pcmWaveFormat ) );
|
||||
m_pwfx->cbSize = cbExtraBytes;
|
||||
|
||||
// Now, read those extra bytes into the structure, if cbExtraAlloc != 0.
|
||||
if( mmioRead( m_hmmio, ( CHAR* )( ( ( BYTE* )&( m_pwfx->cbSize ) ) + sizeof( WORD ) ),
|
||||
cbExtraBytes ) != cbExtraBytes )
|
||||
{
|
||||
SAFE_DELETE( m_pwfx );
|
||||
return DXTRACE_ERR( L"mmioRead", E_FAIL );
|
||||
}
|
||||
}
|
||||
|
||||
// Ascend the input file out of the 'fmt ' chunk.
|
||||
if( 0 != mmioAscend( m_hmmio, &ckIn, 0 ) )
|
||||
{
|
||||
SAFE_DELETE( m_pwfx );
|
||||
return DXTRACE_ERR( L"mmioAscend", E_FAIL );
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: CWaveFile::GetSize()
|
||||
// Desc: Retuns the size of the read access wave file
|
||||
//-----------------------------------------------------------------------------
|
||||
DWORD CWaveFile::GetSize()
|
||||
{
|
||||
return m_dwSize;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: CWaveFile::ResetFile()
|
||||
// Desc: Resets the internal m_ck pointer so reading starts from the
|
||||
// beginning of the file again
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT CWaveFile::ResetFile()
|
||||
{
|
||||
if( m_bIsReadingFromMemory )
|
||||
{
|
||||
m_pbDataCur = m_pbData;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_hmmio == NULL )
|
||||
return CO_E_NOTINITIALIZED;
|
||||
|
||||
if( m_dwFlags == WAVEFILE_READ )
|
||||
{
|
||||
// Seek to the data
|
||||
if( -1 == mmioSeek( m_hmmio, m_ckRiff.dwDataOffset + sizeof( FOURCC ),
|
||||
SEEK_SET ) )
|
||||
return DXTRACE_ERR( L"mmioSeek", E_FAIL );
|
||||
|
||||
// Search the input file for the 'data' chunk.
|
||||
m_ck.ckid = mmioFOURCC( 'd', 'a', 't', 'a' );
|
||||
if( 0 != mmioDescend( m_hmmio, &m_ck, &m_ckRiff, MMIO_FINDCHUNK ) )
|
||||
return DXTRACE_ERR( L"mmioDescend", E_FAIL );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create the 'data' chunk that holds the waveform samples.
|
||||
m_ck.ckid = mmioFOURCC( 'd', 'a', 't', 'a' );
|
||||
m_ck.cksize = 0;
|
||||
|
||||
if( 0 != mmioCreateChunk( m_hmmio, &m_ck, 0 ) )
|
||||
return DXTRACE_ERR( L"mmioCreateChunk", E_FAIL );
|
||||
|
||||
if( 0 != mmioGetInfo( m_hmmio, &m_mmioinfoOut, 0 ) )
|
||||
return DXTRACE_ERR( L"mmioGetInfo", E_FAIL );
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: CWaveFile::Read()
|
||||
// Desc: Reads section of data from a wave file into pBuffer and returns
|
||||
// how much read in pdwSizeRead, reading not more than dwSizeToRead.
|
||||
// This uses m_ck to determine where to start reading from. So
|
||||
// subsequent calls will be continue where the last left off unless
|
||||
// Reset() is called.
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT CWaveFile::Read( BYTE* pBuffer, DWORD dwSizeToRead, DWORD* pdwSizeRead )
|
||||
{
|
||||
if( m_bIsReadingFromMemory )
|
||||
{
|
||||
if( m_pbDataCur == NULL )
|
||||
return CO_E_NOTINITIALIZED;
|
||||
if( pdwSizeRead != NULL )
|
||||
*pdwSizeRead = 0;
|
||||
|
||||
if( ( BYTE* )( m_pbDataCur + dwSizeToRead ) >
|
||||
( BYTE* )( m_pbData + m_ulDataSize ) )
|
||||
{
|
||||
dwSizeToRead = m_ulDataSize - ( DWORD )( m_pbDataCur - m_pbData );
|
||||
}
|
||||
|
||||
#pragma warning( disable: 4616 ) // disable warning about warning number '22104' being out of range
|
||||
#pragma warning( disable: 22104 ) // disable PREfast warning during static code analysis
|
||||
CopyMemory( pBuffer, m_pbDataCur, dwSizeToRead );
|
||||
#pragma warning( default: 22104 )
|
||||
#pragma warning( default: 4616 )
|
||||
|
||||
if( pdwSizeRead != NULL )
|
||||
*pdwSizeRead = dwSizeToRead;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
MMIOINFO mmioinfoIn; // current status of m_hmmio
|
||||
|
||||
if( m_hmmio == NULL )
|
||||
return CO_E_NOTINITIALIZED;
|
||||
if( pBuffer == NULL || pdwSizeRead == NULL )
|
||||
return E_INVALIDARG;
|
||||
|
||||
*pdwSizeRead = 0;
|
||||
|
||||
if( 0 != mmioGetInfo( m_hmmio, &mmioinfoIn, 0 ) )
|
||||
return DXTRACE_ERR( L"mmioGetInfo", E_FAIL );
|
||||
|
||||
UINT cbDataIn = dwSizeToRead;
|
||||
if( cbDataIn > m_ck.cksize )
|
||||
cbDataIn = m_ck.cksize;
|
||||
|
||||
m_ck.cksize -= cbDataIn;
|
||||
|
||||
for( DWORD cT = 0; cT < cbDataIn; cT++ )
|
||||
{
|
||||
// Copy the bytes from the io to the buffer.
|
||||
if( mmioinfoIn.pchNext == mmioinfoIn.pchEndRead )
|
||||
{
|
||||
if( 0 != mmioAdvance( m_hmmio, &mmioinfoIn, MMIO_READ ) )
|
||||
return DXTRACE_ERR( L"mmioAdvance", E_FAIL );
|
||||
|
||||
if( mmioinfoIn.pchNext == mmioinfoIn.pchEndRead )
|
||||
return DXTRACE_ERR( L"mmioinfoIn.pchNext", E_FAIL );
|
||||
}
|
||||
|
||||
// Actual copy.
|
||||
*( ( BYTE* )pBuffer + cT ) = *( ( BYTE* )mmioinfoIn.pchNext );
|
||||
mmioinfoIn.pchNext++;
|
||||
}
|
||||
|
||||
if( 0 != mmioSetInfo( m_hmmio, &mmioinfoIn, 0 ) )
|
||||
return DXTRACE_ERR( L"mmioSetInfo", E_FAIL );
|
||||
|
||||
*pdwSizeRead = cbDataIn;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: CWaveFile::Close()
|
||||
// Desc: Closes the wave file
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT CWaveFile::Close()
|
||||
{
|
||||
if( m_dwFlags == WAVEFILE_READ )
|
||||
{
|
||||
mmioClose( m_hmmio, 0 );
|
||||
m_hmmio = NULL;
|
||||
SAFE_DELETE_ARRAY( m_pResourceBuffer );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_mmioinfoOut.dwFlags |= MMIO_DIRTY;
|
||||
|
||||
if( m_hmmio == NULL )
|
||||
return CO_E_NOTINITIALIZED;
|
||||
|
||||
if( 0 != mmioSetInfo( m_hmmio, &m_mmioinfoOut, 0 ) )
|
||||
return DXTRACE_ERR( L"mmioSetInfo", E_FAIL );
|
||||
|
||||
// Ascend the output file out of the 'data' chunk -- this will cause
|
||||
// the chunk size of the 'data' chunk to be written.
|
||||
if( 0 != mmioAscend( m_hmmio, &m_ck, 0 ) )
|
||||
return DXTRACE_ERR( L"mmioAscend", E_FAIL );
|
||||
|
||||
// Do this here instead...
|
||||
if( 0 != mmioAscend( m_hmmio, &m_ckRiff, 0 ) )
|
||||
return DXTRACE_ERR( L"mmioAscend", E_FAIL );
|
||||
|
||||
mmioSeek( m_hmmio, 0, SEEK_SET );
|
||||
|
||||
if( 0 != ( INT )mmioDescend( m_hmmio, &m_ckRiff, NULL, 0 ) )
|
||||
return DXTRACE_ERR( L"mmioDescend", E_FAIL );
|
||||
|
||||
m_ck.ckid = mmioFOURCC( 'f', 'a', 'c', 't' );
|
||||
|
||||
if( 0 == mmioDescend( m_hmmio, &m_ck, &m_ckRiff, MMIO_FINDCHUNK ) )
|
||||
{
|
||||
DWORD dwSamples = 0;
|
||||
mmioWrite( m_hmmio, ( HPSTR )&dwSamples, sizeof( DWORD ) );
|
||||
mmioAscend( m_hmmio, &m_ck, 0 );
|
||||
}
|
||||
|
||||
// Ascend the output file out of the 'RIFF' chunk -- this will cause
|
||||
// the chunk size of the 'RIFF' chunk to be written.
|
||||
if( 0 != mmioAscend( m_hmmio, &m_ckRiff, 0 ) )
|
||||
return DXTRACE_ERR( L"mmioAscend", E_FAIL );
|
||||
|
||||
mmioClose( m_hmmio, 0 );
|
||||
m_hmmio = NULL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: CWaveFile::WriteMMIO()
|
||||
// Desc: Support function for reading from a multimedia I/O stream
|
||||
// pwfxDest is the WAVEFORMATEX for this new wave file.
|
||||
// m_hmmio must be valid before calling. This function uses it to
|
||||
// update m_ckRiff, and m_ck.
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT CWaveFile::WriteMMIO( WAVEFORMATEX* pwfxDest )
|
||||
{
|
||||
DWORD dwFactChunk; // Contains the actual fact chunk. Garbage until WaveCloseWriteFile.
|
||||
MMCKINFO ckOut1;
|
||||
|
||||
dwFactChunk = ( DWORD )-1;
|
||||
|
||||
// Create the output file RIFF chunk of form type 'WAVE'.
|
||||
m_ckRiff.fccType = mmioFOURCC( 'W', 'A', 'V', 'E' );
|
||||
m_ckRiff.cksize = 0;
|
||||
|
||||
if( 0 != mmioCreateChunk( m_hmmio, &m_ckRiff, MMIO_CREATERIFF ) )
|
||||
return DXTRACE_ERR( L"mmioCreateChunk", E_FAIL );
|
||||
|
||||
// We are now descended into the 'RIFF' chunk we just created.
|
||||
// Now create the 'fmt ' chunk. Since we know the size of this chunk,
|
||||
// specify it in the MMCKINFO structure so MMIO doesn't have to seek
|
||||
// back and set the chunk size after ascending from the chunk.
|
||||
m_ck.ckid = mmioFOURCC( 'f', 'm', 't', ' ' );
|
||||
m_ck.cksize = sizeof( PCMWAVEFORMAT );
|
||||
|
||||
if( 0 != mmioCreateChunk( m_hmmio, &m_ck, 0 ) )
|
||||
return DXTRACE_ERR( L"mmioCreateChunk", E_FAIL );
|
||||
|
||||
// Write the PCMWAVEFORMAT structure to the 'fmt ' chunk if its that type.
|
||||
if( pwfxDest->wFormatTag == WAVE_FORMAT_PCM )
|
||||
{
|
||||
if( mmioWrite( m_hmmio, ( HPSTR )pwfxDest,
|
||||
sizeof( PCMWAVEFORMAT ) ) != sizeof( PCMWAVEFORMAT ) )
|
||||
return DXTRACE_ERR( L"mmioWrite", E_FAIL );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Write the variable length size.
|
||||
if( ( UINT )mmioWrite( m_hmmio, ( HPSTR )pwfxDest,
|
||||
sizeof( *pwfxDest ) + pwfxDest->cbSize ) !=
|
||||
( sizeof( *pwfxDest ) + pwfxDest->cbSize ) )
|
||||
return DXTRACE_ERR( L"mmioWrite", E_FAIL );
|
||||
}
|
||||
|
||||
// Ascend out of the 'fmt ' chunk, back into the 'RIFF' chunk.
|
||||
if( 0 != mmioAscend( m_hmmio, &m_ck, 0 ) )
|
||||
return DXTRACE_ERR( L"mmioAscend", E_FAIL );
|
||||
|
||||
// Now create the fact chunk, not required for PCM but nice to have. This is filled
|
||||
// in when the close routine is called.
|
||||
ckOut1.ckid = mmioFOURCC( 'f', 'a', 'c', 't' );
|
||||
ckOut1.cksize = 0;
|
||||
|
||||
if( 0 != mmioCreateChunk( m_hmmio, &ckOut1, 0 ) )
|
||||
return DXTRACE_ERR( L"mmioCreateChunk", E_FAIL );
|
||||
|
||||
if( mmioWrite( m_hmmio, ( HPSTR )&dwFactChunk, sizeof( dwFactChunk ) ) !=
|
||||
sizeof( dwFactChunk ) )
|
||||
return DXTRACE_ERR( L"mmioWrite", E_FAIL );
|
||||
|
||||
// Now ascend out of the fact chunk...
|
||||
if( 0 != mmioAscend( m_hmmio, &ckOut1, 0 ) )
|
||||
return DXTRACE_ERR( L"mmioAscend", E_FAIL );
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: CWaveFile::Write()
|
||||
// Desc: Writes data to the open wave file
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT CWaveFile::Write( UINT nSizeToWrite, BYTE* pbSrcData, UINT* pnSizeWrote )
|
||||
{
|
||||
UINT cT;
|
||||
|
||||
if( m_bIsReadingFromMemory )
|
||||
return E_NOTIMPL;
|
||||
if( m_hmmio == NULL )
|
||||
return CO_E_NOTINITIALIZED;
|
||||
if( pnSizeWrote == NULL || pbSrcData == NULL )
|
||||
return E_INVALIDARG;
|
||||
|
||||
*pnSizeWrote = 0;
|
||||
|
||||
for( cT = 0; cT < nSizeToWrite; cT++ )
|
||||
{
|
||||
if( m_mmioinfoOut.pchNext == m_mmioinfoOut.pchEndWrite )
|
||||
{
|
||||
m_mmioinfoOut.dwFlags |= MMIO_DIRTY;
|
||||
if( 0 != mmioAdvance( m_hmmio, &m_mmioinfoOut, MMIO_WRITE ) )
|
||||
return DXTRACE_ERR( L"mmioAdvance", E_FAIL );
|
||||
}
|
||||
|
||||
*( ( BYTE* )m_mmioinfoOut.pchNext ) = *( ( BYTE* )pbSrcData + cT );
|
||||
( BYTE* )m_mmioinfoOut.pchNext++;
|
||||
|
||||
( *pnSizeWrote )++;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
59
Demos/DX11ClothDemo/DXUT/Optional/SDKwavefile.h
Normal file
59
Demos/DX11ClothDemo/DXUT/Optional/SDKwavefile.h
Normal file
@@ -0,0 +1,59 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// File: WaveFile.h
|
||||
//
|
||||
// Copyright (c) Microsoft Corp. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef DXUTWAVEFILE_H
|
||||
#define DXUTWAVEFILE_H
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Typing macros
|
||||
//-----------------------------------------------------------------------------
|
||||
#define WAVEFILE_READ 1
|
||||
#define WAVEFILE_WRITE 2
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: class CWaveFile
|
||||
// Desc: Encapsulates reading or writing sound data to or from a wave file
|
||||
//-----------------------------------------------------------------------------
|
||||
class CWaveFile
|
||||
{
|
||||
public:
|
||||
WAVEFORMATEX* m_pwfx; // Pointer to WAVEFORMATEX structure
|
||||
HMMIO m_hmmio; // MM I/O handle for the WAVE
|
||||
MMCKINFO m_ck; // Multimedia RIFF chunk
|
||||
MMCKINFO m_ckRiff; // Use in opening a WAVE file
|
||||
DWORD m_dwSize; // The size of the wave file
|
||||
MMIOINFO m_mmioinfoOut;
|
||||
DWORD m_dwFlags;
|
||||
BOOL m_bIsReadingFromMemory;
|
||||
BYTE* m_pbData;
|
||||
BYTE* m_pbDataCur;
|
||||
ULONG m_ulDataSize;
|
||||
CHAR* m_pResourceBuffer;
|
||||
|
||||
protected:
|
||||
HRESULT ReadMMIO();
|
||||
HRESULT WriteMMIO( WAVEFORMATEX* pwfxDest );
|
||||
|
||||
public:
|
||||
CWaveFile();
|
||||
~CWaveFile();
|
||||
|
||||
HRESULT Open( LPWSTR strFileName, WAVEFORMATEX* pwfx, DWORD dwFlags );
|
||||
HRESULT OpenFromMemory( BYTE* pbData, ULONG ulDataSize, WAVEFORMATEX* pwfx, DWORD dwFlags );
|
||||
HRESULT Close();
|
||||
|
||||
HRESULT Read( BYTE* pBuffer, DWORD dwSizeToRead, DWORD* pdwSizeRead );
|
||||
HRESULT Write( UINT nSizeToWrite, BYTE* pbData, UINT* pnSizeWrote );
|
||||
|
||||
DWORD GetSize();
|
||||
HRESULT ResetFile();
|
||||
WAVEFORMATEX* GetFormat()
|
||||
{
|
||||
return m_pwfx;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#endif // DXUTWAVEFILE_H
|
||||
BIN
Demos/DX11ClothDemo/DXUT/Optional/directx.ico
Normal file
BIN
Demos/DX11ClothDemo/DXUT/Optional/directx.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
BIN
Demos/DX11ClothDemo/Media/Tiny/Tiny_skin.dds
Normal file
BIN
Demos/DX11ClothDemo/Media/Tiny/Tiny_skin.dds
Normal file
Binary file not shown.
BIN
Demos/DX11ClothDemo/Media/Tiny/tiny.sdkmesh
Normal file
BIN
Demos/DX11ClothDemo/Media/Tiny/tiny.sdkmesh
Normal file
Binary file not shown.
53984
Demos/DX11ClothDemo/Media/Tiny/tiny.x
Normal file
53984
Demos/DX11ClothDemo/Media/Tiny/tiny.x
Normal file
File diff suppressed because it is too large
Load Diff
69
Demos/DX11ClothDemo/Media/UI/DXUTShared.fx
Normal file
69
Demos/DX11ClothDemo/Media/UI/DXUTShared.fx
Normal file
@@ -0,0 +1,69 @@
|
||||
//--------------------------------------------------------------------------------------
|
||||
// File: DXUTShared.fx
|
||||
//
|
||||
//
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Global variables
|
||||
//--------------------------------------------------------------------------------------
|
||||
float4 g_MaterialDiffuseColor; // Material's diffuse color
|
||||
float3 g_LightDir; // Light's direction in world space
|
||||
float4x4 g_mWorld; // World matrix for object
|
||||
float4x4 g_mWorldViewProjection; // World * View * Projection matrix
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Vertex shader output structure
|
||||
//--------------------------------------------------------------------------------------
|
||||
struct VS_OUTPUT
|
||||
{
|
||||
float4 Position : POSITION; // vertex position
|
||||
float4 Diffuse : COLOR0; // vertex diffuse color
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// This shader computes standard transform and lighting
|
||||
//--------------------------------------------------------------------------------------
|
||||
VS_OUTPUT RenderWith1LightNoTextureVS( float4 vPos : POSITION,
|
||||
float3 vNormal : NORMAL )
|
||||
{
|
||||
VS_OUTPUT Output;
|
||||
|
||||
// Transform the position from object space to homogeneous projection space
|
||||
Output.Position = mul(vPos, g_mWorldViewProjection);
|
||||
|
||||
// Transform the normal from object space to world space
|
||||
float3 vNormalWorldSpace;
|
||||
vNormalWorldSpace = normalize(mul(vNormal, (float3x3)g_mWorld)); // normal (world space)
|
||||
|
||||
// Compute simple directional lighting equation
|
||||
Output.Diffuse.rgb = g_MaterialDiffuseColor * max(0,dot(vNormalWorldSpace, g_LightDir));
|
||||
Output.Diffuse.a = 1.0f;
|
||||
|
||||
return Output;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
float4 RenderWith1LightNoTexturePS( float4 Diffuse : COLOR0 ) : COLOR0
|
||||
{
|
||||
return Diffuse;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
technique RenderWith1LightNoTexture
|
||||
{
|
||||
pass P0
|
||||
{
|
||||
VertexShader = compile vs_1_1 RenderWith1LightNoTextureVS();
|
||||
PixelShader = compile ps_1_1 RenderWith1LightNoTexturePS();
|
||||
}
|
||||
}
|
||||
|
||||
BIN
Demos/DX11ClothDemo/Media/UI/Font.dds
Normal file
BIN
Demos/DX11ClothDemo/Media/UI/Font.dds
Normal file
Binary file not shown.
1050
Demos/DX11ClothDemo/Media/UI/arrow.x
Normal file
1050
Demos/DX11ClothDemo/Media/UI/arrow.x
Normal file
File diff suppressed because it is too large
Load Diff
BIN
Demos/DX11ClothDemo/Media/UI/dxutcontrols.dds
Normal file
BIN
Demos/DX11ClothDemo/Media/UI/dxutcontrols.dds
Normal file
Binary file not shown.
BIN
Demos/DX11ClothDemo/amdFlag.bmp
Normal file
BIN
Demos/DX11ClothDemo/amdFlag.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 MiB |
BIN
Demos/DX11ClothDemo/atiFlag.bmp
Normal file
BIN
Demos/DX11ClothDemo/atiFlag.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 MiB |
178
Demos/DX11ClothDemo/btDirectComputeSupport.h
Normal file
178
Demos/DX11ClothDemo/btDirectComputeSupport.h
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef BT_DIRECT_COMPUTE_SUPPORT_HPP
|
||||
#define BT_DIRECT_COMPUTE_SUPPORT_HPP
|
||||
|
||||
// DX11 support
|
||||
#include <windows.h>
|
||||
#include <crtdbg.h>
|
||||
#include <d3d11.h>
|
||||
#include <d3dx11.h>
|
||||
#include <d3dcompiler.h>
|
||||
|
||||
#ifndef SAFE_RELEASE
|
||||
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
|
||||
#endif
|
||||
|
||||
namespace BTAcceleratedSoftBody
|
||||
{
|
||||
|
||||
/**
|
||||
* Class to provide basic DX11 support to an application, wrapping the device creation functionality and necessary pointers.
|
||||
*/
|
||||
class DX11SupportHelper
|
||||
{
|
||||
private:
|
||||
|
||||
ID3D11Device* m_pd3dDevice;
|
||||
ID3D11DeviceContext* m_pd3dImmediateContext;
|
||||
typedef HRESULT (WINAPI * LPD3D11CREATEDEVICE)( IDXGIAdapter*, D3D_DRIVER_TYPE, HMODULE, UINT32, D3D_FEATURE_LEVEL*, UINT, UINT32, ID3D11Device**, D3D_FEATURE_LEVEL*, ID3D11DeviceContext** );
|
||||
HMODULE m_s_hModD3D11;
|
||||
LPD3D11CREATEDEVICE m_s_DynamicD3D11CreateDevice;
|
||||
|
||||
|
||||
bool Dynamic_EnsureD3D11APIs( void )
|
||||
{
|
||||
// If both modules are non-NULL, this function has already been called. Note
|
||||
// that this doesn't guarantee that all ProcAddresses were found.
|
||||
if( m_s_hModD3D11 != NULL )
|
||||
return true;
|
||||
|
||||
// This may fail if Direct3D 11 isn't installed
|
||||
m_s_hModD3D11 = LoadLibraryA( "d3d11.dll" );
|
||||
if( m_s_hModD3D11 != NULL )
|
||||
{
|
||||
m_s_DynamicD3D11CreateDevice = ( LPD3D11CREATEDEVICE )GetProcAddress( m_s_hModD3D11, "D3D11CreateDevice" );
|
||||
}
|
||||
|
||||
return ( m_s_hModD3D11 != NULL );
|
||||
}
|
||||
|
||||
// Helper to call D3D11CreateDevice from d3d11.dll
|
||||
HRESULT WINAPI Dynamic_D3D11CreateDevice( IDXGIAdapter* pAdapter,
|
||||
D3D_DRIVER_TYPE DriverType,
|
||||
HMODULE Software,
|
||||
UINT32 Flags,
|
||||
D3D_FEATURE_LEVEL* pFeatureLevels,
|
||||
UINT FeatureLevels,
|
||||
UINT32 SDKVersion,
|
||||
ID3D11Device** ppDevice,
|
||||
D3D_FEATURE_LEVEL* pFeatureLevel,
|
||||
ID3D11DeviceContext** ppImmediateContext )
|
||||
{
|
||||
if( Dynamic_EnsureD3D11APIs() && m_s_DynamicD3D11CreateDevice != NULL )
|
||||
{
|
||||
return m_s_DynamicD3D11CreateDevice(
|
||||
pAdapter,
|
||||
DriverType,
|
||||
Software,
|
||||
Flags,
|
||||
pFeatureLevels,
|
||||
FeatureLevels,
|
||||
SDKVersion,
|
||||
ppDevice,
|
||||
pFeatureLevel,
|
||||
ppImmediateContext );
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBoxA( 0, "Could not locate resources need by d3d11."\
|
||||
" Please install the latest DirectX SDK.", "Error", MB_ICONEXCLAMATION );
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
DX11SupportHelper()
|
||||
{
|
||||
m_s_hModD3D11 = 0;
|
||||
m_s_DynamicD3D11CreateDevice = 0;
|
||||
m_pd3dDevice = 0;
|
||||
m_pd3dImmediateContext = 0;
|
||||
}
|
||||
|
||||
virtual ~DX11SupportHelper()
|
||||
{
|
||||
SAFE_RELEASE( m_pd3dDevice );
|
||||
SAFE_RELEASE( m_pd3dImmediateContext );
|
||||
}
|
||||
|
||||
ID3D11Device* getDevice()
|
||||
{
|
||||
return m_pd3dDevice;
|
||||
}
|
||||
|
||||
ID3D11DeviceContext* getContext()
|
||||
{
|
||||
return m_pd3dImmediateContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do a simplistic initialisation of the first DirectCompute device in the system.
|
||||
* Clearly the user can do their own version for more flexibility.
|
||||
*/
|
||||
bool InitComputeShaderDevice()
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
UINT createDeviceFlags = 0;
|
||||
#ifdef _DEBUG
|
||||
createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
|
||||
#endif
|
||||
|
||||
D3D_FEATURE_LEVEL fl[] = {
|
||||
D3D_FEATURE_LEVEL_11_0,
|
||||
D3D_FEATURE_LEVEL_10_1,
|
||||
D3D_FEATURE_LEVEL_10_0
|
||||
};
|
||||
|
||||
// Create a hardware Direct3D 11 device
|
||||
hr = Dynamic_D3D11CreateDevice( NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags,
|
||||
fl, _countof(fl), D3D11_SDK_VERSION, &m_pd3dDevice, NULL, &m_pd3dImmediateContext );
|
||||
|
||||
// Check if the hardware device supports Compute Shader 4.0
|
||||
D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS hwopts;
|
||||
m_pd3dDevice->CheckFeatureSupport(D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS, &hwopts, sizeof(hwopts));
|
||||
if( !hwopts.ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x ) {
|
||||
SAFE_RELEASE( m_pd3dImmediateContext );
|
||||
SAFE_RELEASE( m_pd3dDevice );
|
||||
|
||||
int result = MessageBoxA(0, "This program needs to use the Direct3D 11 reference device. This device implements the entire Direct3D 11 feature set, but runs very slowly. Do you wish to continue?", "Compute Shader Sort", MB_ICONINFORMATION | MB_YESNO);
|
||||
if( result == IDNO )
|
||||
return false;//E_FAIL;
|
||||
|
||||
// Create a reference device if hardware is not available
|
||||
hr = Dynamic_D3D11CreateDevice( NULL, D3D_DRIVER_TYPE_REFERENCE, NULL, createDeviceFlags,
|
||||
fl, _countof(fl), D3D11_SDK_VERSION, &m_pd3dDevice, NULL, &m_pd3dImmediateContext );
|
||||
if( FAILED( hr ) )
|
||||
return (hr==S_OK);
|
||||
|
||||
printf("Using Direct3D 11 Reference Device\n");
|
||||
}
|
||||
|
||||
bool returnVal = (hr==S_OK);
|
||||
|
||||
|
||||
return returnVal;
|
||||
|
||||
} // InitComputeShaderDevice
|
||||
|
||||
}; // DX11SupportHelper
|
||||
|
||||
} // namespace BTAcceleratedSoftBody
|
||||
|
||||
|
||||
#endif // #ifndef BT_DIRECT_COMPUTE_SUPPORT_HPP
|
||||
274
Demos/DX11ClothDemo/cap.h
Normal file
274
Demos/DX11ClothDemo/cap.h
Normal file
@@ -0,0 +1,274 @@
|
||||
|
||||
class cap
|
||||
{
|
||||
public:
|
||||
|
||||
ID3D11Buffer* g_pIndexBuffer;
|
||||
ID3D11Buffer* pVB[1];
|
||||
UINT Strides[1];
|
||||
UINT Offsets[1];
|
||||
|
||||
double x_offset, y_offset, z_offset;
|
||||
|
||||
int width,height;
|
||||
bool top;
|
||||
|
||||
ID3D11Texture2D *texture2D;
|
||||
ID3D11ShaderResourceView *texture2D_view;
|
||||
btCollisionShape *collisionShape;
|
||||
btCollisionObject *collisionObject;
|
||||
|
||||
void set_collision_object(btCollisionObject* co)
|
||||
{
|
||||
collisionObject = co;
|
||||
}
|
||||
|
||||
void set_collision_shape(btCollisionShape* cs)
|
||||
{
|
||||
collisionShape = cs;
|
||||
}
|
||||
|
||||
void create_texture(void)
|
||||
{
|
||||
D3DX11_IMAGE_LOAD_INFO loadInfo;
|
||||
ZeroMemory(&loadInfo, sizeof(D3DX11_IMAGE_LOAD_INFO) );
|
||||
loadInfo.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
loadInfo.Format = DXGI_FORMAT_BC1_UNORM;
|
||||
|
||||
HRESULT hr = D3DX11CreateShaderResourceViewFromFile(g_pd3dDevice, L"texture.bmp", &loadInfo, NULL, &texture2D_view, NULL);
|
||||
hr = hr;
|
||||
}
|
||||
|
||||
void destroy()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void draw(void)
|
||||
{
|
||||
|
||||
ID3D11DeviceContext* pd3dImmediateContext = DXUTGetD3D11DeviceContext();
|
||||
|
||||
D3DXMATRIX mWorldViewProjection;
|
||||
D3DXVECTOR3 vLightDir;
|
||||
D3DXMATRIX mWorld;
|
||||
D3DXMATRIX mView;
|
||||
D3DXMATRIX mProj;
|
||||
|
||||
// Get the projection & view matrix from the camera class
|
||||
mProj = *g_Camera.GetProjMatrix();
|
||||
mView = *g_Camera.GetViewMatrix();
|
||||
|
||||
// Get the light direction
|
||||
vLightDir = g_LightControl.GetLightDirection();
|
||||
|
||||
// Per frame cb update
|
||||
D3D11_MAPPED_SUBRESOURCE MappedResource;
|
||||
|
||||
HRESULT hr;
|
||||
|
||||
V( pd3dImmediateContext->Map( g_pcbPSPerFrame, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) );
|
||||
CB_PS_PER_FRAME* pPerFrame = ( CB_PS_PER_FRAME* )MappedResource.pData;
|
||||
float fAmbient = 0.1f;
|
||||
pPerFrame->m_vLightDirAmbient = D3DXVECTOR4( vLightDir.x, vLightDir.y, vLightDir.z, fAmbient );
|
||||
pd3dImmediateContext->Unmap( g_pcbPSPerFrame, 0 );
|
||||
|
||||
pd3dImmediateContext->PSSetConstantBuffers( g_iCBPSPerFrameBind, 1, &g_pcbPSPerFrame );
|
||||
|
||||
|
||||
///////////////////////////////////////Modify below//////////////////////////////////////////////////////
|
||||
|
||||
//Get the mesh
|
||||
//IA setup
|
||||
pd3dImmediateContext->IASetInputLayout( g_pVertexLayout11 );
|
||||
|
||||
//This is where we pass the vertex buffer to DX
|
||||
pd3dImmediateContext->IASetVertexBuffers( 0, 1, pVB, Strides, Offsets );
|
||||
|
||||
//This is where we pass the index buffer to DX
|
||||
pd3dImmediateContext->IASetIndexBuffer( g_pIndexBuffer, DXGI_FORMAT_R32_UINT, 0 );
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Set the shaders
|
||||
pd3dImmediateContext->VSSetShader( g_pVertexShader, NULL, 0 );
|
||||
pd3dImmediateContext->PSSetShader( g_pPixelShader, NULL, 0 );
|
||||
pd3dImmediateContext->GSSetShader( g_pGeometryShader, NULL, 0);
|
||||
|
||||
// Set the per object constant data
|
||||
|
||||
|
||||
|
||||
btTransform trans = collisionObject->getWorldTransform();
|
||||
|
||||
|
||||
|
||||
btVector3 origin = trans.getOrigin();
|
||||
btMatrix3x3 btM = trans.getBasis();
|
||||
|
||||
btScalar* scalar_matrix = new btScalar[16];;
|
||||
trans.getOpenGLMatrix(scalar_matrix);
|
||||
|
||||
D3DXMATRIXA16 m_trans(scalar_matrix[0],scalar_matrix[1],scalar_matrix[2],scalar_matrix[3],
|
||||
scalar_matrix[4],scalar_matrix[5],scalar_matrix[6],scalar_matrix[7],
|
||||
scalar_matrix[8],scalar_matrix[9],scalar_matrix[10],scalar_matrix[11],
|
||||
scalar_matrix[12],scalar_matrix[13],scalar_matrix[14],scalar_matrix[15]);
|
||||
|
||||
D3DXMATRIXA16 m_scale;
|
||||
float sc = 10;
|
||||
D3DXMatrixScaling(&m_scale,sc,sc,sc);
|
||||
|
||||
|
||||
D3DXVECTOR3 vCenter( global_shift_x, global_shift_y, global_shift_z);
|
||||
|
||||
D3DXMatrixTranslation( &g_mCenterMesh, -vCenter.x+x_offset, -vCenter.y+y_offset, -vCenter.z+z_offset );
|
||||
|
||||
|
||||
D3DXMATRIXA16 m_trans_transpose;
|
||||
D3DXMatrixTranspose(&m_trans_transpose,&m_trans);
|
||||
|
||||
mWorld = *g_Camera.GetWorldMatrix() ;
|
||||
mProj = *g_Camera.GetProjMatrix();
|
||||
mView = m_trans * *g_Camera.GetViewMatrix();
|
||||
|
||||
mWorldViewProjection = mView * mProj;
|
||||
|
||||
|
||||
// VS Per object
|
||||
V( pd3dImmediateContext->Map( g_pcbVSPerObject, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) );
|
||||
CB_VS_PER_OBJECT* pVSPerObject = ( CB_VS_PER_OBJECT* )MappedResource.pData;
|
||||
D3DXMatrixTranspose( &pVSPerObject->m_WorldViewProj, &mWorldViewProjection );
|
||||
D3DXMatrixTranspose( &pVSPerObject->m_World, &mWorld );
|
||||
pd3dImmediateContext->Unmap( g_pcbVSPerObject, 0 );
|
||||
|
||||
pd3dImmediateContext->VSSetConstantBuffers( g_iCBVSPerObjectBind, 1, &g_pcbVSPerObject );
|
||||
|
||||
// PS Per object
|
||||
V( pd3dImmediateContext->Map( g_pcbPSPerObject, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) );
|
||||
CB_PS_PER_OBJECT* pPSPerObject = ( CB_PS_PER_OBJECT* )MappedResource.pData;
|
||||
pPSPerObject->m_vObjectColor = D3DXVECTOR4( 1, 1, 1, 1 );
|
||||
pd3dImmediateContext->Unmap( g_pcbPSPerObject, 0 );
|
||||
|
||||
pd3dImmediateContext->PSSetConstantBuffers( g_iCBPSPerObjectBind, 1, &g_pcbPSPerObject );
|
||||
|
||||
//Render
|
||||
SDKMESH_SUBSET* pSubset = NULL;
|
||||
D3D11_PRIMITIVE_TOPOLOGY PrimType;
|
||||
|
||||
pd3dImmediateContext->PSSetSamplers( 0, 1, &g_pSamLinear );
|
||||
|
||||
{
|
||||
// Get the subset
|
||||
pSubset = g_Mesh11.GetSubset( 0, 0 );
|
||||
|
||||
pd3dImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
|
||||
pd3dImmediateContext->PSSetShaderResources(0,1,&texture2D_view);
|
||||
|
||||
pd3dImmediateContext->DrawIndexed( (width*3*2+2 + height*width*3*2), 0, ( UINT )pSubset->VertexStart );
|
||||
}
|
||||
|
||||
SAFE_RELEASE(pd3dImmediateContext);
|
||||
}
|
||||
|
||||
|
||||
void create_buffers(int width_, int height_, bool top_)
|
||||
{
|
||||
|
||||
top = top_;
|
||||
width = width_;
|
||||
height = height_;
|
||||
|
||||
D3D11_BUFFER_DESC bufferDesc;
|
||||
bufferDesc.Usage = D3D11_USAGE_DEFAULT;
|
||||
bufferDesc.ByteWidth = sizeof(vertex_struct)*width*height;
|
||||
bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
||||
bufferDesc.CPUAccessFlags = 0;
|
||||
bufferDesc.MiscFlags = 0;
|
||||
|
||||
|
||||
vertex_struct *vertices = new vertex_struct[width*height];
|
||||
|
||||
btCapsuleShape* cs = static_cast<btCapsuleShape*>(collisionShape);
|
||||
float radius = cs->getRadius();
|
||||
float halfHeight = cs->getHalfHeight();
|
||||
|
||||
|
||||
if (top)
|
||||
{
|
||||
for(int y = 0; y < height; y++)
|
||||
{
|
||||
for(int x = 0; x < width; x++)
|
||||
{
|
||||
float X = (x/((float)(width-1)))*3.14159;
|
||||
float Y = (y/((float)(height-1)))*3.14159;
|
||||
float z_coord = radius*cos(X)*sin(Y);
|
||||
float y_coord = radius*sin(X)*sin(Y) + halfHeight;
|
||||
float x_coord = radius*cos(Y);
|
||||
vertices[y*width+x].Pos = D3DXVECTOR3(x_coord, y_coord, z_coord);
|
||||
vertices[y*width+x].Normal = D3DXVECTOR3(x_coord,y_coord-halfHeight,z_coord);
|
||||
vertices[y*width+x].Texcoord = D3DXVECTOR2(x/( (float)(width-1)), y/((float)(height-1)));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else
|
||||
|
||||
{
|
||||
|
||||
for(int y = 0; y < height; y++)
|
||||
{
|
||||
for(int x = 0; x < width; x++)
|
||||
{
|
||||
float X = (x/((float)(width-1)))*3.14159;
|
||||
float Y = (y/((float)(height-1)))*3.14159;
|
||||
float z_coord = radius*cos(X)*sin(Y);
|
||||
float y_coord = -radius*sin(X)*sin(Y) - halfHeight;
|
||||
float x_coord = radius*cos(Y);
|
||||
vertices[y*width+x].Pos = D3DXVECTOR3(x_coord, y_coord, z_coord);
|
||||
vertices[y*width+x].Normal = D3DXVECTOR3(x_coord,y_coord+halfHeight,z_coord);
|
||||
vertices[y*width+x].Texcoord = D3DXVECTOR2(x/( (float)(width-1)), y/((float)(height-1)));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
D3D11_SUBRESOURCE_DATA InitData;
|
||||
InitData.pSysMem = vertices;
|
||||
InitData.SysMemPitch = 0;
|
||||
InitData.SysMemSlicePitch = 0;
|
||||
|
||||
HRESULT hr = g_pd3dDevice->CreateBuffer(&bufferDesc, &InitData, &pVB[0]);
|
||||
|
||||
|
||||
|
||||
//What is this vertex stride thing all about?
|
||||
Strides[0] = ( UINT )g_Mesh11.GetVertexStride( 0, 0 );
|
||||
Offsets[0] = 0;
|
||||
|
||||
unsigned int* indices = new unsigned int[width*3*2+2 + height*width*3*2];
|
||||
|
||||
for(int y = 0; y < height-1; y++)
|
||||
{
|
||||
for(int x = 0; x < width-1; x++)
|
||||
{
|
||||
indices[x*3*2 + y*width*3*2] = x + y*width;
|
||||
indices[x*3*2+1 + y*width*3*2] = x+1 + y*width;
|
||||
indices[x*3*2+2 + y*width*3*2] = x+width + y*width;
|
||||
|
||||
indices[x*3*2 + 3 + y*width*3*2] = x + 1 + y*width;
|
||||
indices[x*3*2 + 4 + y*width*3*2] = x+(width+1) + y*width;
|
||||
indices[x*3*2 + 5 + y*width*3*2] = x+width + y*width;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bufferDesc.ByteWidth = sizeof(unsigned int)*(width*3*2+2 + height*width*3*2);
|
||||
bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
|
||||
|
||||
InitData.pSysMem = indices;
|
||||
|
||||
hr = g_pd3dDevice->CreateBuffer(&bufferDesc, &InitData, &g_pIndexBuffer);
|
||||
hr = hr;
|
||||
}
|
||||
};
|
||||
286
Demos/DX11ClothDemo/cloth.h
Normal file
286
Demos/DX11ClothDemo/cloth.h
Normal file
@@ -0,0 +1,286 @@
|
||||
|
||||
|
||||
class piece_of_cloth
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
void destroy(void)
|
||||
{
|
||||
|
||||
if(created)
|
||||
{
|
||||
SAFE_RELEASE(g_pIndexBuffer);
|
||||
SAFE_RELEASE(pVB[0]);
|
||||
SAFE_RELEASE(g_pVB_UAV);
|
||||
SAFE_RELEASE(pVB_staging);
|
||||
SAFE_RELEASE(texture2D_view);
|
||||
if(m_vertexBufferDescriptor) delete [] m_vertexBufferDescriptor;
|
||||
if(cpu_buffer) delete [] cpu_buffer;
|
||||
}
|
||||
}
|
||||
|
||||
piece_of_cloth()
|
||||
{
|
||||
created = false;
|
||||
m_vertexBufferDescriptor = NULL;
|
||||
cpu_buffer = NULL;
|
||||
}
|
||||
bool created;
|
||||
|
||||
ID3D11Buffer* g_pIndexBuffer;
|
||||
ID3D11Buffer* pVB[1];
|
||||
ID3D11Buffer* pVB_staging;
|
||||
|
||||
float* cpu_buffer;
|
||||
|
||||
ID3D11UnorderedAccessView* g_pVB_UAV;
|
||||
UINT Strides[1];
|
||||
UINT Offsets[1];
|
||||
|
||||
double x_offset, y_offset, z_offset;
|
||||
|
||||
|
||||
ID3D11ShaderResourceView *texture2D_view;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
|
||||
btVertexBufferDescriptor *m_vertexBufferDescriptor;
|
||||
|
||||
void create_texture(std::wstring filename)
|
||||
{
|
||||
D3DX11_IMAGE_LOAD_INFO loadInfo;
|
||||
ZeroMemory(&loadInfo, sizeof(D3DX11_IMAGE_LOAD_INFO) );
|
||||
loadInfo.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
loadInfo.Format = DXGI_FORMAT_BC1_UNORM;
|
||||
|
||||
HRESULT hr = D3DX11CreateShaderResourceViewFromFile(g_pd3dDevice, filename.c_str(), &loadInfo, NULL, &texture2D_view, NULL);
|
||||
hr = hr;
|
||||
|
||||
}
|
||||
|
||||
void draw(void)
|
||||
{
|
||||
|
||||
ID3D11DeviceContext* pd3dImmediateContext = DXUTGetD3D11DeviceContext();
|
||||
|
||||
D3DXMATRIX mWorldViewProjection;
|
||||
D3DXVECTOR3 vLightDir;
|
||||
D3DXMATRIX mWorld;
|
||||
D3DXMATRIX mView;
|
||||
D3DXMATRIX mProj;
|
||||
|
||||
// Get the projection & view matrix from the camera class
|
||||
mProj = *g_Camera.GetProjMatrix();
|
||||
mView = *g_Camera.GetViewMatrix();
|
||||
|
||||
// Get the light direction
|
||||
vLightDir = g_LightControl.GetLightDirection();
|
||||
|
||||
// Per frame cb update
|
||||
D3D11_MAPPED_SUBRESOURCE MappedResource;
|
||||
|
||||
HRESULT hr;
|
||||
#ifndef USE_GPU_COPY
|
||||
pd3dImmediateContext->Map( pVB_staging, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource );
|
||||
memcpy( MappedResource.pData, cpu_buffer, 4*width*height*8 );
|
||||
pd3dImmediateContext->Unmap(pVB_staging, 0 );
|
||||
pd3dImmediateContext->CopyResource(pVB[0], pVB_staging);
|
||||
#endif // #ifndef USE_GPU_COPY
|
||||
|
||||
V( pd3dImmediateContext->Map( g_pcbPSPerFrame, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) );
|
||||
CB_PS_PER_FRAME* pPerFrame = ( CB_PS_PER_FRAME* )MappedResource.pData;
|
||||
float fAmbient = 0.1f;
|
||||
pPerFrame->m_vLightDirAmbient = D3DXVECTOR4( vLightDir.x, vLightDir.y, vLightDir.z, fAmbient );
|
||||
pd3dImmediateContext->Unmap( g_pcbPSPerFrame, 0 );
|
||||
|
||||
pd3dImmediateContext->PSSetConstantBuffers( g_iCBPSPerFrameBind, 1, &g_pcbPSPerFrame );
|
||||
|
||||
|
||||
///////////////////////////////////////Modify below//////////////////////////////////////////////////////
|
||||
|
||||
//Get the mesh
|
||||
//IA setup
|
||||
pd3dImmediateContext->IASetInputLayout( g_pVertexLayout11 );
|
||||
|
||||
//This is where we pass the vertex buffer to DX
|
||||
pd3dImmediateContext->IASetVertexBuffers( 0, 1, pVB, Strides, Offsets );
|
||||
|
||||
//This is where we pass the index buffer to DX
|
||||
pd3dImmediateContext->IASetIndexBuffer( g_pIndexBuffer, DXGI_FORMAT_R32_UINT, 0 );
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Set the shaders
|
||||
pd3dImmediateContext->VSSetShader( g_pVertexShader, NULL, 0 );
|
||||
pd3dImmediateContext->PSSetShader( g_pPixelShader, NULL, 0 );
|
||||
pd3dImmediateContext->GSSetShader( g_pGeometryShader, NULL, 0);
|
||||
|
||||
// Set the per object constant data
|
||||
|
||||
D3DXMATRIXA16 m_scale;
|
||||
float sc = 10;
|
||||
D3DXMatrixScaling(&m_scale,sc,sc,sc);
|
||||
|
||||
|
||||
D3DXVECTOR3 vCenter( global_shift_x, global_shift_y, global_shift_z);
|
||||
|
||||
D3DXMatrixTranslation( &g_mCenterMesh, -vCenter.x+x_offset, -vCenter.y+y_offset, -vCenter.z+z_offset );
|
||||
|
||||
|
||||
mWorld = *g_Camera.GetWorldMatrix();
|
||||
mProj = *g_Camera.GetProjMatrix();
|
||||
mView = *g_Camera.GetViewMatrix();
|
||||
|
||||
mWorldViewProjection = mView * mProj;
|
||||
|
||||
|
||||
// VS Per object
|
||||
V( pd3dImmediateContext->Map( g_pcbVSPerObject, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) );
|
||||
CB_VS_PER_OBJECT* pVSPerObject = ( CB_VS_PER_OBJECT* )MappedResource.pData;
|
||||
D3DXMatrixTranspose( &pVSPerObject->m_WorldViewProj, &mWorldViewProjection );
|
||||
D3DXMatrixTranspose( &pVSPerObject->m_World, &mWorld );
|
||||
pd3dImmediateContext->Unmap( g_pcbVSPerObject, 0 );
|
||||
|
||||
pd3dImmediateContext->VSSetConstantBuffers( g_iCBVSPerObjectBind, 1, &g_pcbVSPerObject );
|
||||
|
||||
// PS Per object
|
||||
V( pd3dImmediateContext->Map( g_pcbPSPerObject, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) );
|
||||
CB_PS_PER_OBJECT* pPSPerObject = ( CB_PS_PER_OBJECT* )MappedResource.pData;
|
||||
pPSPerObject->m_vObjectColor = D3DXVECTOR4( 1, 1, 1, 1 );
|
||||
pd3dImmediateContext->Unmap( g_pcbPSPerObject, 0 );
|
||||
|
||||
pd3dImmediateContext->PSSetConstantBuffers( g_iCBPSPerObjectBind, 1, &g_pcbPSPerObject );
|
||||
|
||||
//Render
|
||||
SDKMESH_SUBSET* pSubset = NULL;
|
||||
D3D11_PRIMITIVE_TOPOLOGY PrimType;
|
||||
|
||||
if( g_wireFrame )
|
||||
pd3dImmediateContext->RSSetState(g_pRasterizerStateWF);
|
||||
else
|
||||
pd3dImmediateContext->RSSetState(g_pRasterizerState);
|
||||
|
||||
pd3dImmediateContext->PSSetSamplers( 0, 1, &g_pSamLinear );
|
||||
|
||||
{
|
||||
// Get the subset
|
||||
pSubset = g_Mesh11.GetSubset( 0, 0 );
|
||||
|
||||
pd3dImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
|
||||
pd3dImmediateContext->PSSetShaderResources(0,1,&texture2D_view);
|
||||
|
||||
pd3dImmediateContext->DrawIndexed( (width*3*2+2 + height*width*3*2), 0, ( UINT )pSubset->VertexStart );
|
||||
}
|
||||
|
||||
SAFE_RELEASE(pd3dImmediateContext);
|
||||
}
|
||||
|
||||
void create_buffers(int width_, int height_)
|
||||
{
|
||||
width = width_;
|
||||
height = height_;
|
||||
|
||||
created = true;
|
||||
|
||||
|
||||
cpu_buffer = new float[width*height*8];
|
||||
memset(cpu_buffer,0,width*height*8*4);
|
||||
|
||||
// Set texture coordinates in output buffers
|
||||
for(int y = 0; y < height; y++)
|
||||
{
|
||||
for(int x = 0; x < width; x++)
|
||||
{
|
||||
cpu_buffer[y*8*width + x*8 + 6] = x/( (float)(width-1));
|
||||
cpu_buffer[y*8*width + x*8 + 7] = 1-y/((float)(height-1));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
D3D11_BUFFER_DESC bufferDesc;
|
||||
ZeroMemory(&bufferDesc, sizeof(bufferDesc));
|
||||
bufferDesc.Usage = D3D11_USAGE_DEFAULT;
|
||||
bufferDesc.ByteWidth = sizeof(vertex_struct)*width*height;
|
||||
bufferDesc.StructureByteStride = 0;//sizeof(vertex_struct);
|
||||
bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER | D3D11_BIND_UNORDERED_ACCESS;
|
||||
bufferDesc.MiscFlags = 0;//D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
|
||||
bufferDesc.CPUAccessFlags = 0;
|
||||
|
||||
vertex_struct *vertices = new vertex_struct[width*height];
|
||||
for(int y = 0; y < height; y++)
|
||||
{
|
||||
for(int x = 0; x < width; x++)
|
||||
{
|
||||
double coord = sin(x/5.0)*50;
|
||||
//coord = sin(y/);
|
||||
|
||||
vertices[y*width+x].Pos = D3DXVECTOR3( (x/((float)(width-1)))*1000, coord, (y/((float)(height-1)))*1000);
|
||||
vertices[y*width+x].Normal = D3DXVECTOR3(1,0,0);
|
||||
vertices[y*width+x].Texcoord = D3DXVECTOR2(x/( (float)(width-1)), 1.f-y/((float)(height-1)));
|
||||
}
|
||||
}
|
||||
|
||||
D3D11_SUBRESOURCE_DATA InitData;
|
||||
InitData.pSysMem = vertices;
|
||||
InitData.SysMemPitch = 0;
|
||||
InitData.SysMemSlicePitch = 0;
|
||||
|
||||
HRESULT hr = g_pd3dDevice->CreateBuffer(&bufferDesc, &InitData, &pVB[0]);
|
||||
|
||||
|
||||
D3D11_UNORDERED_ACCESS_VIEW_DESC uavbuffer_desc;
|
||||
ZeroMemory(&uavbuffer_desc, sizeof(uavbuffer_desc));
|
||||
uavbuffer_desc.Format = DXGI_FORMAT_R32_FLOAT;
|
||||
uavbuffer_desc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
|
||||
|
||||
uavbuffer_desc.Buffer.NumElements = width*height*sizeof(vertex_struct)/4;
|
||||
hr = g_pd3dDevice->CreateUnorderedAccessView(pVB[0], &uavbuffer_desc, &g_pVB_UAV);
|
||||
|
||||
|
||||
//What is this vertex stride thing all about?
|
||||
Strides[0] = ( UINT )g_Mesh11.GetVertexStride( 0, 0 );
|
||||
Offsets[0] = 0;
|
||||
|
||||
|
||||
//unsigned int indices[] = {0,1,2, 1,3,2};
|
||||
unsigned int* indices = new unsigned int[width*3*2+2 + height*width*3*2];
|
||||
|
||||
for(int y = 0; y < height-1; y++)
|
||||
{
|
||||
for(int x = 0; x < width-1; x++)
|
||||
{
|
||||
// *3 indices/triangle, *2 triangles/quad
|
||||
int baseIndex = (x + y*(width-1))*3*2;
|
||||
indices[baseIndex] = x + y*width;
|
||||
indices[baseIndex+1] = x+1 + y*width;
|
||||
indices[baseIndex+2] = x+width + y*width;
|
||||
|
||||
|
||||
indices[baseIndex+3] = x + 1 + y*width;
|
||||
indices[baseIndex+4] = x+(width+1) + y*width;
|
||||
indices[baseIndex+5] = x+width + y*width;
|
||||
}
|
||||
}
|
||||
|
||||
bufferDesc.ByteWidth = sizeof(unsigned int)*(width*3*2+2 + height*width*3*2);
|
||||
bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
|
||||
|
||||
InitData.pSysMem = indices;
|
||||
|
||||
hr = g_pd3dDevice->CreateBuffer(&bufferDesc, &InitData, &g_pIndexBuffer);
|
||||
|
||||
bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||
bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
bufferDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
bufferDesc.ByteWidth = sizeof(vertex_struct)*width*height;
|
||||
|
||||
hr = g_pd3dDevice->CreateBuffer(&bufferDesc, NULL, &pVB_staging);
|
||||
|
||||
delete [] indices;
|
||||
delete [] vertices;
|
||||
}
|
||||
|
||||
};
|
||||
1298
Demos/DX11ClothDemo/cloth_renderer.cpp
Normal file
1298
Demos/DX11ClothDemo/cloth_renderer.cpp
Normal file
File diff suppressed because it is too large
Load Diff
157
Demos/DX11ClothDemo/cloth_renderer.fx
Normal file
157
Demos/DX11ClothDemo/cloth_renderer.fx
Normal file
@@ -0,0 +1,157 @@
|
||||
//--------------------------------------------------------------------------------------
|
||||
// File: BasicHLSL.fx
|
||||
//
|
||||
// The effect file for the BasicHLSL sample.
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Global variables
|
||||
//--------------------------------------------------------------------------------------
|
||||
float4 g_MaterialAmbientColor; // Material's ambient color
|
||||
float4 g_MaterialDiffuseColor; // Material's diffuse color
|
||||
int g_nNumLights;
|
||||
|
||||
float3 g_LightDir; // Light's direction in world space
|
||||
float4 g_LightDiffuse; // Light's diffuse color
|
||||
float4 g_LightAmbient; // Light's ambient color
|
||||
|
||||
texture g_MeshTexture; // Color texture for mesh
|
||||
|
||||
float g_fTime; // App's time in seconds
|
||||
float4x4 g_mWorld; // World matrix for object
|
||||
float4x4 g_mWorldViewProjection; // World * View * Projection matrix
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Texture samplers
|
||||
//--------------------------------------------------------------------------------------
|
||||
sampler MeshTextureSampler =
|
||||
sampler_state
|
||||
{
|
||||
Texture = <g_MeshTexture>;
|
||||
MipFilter = LINEAR;
|
||||
MinFilter = LINEAR;
|
||||
MagFilter = LINEAR;
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Vertex shader output structure
|
||||
//--------------------------------------------------------------------------------------
|
||||
struct VS_OUTPUT
|
||||
{
|
||||
float4 Position : POSITION; // vertex position
|
||||
float4 Diffuse : COLOR0; // vertex diffuse color (note that COLOR0 is clamped from 0..1)
|
||||
float2 TextureUV : TEXCOORD0; // vertex texture coords
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// This shader computes standard transform and lighting
|
||||
//--------------------------------------------------------------------------------------
|
||||
VS_OUTPUT RenderSceneVS( float4 vPos : POSITION,
|
||||
float3 vNormal : NORMAL,
|
||||
float2 vTexCoord0 : TEXCOORD0,
|
||||
uniform int nNumLights,
|
||||
uniform bool bTexture,
|
||||
uniform bool bAnimate )
|
||||
{
|
||||
|
||||
VS_OUTPUT Output;
|
||||
float3 vNormalWorldSpace;
|
||||
|
||||
// Transform the position from object space to homogeneous projection space
|
||||
Output.Position = mul(vPos, g_mWorldViewProjection);
|
||||
|
||||
// Transform the normal from object space to world space
|
||||
vNormalWorldSpace = normalize(mul(vNormal, (float3x3)g_mWorld)); // normal (world space)
|
||||
|
||||
// Compute simple directional lighting equation
|
||||
float3 vTotalLightDiffuse = float3(0,0,0);
|
||||
for(int i=0; i<nNumLights; i++ )
|
||||
vTotalLightDiffuse += g_LightDiffuse * max(0,dot(vNormalWorldSpace, g_LightDir));
|
||||
|
||||
Output.Diffuse.rgb = g_MaterialDiffuseColor * vTotalLightDiffuse +
|
||||
g_MaterialAmbientColor * g_LightAmbient;
|
||||
Output.Diffuse.a = 1.0f;
|
||||
|
||||
// Just copy the texture coordinate through
|
||||
if( bTexture )
|
||||
Output.TextureUV = vTexCoord0;
|
||||
else
|
||||
Output.TextureUV = 0;
|
||||
|
||||
return Output;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Pixel shader output structure
|
||||
//--------------------------------------------------------------------------------------
|
||||
struct PS_OUTPUT
|
||||
{
|
||||
float4 RGBColor : COLOR0; // Pixel color
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// This shader outputs the pixel's color by modulating the texture's
|
||||
// color with diffuse material color
|
||||
//--------------------------------------------------------------------------------------
|
||||
PS_OUTPUT RenderScenePS( VS_OUTPUT In,
|
||||
uniform bool bTexture )
|
||||
{
|
||||
PS_OUTPUT Output;
|
||||
|
||||
// Lookup mesh texture and modulate it with diffuse
|
||||
if( bTexture )
|
||||
Output.RGBColor = tex2D(MeshTextureSampler, In.TextureUV) * In.Diffuse;
|
||||
else
|
||||
Output.RGBColor = In.Diffuse;
|
||||
|
||||
return Output;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Renders scene to render target
|
||||
//--------------------------------------------------------------------------------------
|
||||
technique RenderSceneWithTexture1Light
|
||||
{
|
||||
pass P0
|
||||
{
|
||||
VertexShader = compile vs_2_0 RenderSceneVS( 1, true, true );
|
||||
PixelShader = compile ps_2_0 RenderScenePS( true ); // trivial pixel shader (could use FF instead if desired)
|
||||
}
|
||||
}
|
||||
|
||||
technique RenderSceneWithTexture2Light
|
||||
{
|
||||
pass P0
|
||||
{
|
||||
VertexShader = compile vs_2_0 RenderSceneVS( 2, true, true );
|
||||
PixelShader = compile ps_2_0 RenderScenePS( true ); // trivial pixel shader (could use FF instead if desired)
|
||||
}
|
||||
}
|
||||
|
||||
technique RenderSceneWithTexture3Light
|
||||
{
|
||||
pass P0
|
||||
{
|
||||
VertexShader = compile vs_2_0 RenderSceneVS( 3, true, true );
|
||||
PixelShader = compile ps_2_0 RenderScenePS( true ); // trivial pixel shader (could use FF instead if desired)
|
||||
}
|
||||
}
|
||||
|
||||
technique RenderSceneNoTexture
|
||||
{
|
||||
pass P0
|
||||
{
|
||||
VertexShader = compile vs_2_0 RenderSceneVS( 1, false, false );
|
||||
PixelShader = compile ps_2_0 RenderScenePS( false ); // trivial pixel shader (could use FF instead if desired)
|
||||
}
|
||||
}
|
||||
77
Demos/DX11ClothDemo/cloth_renderer.rc
Normal file
77
Demos/DX11ClothDemo/cloth_renderer.rc
Normal file
@@ -0,0 +1,77 @@
|
||||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#define IDC_STATIC -1
|
||||
#include <WinResRc.h>
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDI_MAIN_ICON ICON "DXUT\Optional\\directx.ico"
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#define IDC_STATIC -1\r\n"
|
||||
"#include <winresrc.h>\r\n"
|
||||
"\r\n"
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
90
Demos/DX11ClothDemo/cloth_renderer_PS.hlsl
Normal file
90
Demos/DX11ClothDemo/cloth_renderer_PS.hlsl
Normal file
@@ -0,0 +1,90 @@
|
||||
//--------------------------------------------------------------------------------------
|
||||
// File: BasicHLSL11_PS.hlsl
|
||||
//
|
||||
// The pixel shader file for the BasicHLSL11 sample.
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Globals
|
||||
//--------------------------------------------------------------------------------------
|
||||
cbuffer cbPerObject : register( b0 )
|
||||
{
|
||||
float4 g_vObjectColor : packoffset( c0 );
|
||||
};
|
||||
|
||||
cbuffer cbPerFrame : register( b1 )
|
||||
{
|
||||
float3 g_vLightDir : packoffset( c0 );
|
||||
float g_fAmbient : packoffset( c0.w );
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Textures and Samplers
|
||||
//--------------------------------------------------------------------------------------
|
||||
Texture2D g_txDiffuse : register( t0 );
|
||||
SamplerState g_samLinear : register( s0 );
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Input / Output structures
|
||||
//--------------------------------------------------------------------------------------
|
||||
struct PS_INPUT
|
||||
{
|
||||
float3 vNormal : NORMAL;
|
||||
float2 vTexcoord : TEXCOORD0;
|
||||
float4 vPosition : SV_POSITION;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Pixel Shader
|
||||
//--------------------------------------------------------------------------------------
|
||||
float4 PSMain( PS_INPUT Input ) : SV_TARGET
|
||||
{
|
||||
float4 vDiffuse = g_txDiffuse.Sample( g_samLinear, Input.vTexcoord );
|
||||
|
||||
|
||||
float fLighting = saturate( dot( g_vLightDir, (Input.vNormal)/length(Input.vNormal) ) );
|
||||
//float fLighting = saturate( dot( g_vLightDir, float3(Input.vTexcoord.x,0,0) ) );
|
||||
fLighting = max( fLighting, g_fAmbient );
|
||||
|
||||
//fLighting = dot(g_vLightDir,float3(0,1,0));
|
||||
|
||||
return vDiffuse * fLighting;
|
||||
}
|
||||
|
||||
|
||||
struct VS_OUTPUT
|
||||
{
|
||||
float3 vNormal : NORMAL;
|
||||
float2 vTexcoord : TEXCOORD0;
|
||||
float4 vPosition : SV_POSITION;
|
||||
};
|
||||
|
||||
[maxvertexcount(3)]
|
||||
void GSMain(triangle VS_OUTPUT input[3], inout TriangleStream<PS_INPUT> OutputStream)
|
||||
{
|
||||
PS_INPUT output = (PS_INPUT)0;
|
||||
|
||||
|
||||
/*
|
||||
float3 v1 = input[1].vPosition - input[0].vPosition;
|
||||
float3 v2 = input[2].vPosition - input[0].vPosition;
|
||||
float3 normal = cross(v1,v2);
|
||||
|
||||
normal = normalize(normal);
|
||||
*/
|
||||
|
||||
|
||||
for(int i = 0; i < 3; i++)
|
||||
{
|
||||
|
||||
output.vNormal = input[i].vNormal;
|
||||
output.vTexcoord = input[i].vTexcoord;
|
||||
output.vPosition = input[i].vPosition;
|
||||
OutputStream.Append(output);
|
||||
}
|
||||
|
||||
OutputStream.RestartStrip();
|
||||
|
||||
}
|
||||
48
Demos/DX11ClothDemo/cloth_renderer_VS.hlsl
Normal file
48
Demos/DX11ClothDemo/cloth_renderer_VS.hlsl
Normal file
@@ -0,0 +1,48 @@
|
||||
//--------------------------------------------------------------------------------------
|
||||
// File: BasicHLSL11_VS.hlsl
|
||||
//
|
||||
// The vertex shader file for the BasicHLSL11 sample.
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Globals
|
||||
//--------------------------------------------------------------------------------------
|
||||
cbuffer cbPerObject : register( b0 )
|
||||
{
|
||||
matrix g_mWorldViewProjection : packoffset( c0 );
|
||||
matrix g_mWorld : packoffset( c4 );
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Input / Output structures
|
||||
//--------------------------------------------------------------------------------------
|
||||
struct VS_INPUT
|
||||
{
|
||||
float4 vPosition : POSITION;
|
||||
float3 vNormal : NORMAL;
|
||||
float2 vTexcoord : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct VS_OUTPUT
|
||||
{
|
||||
float3 vNormal : NORMAL;
|
||||
float2 vTexcoord : TEXCOORD0;
|
||||
float4 vPosition : SV_POSITION;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Vertex Shader
|
||||
//--------------------------------------------------------------------------------------
|
||||
VS_OUTPUT VSMain( VS_INPUT Input )
|
||||
{
|
||||
VS_OUTPUT Output;
|
||||
|
||||
Output.vPosition = mul( Input.vPosition, g_mWorldViewProjection );
|
||||
Output.vNormal = mul( Input.vNormal, (float3x3)g_mWorld );
|
||||
Output.vTexcoord = Input.vTexcoord;
|
||||
|
||||
return Output;
|
||||
}
|
||||
|
||||
267
Demos/DX11ClothDemo/cylinder.h
Normal file
267
Demos/DX11ClothDemo/cylinder.h
Normal file
@@ -0,0 +1,267 @@
|
||||
|
||||
class cylinder
|
||||
{
|
||||
public:
|
||||
|
||||
ID3D11Buffer* g_pIndexBuffer;
|
||||
ID3D11Buffer* pVB[1];
|
||||
UINT Strides[1];
|
||||
UINT Offsets[1];
|
||||
|
||||
double x_offset, y_offset, z_offset;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
|
||||
ID3D11Texture2D *texture2D;
|
||||
ID3D11ShaderResourceView *texture2D_view;
|
||||
|
||||
btCollisionShape *collisionShape;
|
||||
|
||||
//static_cast<btCapsuleShape*>(capsuleShape)
|
||||
|
||||
|
||||
btCollisionObject *collisionObject;
|
||||
|
||||
void set_collision_object(btCollisionObject* co)
|
||||
{
|
||||
collisionObject = co;
|
||||
}
|
||||
|
||||
void set_collision_shape(btCollisionShape* cs)
|
||||
{
|
||||
collisionShape = cs;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void create_texture(void)
|
||||
{
|
||||
D3DX11_IMAGE_LOAD_INFO loadInfo;
|
||||
ZeroMemory(&loadInfo, sizeof(D3DX11_IMAGE_LOAD_INFO) );
|
||||
loadInfo.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
loadInfo.Format = DXGI_FORMAT_BC1_UNORM;
|
||||
|
||||
HRESULT hr = D3DX11CreateShaderResourceViewFromFile(g_pd3dDevice, L"texture.bmp", &loadInfo, NULL, &texture2D_view, NULL);
|
||||
hr = hr;
|
||||
|
||||
}
|
||||
|
||||
void draw(void)
|
||||
{
|
||||
|
||||
ID3D11DeviceContext* pd3dImmediateContext = DXUTGetD3D11DeviceContext();
|
||||
|
||||
D3DXMATRIX mWorldViewProjection;
|
||||
D3DXVECTOR3 vLightDir;
|
||||
D3DXMATRIX mWorld;
|
||||
D3DXMATRIX mView;
|
||||
D3DXMATRIX mProj;
|
||||
|
||||
// Get the projection & view matrix from the camera class
|
||||
mProj = *g_Camera.GetProjMatrix();
|
||||
mView = *g_Camera.GetViewMatrix();
|
||||
|
||||
// Get the light direction
|
||||
vLightDir = g_LightControl.GetLightDirection();
|
||||
|
||||
// Per frame cb update
|
||||
D3D11_MAPPED_SUBRESOURCE MappedResource;
|
||||
|
||||
HRESULT hr;
|
||||
|
||||
V( pd3dImmediateContext->Map( g_pcbPSPerFrame, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) );
|
||||
CB_PS_PER_FRAME* pPerFrame = ( CB_PS_PER_FRAME* )MappedResource.pData;
|
||||
float fAmbient = 0.1f;
|
||||
pPerFrame->m_vLightDirAmbient = D3DXVECTOR4( vLightDir.x, vLightDir.y, vLightDir.z, fAmbient );
|
||||
pd3dImmediateContext->Unmap( g_pcbPSPerFrame, 0 );
|
||||
|
||||
pd3dImmediateContext->PSSetConstantBuffers( g_iCBPSPerFrameBind, 1, &g_pcbPSPerFrame );
|
||||
|
||||
|
||||
///////////////////////////////////////Modify below//////////////////////////////////////////////////////
|
||||
|
||||
//Get the mesh
|
||||
//IA setup
|
||||
pd3dImmediateContext->IASetInputLayout( g_pVertexLayout11 );
|
||||
|
||||
//This is where we pass the vertex buffer to DX
|
||||
pd3dImmediateContext->IASetVertexBuffers( 0, 1, pVB, Strides, Offsets );
|
||||
|
||||
//This is where we pass the index buffer to DX
|
||||
pd3dImmediateContext->IASetIndexBuffer( g_pIndexBuffer, DXGI_FORMAT_R32_UINT, 0 );
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Set the shaders
|
||||
pd3dImmediateContext->VSSetShader( g_pVertexShader, NULL, 0 );
|
||||
pd3dImmediateContext->PSSetShader( g_pPixelShader, NULL, 0 );
|
||||
pd3dImmediateContext->GSSetShader( g_pGeometryShader, NULL, 0);
|
||||
|
||||
// Set the per object constant data
|
||||
|
||||
|
||||
|
||||
btTransform trans = collisionObject->getWorldTransform();
|
||||
|
||||
|
||||
|
||||
btVector3 origin = trans.getOrigin();
|
||||
btMatrix3x3 btM = trans.getBasis();
|
||||
|
||||
btScalar* scalar_matrix = new btScalar[16];;
|
||||
trans.getOpenGLMatrix(scalar_matrix);
|
||||
|
||||
D3DXMATRIXA16 m_trans(scalar_matrix[0],scalar_matrix[1],scalar_matrix[2],scalar_matrix[3],
|
||||
scalar_matrix[4],scalar_matrix[5],scalar_matrix[6],scalar_matrix[7],
|
||||
scalar_matrix[8],scalar_matrix[9],scalar_matrix[10],scalar_matrix[11],
|
||||
scalar_matrix[12],scalar_matrix[13],scalar_matrix[14],scalar_matrix[15]);
|
||||
|
||||
D3DXMATRIXA16 m_scale;
|
||||
float sc = 10;
|
||||
D3DXMatrixScaling(&m_scale,sc,sc,sc);
|
||||
|
||||
|
||||
D3DXVECTOR3 vCenter( global_shift_x, global_shift_y, global_shift_z);
|
||||
|
||||
D3DXMatrixTranslation( &g_mCenterMesh, -vCenter.x+x_offset, -vCenter.y+y_offset, -vCenter.z+z_offset );
|
||||
|
||||
|
||||
D3DXMATRIXA16 m_trans_transpose;
|
||||
D3DXMatrixTranspose(&m_trans_transpose,&m_trans);
|
||||
|
||||
mWorld = *g_Camera.GetWorldMatrix() ;
|
||||
mProj = *g_Camera.GetProjMatrix();
|
||||
mView = m_trans * *g_Camera.GetViewMatrix();
|
||||
|
||||
mWorldViewProjection = mView * mProj;
|
||||
|
||||
|
||||
// VS Per object
|
||||
V( pd3dImmediateContext->Map( g_pcbVSPerObject, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) );
|
||||
CB_VS_PER_OBJECT* pVSPerObject = ( CB_VS_PER_OBJECT* )MappedResource.pData;
|
||||
D3DXMatrixTranspose( &pVSPerObject->m_WorldViewProj, &mWorldViewProjection );
|
||||
D3DXMatrixTranspose( &pVSPerObject->m_World, &mWorld );
|
||||
pd3dImmediateContext->Unmap( g_pcbVSPerObject, 0 );
|
||||
|
||||
pd3dImmediateContext->VSSetConstantBuffers( g_iCBVSPerObjectBind, 1, &g_pcbVSPerObject );
|
||||
|
||||
// PS Per object
|
||||
V( pd3dImmediateContext->Map( g_pcbPSPerObject, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) );
|
||||
CB_PS_PER_OBJECT* pPSPerObject = ( CB_PS_PER_OBJECT* )MappedResource.pData;
|
||||
pPSPerObject->m_vObjectColor = D3DXVECTOR4( 1, 1, 1, 1 );
|
||||
pd3dImmediateContext->Unmap( g_pcbPSPerObject, 0 );
|
||||
|
||||
pd3dImmediateContext->PSSetConstantBuffers( g_iCBPSPerObjectBind, 1, &g_pcbPSPerObject );
|
||||
|
||||
//Render
|
||||
SDKMESH_SUBSET* pSubset = NULL;
|
||||
D3D11_PRIMITIVE_TOPOLOGY PrimType;
|
||||
|
||||
pd3dImmediateContext->PSSetSamplers( 0, 1, &g_pSamLinear );
|
||||
|
||||
{
|
||||
// Get the subset
|
||||
pSubset = g_Mesh11.GetSubset( 0, 0 );
|
||||
|
||||
pd3dImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
|
||||
pd3dImmediateContext->PSSetShaderResources(0,1,&texture2D_view);
|
||||
|
||||
pd3dImmediateContext->DrawIndexed( (width*3*2+2 + height*width*3*2), 0, ( UINT )pSubset->VertexStart );
|
||||
}
|
||||
|
||||
SAFE_RELEASE(pd3dImmediateContext);
|
||||
}
|
||||
|
||||
void create_buffers(int width_, int height_)
|
||||
{
|
||||
width = width_;
|
||||
height = height_;
|
||||
|
||||
|
||||
D3D11_BUFFER_DESC bufferDesc;
|
||||
bufferDesc.Usage = D3D11_USAGE_DEFAULT;
|
||||
bufferDesc.ByteWidth = sizeof(vertex_struct)*width*height;
|
||||
bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
||||
bufferDesc.CPUAccessFlags = 0;
|
||||
bufferDesc.MiscFlags = 0;
|
||||
|
||||
vertex_struct *vertices = new vertex_struct[width*height];
|
||||
|
||||
btCapsuleShape* cs = static_cast<btCapsuleShape*>(collisionShape);
|
||||
float radius = cs->getRadius();
|
||||
float halfHeight = cs->getHalfHeight();
|
||||
|
||||
for(int y = 0; y < height; y++)
|
||||
{
|
||||
for(int x = 0; x < width; x++)
|
||||
{
|
||||
double coord_2 = sin(2.2*3.141159*y/(float)height)*radius;
|
||||
double coord_1 = cos(2.2*3.141159*y/(float)height)*radius;
|
||||
//double coord_2 = (y/((float)(height-1)))*1000;
|
||||
|
||||
//coord = sin(y/);
|
||||
|
||||
vertices[y*width+x].Pos = D3DXVECTOR3(coord_1, ((x/((float)(width-1)))-.5)*halfHeight*2, coord_2);
|
||||
vertices[y*width+x].Normal = D3DXVECTOR3(coord_1,0,coord_2);
|
||||
vertices[y*width+x].Texcoord = D3DXVECTOR2(x/( (float)(width-1)), y/((float)(height-1)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
for(int y = 0; y < height; y++)
|
||||
{
|
||||
for(int x = 0; x < width; x++)
|
||||
{
|
||||
double coord = sin(x/5.0)*50;
|
||||
//coord = sin(y/);
|
||||
|
||||
vertices[y*width+x].Pos = D3DXVECTOR3( (x/((float)(width-1)))*1000, coord, (y/((float)(height-1)))*1000);
|
||||
vertices[y*width+x].Normal = D3DXVECTOR3(1,0,0);
|
||||
vertices[y*width+x].Texcoord = D3DXVECTOR2(x/( (float)(width-1)), y/((float)(height-1)));
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
D3D11_SUBRESOURCE_DATA InitData;
|
||||
InitData.pSysMem = vertices;
|
||||
InitData.SysMemPitch = 0;
|
||||
InitData.SysMemSlicePitch = 0;
|
||||
|
||||
HRESULT hr = g_pd3dDevice->CreateBuffer(&bufferDesc, &InitData, &pVB[0]);
|
||||
|
||||
|
||||
//What is this vertex stride thing all about?
|
||||
Strides[0] = ( UINT )g_Mesh11.GetVertexStride( 0, 0 );
|
||||
Offsets[0] = 0;
|
||||
|
||||
//unsigned int indices[] = {0,1,2, 1,3,2};
|
||||
unsigned int* indices = new unsigned int[width*3*2+2 + height*width*3*2];
|
||||
|
||||
for(int y = 0; y < height-1; y++)
|
||||
{
|
||||
for(int x = 0; x < width-1; x++)
|
||||
{
|
||||
indices[x*3*2 + y*width*3*2] = x + y*width;
|
||||
indices[x*3*2+1 + y*width*3*2] = x+1 + y*width;
|
||||
indices[x*3*2+2 + y*width*3*2] = x+width + y*width;
|
||||
|
||||
indices[x*3*2 + 3 + y*width*3*2] = x + 1 + y*width;
|
||||
indices[x*3*2 + 4 + y*width*3*2] = x+(width+1) + y*width;
|
||||
indices[x*3*2 + 5 + y*width*3*2] = x+width + y*width;
|
||||
}
|
||||
}
|
||||
|
||||
bufferDesc.ByteWidth = sizeof(unsigned int)*(width*3*2+2 + height*width*3*2);
|
||||
bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
|
||||
|
||||
InitData.pSysMem = indices;
|
||||
|
||||
hr = g_pd3dDevice->CreateBuffer(&bufferDesc, &InitData, &g_pIndexBuffer);
|
||||
hr = hr;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
16
Demos/DX11ClothDemo/resource.h
Normal file
16
Demos/DX11ClothDemo/resource.h
Normal file
@@ -0,0 +1,16 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by BasicHLSL10.rc
|
||||
//
|
||||
#define IDI_MAIN_ICON 101
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 113
|
||||
#define _APS_NEXT_COMMAND_VALUE 40029
|
||||
#define _APS_NEXT_CONTROL_VALUE 1000
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
BIN
Demos/DX11ClothDemo/texture.bmp
Normal file
BIN
Demos/DX11ClothDemo/texture.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 257 KiB |
BIN
Demos/DX11ClothDemo/texture.png
Normal file
BIN
Demos/DX11ClothDemo/texture.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.7 KiB |
@@ -77,6 +77,12 @@ ADD_LIBRARY(BulletMultiThreaded
|
||||
../MiniCL/cl_MiniCL_Defs.h
|
||||
)
|
||||
|
||||
#for now, only Direct 11 (Direct Compute)
|
||||
IF(USE_DX11)
|
||||
SUBDIRS(GpuSoftBodySolvers)
|
||||
ENDIF(USE_DX11)
|
||||
|
||||
|
||||
IF (BUILD_SHARED_LIBS)
|
||||
TARGET_LINK_LIBRARIES(BulletMultiThreaded BulletDynamics BulletCollision)
|
||||
ENDIF (BUILD_SHARED_LIBS)
|
||||
|
||||
22
src/BulletMultiThreaded/GpuSoftBodySolvers/CMakeLists.txt
Normal file
22
src/BulletMultiThreaded/GpuSoftBodySolvers/CMakeLists.txt
Normal file
@@ -0,0 +1,22 @@
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/src
|
||||
)
|
||||
|
||||
LIST(APPEND SubDirList "CPU")
|
||||
|
||||
|
||||
# Configure use of OpenCL and DX11
|
||||
# Generates the settings file and defines libraries and include paths
|
||||
OPTION(USE_OPENCL "Use OpenCL" OFF)
|
||||
|
||||
|
||||
|
||||
if( USE_OPENCL )
|
||||
LIST(APPEND SubDirList "OpenCL")
|
||||
endif( USE_OPENCL )
|
||||
if( USE_DX11 )
|
||||
LIST(APPEND SubDirList "DX11")
|
||||
endif( USE_DX11 )
|
||||
|
||||
SUBDIRS( ${SubDirList} )
|
||||
@@ -0,0 +1,39 @@
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/src
|
||||
${VECTOR_MATH_INCLUDE}
|
||||
)
|
||||
|
||||
|
||||
|
||||
SET(BulletSoftBodyCPUSolvers_SRCS
|
||||
btSoftBodySolver_CPU.cpp
|
||||
)
|
||||
|
||||
SET(BulletSoftBodyCPUSolvers_HDRS
|
||||
btSoftBodySolver_CPU.h
|
||||
btSoftBodySolverData.h
|
||||
)
|
||||
|
||||
|
||||
ADD_LIBRARY(BulletSoftBodySolvers_CPU ${BulletSoftBodyCPUSolvers_SRCS} ${BulletSoftBodyCPUSolvers_HDRS} )
|
||||
SET_TARGET_PROPERTIES(BulletSoftBodySolvers_CPU PROPERTIES VERSION ${BULLET_VERSION})
|
||||
SET_TARGET_PROPERTIES(BulletSoftBodySolvers_CPU PROPERTIES SOVERSION ${BULLET_VERSION})
|
||||
|
||||
IF (INSTALL_LIBS)
|
||||
IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES)
|
||||
IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5)
|
||||
IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
INSTALL(TARGETS BulletSoftBodySolvers_CPU DESTINATION .)
|
||||
ELSE (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
INSTALL(TARGETS BulletSoftBodySolvers_CPU DESTINATION lib${LIB_SUFFIX})
|
||||
INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DESTINATION include FILES_MATCHING PATTERN "*.h")
|
||||
ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5)
|
||||
|
||||
IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
SET_TARGET_PROPERTIES(BulletSoftBodySolvers_CPU PROPERTIES FRAMEWORK true)
|
||||
SET_TARGET_PROPERTIES(BulletSoftBodySolvers_CPU PROPERTIES PUBLIC_HEADER "${BulletSoftBodyCPUSolvers_HDRS}")
|
||||
ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES)
|
||||
ENDIF (INSTALL_LIBS)
|
||||
@@ -0,0 +1,717 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef BT_SOFT_BODY_SOLVER_DATA_H
|
||||
#define BT_SOFT_BODY_SOLVER_DATA_H
|
||||
|
||||
#include "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h"
|
||||
#include "vectormath_aos.h"
|
||||
|
||||
|
||||
class btSoftBodyLinkData
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Class representing a link as a set of three indices into the vertex array.
|
||||
*/
|
||||
class LinkNodePair
|
||||
{
|
||||
public:
|
||||
int vertex0;
|
||||
int vertex1;
|
||||
|
||||
LinkNodePair()
|
||||
{
|
||||
vertex0 = 0;
|
||||
vertex1 = 0;
|
||||
}
|
||||
|
||||
LinkNodePair( int v0, int v1 )
|
||||
{
|
||||
vertex0 = v0;
|
||||
vertex1 = v1;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Class describing a link for input into the system.
|
||||
*/
|
||||
class LinkDescription
|
||||
{
|
||||
protected:
|
||||
int m_vertex0;
|
||||
int m_vertex1;
|
||||
float m_linkLinearStiffness;
|
||||
float m_linkStrength;
|
||||
|
||||
public:
|
||||
|
||||
LinkDescription()
|
||||
{
|
||||
m_vertex0 = 0;
|
||||
m_vertex1 = 0;
|
||||
m_linkLinearStiffness = 1.0;
|
||||
m_linkStrength = 1.0;
|
||||
}
|
||||
|
||||
LinkDescription( int newVertex0, int newVertex1, float linkLinearStiffness )
|
||||
{
|
||||
m_vertex0 = newVertex0;
|
||||
m_vertex1 = newVertex1;
|
||||
m_linkLinearStiffness = linkLinearStiffness;
|
||||
m_linkStrength = 1.0;
|
||||
}
|
||||
|
||||
LinkNodePair getVertexPair() const
|
||||
{
|
||||
LinkNodePair nodes;
|
||||
nodes.vertex0 = m_vertex0;
|
||||
nodes.vertex1 = m_vertex1;
|
||||
return nodes;
|
||||
}
|
||||
|
||||
void setVertex0( int vertex )
|
||||
{
|
||||
m_vertex0 = vertex;
|
||||
}
|
||||
|
||||
void setVertex1( int vertex )
|
||||
{
|
||||
m_vertex1 = vertex;
|
||||
}
|
||||
|
||||
void setLinkLinearStiffness( float linearStiffness )
|
||||
{
|
||||
m_linkLinearStiffness = linearStiffness;
|
||||
}
|
||||
|
||||
void setLinkStrength( float strength )
|
||||
{
|
||||
m_linkStrength = strength;
|
||||
}
|
||||
|
||||
int getVertex0() const
|
||||
{
|
||||
return m_vertex0;
|
||||
}
|
||||
|
||||
int getVertex1() const
|
||||
{
|
||||
return m_vertex1;
|
||||
}
|
||||
|
||||
float getLinkStrength() const
|
||||
{
|
||||
return m_linkStrength;
|
||||
}
|
||||
|
||||
float getLinkLinearStiffness() const
|
||||
{
|
||||
return m_linkLinearStiffness;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
protected:
|
||||
// NOTE:
|
||||
// Vertex reference data is stored relative to global array, not relative to individual cloth.
|
||||
// Values must be correct if being passed into single-cloth VBOs or when migrating from one solver
|
||||
// to another.
|
||||
|
||||
btAlignedObjectArray< LinkNodePair > m_links; // Vertex pair for the link
|
||||
btAlignedObjectArray< float > m_linkStrength; // Strength of each link
|
||||
// (inverseMassA + inverseMassB)/ linear stiffness coefficient
|
||||
btAlignedObjectArray< float > m_linksMassLSC;
|
||||
btAlignedObjectArray< float > m_linksRestLengthSquared;
|
||||
// Current vector length of link
|
||||
btAlignedObjectArray< Vectormath::Aos::Vector3 > m_linksCLength;
|
||||
// 1/(current length * current length * massLSC)
|
||||
btAlignedObjectArray< float > m_linksLengthRatio;
|
||||
btAlignedObjectArray< float > m_linksRestLength;
|
||||
btAlignedObjectArray< float > m_linksMaterialLinearStiffnessCoefficient;
|
||||
|
||||
public:
|
||||
btSoftBodyLinkData()
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~btSoftBodyLinkData()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void clear()
|
||||
{
|
||||
m_links.resize(0);
|
||||
m_linkStrength.resize(0);
|
||||
m_linksMassLSC.resize(0);
|
||||
m_linksRestLengthSquared.resize(0);
|
||||
m_linksLengthRatio.resize(0);
|
||||
m_linksRestLength.resize(0);
|
||||
m_linksMaterialLinearStiffnessCoefficient.resize(0);
|
||||
}
|
||||
|
||||
int getNumLinks()
|
||||
{
|
||||
return m_links.size();
|
||||
}
|
||||
|
||||
/** Allocate enough space in all link-related arrays to fit numLinks links */
|
||||
virtual void createLinks( int numLinks )
|
||||
{
|
||||
int previousSize = m_links.size();
|
||||
int newSize = previousSize + numLinks;
|
||||
|
||||
// Resize all the arrays that store link data
|
||||
m_links.resize( newSize );
|
||||
m_linkStrength.resize( newSize );
|
||||
m_linksMassLSC.resize( newSize );
|
||||
m_linksRestLengthSquared.resize( newSize );
|
||||
m_linksCLength.resize( newSize );
|
||||
m_linksLengthRatio.resize( newSize );
|
||||
m_linksRestLength.resize( newSize );
|
||||
m_linksMaterialLinearStiffnessCoefficient.resize( newSize );
|
||||
}
|
||||
|
||||
/** Insert the link described into the correct data structures assuming space has already been allocated by a call to createLinks */
|
||||
virtual void setLinkAt( const LinkDescription &link, int linkIndex )
|
||||
{
|
||||
m_links[linkIndex] = link.getVertexPair();
|
||||
m_linkStrength[linkIndex] = link.getLinkStrength();
|
||||
m_linksMassLSC[linkIndex] = 0.f;
|
||||
m_linksRestLengthSquared[linkIndex] = 0.f;
|
||||
m_linksCLength[linkIndex] = Vectormath::Aos::Vector3(0.f, 0.f, 0.f);
|
||||
m_linksLengthRatio[linkIndex] = 0.f;
|
||||
m_linksRestLength[linkIndex] = 0.f;
|
||||
m_linksMaterialLinearStiffnessCoefficient[linkIndex] = link.getLinkLinearStiffness();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return true if data is on the accelerator.
|
||||
* The CPU version of this class will return true here because
|
||||
* the CPU is the same as the accelerator.
|
||||
*/
|
||||
virtual bool onAccelerator()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move data from host memory to the accelerator.
|
||||
* The CPU version will always return that it has moved it.
|
||||
*/
|
||||
virtual bool moveToAccelerator()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move data from host memory from the accelerator.
|
||||
* The CPU version will always return that it has moved it.
|
||||
*/
|
||||
virtual bool moveFromAccelerator()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return reference to the vertex index pair for link linkIndex as stored on the host.
|
||||
*/
|
||||
LinkNodePair &getVertexPair( int linkIndex )
|
||||
{
|
||||
return m_links[linkIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return reference to strength of link linkIndex as stored on the host.
|
||||
*/
|
||||
float &getStrength( int linkIndex )
|
||||
{
|
||||
return m_linkStrength[linkIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a reference to the strength of the link corrected for link sorting.
|
||||
* This is important if we are using data on an accelerator which has the data sorted in some fashion.
|
||||
*/
|
||||
virtual float &getStrengthCorrected( int linkIndex )
|
||||
{
|
||||
return getStrength( linkIndex );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return reference to the rest length of link linkIndex as stored on the host.
|
||||
*/
|
||||
float &getRestLength( int linkIndex )
|
||||
{
|
||||
return m_linksRestLength[linkIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return reference to linear stiffness coefficient for link linkIndex as stored on the host.
|
||||
*/
|
||||
float &getLinearStiffnessCoefficient( int linkIndex )
|
||||
{
|
||||
return m_linksMaterialLinearStiffnessCoefficient[linkIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return reference to the MassLSC value for link linkIndex as stored on the host.
|
||||
*/
|
||||
float &getMassLSC( int linkIndex )
|
||||
{
|
||||
return m_linksMassLSC[linkIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return reference to rest length squared for link linkIndex as stored on the host.
|
||||
*/
|
||||
float &getRestLengthSquared( int linkIndex )
|
||||
{
|
||||
return m_linksRestLengthSquared[linkIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return reference to current length of link linkIndex as stored on the host.
|
||||
*/
|
||||
Vectormath::Aos::Vector3 &getCurrentLength( int linkIndex )
|
||||
{
|
||||
return m_linksCLength[linkIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the link length ratio from for link linkIndex as stored on the host.
|
||||
*/
|
||||
float &getLinkLengthRatio( int linkIndex )
|
||||
{
|
||||
return m_linksLengthRatio[linkIndex];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper for vertex data information.
|
||||
* By wrapping it like this we stand a good chance of being able to optimise for storage format easily.
|
||||
* It should also help us make sure all the data structures remain consistent.
|
||||
*/
|
||||
class btSoftBodyVertexData
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Class describing a vertex for input into the system.
|
||||
*/
|
||||
class VertexDescription
|
||||
{
|
||||
private:
|
||||
Vectormath::Aos::Point3 m_position;
|
||||
/** Inverse mass. If this is 0f then the mass was 0 because that simplifies calculations. */
|
||||
float m_inverseMass;
|
||||
|
||||
public:
|
||||
VertexDescription()
|
||||
{
|
||||
m_position = Vectormath::Aos::Point3( 0.f, 0.f, 0.f );
|
||||
m_inverseMass = 0.f;
|
||||
}
|
||||
|
||||
VertexDescription( const Vectormath::Aos::Point3 &position, float mass )
|
||||
{
|
||||
m_position = position;
|
||||
if( mass > 0.f )
|
||||
m_inverseMass = 1.0f/mass;
|
||||
else
|
||||
m_inverseMass = 0.f;
|
||||
}
|
||||
|
||||
void setPosition( const Vectormath::Aos::Point3 &position )
|
||||
{
|
||||
m_position = position;
|
||||
}
|
||||
|
||||
void setInverseMass( float inverseMass )
|
||||
{
|
||||
m_inverseMass = inverseMass;
|
||||
}
|
||||
|
||||
void setMass( float mass )
|
||||
{
|
||||
if( mass > 0.f )
|
||||
m_inverseMass = 1.0f/mass;
|
||||
else
|
||||
m_inverseMass = 0.f;
|
||||
}
|
||||
|
||||
Vectormath::Aos::Point3 getPosition() const
|
||||
{
|
||||
return m_position;
|
||||
}
|
||||
|
||||
float getInverseMass() const
|
||||
{
|
||||
return m_inverseMass;
|
||||
}
|
||||
|
||||
float getMass() const
|
||||
{
|
||||
if( m_inverseMass == 0.f )
|
||||
return 0.f;
|
||||
else
|
||||
return 1.0f/m_inverseMass;
|
||||
}
|
||||
};
|
||||
protected:
|
||||
|
||||
// identifier for the individual cloth
|
||||
// For the CPU we don't really need this as we can grab the cloths and iterate over only their vertices
|
||||
// For a parallel accelerator knowing on a per-vertex basis which cloth we're part of will help for obtaining
|
||||
// per-cloth data
|
||||
// For sorting etc it might also be helpful to be able to use in-array data such as this.
|
||||
btAlignedObjectArray< int > m_clothIdentifier;
|
||||
btAlignedObjectArray< Vectormath::Aos::Point3 > m_vertexPosition; // vertex positions
|
||||
btAlignedObjectArray< Vectormath::Aos::Point3 > m_vertexPreviousPosition; // vertex positions
|
||||
btAlignedObjectArray< Vectormath::Aos::Vector3 > m_vertexVelocity; // Velocity
|
||||
btAlignedObjectArray< Vectormath::Aos::Vector3 > m_vertexForceAccumulator; // Force accumulator
|
||||
btAlignedObjectArray< Vectormath::Aos::Vector3 > m_vertexNormal; // Normals
|
||||
btAlignedObjectArray< float > m_vertexInverseMass; // Inverse mass
|
||||
btAlignedObjectArray< float > m_vertexArea; // Area controlled by the vertex
|
||||
btAlignedObjectArray< int > m_vertexTriangleCount; // Number of triangles touching this vertex
|
||||
|
||||
public:
|
||||
btSoftBodyVertexData()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void clear()
|
||||
{
|
||||
m_clothIdentifier.resize(0);
|
||||
m_vertexPosition.resize(0);
|
||||
m_vertexPreviousPosition.resize(0);
|
||||
m_vertexVelocity.resize(0);
|
||||
m_vertexForceAccumulator.resize(0);
|
||||
m_vertexNormal.resize(0);
|
||||
m_vertexInverseMass.resize(0);
|
||||
m_vertexArea.resize(0);
|
||||
m_vertexTriangleCount.resize(0);
|
||||
}
|
||||
|
||||
int getNumVertices()
|
||||
{
|
||||
return m_vertexPosition.size();
|
||||
}
|
||||
|
||||
int getClothIdentifier( int vertexIndex )
|
||||
{
|
||||
return m_clothIdentifier[vertexIndex];
|
||||
}
|
||||
|
||||
void setVertexAt( const VertexDescription &vertex, int vertexIndex )
|
||||
{
|
||||
m_vertexPosition[vertexIndex] = vertex.getPosition();
|
||||
m_vertexPreviousPosition[vertexIndex] = vertex.getPosition();
|
||||
m_vertexVelocity[vertexIndex] = Vectormath::Aos::Vector3(0.f, 0.f, 0.f);
|
||||
m_vertexForceAccumulator[vertexIndex] = Vectormath::Aos::Vector3(0.f, 0.f, 0.f);
|
||||
m_vertexNormal[vertexIndex] = Vectormath::Aos::Vector3(0.f, 0.f, 0.f);
|
||||
m_vertexInverseMass[vertexIndex] = vertex.getInverseMass();
|
||||
m_vertexArea[vertexIndex] = 0.f;
|
||||
m_vertexTriangleCount[vertexIndex] = 0;
|
||||
}
|
||||
|
||||
/** Create numVertices new vertices for cloth clothIdentifier */
|
||||
void createVertices( int numVertices, int clothIdentifier )
|
||||
{
|
||||
int previousSize = m_vertexPosition.size();
|
||||
int newSize = previousSize + numVertices;
|
||||
|
||||
// Resize all the arrays that store vertex data
|
||||
m_clothIdentifier.resize( newSize );
|
||||
m_vertexPosition.resize( newSize );
|
||||
m_vertexPreviousPosition.resize( newSize );
|
||||
m_vertexVelocity.resize( newSize );
|
||||
m_vertexForceAccumulator.resize( newSize );
|
||||
m_vertexNormal.resize( newSize );
|
||||
m_vertexInverseMass.resize( newSize );
|
||||
m_vertexArea.resize( newSize );
|
||||
m_vertexTriangleCount.resize( newSize );
|
||||
|
||||
for( int vertexIndex = previousSize; vertexIndex < newSize; ++vertexIndex )
|
||||
m_clothIdentifier[vertexIndex] = clothIdentifier;
|
||||
}
|
||||
|
||||
// Get and set methods in header so they can be inlined
|
||||
|
||||
/**
|
||||
* Return a reference to the position of vertex vertexIndex as stored on the host.
|
||||
*/
|
||||
Vectormath::Aos::Point3 &getPosition( int vertexIndex )
|
||||
{
|
||||
return m_vertexPosition[vertexIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a reference to the previous position of vertex vertexIndex as stored on the host.
|
||||
*/
|
||||
Vectormath::Aos::Point3 &getPreviousPosition( int vertexIndex )
|
||||
{
|
||||
return m_vertexPreviousPosition[vertexIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a reference to the velocity of vertex vertexIndex as stored on the host.
|
||||
*/
|
||||
Vectormath::Aos::Vector3 &getVelocity( int vertexIndex )
|
||||
{
|
||||
return m_vertexVelocity[vertexIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a reference to the force accumulator of vertex vertexIndex as stored on the host.
|
||||
*/
|
||||
Vectormath::Aos::Vector3 &getForceAccumulator( int vertexIndex )
|
||||
{
|
||||
return m_vertexForceAccumulator[vertexIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a reference to the normal of vertex vertexIndex as stored on the host.
|
||||
*/
|
||||
Vectormath::Aos::Vector3 &getNormal( int vertexIndex )
|
||||
{
|
||||
return m_vertexNormal[vertexIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a reference to the inverse mass of vertex vertexIndex as stored on the host.
|
||||
*/
|
||||
float &getInverseMass( int vertexIndex )
|
||||
{
|
||||
return m_vertexInverseMass[vertexIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get access to the area controlled by this vertex.
|
||||
*/
|
||||
float &getArea( int vertexIndex )
|
||||
{
|
||||
return m_vertexArea[vertexIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get access to the array of how many triangles touch each vertex.
|
||||
*/
|
||||
int &getTriangleCount( int vertexIndex )
|
||||
{
|
||||
return m_vertexTriangleCount[vertexIndex];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return true if data is on the accelerator.
|
||||
* The CPU version of this class will return true here because
|
||||
* the CPU is the same as the accelerator.
|
||||
*/
|
||||
virtual bool onAccelerator()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move data from host memory to the accelerator.
|
||||
* The CPU version will always return that it has moved it.
|
||||
*/
|
||||
virtual bool moveToAccelerator()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move data from host memory from the accelerator.
|
||||
* The CPU version will always return that it has moved it.
|
||||
*/
|
||||
virtual bool moveFromAccelerator()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
btAlignedObjectArray< Vectormath::Aos::Point3 > &getVertexPositions()
|
||||
{
|
||||
return m_vertexPosition;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class btSoftBodyTriangleData
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Class representing a triangle as a set of three indices into the
|
||||
* vertex array.
|
||||
*/
|
||||
class TriangleNodeSet
|
||||
{
|
||||
public:
|
||||
int vertex0;
|
||||
int vertex1;
|
||||
int vertex2;
|
||||
int _padding;
|
||||
|
||||
TriangleNodeSet( )
|
||||
{
|
||||
vertex0 = 0;
|
||||
vertex1 = 0;
|
||||
vertex2 = 0;
|
||||
_padding = -1;
|
||||
}
|
||||
|
||||
TriangleNodeSet( int newVertex0, int newVertex1, int newVertex2 )
|
||||
{
|
||||
vertex0 = newVertex0;
|
||||
vertex1 = newVertex1;
|
||||
vertex2 = newVertex2;
|
||||
}
|
||||
};
|
||||
|
||||
class TriangleDescription
|
||||
{
|
||||
protected:
|
||||
int m_vertex0;
|
||||
int m_vertex1;
|
||||
int m_vertex2;
|
||||
|
||||
public:
|
||||
TriangleDescription()
|
||||
{
|
||||
m_vertex0 = 0;
|
||||
m_vertex1 = 0;
|
||||
m_vertex2 = 0;
|
||||
}
|
||||
|
||||
TriangleDescription( int newVertex0, int newVertex1, int newVertex2 )
|
||||
{
|
||||
m_vertex0 = newVertex0;
|
||||
m_vertex1 = newVertex1;
|
||||
m_vertex2 = newVertex2;
|
||||
}
|
||||
|
||||
TriangleNodeSet getVertexSet() const
|
||||
{
|
||||
btSoftBodyTriangleData::TriangleNodeSet nodes;
|
||||
nodes.vertex0 = m_vertex0;
|
||||
nodes.vertex1 = m_vertex1;
|
||||
nodes.vertex2 = m_vertex2;
|
||||
return nodes;
|
||||
}
|
||||
};
|
||||
|
||||
protected:
|
||||
// NOTE:
|
||||
// Vertex reference data is stored relative to global array, not relative to individual cloth.
|
||||
// Values must be correct if being passed into single-cloth VBOs or when migrating from one solver
|
||||
// to another.
|
||||
btAlignedObjectArray< TriangleNodeSet > m_vertexIndices;
|
||||
btAlignedObjectArray< float > m_area;
|
||||
btAlignedObjectArray< Vectormath::Aos::Vector3 > m_normal;
|
||||
|
||||
public:
|
||||
btSoftBodyTriangleData()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void clear()
|
||||
{
|
||||
m_vertexIndices.resize(0);
|
||||
m_area.resize(0);
|
||||
m_normal.resize(0);
|
||||
}
|
||||
|
||||
int getNumTriangles()
|
||||
{
|
||||
return m_vertexIndices.size();
|
||||
}
|
||||
|
||||
virtual void setTriangleAt( const TriangleDescription &triangle, int triangleIndex )
|
||||
{
|
||||
m_vertexIndices[triangleIndex] = triangle.getVertexSet();
|
||||
}
|
||||
|
||||
virtual void createTriangles( int numTriangles )
|
||||
{
|
||||
int previousSize = m_vertexIndices.size();
|
||||
int newSize = previousSize + numTriangles;
|
||||
|
||||
// Resize all the arrays that store triangle data
|
||||
m_vertexIndices.resize( newSize );
|
||||
m_area.resize( newSize );
|
||||
m_normal.resize( newSize );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the vertex index set for triangle triangleIndex as stored on the host.
|
||||
*/
|
||||
const TriangleNodeSet &getVertexSet( int triangleIndex )
|
||||
{
|
||||
return m_vertexIndices[triangleIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get access to the triangle area.
|
||||
*/
|
||||
float &getTriangleArea( int triangleIndex )
|
||||
{
|
||||
return m_area[triangleIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get access to the normal vector for this triangle.
|
||||
*/
|
||||
Vectormath::Aos::Vector3 &getNormal( int triangleIndex )
|
||||
{
|
||||
return m_normal[triangleIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if data is on the accelerator.
|
||||
* The CPU version of this class will return true here because
|
||||
* the CPU is the same as the accelerator.
|
||||
*/
|
||||
virtual bool onAccelerator()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move data from host memory to the accelerator.
|
||||
* The CPU version will always return that it has moved it.
|
||||
*/
|
||||
virtual bool moveToAccelerator()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move data from host memory from the accelerator.
|
||||
* The CPU version will always return that it has moved it.
|
||||
*/
|
||||
virtual bool moveFromAccelerator()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif // #ifndef BT_SOFT_BODY_SOLVER_DATA_H
|
||||
@@ -0,0 +1,766 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
|
||||
#include "BulletCollision/CollisionShapes/btCollisionShape.h"
|
||||
#include "vectormath_aos.h"
|
||||
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/CPU/btSoftBodySolver_CPU.h"
|
||||
#include "BulletSoftBody/btSoftBody.h"
|
||||
#include "BulletCollision/CollisionShapes/btCapsuleShape.h"
|
||||
|
||||
|
||||
btCPUSoftBodySolver::btCPUSoftBodySolver()
|
||||
{
|
||||
// Initial we will clearly need to update solver constants
|
||||
// For now this is global for the cloths linked with this solver - we should probably make this body specific
|
||||
// for performance in future once we understand more clearly when constants need to be updated
|
||||
m_updateSolverConstants = true;
|
||||
}
|
||||
|
||||
btCPUSoftBodySolver::~btCPUSoftBodySolver()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
btSoftBodyLinkData &btCPUSoftBodySolver::getLinkData()
|
||||
{
|
||||
return m_linkData;
|
||||
}
|
||||
|
||||
btSoftBodyVertexData &btCPUSoftBodySolver::getVertexData()
|
||||
{
|
||||
return m_vertexData;
|
||||
}
|
||||
|
||||
btSoftBodyTriangleData &btCPUSoftBodySolver::getTriangleData()
|
||||
{
|
||||
return m_triangleData;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static Vectormath::Aos::Vector3 toVector3( const btVector3 &vec )
|
||||
{
|
||||
Vectormath::Aos::Vector3 outVec( vec.getX(), vec.getY(), vec.getZ() );
|
||||
return outVec;
|
||||
}
|
||||
|
||||
static Vectormath::Aos::Transform3 toTransform3( const btTransform &transform )
|
||||
{
|
||||
Vectormath::Aos::Transform3 outTransform;
|
||||
outTransform.setCol(0, toVector3(transform.getBasis().getColumn(0)));
|
||||
outTransform.setCol(1, toVector3(transform.getBasis().getColumn(1)));
|
||||
outTransform.setCol(2, toVector3(transform.getBasis().getColumn(2)));
|
||||
outTransform.setCol(3, toVector3(transform.getOrigin()));
|
||||
return outTransform;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void btCPUSoftBodySolver::optimize( btAlignedObjectArray< btSoftBody * > &softBodies )
|
||||
{
|
||||
if( m_softBodySet.size() != softBodies.size() )
|
||||
{
|
||||
// Have a change in the soft body set so update, reloading all the data
|
||||
getVertexData().clear();
|
||||
getTriangleData().clear();
|
||||
getLinkData().clear();
|
||||
m_softBodySet.resize(0);
|
||||
|
||||
|
||||
for( int softBodyIndex = 0; softBodyIndex < softBodies.size(); ++softBodyIndex )
|
||||
{
|
||||
btSoftBody *softBody = softBodies[ softBodyIndex ];
|
||||
using Vectormath::Aos::Matrix3;
|
||||
using Vectormath::Aos::Point3;
|
||||
|
||||
// Create SoftBody that will store the information within the solver
|
||||
btAcceleratedSoftBodyInterface *newSoftBody = new btAcceleratedSoftBodyInterface( softBody );
|
||||
m_softBodySet.push_back( newSoftBody );
|
||||
|
||||
m_perClothAcceleration.push_back( toVector3(softBody->getWorldInfo()->m_gravity) );
|
||||
m_perClothDampingFactor.push_back(softBody->m_cfg.kDP);
|
||||
m_perClothVelocityCorrectionCoefficient.push_back( softBody->m_cfg.kVCF );
|
||||
m_perClothLiftFactor.push_back( softBody->m_cfg.kLF );
|
||||
m_perClothDragFactor.push_back( softBody->m_cfg.kDG );
|
||||
m_perClothMediumDensity.push_back(softBody->getWorldInfo()->air_density);
|
||||
|
||||
// Add space for new vertices and triangles in the default solver for now
|
||||
// TODO: Include space here for tearing too later
|
||||
int firstVertex = getVertexData().getNumVertices();
|
||||
int numVertices = softBody->m_nodes.size();
|
||||
int maxVertices = numVertices;
|
||||
// Allocate space for new vertices in all the vertex arrays
|
||||
getVertexData().createVertices( maxVertices, softBodyIndex );
|
||||
|
||||
int firstTriangle = getTriangleData().getNumTriangles();
|
||||
int numTriangles = softBody->m_faces.size();
|
||||
int maxTriangles = numTriangles;
|
||||
getTriangleData().createTriangles( maxTriangles );
|
||||
|
||||
// Copy vertices from softbody into the solver
|
||||
for( int vertex = 0; vertex < numVertices; ++vertex )
|
||||
{
|
||||
Point3 multPoint(softBody->m_nodes[vertex].m_x.getX(), softBody->m_nodes[vertex].m_x.getY(), softBody->m_nodes[vertex].m_x.getZ());
|
||||
btSoftBodyVertexData::VertexDescription desc;
|
||||
|
||||
// TODO: Position in the softbody might be pre-transformed
|
||||
// or we may need to adapt for the pose.
|
||||
//desc.setPosition( cloth.getMeshTransform()*multPoint );
|
||||
desc.setPosition( multPoint );
|
||||
|
||||
float vertexInverseMass = softBody->m_nodes[vertex].m_im;
|
||||
desc.setInverseMass(vertexInverseMass);
|
||||
getVertexData().setVertexAt( desc, firstVertex + vertex );
|
||||
}
|
||||
|
||||
// Copy triangles similarly
|
||||
// We're assuming here that vertex indices are based on the firstVertex rather than the entire scene
|
||||
for( int triangle = 0; triangle < numTriangles; ++triangle )
|
||||
{
|
||||
// Note that large array storage is relative to the array not to the cloth
|
||||
// So we need to add firstVertex to each value
|
||||
int vertexIndex0 = (softBody->m_faces[triangle].m_n[0] - &(softBody->m_nodes[0]));
|
||||
int vertexIndex1 = (softBody->m_faces[triangle].m_n[1] - &(softBody->m_nodes[0]));
|
||||
int vertexIndex2 = (softBody->m_faces[triangle].m_n[2] - &(softBody->m_nodes[0]));
|
||||
btSoftBodyTriangleData::TriangleDescription newTriangle(vertexIndex0 + firstVertex, vertexIndex1 + firstVertex, vertexIndex2 + firstVertex);
|
||||
getTriangleData().setTriangleAt( newTriangle, firstTriangle + triangle );
|
||||
|
||||
// Increase vertex triangle counts for this triangle
|
||||
getVertexData().getTriangleCount(newTriangle.getVertexSet().vertex0)++;
|
||||
getVertexData().getTriangleCount(newTriangle.getVertexSet().vertex1)++;
|
||||
getVertexData().getTriangleCount(newTriangle.getVertexSet().vertex2)++;
|
||||
}
|
||||
|
||||
int firstLink = getLinkData().getNumLinks();
|
||||
int numLinks = softBody->m_links.size();
|
||||
int maxLinks = numLinks;
|
||||
|
||||
// Allocate space for the links
|
||||
getLinkData().createLinks( numLinks );
|
||||
|
||||
// Add the links
|
||||
for( int link = 0; link < numLinks; ++link )
|
||||
{
|
||||
int vertexIndex0 = softBody->m_links[link].m_n[0] - &(softBody->m_nodes[0]);
|
||||
int vertexIndex1 = softBody->m_links[link].m_n[1] - &(softBody->m_nodes[0]);
|
||||
|
||||
btSoftBodyLinkData::LinkDescription newLink(vertexIndex0 + firstVertex, vertexIndex1 + firstVertex, softBody->m_links[link].m_material->m_kLST);
|
||||
newLink.setLinkStrength(1.f);
|
||||
getLinkData().setLinkAt(newLink, firstLink + link);
|
||||
}
|
||||
|
||||
newSoftBody->setFirstVertex( firstVertex );
|
||||
newSoftBody->setFirstTriangle( firstTriangle );
|
||||
newSoftBody->setNumVertices( numVertices );
|
||||
newSoftBody->setMaxVertices( maxVertices );
|
||||
newSoftBody->setNumTriangles( numTriangles );
|
||||
newSoftBody->setMaxTriangles( maxTriangles );
|
||||
newSoftBody->setFirstLink( firstLink );
|
||||
newSoftBody->setNumLinks( numLinks );
|
||||
}
|
||||
|
||||
|
||||
|
||||
updateConstants(0.f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void btCPUSoftBodySolver::updateSoftBodies()
|
||||
{
|
||||
using namespace Vectormath::Aos;
|
||||
|
||||
int numVertices = m_vertexData.getNumVertices();
|
||||
int numTriangles = m_triangleData.getNumTriangles();
|
||||
|
||||
// Initialise normal and vertex counts
|
||||
for( int vertexIndex = 0; vertexIndex < numVertices; ++vertexIndex )
|
||||
{
|
||||
m_vertexData.getArea(vertexIndex) = 0.f;
|
||||
m_vertexData.getNormal(vertexIndex) = Vector3(0.f, 0.f, 0.f);
|
||||
}
|
||||
|
||||
// Update the areas for the triangles and vertices.
|
||||
for( int triangleIndex = 0; triangleIndex < numTriangles; ++triangleIndex )
|
||||
{
|
||||
float &triangleArea( m_triangleData.getTriangleArea( triangleIndex ) );
|
||||
const btSoftBodyTriangleData::TriangleNodeSet &vertices( m_triangleData.getVertexSet(triangleIndex) );
|
||||
|
||||
Point3 &vertexPosition0( m_vertexData.getPosition( vertices.vertex0 ) );
|
||||
Point3 &vertexPosition1( m_vertexData.getPosition( vertices.vertex1 ) );
|
||||
Point3 &vertexPosition2( m_vertexData.getPosition( vertices.vertex2 ) );
|
||||
|
||||
triangleArea = computeTriangleArea( vertexPosition0, vertexPosition1, vertexPosition2 );
|
||||
|
||||
// Add to areas for vertices and increase the count of the number of triangles affecting the vertex
|
||||
m_vertexData.getArea(vertices.vertex0) += triangleArea;
|
||||
m_vertexData.getArea(vertices.vertex1) += triangleArea;
|
||||
m_vertexData.getArea(vertices.vertex2) += triangleArea;
|
||||
|
||||
Point3 &vertex0( m_vertexData.getPosition(vertices.vertex0) );
|
||||
Point3 &vertex1( m_vertexData.getPosition(vertices.vertex1) );
|
||||
Point3 &vertex2( m_vertexData.getPosition(vertices.vertex2) );
|
||||
|
||||
Vector3 triangleNormal = cross( vertex1-vertex0, vertex2 - vertex0 );
|
||||
|
||||
m_triangleData.getNormal(triangleIndex) = normalize(triangleNormal);
|
||||
|
||||
m_vertexData.getNormal(vertices.vertex0) += triangleNormal;
|
||||
m_vertexData.getNormal(vertices.vertex1) += triangleNormal;
|
||||
m_vertexData.getNormal(vertices.vertex2) += triangleNormal;
|
||||
|
||||
}
|
||||
|
||||
// Normalise the area and normals
|
||||
for( int vertexIndex = 0; vertexIndex < numVertices; ++vertexIndex )
|
||||
{
|
||||
m_vertexData.getArea(vertexIndex) /= m_vertexData.getTriangleCount(vertexIndex);
|
||||
m_vertexData.getNormal(vertexIndex) = normalize( m_vertexData.getNormal(vertexIndex) );
|
||||
}
|
||||
|
||||
|
||||
// Clear the collision shape array for the next frame
|
||||
m_collisionObjectDetails.clear();
|
||||
|
||||
} // updateSoftBodies
|
||||
|
||||
|
||||
Vectormath::Aos::Vector3 btCPUSoftBodySolver::ProjectOnAxis( const Vectormath::Aos::Vector3 &v, const Vectormath::Aos::Vector3 &a )
|
||||
{
|
||||
return a*Vectormath::Aos::dot(v, a);
|
||||
}
|
||||
|
||||
void btCPUSoftBodySolver::ApplyClampedForce( float solverdt, const Vectormath::Aos::Vector3 &force, const Vectormath::Aos::Vector3 &vertexVelocity, float inverseMass, Vectormath::Aos::Vector3 &vertexForce )
|
||||
{
|
||||
float dtInverseMass = solverdt*inverseMass;
|
||||
if( Vectormath::Aos::lengthSqr(force * dtInverseMass) > Vectormath::Aos::lengthSqr(vertexVelocity) )
|
||||
{
|
||||
vertexForce -= ProjectOnAxis( vertexVelocity, normalize( force ) )/dtInverseMass;
|
||||
} else {
|
||||
vertexForce += force;
|
||||
}
|
||||
}
|
||||
|
||||
bool btCPUSoftBodySolver::checkInitialized()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void btCPUSoftBodySolver::applyForces( float solverdt )
|
||||
{
|
||||
using namespace Vectormath::Aos;
|
||||
|
||||
int numVertices = m_vertexData.getNumVertices();
|
||||
for( int clothIndex = 0; clothIndex < m_softBodySet.size(); ++clothIndex )
|
||||
{
|
||||
btAcceleratedSoftBodyInterface *currentCloth = m_softBodySet[clothIndex];
|
||||
const int startVertex = currentCloth->getFirstVertex();
|
||||
const int numVertices = currentCloth->getNumVertices();
|
||||
|
||||
Vector3 velocityChange = m_perClothAcceleration[clothIndex]*solverdt;
|
||||
for( int vertexIndex = startVertex; vertexIndex < (startVertex + numVertices); ++vertexIndex )
|
||||
{
|
||||
float inverseMass = m_vertexData.getInverseMass( vertexIndex );
|
||||
Vector3 &vertexVelocity( m_vertexData.getVelocity( vertexIndex ) );
|
||||
|
||||
// First apply the global acceleration to all vertices
|
||||
if( inverseMass > 0 )
|
||||
vertexVelocity += velocityChange;
|
||||
|
||||
// If it's a non-static vertex
|
||||
if( m_vertexData.getInverseMass(vertexIndex) > 0 )
|
||||
{
|
||||
// Wind effects on a wind-per-cloth basis
|
||||
float liftFactor = m_perClothLiftFactor[clothIndex];
|
||||
float dragFactor = m_perClothDragFactor[clothIndex];
|
||||
if( (liftFactor > 0.f) || (dragFactor > 0.f) )
|
||||
{
|
||||
Vector3 normal = m_vertexData.getNormal(vertexIndex);
|
||||
Vector3 relativeWindVelocity = m_vertexData.getVelocity(vertexIndex) - m_perClothWindVelocity[clothIndex];
|
||||
float relativeSpeedSquared = lengthSqr(relativeWindVelocity);
|
||||
if( relativeSpeedSquared > FLT_EPSILON )
|
||||
{
|
||||
normal = normal * (dot(normal, relativeWindVelocity) < 0 ? -1.f : +1.f);
|
||||
float dvNormal = dot(normal, relativeWindVelocity);
|
||||
if( dvNormal > 0 )
|
||||
{
|
||||
Vector3 force( 0.f, 0.f, 0.f );
|
||||
float c0 = m_vertexData.getArea(vertexIndex) * dvNormal * relativeSpeedSquared / 2;
|
||||
float c1 = c0 * m_perClothMediumDensity[clothIndex];
|
||||
force += normal * (-c1 * liftFactor);
|
||||
force += normalize(relativeWindVelocity)*(-c1 * dragFactor);
|
||||
|
||||
Vectormath::Aos::Vector3 &vertexForce( m_vertexData.getForceAccumulator(vertexIndex) );
|
||||
ApplyClampedForce( solverdt, force, vertexVelocity, inverseMass, vertexForce );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // btCPUSoftBodySolver::applyForces
|
||||
|
||||
/**
|
||||
* Integrate motion on the solver.
|
||||
*/
|
||||
void btCPUSoftBodySolver::integrate( float solverdt )
|
||||
{
|
||||
using namespace Vectormath::Aos;
|
||||
int numVertices = m_vertexData.getNumVertices();
|
||||
for( int vertexIndex = 0; vertexIndex < numVertices; ++vertexIndex )
|
||||
{
|
||||
Point3 &position( m_vertexData.getPosition(vertexIndex) );
|
||||
Point3 &previousPosition( m_vertexData.getPreviousPosition(vertexIndex) );
|
||||
Vector3 &forceAccumulator( m_vertexData.getForceAccumulator(vertexIndex) );
|
||||
Vector3 &velocity( m_vertexData.getVelocity(vertexIndex) );
|
||||
float inverseMass = m_vertexData.getInverseMass(vertexIndex);
|
||||
|
||||
previousPosition = position;
|
||||
velocity += forceAccumulator * inverseMass * solverdt;
|
||||
position += velocity * solverdt;
|
||||
forceAccumulator = Vector3(0.f, 0.f, 0.f);
|
||||
}
|
||||
} // btCPUSoftBodySolver::integrate
|
||||
|
||||
float btCPUSoftBodySolver::computeTriangleArea(
|
||||
const Vectormath::Aos::Point3 &vertex0,
|
||||
const Vectormath::Aos::Point3 &vertex1,
|
||||
const Vectormath::Aos::Point3 &vertex2 )
|
||||
{
|
||||
Vectormath::Aos::Vector3 a = vertex1 - vertex0;
|
||||
Vectormath::Aos::Vector3 b = vertex2 - vertex0;
|
||||
Vectormath::Aos::Vector3 crossProduct = cross(a, b);
|
||||
float area = length( crossProduct );
|
||||
return area;
|
||||
}
|
||||
|
||||
void btCPUSoftBodySolver::updateConstants( float timeStep )
|
||||
{
|
||||
using namespace Vectormath::Aos;
|
||||
|
||||
if( m_updateSolverConstants )
|
||||
{
|
||||
m_updateSolverConstants = false;
|
||||
|
||||
// Will have to redo this if we change the structure (tear, maybe) or various other possible changes
|
||||
|
||||
// Initialise link constants
|
||||
const int numLinks = m_linkData.getNumLinks();
|
||||
for( int linkIndex = 0; linkIndex < numLinks; ++linkIndex )
|
||||
{
|
||||
btSoftBodyLinkData::LinkNodePair &vertices( m_linkData.getVertexPair(linkIndex) );
|
||||
m_linkData.getRestLength(linkIndex) = length((m_vertexData.getPosition( vertices.vertex0 ) - m_vertexData.getPosition( vertices.vertex1 )));
|
||||
float invMass0 = m_vertexData.getInverseMass(vertices.vertex0);
|
||||
float invMass1 = m_vertexData.getInverseMass(vertices.vertex1);
|
||||
float linearStiffness = m_linkData.getLinearStiffnessCoefficient(linkIndex);
|
||||
float massLSC = (invMass0 + invMass1)/linearStiffness;
|
||||
m_linkData.getMassLSC(linkIndex) = massLSC;
|
||||
float restLength = m_linkData.getRestLength(linkIndex);
|
||||
float restLengthSquared = restLength*restLength;
|
||||
m_linkData.getRestLengthSquared(linkIndex) = restLengthSquared;
|
||||
}
|
||||
}
|
||||
} // btCPUSoftBodySolver::updateConstants
|
||||
|
||||
/**
|
||||
* Sort the collision object details array and generate indexing into it for the per-cloth collision object array.
|
||||
*/
|
||||
void btCPUSoftBodySolver::prepareCollisionConstraints()
|
||||
{
|
||||
// First do a simple radix sort on the collision objects
|
||||
btAlignedObjectArray<int> numObjectsPerClothPrefixSum;
|
||||
btAlignedObjectArray<int> numObjectsPerCloth;
|
||||
numObjectsPerCloth.resize( m_softBodySet.size(), 0 );
|
||||
numObjectsPerClothPrefixSum.resize( m_softBodySet.size(), 0 );
|
||||
|
||||
btAlignedObjectArray< CollisionShapeDescription > m_collisionObjectDetailsCopy(m_collisionObjectDetails);
|
||||
// Count and prefix sum number of previous cloths
|
||||
for( int collisionObject = 0; collisionObject < m_collisionObjectDetailsCopy.size(); ++collisionObject )
|
||||
{
|
||||
CollisionShapeDescription &shapeDescription( m_collisionObjectDetailsCopy[collisionObject] );
|
||||
++numObjectsPerClothPrefixSum[shapeDescription.softBodyIdentifier];
|
||||
}
|
||||
int sum = 0;
|
||||
for( int cloth = 0; cloth < m_softBodySet.size(); ++cloth )
|
||||
{
|
||||
int currentValue = numObjectsPerClothPrefixSum[cloth];
|
||||
numObjectsPerClothPrefixSum[cloth] = sum;
|
||||
sum += currentValue;
|
||||
}
|
||||
// Move into the target array
|
||||
for( int collisionObject = 0; collisionObject < m_collisionObjectDetailsCopy.size(); ++collisionObject )
|
||||
{
|
||||
CollisionShapeDescription &shapeDescription( m_collisionObjectDetailsCopy[collisionObject] );
|
||||
int clothID = shapeDescription.softBodyIdentifier;
|
||||
int newLocation = numObjectsPerClothPrefixSum[clothID] + numObjectsPerCloth[clothID];
|
||||
numObjectsPerCloth[shapeDescription.softBodyIdentifier]++;
|
||||
m_collisionObjectDetails[newLocation] = shapeDescription;
|
||||
}
|
||||
for( int collisionObject = 0; collisionObject < m_collisionObjectDetailsCopy.size(); ++collisionObject )
|
||||
{
|
||||
CollisionShapeDescription &shapeDescription( m_collisionObjectDetails[collisionObject] );
|
||||
}
|
||||
|
||||
// Generating indexing for perClothCollisionObjects
|
||||
// First clear the previous values
|
||||
for( int clothIndex = 0; clothIndex < m_perClothCollisionObjects.size(); ++clothIndex )
|
||||
{
|
||||
m_perClothCollisionObjects[clothIndex].firstObject = 0;
|
||||
m_perClothCollisionObjects[clothIndex].endObject = 0;
|
||||
}
|
||||
int currentCloth = 0;
|
||||
int startIndex = 0;
|
||||
for( int collisionObject = 0; collisionObject < m_collisionObjectDetails.size(); ++collisionObject )
|
||||
{
|
||||
int nextCloth = m_collisionObjectDetails[collisionObject].softBodyIdentifier;
|
||||
if( nextCloth != currentCloth )
|
||||
{
|
||||
// Changed cloth in the array
|
||||
// Set the end index and the range is what we need for currentCloth
|
||||
m_perClothCollisionObjects[currentCloth].firstObject = startIndex;
|
||||
m_perClothCollisionObjects[currentCloth].endObject = collisionObject;
|
||||
currentCloth = nextCloth;
|
||||
startIndex = collisionObject;
|
||||
}
|
||||
}
|
||||
//m_perClothCollisionObjects
|
||||
} // prepareCollisionConstraints
|
||||
|
||||
|
||||
void btCPUSoftBodySolver::solveConstraints( float solverdt )
|
||||
{
|
||||
using Vectormath::Aos::Vector3;
|
||||
using Vectormath::Aos::Point3;
|
||||
using Vectormath::Aos::lengthSqr;
|
||||
using Vectormath::Aos::dot;
|
||||
|
||||
// Prepare links
|
||||
int numLinks = m_linkData.getNumLinks();
|
||||
int numVertices = m_vertexData.getNumVertices();
|
||||
|
||||
float kst = 1.f;
|
||||
|
||||
for( int linkIndex = 0; linkIndex < numLinks; ++linkIndex )
|
||||
{
|
||||
btSoftBodyLinkData::LinkNodePair &nodePair( m_linkData.getVertexPair(linkIndex) );
|
||||
Vector3 currentLength = m_vertexData.getPreviousPosition( nodePair.vertex1 ) - m_vertexData.getPreviousPosition( nodePair.vertex0 );
|
||||
m_linkData.getCurrentLength(linkIndex) = currentLength;
|
||||
|
||||
// If mass at both ends of links is 0 (both static points) then we don't want this information.
|
||||
// In reality this would be a fairly pointless link, but it could have been inserted
|
||||
float linkLengthRatio = 0;
|
||||
if( m_linkData.getMassLSC(linkIndex) > 0 )
|
||||
linkLengthRatio = 1.f/(lengthSqr(currentLength) * m_linkData.getMassLSC(linkIndex));
|
||||
m_linkData.getLinkLengthRatio(linkIndex) = linkLengthRatio;
|
||||
|
||||
}
|
||||
|
||||
#if 0
|
||||
prepareCollisionConstraints();
|
||||
|
||||
// Solve collision constraints
|
||||
// Very simple solver that pushes the vertex out of collision imposters for now
|
||||
// to test integration with the broad phase code.
|
||||
// May also want to put this into position solver loop every n iterations depending on
|
||||
// how it behaves
|
||||
for( int clothIndex = 0; clothIndex < m_softBodySet.size(); ++clothIndex )
|
||||
{
|
||||
btAcceleratedSoftBodyInterface *currentCloth = m_softBodySet[clothIndex];
|
||||
|
||||
const int startVertex = currentCloth->getFirstVertex();
|
||||
const int numVertices = currentCloth->getNumVertices();
|
||||
int endVertex = startVertex + numVertices;
|
||||
|
||||
int startObject = m_perClothCollisionObjects[clothIndex].firstObject;
|
||||
int endObject = m_perClothCollisionObjects[clothIndex].endObject;
|
||||
|
||||
for( int collisionObject = startObject; collisionObject < endObject; ++collisionObject )
|
||||
{
|
||||
CollisionShapeDescription &shapeDescription( m_collisionObjectDetails[collisionObject] );
|
||||
|
||||
if( shapeDescription.collisionShapeType == CAPSULE_SHAPE_PROXYTYPE )
|
||||
{
|
||||
using namespace Vectormath::Aos;
|
||||
|
||||
float capsuleHalfHeight = shapeDescription.shapeInformation.capsule.halfHeight;
|
||||
float capsuleRadius = shapeDescription.shapeInformation.capsule.radius;
|
||||
Transform3 worldTransform = shapeDescription.shapeTransform;
|
||||
for( int vertexIndex = startVertex; vertexIndex < endVertex; ++vertexIndex )
|
||||
{
|
||||
Point3 vertex( m_vertexData.getPosition( vertexIndex ) );
|
||||
Point3 c1(0.f, -capsuleHalfHeight, 0.f);
|
||||
Point3 c2(0.f, +capsuleHalfHeight, 0.f);
|
||||
Point3 worldC1 = worldTransform * c1;
|
||||
Point3 worldC2 = worldTransform * c2;
|
||||
Vector3 segment = worldC2 - worldC1;
|
||||
|
||||
// compute distance of tangent to vertex along line segment in capsule
|
||||
float distanceAlongSegment = -( dot( worldC1 - vertex, segment ) / lengthSqr(segment) );
|
||||
|
||||
Point3 closestPoint = (worldC1 + segment * distanceAlongSegment);
|
||||
float distanceFromLine = length(vertex - closestPoint);
|
||||
float distanceFromC1 = length(worldC1 - vertex);
|
||||
float distanceFromC2 = length(worldC2 - vertex);
|
||||
|
||||
// Final distance from collision, point to push from, direction to push in
|
||||
// for impulse force
|
||||
float distance;
|
||||
Point3 sourcePoint;
|
||||
Vector3 pushVector;
|
||||
if( distanceAlongSegment < 0 )
|
||||
{
|
||||
distance = distanceFromC1;
|
||||
sourcePoint = worldC1;
|
||||
pushVector = normalize(vertex - worldC1);
|
||||
} else if( distanceAlongSegment > 1.f ) {
|
||||
distance = distanceFromC1;
|
||||
sourcePoint = worldC1;
|
||||
pushVector = normalize(vertex - worldC1);
|
||||
} else {
|
||||
distance = distanceFromLine;
|
||||
sourcePoint = closestPoint;
|
||||
pushVector = normalize(vertex - closestPoint);
|
||||
}
|
||||
|
||||
// For now just update vertex position by moving to radius distance along the push vector
|
||||
// Could use this as the basis for simple vector distance constraint for the point later, possibly?
|
||||
// That way in the main solver loop all shape types could be the same... though when
|
||||
// we need to apply bi-directionally it becomes more complicated
|
||||
m_vertexData.getPosition( vertexIndex ) = closestPoint + capsuleRadius * pushVector;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
for( int iteration = 0; iteration < m_numberOfVelocityIterations ; ++iteration )
|
||||
{
|
||||
// Solve velocity
|
||||
for(int linkIndex = 0; linkIndex < numLinks; ++linkIndex)
|
||||
{
|
||||
|
||||
int vertexIndex0 = m_linkData.getVertexPair(linkIndex).vertex0;
|
||||
int vertexIndex1 = m_linkData.getVertexPair(linkIndex).vertex1;
|
||||
|
||||
float j = -dot(m_linkData.getCurrentLength(linkIndex), m_vertexData.getVelocity(vertexIndex0) - m_vertexData.getVelocity(vertexIndex1)) * m_linkData.getLinkLengthRatio(linkIndex)*kst;
|
||||
|
||||
// If both ends of the link have no mass then this will be zero. Catch that case.
|
||||
// TODO: Should really catch the /0 in the link setup, too
|
||||
//if(psb->m_linksc0[i]>0)
|
||||
{
|
||||
m_vertexData.getVelocity(vertexIndex0) = m_vertexData.getVelocity(vertexIndex0) + m_linkData.getCurrentLength(linkIndex)*j*m_vertexData.getInverseMass(vertexIndex0);
|
||||
m_vertexData.getVelocity(vertexIndex1) = m_vertexData.getVelocity(vertexIndex1) - m_linkData.getCurrentLength(linkIndex)*j*m_vertexData.getInverseMass(vertexIndex1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Compute new positions from velocity
|
||||
// Also update the previous position so that our position computation is now based on the new position from the velocity solution
|
||||
// rather than based directly on the original positions
|
||||
if( m_numberOfVelocityIterations > 0 )
|
||||
{
|
||||
for(int vertexIndex = 0; vertexIndex < numVertices; ++vertexIndex)
|
||||
{
|
||||
m_vertexData.getPosition(vertexIndex) = m_vertexData.getPreviousPosition(vertexIndex) + m_vertexData.getVelocity(vertexIndex) * solverdt;
|
||||
m_vertexData.getPreviousPosition(vertexIndex) = m_vertexData.getPosition(vertexIndex);
|
||||
}
|
||||
}
|
||||
|
||||
// Solve drift
|
||||
for( int iteration = 0; iteration < m_numberOfPositionIterations ; ++iteration )
|
||||
{
|
||||
for( int clothIndex = 0; clothIndex < m_softBodySet.size(); ++clothIndex )
|
||||
{
|
||||
btAcceleratedSoftBodyInterface *currentCloth = m_softBodySet[clothIndex];
|
||||
|
||||
const int startLink = currentCloth->getFirstLink();
|
||||
const int numLinks = currentCloth->getNumLinks();
|
||||
|
||||
int endLink = startLink + numLinks;
|
||||
for(int linkIndex = startLink; linkIndex < endLink; ++linkIndex)
|
||||
{
|
||||
int vertexIndex0 = m_linkData.getVertexPair(linkIndex).vertex0;
|
||||
int vertexIndex1 = m_linkData.getVertexPair(linkIndex).vertex1;
|
||||
|
||||
float massLSC = m_linkData.getMassLSC(linkIndex);
|
||||
if( massLSC > 0.f )
|
||||
{
|
||||
Point3 &vertexPosition0( m_vertexData.getPosition( vertexIndex0 ) );
|
||||
Point3 &vertexPosition1( m_vertexData.getPosition( vertexIndex1 ) );
|
||||
|
||||
Vector3 del = vertexPosition1 - vertexPosition0;
|
||||
float len = lengthSqr(del);
|
||||
float restLength2 = m_linkData.getRestLengthSquared(linkIndex);
|
||||
float k = ((restLength2 - len) / (massLSC * (restLength2 + len) ) )*kst;
|
||||
|
||||
vertexPosition0 -= del*(k*m_vertexData.getInverseMass(vertexIndex0));
|
||||
vertexPosition1 += del*(k*m_vertexData.getInverseMass(vertexIndex1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( int clothIndex = 0; clothIndex < m_softBodySet.size(); ++clothIndex )
|
||||
{
|
||||
btAcceleratedSoftBodyInterface *currentCloth = m_softBodySet[clothIndex];
|
||||
|
||||
const int startLink = currentCloth->getFirstLink();
|
||||
const int numLinks = currentCloth->getNumLinks();
|
||||
const int startVertex = currentCloth->getFirstVertex();
|
||||
const int numVertices = currentCloth->getNumVertices();
|
||||
const int lastVertex = startVertex + numVertices;
|
||||
// Update the velocities based on the change in position
|
||||
// TODO: Damping should only be applied to the action of link constraints so the cloth still falls but then moves stiffly once it hits something
|
||||
float velocityCoefficient = (1.f - m_perClothDampingFactor[clothIndex]);
|
||||
float velocityCorrectionCoefficient = m_perClothVelocityCorrectionCoefficient[clothIndex];
|
||||
float isolverDt = 1.f/solverdt;
|
||||
|
||||
if( m_numberOfVelocityIterations > 0 )
|
||||
{
|
||||
for(int vertexIndex = startVertex; vertexIndex < lastVertex; ++vertexIndex)
|
||||
{
|
||||
m_vertexData.getVelocity(vertexIndex) += (m_vertexData.getPosition(vertexIndex) - m_vertexData.getPreviousPosition(vertexIndex)) * velocityCorrectionCoefficient * isolverDt;
|
||||
m_vertexData.getVelocity(vertexIndex) *= velocityCoefficient;
|
||||
m_vertexData.getForceAccumulator( vertexIndex ) = Vector3(0.f, 0.f, 0.f);
|
||||
}
|
||||
} else {
|
||||
// If we didn't compute the velocity iteratively then we compute it purely based on the position change
|
||||
for(int vertexIndex = startVertex; vertexIndex < lastVertex; ++vertexIndex)
|
||||
{
|
||||
m_vertexData.getVelocity(vertexIndex) = (m_vertexData.getPosition(vertexIndex) - m_vertexData.getPreviousPosition(vertexIndex)) * velocityCoefficient * isolverDt;
|
||||
m_vertexData.getForceAccumulator( vertexIndex ) = Vector3(0.f, 0.f, 0.f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // btCPUSoftBodySolver::solveConstraints
|
||||
|
||||
|
||||
btCPUSoftBodySolver::btAcceleratedSoftBodyInterface *btCPUSoftBodySolver::findSoftBodyInterface( const btSoftBody* const softBody )
|
||||
{
|
||||
for( int softBodyIndex = 0; softBodyIndex < m_softBodySet.size(); ++softBodyIndex )
|
||||
{
|
||||
btAcceleratedSoftBodyInterface *softBodyInterface = m_softBodySet[softBodyIndex];
|
||||
if( softBodyInterface->getSoftBody() == softBody )
|
||||
return softBodyInterface;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void btCPUSoftBodySolver::copySoftBodyToVertexBuffer( const btSoftBody * const softBody, btVertexBufferDescriptor *vertexBuffer )
|
||||
{
|
||||
// Currently only support CPU output buffers
|
||||
// TODO: check for DX11 buffers. Take all offsets into the same DX11 buffer
|
||||
// and use them together on a single kernel call if possible by setting up a
|
||||
// per-cloth target buffer array for the copy kernel.
|
||||
|
||||
btAcceleratedSoftBodyInterface *currentCloth = findSoftBodyInterface( softBody );
|
||||
|
||||
if( vertexBuffer->getBufferType() == btVertexBufferDescriptor::CPU_BUFFER )
|
||||
{
|
||||
const int firstVertex = currentCloth->getFirstVertex();
|
||||
const int lastVertex = firstVertex + currentCloth->getNumVertices();
|
||||
const btCPUVertexBufferDescriptor *cpuVertexBuffer = static_cast< btCPUVertexBufferDescriptor* >(vertexBuffer);
|
||||
float *basePointer = cpuVertexBuffer->getBasePointer();
|
||||
|
||||
if( vertexBuffer->hasVertexPositions() )
|
||||
{
|
||||
const int vertexOffset = cpuVertexBuffer->getVertexOffset();
|
||||
const int vertexStride = cpuVertexBuffer->getVertexStride();
|
||||
float *vertexPointer = basePointer + vertexOffset;
|
||||
|
||||
for( int vertexIndex = firstVertex; vertexIndex < lastVertex; ++vertexIndex )
|
||||
{
|
||||
Vectormath::Aos::Point3 position = m_vertexData.getPosition(vertexIndex);
|
||||
*(vertexPointer + 0) = position.getX();
|
||||
*(vertexPointer + 1) = position.getY();
|
||||
*(vertexPointer + 2) = position.getZ();
|
||||
vertexPointer += vertexStride;
|
||||
}
|
||||
}
|
||||
if( vertexBuffer->hasNormals() )
|
||||
{
|
||||
const int normalOffset = cpuVertexBuffer->getNormalOffset();
|
||||
const int normalStride = cpuVertexBuffer->getNormalStride();
|
||||
float *normalPointer = basePointer + normalOffset;
|
||||
|
||||
for( int vertexIndex = firstVertex; vertexIndex < lastVertex; ++vertexIndex )
|
||||
{
|
||||
Vectormath::Aos::Vector3 normal = m_vertexData.getNormal(vertexIndex);
|
||||
*(normalPointer + 0) = normal.getX();
|
||||
*(normalPointer + 1) = normal.getY();
|
||||
*(normalPointer + 2) = normal.getZ();
|
||||
normalPointer += normalStride;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // btCPUSoftBodySolver::outputToVertexBuffers
|
||||
|
||||
|
||||
|
||||
void btCPUSoftBodySolver::addCollisionObjectForSoftBody( int clothIndex, btCollisionObject *collisionObject )
|
||||
{
|
||||
btCollisionShape *collisionShape = collisionObject->getCollisionShape();
|
||||
int shapeType = collisionShape->getShapeType();
|
||||
if( shapeType == CAPSULE_SHAPE_PROXYTYPE )
|
||||
{
|
||||
// Add to the list of expected collision objects
|
||||
CollisionShapeDescription newCollisionShapeDescription;
|
||||
newCollisionShapeDescription.softBodyIdentifier = clothIndex;
|
||||
newCollisionShapeDescription.collisionShapeType = shapeType;
|
||||
newCollisionShapeDescription.shapeTransform = toTransform3(collisionObject->getWorldTransform());
|
||||
btCapsuleShape *capsule = static_cast<btCapsuleShape*>( collisionShape );
|
||||
newCollisionShapeDescription.shapeInformation.capsule.radius = capsule->getRadius();
|
||||
newCollisionShapeDescription.shapeInformation.capsule.halfHeight = capsule->getHalfHeight();
|
||||
m_collisionObjectDetails.push_back( newCollisionShapeDescription );
|
||||
|
||||
// TODO: In the collision function, sort the above array on the clothIndex and generate the start and end indices
|
||||
} else {
|
||||
btAssert("Unsupported collision shape type\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void btCPUSoftBodySolver::predictMotion( float timeStep )
|
||||
{
|
||||
// Fill the force arrays with current acceleration data etc
|
||||
m_perClothWindVelocity.resize( m_softBodySet.size() );
|
||||
for( int softBodyIndex = 0; softBodyIndex < m_softBodySet.size(); ++softBodyIndex )
|
||||
{
|
||||
btSoftBody *softBody = m_softBodySet[softBodyIndex]->getSoftBody();
|
||||
|
||||
m_perClothWindVelocity[softBodyIndex] = toVector3(softBody->getWindVelocity());
|
||||
}
|
||||
|
||||
|
||||
// Apply forces that we know about to the cloths
|
||||
applyForces( timeStep * getTimeScale() );
|
||||
|
||||
// Itegrate motion for all soft bodies dealt with by the solver
|
||||
integrate( timeStep * getTimeScale() );
|
||||
// End prediction work for solvers
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,345 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef BT_ACCELERATED_SOFT_BODY_CPU_SOLVER_H
|
||||
#define BT_ACCELERATED_SOFT_BODY_CPU_SOLVER_H
|
||||
|
||||
#include "vectormath_aos.h"
|
||||
|
||||
#include "BulletSoftBody/btSoftBodySolvers.h"
|
||||
#include "BulletSoftBody/btSoftBodySolverVertexBuffer.h"
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/CPU/btSoftBodySolverData.h"
|
||||
|
||||
|
||||
|
||||
class btCPUSoftBodySolver : public btSoftBodySolver
|
||||
{
|
||||
protected:
|
||||
/**
|
||||
* Entry in the collision shape array.
|
||||
* Specifies the shape type, the transform matrix and the necessary details of the collisionShape.
|
||||
*/
|
||||
struct CollisionShapeDescription
|
||||
{
|
||||
int softBodyIdentifier;
|
||||
int collisionShapeType;
|
||||
Vectormath::Aos::Transform3 shapeTransform;
|
||||
union
|
||||
{
|
||||
struct Sphere
|
||||
{
|
||||
float radius;
|
||||
} sphere;
|
||||
struct Capsule
|
||||
{
|
||||
float radius;
|
||||
float halfHeight;
|
||||
} capsule;
|
||||
} shapeInformation;
|
||||
|
||||
CollisionShapeDescription()
|
||||
{
|
||||
collisionShapeType = 0;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* SoftBody class to maintain information about a soft body instance
|
||||
* within a solver.
|
||||
* This data addresses the main solver arrays.
|
||||
*/
|
||||
class btAcceleratedSoftBodyInterface
|
||||
{
|
||||
protected:
|
||||
/** Current number of vertices that are part of this cloth */
|
||||
int m_numVertices;
|
||||
/** Maximum number of vertices allocated to be part of this cloth */
|
||||
int m_maxVertices;
|
||||
/** Current number of triangles that are part of this cloth */
|
||||
int m_numTriangles;
|
||||
/** Maximum number of triangles allocated to be part of this cloth */
|
||||
int m_maxTriangles;
|
||||
/** Index of first vertex in the world allocated to this cloth */
|
||||
int m_firstVertex;
|
||||
/** Index of first triangle in the world allocated to this cloth */
|
||||
int m_firstTriangle;
|
||||
/** Index of first link in the world allocated to this cloth */
|
||||
int m_firstLink;
|
||||
/** Maximum number of links allocated to this cloth */
|
||||
int m_maxLinks;
|
||||
/** Current number of links allocated to this cloth */
|
||||
int m_numLinks;
|
||||
|
||||
/** The actual soft body this data represents */
|
||||
btSoftBody *m_softBody;
|
||||
|
||||
|
||||
public:
|
||||
btAcceleratedSoftBodyInterface( btSoftBody *softBody ) :
|
||||
m_softBody( softBody )
|
||||
{
|
||||
m_numVertices = 0;
|
||||
m_maxVertices = 0;
|
||||
m_numTriangles = 0;
|
||||
m_maxTriangles = 0;
|
||||
m_firstVertex = 0;
|
||||
m_firstTriangle = 0;
|
||||
m_firstLink = 0;
|
||||
m_maxLinks = 0;
|
||||
m_numLinks = 0;
|
||||
}
|
||||
int getNumVertices()
|
||||
{
|
||||
return m_numVertices;
|
||||
}
|
||||
|
||||
int getNumTriangles()
|
||||
{
|
||||
return m_numTriangles;
|
||||
}
|
||||
|
||||
int getMaxVertices()
|
||||
{
|
||||
return m_maxVertices;
|
||||
}
|
||||
|
||||
int getMaxTriangles()
|
||||
{
|
||||
return m_maxTriangles;
|
||||
}
|
||||
|
||||
int getFirstVertex()
|
||||
{
|
||||
return m_firstVertex;
|
||||
}
|
||||
|
||||
int getFirstTriangle()
|
||||
{
|
||||
return m_firstTriangle;
|
||||
}
|
||||
|
||||
// TODO: All of these set functions will have to do checks and
|
||||
// update the world because restructuring of the arrays will be necessary
|
||||
// Reasonable use of "friend"?
|
||||
void setNumVertices( int numVertices )
|
||||
{
|
||||
m_numVertices = numVertices;
|
||||
}
|
||||
|
||||
void setNumTriangles( int numTriangles )
|
||||
{
|
||||
m_numTriangles = numTriangles;
|
||||
}
|
||||
|
||||
void setMaxVertices( int maxVertices )
|
||||
{
|
||||
m_maxVertices = maxVertices;
|
||||
}
|
||||
|
||||
void setMaxTriangles( int maxTriangles )
|
||||
{
|
||||
m_maxTriangles = maxTriangles;
|
||||
}
|
||||
|
||||
void setFirstVertex( int firstVertex )
|
||||
{
|
||||
m_firstVertex = firstVertex;
|
||||
}
|
||||
|
||||
void setFirstTriangle( int firstTriangle )
|
||||
{
|
||||
m_firstTriangle = firstTriangle;
|
||||
}
|
||||
|
||||
void setMaxLinks( int maxLinks )
|
||||
{
|
||||
m_maxLinks = maxLinks;
|
||||
}
|
||||
|
||||
void setNumLinks( int numLinks )
|
||||
{
|
||||
m_numLinks = numLinks;
|
||||
}
|
||||
|
||||
void setFirstLink( int firstLink )
|
||||
{
|
||||
m_firstLink = firstLink;
|
||||
}
|
||||
|
||||
int getMaxLinks()
|
||||
{
|
||||
return m_maxLinks;
|
||||
}
|
||||
|
||||
int getNumLinks()
|
||||
{
|
||||
return m_numLinks;
|
||||
}
|
||||
|
||||
int getFirstLink()
|
||||
{
|
||||
return m_firstLink;
|
||||
}
|
||||
|
||||
btSoftBody* getSoftBody()
|
||||
{
|
||||
return m_softBody;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void setAcceleration( Vectormath::Aos::Vector3 acceleration )
|
||||
{
|
||||
m_currentSolver->setPerClothAcceleration( m_clothIdentifier, acceleration );
|
||||
}
|
||||
|
||||
void setWindVelocity( Vectormath::Aos::Vector3 windVelocity )
|
||||
{
|
||||
m_currentSolver->setPerClothWindVelocity( m_clothIdentifier, windVelocity );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the density of the air in which the cloth is situated.
|
||||
*/
|
||||
void setAirDensity( btScalar density )
|
||||
{
|
||||
m_currentSolver->setPerClothMediumDensity( m_clothIdentifier, static_cast<float>(density) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a collision object to this soft body.
|
||||
*/
|
||||
void addCollisionObject( btCollisionObject *collisionObject )
|
||||
{
|
||||
m_currentSolver->addCollisionObjectForSoftBody( m_clothIdentifier, collisionObject );
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
struct CollisionObjectIndices
|
||||
{
|
||||
int firstObject;
|
||||
int endObject;
|
||||
};
|
||||
|
||||
|
||||
|
||||
btSoftBodyLinkData m_linkData;
|
||||
btSoftBodyVertexData m_vertexData;
|
||||
btSoftBodyTriangleData m_triangleData;
|
||||
|
||||
/** Variable to define whether we need to update solver constants on the next iteration */
|
||||
bool m_updateSolverConstants;
|
||||
|
||||
/**
|
||||
* Cloths owned by this solver.
|
||||
* Only our cloths are in this array.
|
||||
*/
|
||||
btAlignedObjectArray< btAcceleratedSoftBodyInterface * > m_softBodySet;
|
||||
|
||||
/** Acceleration value to be applied to all non-static vertices in the solver.
|
||||
* Index n is cloth n, array sized by number of cloths in the world not the solver.
|
||||
*/
|
||||
btAlignedObjectArray< Vectormath::Aos::Vector3 > m_perClothAcceleration;
|
||||
|
||||
/** Wind velocity to be applied normal to all non-static vertices in the solver.
|
||||
* Index n is cloth n, array sized by number of cloths in the world not the solver.
|
||||
*/
|
||||
btAlignedObjectArray< Vectormath::Aos::Vector3 > m_perClothWindVelocity;
|
||||
|
||||
/** Velocity damping factor */
|
||||
btAlignedObjectArray< float > m_perClothDampingFactor;
|
||||
|
||||
/** Velocity correction coefficient */
|
||||
btAlignedObjectArray< float > m_perClothVelocityCorrectionCoefficient;
|
||||
|
||||
/** Lift parameter for wind effect on cloth. */
|
||||
btAlignedObjectArray< float > m_perClothLiftFactor;
|
||||
|
||||
/** Drag parameter for wind effect on cloth. */
|
||||
btAlignedObjectArray< float > m_perClothDragFactor;
|
||||
|
||||
/** Density of the medium in which each cloth sits */
|
||||
btAlignedObjectArray< float > m_perClothMediumDensity;
|
||||
|
||||
/**
|
||||
* Collision shape details: pair of index of first collision shape for the cloth and number of collision objects.
|
||||
*/
|
||||
btAlignedObjectArray< CollisionObjectIndices > m_perClothCollisionObjects;
|
||||
|
||||
/**
|
||||
* Collision shapes being passed across to the cloths in this solver.
|
||||
*/
|
||||
btAlignedObjectArray< CollisionShapeDescription > m_collisionObjectDetails;
|
||||
|
||||
|
||||
void prepareCollisionConstraints();
|
||||
|
||||
Vectormath::Aos::Vector3 ProjectOnAxis( const Vectormath::Aos::Vector3 &v, const Vectormath::Aos::Vector3 &a );
|
||||
|
||||
void ApplyClampedForce( float solverdt, const Vectormath::Aos::Vector3 &force, const Vectormath::Aos::Vector3 &vertexVelocity, float inverseMass, Vectormath::Aos::Vector3 &vertexForce );
|
||||
|
||||
float computeTriangleArea(
|
||||
const Vectormath::Aos::Point3 &vertex0,
|
||||
const Vectormath::Aos::Point3 &vertex1,
|
||||
const Vectormath::Aos::Point3 &vertex2 );
|
||||
|
||||
void applyForces( float solverdt );
|
||||
void integrate( float solverdt );
|
||||
void updateConstants( float timeStep );
|
||||
btAcceleratedSoftBodyInterface *findSoftBodyInterface( const btSoftBody* const softBody );
|
||||
|
||||
|
||||
public:
|
||||
btCPUSoftBodySolver();
|
||||
|
||||
virtual ~btCPUSoftBodySolver();
|
||||
|
||||
|
||||
virtual btSoftBodyLinkData &getLinkData();
|
||||
|
||||
virtual btSoftBodyVertexData &getVertexData();
|
||||
|
||||
virtual btSoftBodyTriangleData &getTriangleData();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Add a collision object to be used by the indicated softbody.
|
||||
*/
|
||||
virtual void addCollisionObjectForSoftBody( int clothIdentifier, btCollisionObject *collisionObject );
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
virtual bool checkInitialized();
|
||||
|
||||
virtual void updateSoftBodies( );
|
||||
|
||||
virtual void optimize( btAlignedObjectArray< btSoftBody * > &softBodies );
|
||||
|
||||
virtual void solveConstraints( float solverdt );
|
||||
|
||||
virtual void predictMotion( float solverdt );
|
||||
|
||||
virtual void copySoftBodyToVertexBuffer( const btSoftBody *const softBody, btVertexBufferDescriptor *vertexBuffer );
|
||||
};
|
||||
|
||||
#endif // #ifndef BT_ACCELERATED_SOFT_BODY_CPU_SOLVER_H
|
||||
@@ -0,0 +1,76 @@
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/src
|
||||
)
|
||||
|
||||
SET(DXSDK_DIR $ENV{DXSDK_DIR})
|
||||
SET(DX11_INCLUDE_PATH "${DIRECTX_SDK_BASE_DIR}/Include" CACHE DOCSTRING "Microsoft directX SDK include path")
|
||||
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
${DX11_INCLUDE_PATH} "../cpu/"
|
||||
${VECTOR_MATH_INCLUDE}
|
||||
)
|
||||
|
||||
SET(BulletSoftBodyDX11Solvers_SRCS
|
||||
btSoftBodySolver_DX11.cpp
|
||||
)
|
||||
|
||||
SET(BulletSoftBodyDX11Solvers_HDRS
|
||||
btSoftBodySolver_DX11.h
|
||||
../cpu/btSoftBodySolverData.h
|
||||
btSoftBodySolverVertexData_DX11.h
|
||||
btSoftBodySolverTriangleData_DX11.h
|
||||
btSoftBodySolverLinkData_DX11.h
|
||||
btSoftBodySolverBuffer_DX11.h
|
||||
btSoftBodySolverVertexBuffer_DX11.h
|
||||
|
||||
)
|
||||
|
||||
# OpenCL and HLSL Shaders.
|
||||
# Build rules generated to stringify these into headers
|
||||
# which are needed by some of the sources
|
||||
SET(BulletSoftBodyDX11Solvers_Shaders
|
||||
OutputToVertexArray
|
||||
UpdateNormals
|
||||
Integrate
|
||||
UpdatePositions
|
||||
UpdateNodes
|
||||
SolvePositions
|
||||
UpdatePositionsFromVelocities
|
||||
ApplyForces
|
||||
PrepareLinks
|
||||
VSolveLinks
|
||||
)
|
||||
|
||||
foreach(f ${BulletSoftBodyDX11Solvers_Shaders})
|
||||
LIST(APPEND BulletSoftBodyDX11Solvers_HLSL "HLSL/${f}.hlsl")
|
||||
endforeach(f)
|
||||
|
||||
|
||||
|
||||
ADD_LIBRARY(BulletSoftBodySolvers_DX11 ${BulletSoftBodyDX11Solvers_SRCS} ${BulletSoftBodyDX11Solvers_HDRS} ${BulletSoftBodyDX11Solvers_HLSL})
|
||||
SET_TARGET_PROPERTIES(BulletSoftBodySolvers_DX11 PROPERTIES VERSION ${BULLET_VERSION})
|
||||
SET_TARGET_PROPERTIES(BulletSoftBodySolvers_DX11 PROPERTIES SOVERSION ${BULLET_VERSION})
|
||||
IF (BUILD_SHARED_LIBS)
|
||||
TARGET_LINK_LIBRARIES(BulletSoftBody BulletDynamics)
|
||||
ENDIF (BUILD_SHARED_LIBS)
|
||||
|
||||
|
||||
IF (INSTALL_LIBS)
|
||||
IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES)
|
||||
IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5)
|
||||
IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
INSTALL(TARGETS BulletSoftBodySolvers_DX11 DESTINATION .)
|
||||
ELSE (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
INSTALL(TARGETS BulletSoftBodySolvers_DX11 DESTINATION lib${LIB_SUFFIX})
|
||||
INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DESTINATION include FILES_MATCHING PATTERN "*.h")
|
||||
ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5)
|
||||
|
||||
IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
SET_TARGET_PROPERTIES(BulletSoftBodySolvers_DX11 PROPERTIES FRAMEWORK true)
|
||||
SET_TARGET_PROPERTIES(BulletSoftBodySolvers_DX11 PROPERTIES PUBLIC_HEADER "${BulletSoftBodyDX11Solvers_HDRS}")
|
||||
ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES)
|
||||
ENDIF (INSTALL_LIBS)
|
||||
@@ -0,0 +1,95 @@
|
||||
MSTRINGIFY(
|
||||
|
||||
cbuffer ApplyForcesCB : register( b0 )
|
||||
{
|
||||
unsigned int numNodes;
|
||||
float solverdt;
|
||||
float epsilon;
|
||||
int padding3;
|
||||
};
|
||||
|
||||
|
||||
StructuredBuffer<int> g_vertexClothIdentifier : register( t0 );
|
||||
StructuredBuffer<float4> g_vertexNormal : register( t1 );
|
||||
StructuredBuffer<float> g_vertexArea : register( t2 );
|
||||
StructuredBuffer<float> g_vertexInverseMass : register( t3 );
|
||||
// TODO: These could be combined into a lift/drag factor array along with medium density
|
||||
StructuredBuffer<float> g_clothLiftFactor : register( t4 );
|
||||
StructuredBuffer<float> g_clothDragFactor : register( t5 );
|
||||
StructuredBuffer<float4> g_clothWindVelocity : register( t6 );
|
||||
StructuredBuffer<float4> g_clothAcceleration : register( t7 );
|
||||
StructuredBuffer<float> g_clothMediumDensity : register( t8 );
|
||||
|
||||
RWStructuredBuffer<float4> g_vertexForceAccumulator : register( u0 );
|
||||
RWStructuredBuffer<float4> g_vertexVelocity : register( u1 );
|
||||
|
||||
float3 projectOnAxis( float3 v, float3 a )
|
||||
{
|
||||
return (a*dot(v, a));
|
||||
}
|
||||
|
||||
[numthreads(128, 1, 1)]
|
||||
void
|
||||
ApplyForcesKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex )
|
||||
{
|
||||
unsigned int nodeID = DTid.x;
|
||||
if( nodeID < numNodes )
|
||||
{
|
||||
int clothId = g_vertexClothIdentifier[nodeID];
|
||||
float nodeIM = g_vertexInverseMass[nodeID];
|
||||
|
||||
if( nodeIM > 0.0f )
|
||||
{
|
||||
float3 nodeV = g_vertexVelocity[nodeID].xyz;
|
||||
float3 normal = g_vertexNormal[nodeID].xyz;
|
||||
float area = g_vertexArea[nodeID];
|
||||
float3 nodeF = g_vertexForceAccumulator[nodeID].xyz;
|
||||
|
||||
// Read per-cloth values
|
||||
float3 clothAcceleration = g_clothAcceleration[clothId].xyz;
|
||||
float3 clothWindVelocity = g_clothWindVelocity[clothId].xyz;
|
||||
float liftFactor = g_clothLiftFactor[clothId];
|
||||
float dragFactor = g_clothDragFactor[clothId];
|
||||
float mediumDensity = g_clothMediumDensity[clothId];
|
||||
|
||||
// Apply the acceleration to the cloth rather than do this via a force
|
||||
nodeV += (clothAcceleration*solverdt);
|
||||
|
||||
g_vertexVelocity[nodeID] = float4(nodeV, 0.f);
|
||||
|
||||
float3 relativeWindVelocity = nodeV - clothWindVelocity;
|
||||
float relativeSpeedSquared = dot(relativeWindVelocity, relativeWindVelocity);
|
||||
|
||||
if( relativeSpeedSquared > epsilon )
|
||||
{
|
||||
// Correct direction of normal relative to wind direction and get dot product
|
||||
normal = normal * (dot(normal, relativeWindVelocity) < 0 ? -1.f : 1.f);
|
||||
float dvNormal = dot(normal, relativeWindVelocity);
|
||||
if( dvNormal > 0 )
|
||||
{
|
||||
float3 force = float3(0.f, 0.f, 0.f);
|
||||
float c0 = area * dvNormal * relativeSpeedSquared / 2.f;
|
||||
float c1 = c0 * mediumDensity;
|
||||
force += normal * (-c1 * liftFactor);
|
||||
force += normalize(relativeWindVelocity)*(-c1 * dragFactor);
|
||||
|
||||
float dtim = solverdt * nodeIM;
|
||||
float3 forceDTIM = force * dtim;
|
||||
|
||||
float3 nodeFPlusForce = nodeF + force;
|
||||
|
||||
// m_nodesf[i] -= ProjectOnAxis(m_nodesv[i], force.normalized())/dtim;
|
||||
float3 nodeFMinus = nodeF - (projectOnAxis(nodeV, normalize(force))/dtim);
|
||||
|
||||
nodeF = nodeFPlusForce;
|
||||
if( dot(forceDTIM, forceDTIM) > dot(nodeV, nodeV) )
|
||||
nodeF = nodeFMinus;
|
||||
|
||||
g_vertexForceAccumulator[nodeID] = float4(nodeF, 0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
@@ -0,0 +1,41 @@
|
||||
MSTRINGIFY(
|
||||
|
||||
cbuffer IntegrateCB : register( b0 )
|
||||
{
|
||||
int numNodes;
|
||||
float solverdt;
|
||||
int padding1;
|
||||
int padding2;
|
||||
};
|
||||
|
||||
// Node indices for each link
|
||||
StructuredBuffer<float> g_vertexInverseMasses : register( t0 );
|
||||
|
||||
RWStructuredBuffer<float4> g_vertexPositions : register( u0 );
|
||||
RWStructuredBuffer<float4> g_vertexVelocity : register( u1 );
|
||||
RWStructuredBuffer<float4> g_vertexPreviousPositions : register( u2 );
|
||||
RWStructuredBuffer<float4> g_vertexForceAccumulator : register( u3 );
|
||||
|
||||
[numthreads(128, 1, 1)]
|
||||
void
|
||||
IntegrateKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex )
|
||||
{
|
||||
int nodeID = DTid.x;
|
||||
if( nodeID < numNodes )
|
||||
{
|
||||
float3 position = g_vertexPositions[nodeID].xyz;
|
||||
float3 velocity = g_vertexVelocity[nodeID].xyz;
|
||||
float3 force = g_vertexForceAccumulator[nodeID].xyz;
|
||||
float inverseMass = g_vertexInverseMasses[nodeID];
|
||||
|
||||
g_vertexPreviousPositions[nodeID] = float4(position, 0.f);
|
||||
velocity += force * inverseMass * solverdt;
|
||||
position += velocity * solverdt;
|
||||
|
||||
g_vertexForceAccumulator[nodeID] = float4(0.f, 0.f, 0.f, 0.0f);
|
||||
g_vertexPositions[nodeID] = float4(position, 0.f);
|
||||
g_vertexVelocity[nodeID] = float4(velocity, 0.f);
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
@@ -0,0 +1,63 @@
|
||||
MSTRINGIFY(
|
||||
|
||||
cbuffer OutputToVertexArrayCB : register( b0 )
|
||||
{
|
||||
int startNode;
|
||||
int numNodes;
|
||||
int positionOffset;
|
||||
int positionStride;
|
||||
|
||||
int normalOffset;
|
||||
int normalStride;
|
||||
int padding1;
|
||||
int padding2;
|
||||
};
|
||||
|
||||
|
||||
StructuredBuffer<float4> g_vertexPositions : register( t0 );
|
||||
StructuredBuffer<float4> g_vertexNormals : register( t1 );
|
||||
|
||||
RWBuffer<float> g_vertexBuffer : register( u0 );
|
||||
|
||||
|
||||
[numthreads(128, 1, 1)]
|
||||
void
|
||||
OutputToVertexArrayWithNormalsKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex )
|
||||
{
|
||||
int nodeID = DTid.x;
|
||||
if( nodeID < numNodes )
|
||||
{
|
||||
float4 position = g_vertexPositions[nodeID + startNode];
|
||||
float4 normal = g_vertexNormals[nodeID + startNode];
|
||||
|
||||
// Stride should account for the float->float4 conversion
|
||||
int positionDestination = nodeID * positionStride + positionOffset;
|
||||
g_vertexBuffer[positionDestination] = position.x;
|
||||
g_vertexBuffer[positionDestination+1] = position.y;
|
||||
g_vertexBuffer[positionDestination+2] = position.z;
|
||||
|
||||
int normalDestination = nodeID * normalStride + normalOffset;
|
||||
g_vertexBuffer[normalDestination] = normal.x;
|
||||
g_vertexBuffer[normalDestination+1] = normal.y;
|
||||
g_vertexBuffer[normalDestination+2] = normal.z;
|
||||
}
|
||||
}
|
||||
|
||||
[numthreads(128, 1, 1)]
|
||||
void
|
||||
OutputToVertexArrayWithoutNormalsKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex )
|
||||
{
|
||||
int nodeID = DTid.x;
|
||||
if( nodeID < numNodes )
|
||||
{
|
||||
float4 position = g_vertexPositions[nodeID + startNode];
|
||||
float4 normal = g_vertexNormals[nodeID + startNode];
|
||||
|
||||
// Stride should account for the float->float4 conversion
|
||||
int positionDestination = nodeID * positionStride + positionOffset;
|
||||
g_vertexBuffer[positionDestination] = position.x;
|
||||
g_vertexBuffer[positionDestination+1] = position.y;
|
||||
g_vertexBuffer[positionDestination+2] = position.z;
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -0,0 +1,44 @@
|
||||
MSTRINGIFY(
|
||||
|
||||
cbuffer PrepareLinksCB : register( b0 )
|
||||
{
|
||||
int numLinks;
|
||||
int padding0;
|
||||
int padding1;
|
||||
int padding2;
|
||||
};
|
||||
|
||||
// Node indices for each link
|
||||
StructuredBuffer<int2> g_linksVertexIndices : register( t0 );
|
||||
StructuredBuffer<float> g_linksMassLSC : register( t1 );
|
||||
StructuredBuffer<float4> g_nodesPreviousPosition : register( t2 );
|
||||
|
||||
RWStructuredBuffer<float> g_linksLengthRatio : register( u0 );
|
||||
RWStructuredBuffer<float4> g_linksCurrentLength : register( u1 );
|
||||
|
||||
[numthreads(128, 1, 1)]
|
||||
void
|
||||
PrepareLinksKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex )
|
||||
{
|
||||
int linkID = DTid.x;
|
||||
if( linkID < numLinks )
|
||||
{
|
||||
int2 nodeIndices = g_linksVertexIndices[linkID];
|
||||
int node0 = nodeIndices.x;
|
||||
int node1 = nodeIndices.y;
|
||||
|
||||
float4 nodePreviousPosition0 = g_nodesPreviousPosition[node0];
|
||||
float4 nodePreviousPosition1 = g_nodesPreviousPosition[node1];
|
||||
|
||||
float massLSC = g_linksMassLSC[linkID];
|
||||
|
||||
float4 linkCurrentLength = nodePreviousPosition1 - nodePreviousPosition0;
|
||||
|
||||
float linkLengthRatio = dot(linkCurrentLength, linkCurrentLength)*massLSC;
|
||||
linkLengthRatio = 1./linkLengthRatio;
|
||||
|
||||
g_linksCurrentLength[linkID] = linkCurrentLength;
|
||||
g_linksLengthRatio[linkID] = linkLengthRatio;
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -0,0 +1,55 @@
|
||||
MSTRINGIFY(
|
||||
|
||||
cbuffer SolvePositionsFromLinksKernelCB : register( b0 )
|
||||
{
|
||||
int startLink;
|
||||
int numLinks;
|
||||
float kst;
|
||||
float ti;
|
||||
};
|
||||
|
||||
// Node indices for each link
|
||||
StructuredBuffer<int2> g_linksVertexIndices : register( t0 );
|
||||
|
||||
StructuredBuffer<float> g_linksMassLSC : register( t1 );
|
||||
StructuredBuffer<float> g_linksRestLengthSquared : register( t2 );
|
||||
StructuredBuffer<float> g_verticesInverseMass : register( t3 );
|
||||
|
||||
RWStructuredBuffer<float4> g_vertexPositions : register( u0 );
|
||||
|
||||
[numthreads(128, 1, 1)]
|
||||
void
|
||||
SolvePositionsFromLinksKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex )
|
||||
{
|
||||
int linkID = DTid.x + startLink;
|
||||
if( DTid.x < numLinks )
|
||||
{
|
||||
float massLSC = g_linksMassLSC[linkID];
|
||||
float restLengthSquared = g_linksRestLengthSquared[linkID];
|
||||
|
||||
if( massLSC > 0.0f )
|
||||
{
|
||||
int2 nodeIndices = g_linksVertexIndices[linkID];
|
||||
int node0 = nodeIndices.x;
|
||||
int node1 = nodeIndices.y;
|
||||
|
||||
float3 position0 = g_vertexPositions[node0].xyz;
|
||||
float3 position1 = g_vertexPositions[node1].xyz;
|
||||
|
||||
float inverseMass0 = g_verticesInverseMass[node0];
|
||||
float inverseMass1 = g_verticesInverseMass[node1];
|
||||
|
||||
float3 del = position1 - position0;
|
||||
float len = dot(del, del);
|
||||
float k = ((restLengthSquared - len)/(massLSC*(restLengthSquared+len)))*kst;
|
||||
position0 = position0 - del*(k*inverseMass0);
|
||||
position1 = position1 + del*(k*inverseMass1);
|
||||
|
||||
g_vertexPositions[node0] = float4(position0, 0.f);
|
||||
g_vertexPositions[node1] = float4(position1, 0.f);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
@@ -0,0 +1,48 @@
|
||||
MSTRINGIFY(
|
||||
|
||||
cbuffer UpdateConstantsCB : register( b0 )
|
||||
{
|
||||
int numLinks;
|
||||
int padding0;
|
||||
int padding1;
|
||||
int padding2;
|
||||
};
|
||||
|
||||
// Node indices for each link
|
||||
StructuredBuffer<int2> g_linksVertexIndices : register( t0 );
|
||||
StructuredBuffer<float4> g_vertexPositions : register( t1 );
|
||||
StructuredBuffer<float> g_vertexInverseMasses : register( t2 );
|
||||
StructuredBuffer<float> g_linksMaterialLSC : register( t3 );
|
||||
|
||||
RWStructuredBuffer<float> g_linksMassLSC : register( u0 );
|
||||
RWStructuredBuffer<float> g_linksRestLengthSquared : register( u1 );
|
||||
RWStructuredBuffer<float> g_linksRestLengths : register( u2 );
|
||||
|
||||
[numthreads(128, 1, 1)]
|
||||
void
|
||||
UpdateConstantsKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex )
|
||||
{
|
||||
int linkID = DTid.x;
|
||||
if( linkID < numLinks )
|
||||
{
|
||||
int2 nodeIndices = g_linksVertexIndices[linkID];
|
||||
int node0 = nodeIndices.x;
|
||||
int node1 = nodeIndices.y;
|
||||
float linearStiffnessCoefficient = g_linksMaterialLSC[ linkID ];
|
||||
|
||||
float3 position0 = g_vertexPositions[node0].xyz;
|
||||
float3 position1 = g_vertexPositions[node1].xyz;
|
||||
float inverseMass0 = g_vertexInverseMasses[node0];
|
||||
float inverseMass1 = g_vertexInverseMasses[node1];
|
||||
|
||||
float3 difference = position0 - position1;
|
||||
float length2 = dot(difference, difference);
|
||||
float length = sqrt(length2);
|
||||
|
||||
g_linksRestLengths[linkID] = length;
|
||||
g_linksMassLSC[linkID] = (inverseMass0 + inverseMass1)/linearStiffnessCoefficient;
|
||||
g_linksRestLengthSquared[linkID] = length*length;
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
@@ -0,0 +1,49 @@
|
||||
MSTRINGIFY(
|
||||
|
||||
cbuffer UpdateVelocitiesFromPositionsWithVelocitiesCB : register( b0 )
|
||||
{
|
||||
int numNodes;
|
||||
float isolverdt;
|
||||
int padding1;
|
||||
int padding2;
|
||||
};
|
||||
|
||||
|
||||
StructuredBuffer<float4> g_vertexPositions : register( t0 );
|
||||
StructuredBuffer<float4> g_vertexPreviousPositions : register( t1 );
|
||||
StructuredBuffer<int> g_vertexClothIndices : register( t2 );
|
||||
StructuredBuffer<float> g_clothVelocityCorrectionCoefficients : register( t3 );
|
||||
StructuredBuffer<float> g_clothDampingFactor : register( t4 );
|
||||
|
||||
RWStructuredBuffer<float4> g_vertexVelocities : register( u0 );
|
||||
RWStructuredBuffer<float4> g_vertexForces : register( u1 );
|
||||
|
||||
|
||||
[numthreads(128, 1, 1)]
|
||||
void
|
||||
updateVelocitiesFromPositionsWithVelocitiesKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex )
|
||||
{
|
||||
int nodeID = DTid.x;
|
||||
if( nodeID < numNodes )
|
||||
{
|
||||
float3 position = g_vertexPositions[nodeID].xyz;
|
||||
float3 previousPosition = g_vertexPreviousPositions[nodeID].xyz;
|
||||
float3 velocity = g_vertexVelocities[nodeID].xyz;
|
||||
int clothIndex = g_vertexClothIndices[nodeID];
|
||||
float velocityCorrectionCoefficient = g_clothVelocityCorrectionCoefficients[clothIndex];
|
||||
float dampingFactor = g_clothDampingFactor[clothIndex];
|
||||
float velocityCoefficient = (1.f - dampingFactor);
|
||||
|
||||
float3 difference = position - previousPosition;
|
||||
|
||||
velocity += difference*velocityCorrectionCoefficient*isolverdt;
|
||||
|
||||
// Damp the velocity
|
||||
velocity *= velocityCoefficient;
|
||||
|
||||
g_vertexVelocities[nodeID] = float4(velocity, 0.f);
|
||||
g_vertexForces[nodeID] = float4(0.f, 0.f, 0.f, 0.f);
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
@@ -0,0 +1,98 @@
|
||||
MSTRINGIFY(
|
||||
|
||||
cbuffer UpdateSoftBodiesCB : register( b0 )
|
||||
{
|
||||
unsigned int numNodes;
|
||||
unsigned int startFace;
|
||||
unsigned int numFaces;
|
||||
float epsilon;
|
||||
};
|
||||
|
||||
|
||||
// Node indices for each link
|
||||
StructuredBuffer<int4> g_triangleVertexIndexSet : register( t0 );
|
||||
StructuredBuffer<float4> g_vertexPositions : register( t1 );
|
||||
StructuredBuffer<int> g_vertexTriangleCount : register( t2 );
|
||||
|
||||
RWStructuredBuffer<float4> g_vertexNormals : register( u0 );
|
||||
RWStructuredBuffer<float> g_vertexArea : register( u1 );
|
||||
RWStructuredBuffer<float4> g_triangleNormals : register( u2 );
|
||||
RWStructuredBuffer<float> g_triangleArea : register( u3 );
|
||||
|
||||
|
||||
[numthreads(128, 1, 1)]
|
||||
void
|
||||
ResetNormalsAndAreasKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex )
|
||||
{
|
||||
if( DTid.x < numNodes )
|
||||
{
|
||||
g_vertexNormals[DTid.x] = float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
g_vertexArea[DTid.x] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[numthreads(128, 1, 1)]
|
||||
void
|
||||
UpdateSoftBodiesKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex )
|
||||
{
|
||||
int faceID = DTid.x + startFace;
|
||||
if( DTid.x < numFaces )
|
||||
{
|
||||
int4 triangleIndexSet = g_triangleVertexIndexSet[ faceID ];
|
||||
int nodeIndex0 = triangleIndexSet.x;
|
||||
int nodeIndex1 = triangleIndexSet.y;
|
||||
int nodeIndex2 = triangleIndexSet.z;
|
||||
|
||||
float3 node0 = g_vertexPositions[nodeIndex0].xyz;
|
||||
float3 node1 = g_vertexPositions[nodeIndex1].xyz;
|
||||
float3 node2 = g_vertexPositions[nodeIndex2].xyz;
|
||||
float3 nodeNormal0 = g_vertexNormals[nodeIndex0].xyz;
|
||||
float3 nodeNormal1 = g_vertexNormals[nodeIndex1].xyz;
|
||||
float3 nodeNormal2 = g_vertexNormals[nodeIndex2].xyz;
|
||||
float vertexArea0 = g_vertexArea[nodeIndex0];
|
||||
float vertexArea1 = g_vertexArea[nodeIndex1];
|
||||
float vertexArea2 = g_vertexArea[nodeIndex2];
|
||||
|
||||
float3 vector0 = node1 - node0;
|
||||
float3 vector1 = node2 - node0;
|
||||
|
||||
float3 faceNormal = cross(vector0.xyz, vector1.xyz);
|
||||
float triangleArea = length(faceNormal);
|
||||
|
||||
nodeNormal0 = nodeNormal0 + faceNormal;
|
||||
nodeNormal1 = nodeNormal1 + faceNormal;
|
||||
nodeNormal2 = nodeNormal2 + faceNormal;
|
||||
vertexArea0 = vertexArea0 + triangleArea;
|
||||
vertexArea1 = vertexArea1 + triangleArea;
|
||||
vertexArea2 = vertexArea2 + triangleArea;
|
||||
|
||||
g_triangleNormals[faceID] = float4(normalize(faceNormal), 0.f);
|
||||
g_vertexNormals[nodeIndex0] = float4(nodeNormal0, 0.f);
|
||||
g_vertexNormals[nodeIndex1] = float4(nodeNormal1, 0.f);
|
||||
g_vertexNormals[nodeIndex2] = float4(nodeNormal2, 0.f);
|
||||
g_triangleArea[faceID] = triangleArea;
|
||||
g_vertexArea[nodeIndex0] = vertexArea0;
|
||||
g_vertexArea[nodeIndex1] = vertexArea1;
|
||||
g_vertexArea[nodeIndex2] = vertexArea2;
|
||||
}
|
||||
}
|
||||
|
||||
[numthreads(128, 1, 1)]
|
||||
void
|
||||
NormalizeNormalsAndAreasKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex )
|
||||
{
|
||||
if( DTid.x < numNodes )
|
||||
{
|
||||
float4 normal = g_vertexNormals[DTid.x];
|
||||
float area = g_vertexArea[DTid.x];
|
||||
int numTriangles = g_vertexTriangleCount[DTid.x];
|
||||
|
||||
float vectorLength = length(normal);
|
||||
|
||||
g_vertexNormals[DTid.x] = normalize(normal);
|
||||
g_vertexArea[DTid.x] = area/float(numTriangles);
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
@@ -0,0 +1,44 @@
|
||||
MSTRINGIFY(
|
||||
|
||||
cbuffer UpdateVelocitiesFromPositionsWithoutVelocitiesCB : register( b0 )
|
||||
{
|
||||
int numNodes;
|
||||
float isolverdt;
|
||||
int padding1;
|
||||
int padding2;
|
||||
};
|
||||
|
||||
|
||||
StructuredBuffer<float4> g_vertexPositions : register( t0 );
|
||||
StructuredBuffer<float4> g_vertexPreviousPositions : register( t1 );
|
||||
StructuredBuffer<int> g_vertexClothIndices : register( t2 );
|
||||
StructuredBuffer<float> g_clothDampingFactor : register( t3 );
|
||||
|
||||
RWStructuredBuffer<float4> g_vertexVelocities : register( u0 );
|
||||
RWStructuredBuffer<float4> g_vertexForces : register( u1 );
|
||||
|
||||
|
||||
[numthreads(128, 1, 1)]
|
||||
void
|
||||
updateVelocitiesFromPositionsWithoutVelocitiesKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex )
|
||||
{
|
||||
int nodeID = DTid.x;
|
||||
if( nodeID < numNodes )
|
||||
{
|
||||
float3 position = g_vertexPositions[nodeID].xyz;
|
||||
float3 previousPosition = g_vertexPreviousPositions[nodeID].xyz;
|
||||
float3 velocity = g_vertexVelocities[nodeID].xyz;
|
||||
int clothIndex = g_vertexClothIndices[nodeID];
|
||||
float dampingFactor = g_clothDampingFactor[clothIndex];
|
||||
float velocityCoefficient = (1.f - dampingFactor);
|
||||
|
||||
float3 difference = position - previousPosition;
|
||||
|
||||
velocity = difference*velocityCoefficient*isolverdt;
|
||||
|
||||
g_vertexVelocities[nodeID] = float4(velocity, 0.f);
|
||||
g_vertexForces[nodeID] = float4(0.f, 0.f, 0.f, 0.f);
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
@@ -0,0 +1,35 @@
|
||||
MSTRINGIFY(
|
||||
|
||||
cbuffer UpdatePositionsFromVelocitiesCB : register( b0 )
|
||||
{
|
||||
int numNodes;
|
||||
float solverSDT;
|
||||
int padding1;
|
||||
int padding2;
|
||||
};
|
||||
|
||||
|
||||
StructuredBuffer<float4> g_vertexVelocities : register( t0 );
|
||||
|
||||
RWStructuredBuffer<float4> g_vertexPreviousPositions : register( u0 );
|
||||
RWStructuredBuffer<float4> g_vertexCurrentPosition : register( u1 );
|
||||
|
||||
|
||||
[numthreads(128, 1, 1)]
|
||||
void
|
||||
UpdatePositionsFromVelocitiesKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex )
|
||||
{
|
||||
int vertexID = DTid.x;
|
||||
if( vertexID < numNodes )
|
||||
{
|
||||
float3 previousPosition = g_vertexPreviousPositions[vertexID].xyz;
|
||||
float3 velocity = g_vertexVelocities[vertexID].xyz;
|
||||
|
||||
float3 newPosition = previousPosition + velocity*solverSDT;
|
||||
|
||||
g_vertexCurrentPosition[vertexID] = float4(newPosition, 0.f);
|
||||
g_vertexPreviousPositions[vertexID] = float4(newPosition, 0.f);
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
@@ -0,0 +1,55 @@
|
||||
MSTRINGIFY(
|
||||
|
||||
cbuffer VSolveLinksCB : register( b0 )
|
||||
{
|
||||
int startLink;
|
||||
int numLinks;
|
||||
float kst;
|
||||
int padding;
|
||||
};
|
||||
|
||||
// Node indices for each link
|
||||
StructuredBuffer<int2> g_linksVertexIndices : register( t0 );
|
||||
|
||||
StructuredBuffer<float> g_linksLengthRatio : register( t1 );
|
||||
StructuredBuffer<float4> g_linksCurrentLength : register( t2 );
|
||||
StructuredBuffer<float> g_vertexInverseMass : register( t3 );
|
||||
|
||||
RWStructuredBuffer<float4> g_vertexVelocity : register( u0 );
|
||||
|
||||
[numthreads(128, 1, 1)]
|
||||
void
|
||||
VSolveLinksKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex )
|
||||
{
|
||||
int linkID = DTid.x + startLink;
|
||||
if( DTid.x < numLinks )
|
||||
{
|
||||
int2 nodeIndices = g_linksVertexIndices[linkID];
|
||||
int node0 = nodeIndices.x;
|
||||
int node1 = nodeIndices.y;
|
||||
|
||||
float linkLengthRatio = g_linksLengthRatio[linkID];
|
||||
float3 linkCurrentLength = g_linksCurrentLength[linkID].xyz;
|
||||
|
||||
float3 vertexVelocity0 = g_vertexVelocity[node0].xyz;
|
||||
float3 vertexVelocity1 = g_vertexVelocity[node1].xyz;
|
||||
|
||||
float vertexInverseMass0 = g_vertexInverseMass[node0];
|
||||
float vertexInverseMass1 = g_vertexInverseMass[node1];
|
||||
|
||||
float3 nodeDifference = vertexVelocity0 - vertexVelocity1;
|
||||
float dotResult = dot(linkCurrentLength, nodeDifference);
|
||||
float j = -dotResult*linkLengthRatio*kst;
|
||||
|
||||
float3 velocityChange0 = linkCurrentLength*(j*vertexInverseMass0);
|
||||
float3 velocityChange1 = linkCurrentLength*(j*vertexInverseMass1);
|
||||
|
||||
vertexVelocity0 += velocityChange0;
|
||||
vertexVelocity1 -= velocityChange1;
|
||||
|
||||
g_vertexVelocity[node0] = float4(vertexVelocity0, 0.f);
|
||||
g_vertexVelocity[node1] = float4(vertexVelocity1, 0.f);
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
@@ -0,0 +1,309 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#ifndef BT_SOFT_BODY_SOLVER_BUFFER_DX11_H
|
||||
#define BT_SOFT_BODY_SOLVER_BUFFER_DX11_H
|
||||
|
||||
// DX11 support
|
||||
#include <windows.h>
|
||||
#include <crtdbg.h>
|
||||
#include <d3d11.h>
|
||||
#include <d3dx11.h>
|
||||
#include <d3dcompiler.h>
|
||||
|
||||
#ifndef SAFE_RELEASE
|
||||
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
|
||||
#endif
|
||||
|
||||
/**
|
||||
* DX11 Buffer that tracks a host buffer on use to ensure size-correctness.
|
||||
*/
|
||||
template <typename ElementType> class btDX11Buffer
|
||||
{
|
||||
protected:
|
||||
ID3D11Device* m_d3dDevice;
|
||||
ID3D11DeviceContext* m_d3dDeviceContext;
|
||||
|
||||
ID3D11Buffer* m_Buffer;
|
||||
ID3D11ShaderResourceView* m_SRV;
|
||||
ID3D11UnorderedAccessView* m_UAV;
|
||||
btAlignedObjectArray< ElementType >* m_CPUBuffer;
|
||||
|
||||
// TODO: Separate this from the main class
|
||||
// as read back buffers can be shared between buffers
|
||||
ID3D11Buffer* m_readBackBuffer;
|
||||
|
||||
int m_gpuSize;
|
||||
bool m_onGPU;
|
||||
|
||||
bool m_readOnlyOnGPU;
|
||||
|
||||
bool createBuffer( ID3D11Buffer *preexistingBuffer = 0)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
// Create all CS buffers
|
||||
if( preexistingBuffer )
|
||||
{
|
||||
m_Buffer = preexistingBuffer;
|
||||
} else {
|
||||
D3D11_BUFFER_DESC buffer_desc;
|
||||
ZeroMemory(&buffer_desc, sizeof(buffer_desc));
|
||||
buffer_desc.Usage = D3D11_USAGE_DEFAULT;
|
||||
if( m_readOnlyOnGPU )
|
||||
buffer_desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
else
|
||||
buffer_desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS;
|
||||
buffer_desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
|
||||
|
||||
buffer_desc.ByteWidth = m_CPUBuffer->size() * sizeof(ElementType);
|
||||
buffer_desc.StructureByteStride = sizeof(ElementType);
|
||||
hr = m_d3dDevice->CreateBuffer(&buffer_desc, NULL, &m_Buffer);
|
||||
if( FAILED( hr ) )
|
||||
return (hr==S_OK);
|
||||
}
|
||||
|
||||
if( m_readOnlyOnGPU )
|
||||
{
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC srvbuffer_desc;
|
||||
ZeroMemory(&srvbuffer_desc, sizeof(srvbuffer_desc));
|
||||
srvbuffer_desc.Format = DXGI_FORMAT_UNKNOWN;
|
||||
srvbuffer_desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
|
||||
|
||||
srvbuffer_desc.Buffer.ElementWidth = m_CPUBuffer->size();
|
||||
hr = m_d3dDevice->CreateShaderResourceView(m_Buffer, &srvbuffer_desc, &m_SRV);
|
||||
if( FAILED( hr ) )
|
||||
return (hr==S_OK);
|
||||
} else {
|
||||
// Create SRV
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC srvbuffer_desc;
|
||||
ZeroMemory(&srvbuffer_desc, sizeof(srvbuffer_desc));
|
||||
srvbuffer_desc.Format = DXGI_FORMAT_UNKNOWN;
|
||||
srvbuffer_desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
|
||||
|
||||
srvbuffer_desc.Buffer.ElementWidth = m_CPUBuffer->size();
|
||||
hr = m_d3dDevice->CreateShaderResourceView(m_Buffer, &srvbuffer_desc, &m_SRV);
|
||||
if( FAILED( hr ) )
|
||||
return (hr==S_OK);
|
||||
|
||||
// Create UAV
|
||||
D3D11_UNORDERED_ACCESS_VIEW_DESC uavbuffer_desc;
|
||||
ZeroMemory(&uavbuffer_desc, sizeof(uavbuffer_desc));
|
||||
uavbuffer_desc.Format = DXGI_FORMAT_UNKNOWN;
|
||||
uavbuffer_desc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
|
||||
|
||||
uavbuffer_desc.Buffer.NumElements = m_CPUBuffer->size();
|
||||
hr = m_d3dDevice->CreateUnorderedAccessView(m_Buffer, &uavbuffer_desc, &m_UAV);
|
||||
if( FAILED( hr ) )
|
||||
return (hr==S_OK);
|
||||
|
||||
// Create read back buffer
|
||||
D3D11_BUFFER_DESC readback_buffer_desc;
|
||||
ZeroMemory(&readback_buffer_desc, sizeof(readback_buffer_desc));
|
||||
|
||||
readback_buffer_desc.ByteWidth = m_CPUBuffer->size() * sizeof(ElementType);
|
||||
readback_buffer_desc.Usage = D3D11_USAGE_STAGING;
|
||||
readback_buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
||||
readback_buffer_desc.StructureByteStride = sizeof(ElementType);
|
||||
hr = m_d3dDevice->CreateBuffer(&readback_buffer_desc, NULL, &m_readBackBuffer);
|
||||
if( FAILED( hr ) )
|
||||
return (hr==S_OK);
|
||||
}
|
||||
|
||||
m_gpuSize = m_CPUBuffer->size();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public:
|
||||
btDX11Buffer( ID3D11Device *d3dDevice, ID3D11DeviceContext *d3dDeviceContext, btAlignedObjectArray< ElementType > *CPUBuffer, bool readOnly )
|
||||
{
|
||||
m_d3dDevice = d3dDevice;
|
||||
m_d3dDeviceContext = d3dDeviceContext;
|
||||
m_Buffer = 0;
|
||||
m_SRV = 0;
|
||||
m_UAV = 0;
|
||||
m_readBackBuffer = 0;
|
||||
|
||||
m_CPUBuffer = CPUBuffer;
|
||||
|
||||
m_gpuSize = 0;
|
||||
m_onGPU = false;
|
||||
|
||||
m_readOnlyOnGPU = readOnly;
|
||||
}
|
||||
|
||||
virtual ~btDX11Buffer()
|
||||
{
|
||||
SAFE_RELEASE(m_Buffer);
|
||||
SAFE_RELEASE(m_SRV);
|
||||
SAFE_RELEASE(m_UAV);
|
||||
SAFE_RELEASE(m_readBackBuffer);
|
||||
}
|
||||
|
||||
ID3D11ShaderResourceView* &getSRV()
|
||||
{
|
||||
return m_SRV;
|
||||
}
|
||||
|
||||
ID3D11UnorderedAccessView* &getUAV()
|
||||
{
|
||||
return m_UAV;
|
||||
}
|
||||
|
||||
ID3D11Buffer* &getBuffer()
|
||||
{
|
||||
return m_Buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the data to the GPU if it is not there already.
|
||||
*/
|
||||
bool moveToGPU()
|
||||
{
|
||||
if( (m_CPUBuffer->size() != m_gpuSize) )
|
||||
m_onGPU = false;
|
||||
if( !m_onGPU && m_CPUBuffer->size() > 0 )
|
||||
{
|
||||
// If the buffer doesn't exist or the CPU-side buffer has changed size, create
|
||||
// We should really delete the old one, too, but let's leave that for later
|
||||
if( !m_Buffer || (m_CPUBuffer->size() != m_gpuSize) )
|
||||
{
|
||||
SAFE_RELEASE(m_Buffer);
|
||||
SAFE_RELEASE(m_SRV);
|
||||
SAFE_RELEASE(m_UAV);
|
||||
SAFE_RELEASE(m_readBackBuffer);
|
||||
if( !createBuffer() )
|
||||
{
|
||||
btAssert("Buffer creation failed.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
D3D11_BOX destRegion;
|
||||
destRegion.left = 0;
|
||||
destRegion.front = 0;
|
||||
destRegion.top = 0;
|
||||
destRegion.bottom = 1;
|
||||
destRegion.back = 1;
|
||||
destRegion.right = (m_CPUBuffer->size())*sizeof(ElementType);
|
||||
m_d3dDeviceContext->UpdateSubresource(m_Buffer, 0, &destRegion, &((*m_CPUBuffer)[0]), 0, 0);
|
||||
|
||||
m_onGPU = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the data back from the GPU if it is on there and isn't read only.
|
||||
*/
|
||||
bool moveFromGPU()
|
||||
{
|
||||
if( m_CPUBuffer->size() > 0 )
|
||||
{
|
||||
if( m_onGPU && !m_readOnlyOnGPU )
|
||||
{
|
||||
// Copy back
|
||||
D3D11_MAPPED_SUBRESOURCE MappedResource = {0};
|
||||
//m_pd3dImmediateContext->CopyResource(m_phAngVelReadBackBuffer, m_phAngVel);
|
||||
|
||||
D3D11_BOX destRegion;
|
||||
destRegion.left = 0;
|
||||
destRegion.front = 0;
|
||||
destRegion.top = 0;
|
||||
destRegion.bottom = 1;
|
||||
destRegion.back = 1;
|
||||
|
||||
destRegion.right = (m_CPUBuffer->size())*sizeof(ElementType);
|
||||
m_d3dDeviceContext->CopySubresourceRegion(
|
||||
m_readBackBuffer,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0 ,
|
||||
m_Buffer,
|
||||
0,
|
||||
&destRegion
|
||||
);
|
||||
|
||||
m_d3dDeviceContext->Map(m_readBackBuffer, 0, D3D11_MAP_READ, 0, &MappedResource);
|
||||
//memcpy(m_hAngVel, MappedResource.pData, (m_maxObjs * sizeof(float) ));
|
||||
memcpy(&((*m_CPUBuffer)[0]), MappedResource.pData, ((m_CPUBuffer->size()) * sizeof(ElementType) ));
|
||||
m_d3dDeviceContext->Unmap(m_readBackBuffer, 0);
|
||||
|
||||
m_onGPU = false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copy the data back from the GPU without changing its state to be CPU-side.
|
||||
* Useful if we just want to view it on the host for visualization.
|
||||
*/
|
||||
bool copyFromGPU()
|
||||
{
|
||||
if( m_CPUBuffer->size() > 0 )
|
||||
{
|
||||
if( m_onGPU && !m_readOnlyOnGPU )
|
||||
{
|
||||
// Copy back
|
||||
D3D11_MAPPED_SUBRESOURCE MappedResource = {0};
|
||||
|
||||
D3D11_BOX destRegion;
|
||||
destRegion.left = 0;
|
||||
destRegion.front = 0;
|
||||
destRegion.top = 0;
|
||||
destRegion.bottom = 1;
|
||||
destRegion.back = 1;
|
||||
|
||||
destRegion.right = (m_CPUBuffer->size())*sizeof(ElementType);
|
||||
m_d3dDeviceContext->CopySubresourceRegion(
|
||||
m_readBackBuffer,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0 ,
|
||||
m_Buffer,
|
||||
0,
|
||||
&destRegion
|
||||
);
|
||||
|
||||
m_d3dDeviceContext->Map(m_readBackBuffer, 0, D3D11_MAP_READ, 0, &MappedResource);
|
||||
//memcpy(m_hAngVel, MappedResource.pData, (m_maxObjs * sizeof(float) ));
|
||||
memcpy(&((*m_CPUBuffer)[0]), MappedResource.pData, ((m_CPUBuffer->size()) * sizeof(ElementType) ));
|
||||
m_d3dDeviceContext->Unmap(m_readBackBuffer, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call if data has changed on the CPU.
|
||||
* Can then trigger a move to the GPU as necessary.
|
||||
*/
|
||||
virtual void changedOnCPU()
|
||||
{
|
||||
m_onGPU = false;
|
||||
}
|
||||
}; // class btDX11Buffer
|
||||
|
||||
|
||||
|
||||
#endif // #ifndef BT_SOFT_BODY_SOLVER_BUFFER_DX11_H
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/CPU/btSoftBodySolverData.h"
|
||||
#include "btSoftBodySolverBuffer_DX11.h"
|
||||
|
||||
|
||||
#ifndef BT_SOFT_BODY_SOLVER_LINK_DATA_DX11_H
|
||||
#define BT_SOFT_BODY_SOLVER_LINK_DATA_DX11_H
|
||||
|
||||
struct ID3D11Device;
|
||||
struct ID3D11DeviceContext;
|
||||
|
||||
|
||||
class btSoftBodyLinkDataDX11 : public btSoftBodyLinkData
|
||||
{
|
||||
public:
|
||||
bool m_onGPU;
|
||||
ID3D11Device *m_d3dDevice;
|
||||
ID3D11DeviceContext *m_d3dDeviceContext;
|
||||
|
||||
|
||||
btDX11Buffer<LinkNodePair> m_dx11Links;
|
||||
btDX11Buffer<float> m_dx11LinkStrength;
|
||||
btDX11Buffer<float> m_dx11LinksMassLSC;
|
||||
btDX11Buffer<float> m_dx11LinksRestLengthSquared;
|
||||
btDX11Buffer<Vectormath::Aos::Vector3> m_dx11LinksCLength;
|
||||
btDX11Buffer<float> m_dx11LinksLengthRatio;
|
||||
btDX11Buffer<float> m_dx11LinksRestLength;
|
||||
btDX11Buffer<float> m_dx11LinksMaterialLinearStiffnessCoefficient;
|
||||
|
||||
struct BatchPair
|
||||
{
|
||||
int start;
|
||||
int length;
|
||||
|
||||
BatchPair() :
|
||||
start(0),
|
||||
length(0)
|
||||
{
|
||||
}
|
||||
|
||||
BatchPair( int s, int l ) :
|
||||
start( s ),
|
||||
length( l )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Link addressing information for each cloth.
|
||||
* Allows link locations to be computed independently of data batching.
|
||||
*/
|
||||
btAlignedObjectArray< int > m_linkAddresses;
|
||||
|
||||
/**
|
||||
* Start and length values for computation batches over link data.
|
||||
*/
|
||||
btAlignedObjectArray< BatchPair > m_batchStartLengths;
|
||||
|
||||
|
||||
//ID3D11Buffer* readBackBuffer;
|
||||
|
||||
btSoftBodyLinkDataDX11( ID3D11Device *d3dDevice, ID3D11DeviceContext *d3dDeviceContext );
|
||||
|
||||
virtual ~btSoftBodyLinkDataDX11();
|
||||
|
||||
/** Allocate enough space in all link-related arrays to fit numLinks links */
|
||||
virtual void createLinks( int numLinks );
|
||||
|
||||
/** Insert the link described into the correct data structures assuming space has already been allocated by a call to createLinks */
|
||||
virtual void setLinkAt( const LinkDescription &link, int linkIndex );
|
||||
|
||||
virtual bool onAccelerator();
|
||||
|
||||
virtual bool moveToAccelerator();
|
||||
|
||||
virtual bool moveFromAccelerator();
|
||||
|
||||
/**
|
||||
* Generate (and later update) the batching for the entire link set.
|
||||
* This redoes a lot of work because it batches the entire set when each cloth is inserted.
|
||||
* In theory we could delay it until just before we need the cloth.
|
||||
* It's a one-off overhead, though, so that is a later optimisation.
|
||||
*/
|
||||
void generateBatches();
|
||||
};
|
||||
|
||||
|
||||
#endif // #ifndef BT_SOFT_BODY_SOLVER_LINK_DATA_DX11_H
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/CPU/btSoftBodySolverData.h"
|
||||
#include "btSoftBodySolverBuffer_DX11.h"
|
||||
|
||||
|
||||
#ifndef BT_SOFT_BODY_SOLVER_TRIANGLE_DATA_DX11_H
|
||||
#define BT_SOFT_BODY_SOLVER_TRIANGLE_DATA_DX11_H
|
||||
|
||||
struct ID3D11Device;
|
||||
struct ID3D11DeviceContext;
|
||||
|
||||
class btSoftBodyTriangleDataDX11 : public btSoftBodyTriangleData
|
||||
{
|
||||
public:
|
||||
bool m_onGPU;
|
||||
ID3D11Device *m_d3dDevice;
|
||||
ID3D11DeviceContext *m_d3dDeviceContext;
|
||||
|
||||
btDX11Buffer<btSoftBodyTriangleData::TriangleNodeSet> m_dx11VertexIndices;
|
||||
btDX11Buffer<float> m_dx11Area;
|
||||
btDX11Buffer<Vectormath::Aos::Vector3> m_dx11Normal;
|
||||
|
||||
struct BatchPair
|
||||
{
|
||||
int start;
|
||||
int length;
|
||||
|
||||
BatchPair() :
|
||||
start(0),
|
||||
length(0)
|
||||
{
|
||||
}
|
||||
|
||||
BatchPair( int s, int l ) :
|
||||
start( s ),
|
||||
length( l )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Link addressing information for each cloth.
|
||||
* Allows link locations to be computed independently of data batching.
|
||||
*/
|
||||
btAlignedObjectArray< int > m_triangleAddresses;
|
||||
|
||||
/**
|
||||
* Start and length values for computation batches over link data.
|
||||
*/
|
||||
btAlignedObjectArray< BatchPair > m_batchStartLengths;
|
||||
|
||||
//ID3D11Buffer* readBackBuffer;
|
||||
|
||||
public:
|
||||
btSoftBodyTriangleDataDX11( ID3D11Device *d3dDevice, ID3D11DeviceContext *d3dDeviceContext );
|
||||
|
||||
virtual ~btSoftBodyTriangleDataDX11();
|
||||
|
||||
|
||||
/** Allocate enough space in all link-related arrays to fit numLinks links */
|
||||
virtual void createTriangles( int numTriangles );
|
||||
|
||||
/** Insert the link described into the correct data structures assuming space has already been allocated by a call to createLinks */
|
||||
virtual void setTriangleAt( const btSoftBodyTriangleData::TriangleDescription &triangle, int triangleIndex );
|
||||
|
||||
virtual bool onAccelerator();
|
||||
virtual bool moveToAccelerator();
|
||||
|
||||
virtual bool moveFromAccelerator();
|
||||
/**
|
||||
* Generate (and later update) the batching for the entire triangle set.
|
||||
* This redoes a lot of work because it batches the entire set when each cloth is inserted.
|
||||
* In theory we could delay it until just before we need the cloth.
|
||||
* It's a one-off overhead, though, so that is a later optimisation.
|
||||
*/
|
||||
void generateBatches();
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // #ifndef BT_SOFT_BODY_SOLVER_TRIANGLE_DATA_DX11_H
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef BT_SOFT_BODY_SOLVER_VERTEX_BUFFER_DX11_H
|
||||
#define BT_SOFT_BODY_SOLVER_VERTEX_BUFFER_DX11_H
|
||||
|
||||
|
||||
#include "BulletSoftBody/btSoftBodySolverVertexBuffer.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <crtdbg.h>
|
||||
#include <d3d11.h>
|
||||
#include <d3dx11.h>
|
||||
#include <d3dcompiler.h>
|
||||
|
||||
class btDX11VertexBufferDescriptor : public btVertexBufferDescriptor
|
||||
{
|
||||
protected:
|
||||
/** Context of the DX11 device on which the vertex buffer is stored. */
|
||||
ID3D11DeviceContext* m_context;
|
||||
/** DX11 vertex buffer */
|
||||
ID3D11Buffer* m_vertexBuffer;
|
||||
/** UAV for DX11 buffer */
|
||||
ID3D11UnorderedAccessView* m_vertexBufferUAV;
|
||||
|
||||
|
||||
public:
|
||||
/**
|
||||
* buffer is a pointer to the DX11 buffer to place the vertex data in.
|
||||
* UAV is a pointer to the UAV representation of the buffer laid out in floats.
|
||||
* vertexOffset is the offset in floats to the first vertex.
|
||||
* vertexStride is the stride in floats between vertices.
|
||||
*/
|
||||
btDX11VertexBufferDescriptor( ID3D11DeviceContext* context, ID3D11Buffer* buffer, ID3D11UnorderedAccessView *UAV, int vertexOffset, int vertexStride )
|
||||
{
|
||||
m_context = context;
|
||||
m_vertexBuffer = buffer;
|
||||
m_vertexBufferUAV = UAV;
|
||||
m_vertexOffset = vertexOffset;
|
||||
m_vertexStride = vertexStride;
|
||||
m_hasVertexPositions = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* buffer is a pointer to the DX11 buffer to place the vertex data in.
|
||||
* UAV is a pointer to the UAV representation of the buffer laid out in floats.
|
||||
* vertexOffset is the offset in floats to the first vertex.
|
||||
* vertexStride is the stride in floats between vertices.
|
||||
* normalOffset is the offset in floats to the first normal.
|
||||
* normalStride is the stride in floats between normals.
|
||||
*/
|
||||
btDX11VertexBufferDescriptor( ID3D11DeviceContext* context, ID3D11Buffer* buffer, ID3D11UnorderedAccessView *UAV, int vertexOffset, int vertexStride, int normalOffset, int normalStride )
|
||||
{
|
||||
m_context = context;
|
||||
m_vertexBuffer = buffer;
|
||||
m_vertexBufferUAV = UAV;
|
||||
m_vertexOffset = vertexOffset;
|
||||
m_vertexStride = vertexStride;
|
||||
m_hasVertexPositions = true;
|
||||
|
||||
m_normalOffset = normalOffset;
|
||||
m_normalStride = normalStride;
|
||||
m_hasNormals = true;
|
||||
}
|
||||
|
||||
virtual ~btDX11VertexBufferDescriptor()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the type of the vertex buffer descriptor.
|
||||
*/
|
||||
virtual BufferTypes getBufferType() const
|
||||
{
|
||||
return DX11_BUFFER;
|
||||
}
|
||||
|
||||
virtual ID3D11DeviceContext* getContext() const
|
||||
{
|
||||
return m_context;
|
||||
}
|
||||
|
||||
virtual ID3D11Buffer* getbtDX11Buffer() const
|
||||
{
|
||||
return m_vertexBuffer;
|
||||
}
|
||||
|
||||
virtual ID3D11UnorderedAccessView* getDX11UAV() const
|
||||
{
|
||||
return m_vertexBufferUAV;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // #ifndef BT_SOFT_BODY_SOLVER_VERTEX_BUFFER_DX11_H
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/CPU/btSoftBodySolverData.h"
|
||||
#include "btSoftBodySolverBuffer_DX11.h"
|
||||
|
||||
|
||||
#ifndef BT_SOFT_BHODY_SOLVER_VERTEX_DATA_DX11_H
|
||||
#define BT_SOFT_BHODY_SOLVER_VERTEX_DATA_DX11_H
|
||||
|
||||
class btSoftBodyLinkData;
|
||||
class btSoftBodyLinkData::LinkDescription;
|
||||
|
||||
struct ID3D11Device;
|
||||
struct ID3D11DeviceContext;
|
||||
|
||||
class btSoftBodyVertexDataDX11 : public btSoftBodyVertexData
|
||||
{
|
||||
protected:
|
||||
bool m_onGPU;
|
||||
ID3D11Device *m_d3dDevice;
|
||||
ID3D11DeviceContext *m_d3dDeviceContext;
|
||||
|
||||
public:
|
||||
btDX11Buffer<int> m_dx11ClothIdentifier;
|
||||
btDX11Buffer<Vectormath::Aos::Point3> m_dx11VertexPosition;
|
||||
btDX11Buffer<Vectormath::Aos::Point3> m_dx11VertexPreviousPosition;
|
||||
btDX11Buffer<Vectormath::Aos::Vector3> m_dx11VertexVelocity;
|
||||
btDX11Buffer<Vectormath::Aos::Vector3> m_dx11VertexForceAccumulator;
|
||||
btDX11Buffer<Vectormath::Aos::Vector3> m_dx11VertexNormal;
|
||||
btDX11Buffer<float> m_dx11VertexInverseMass;
|
||||
btDX11Buffer<float> m_dx11VertexArea;
|
||||
btDX11Buffer<int> m_dx11VertexTriangleCount;
|
||||
|
||||
|
||||
//ID3D11Buffer* readBackBuffer;
|
||||
|
||||
public:
|
||||
btSoftBodyVertexDataDX11( ID3D11Device *d3dDevice, ID3D11DeviceContext *d3dDeviceContext );
|
||||
virtual ~btSoftBodyVertexDataDX11();
|
||||
|
||||
virtual bool onAccelerator();
|
||||
virtual bool moveToAccelerator();
|
||||
|
||||
virtual bool moveFromAccelerator();
|
||||
};
|
||||
|
||||
|
||||
#endif // #ifndef BT_SOFT_BHODY_SOLVER_VERTEX_DATA_DX11_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,480 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#include "vectormath_aos.h"
|
||||
|
||||
#include "BulletSoftBody/btSoftBodySolvers.h"
|
||||
#include "btSoftBodySolverVertexBuffer_DX11.h"
|
||||
#include "btSoftBodySolverLinkData_DX11.h"
|
||||
#include "btSoftBodySolverVertexData_DX11.h"
|
||||
#include "btSoftBodySolverTriangleData_DX11.h"
|
||||
|
||||
|
||||
#ifndef BT_ACCELERATED_SOFT_BODY_DX11_SOLVER_H
|
||||
#define BT_ACCELERATED_SOFT_BODY_DX11_SOLVER_H
|
||||
|
||||
class btDX11SoftBodySolver : public btSoftBodySolver
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* SoftBody class to maintain information about a soft body instance
|
||||
* within a solver.
|
||||
* This data addresses the main solver arrays.
|
||||
*/
|
||||
class btAcceleratedSoftBodyInterface
|
||||
{
|
||||
protected:
|
||||
/** Current number of vertices that are part of this cloth */
|
||||
int m_numVertices;
|
||||
/** Maximum number of vertices allocated to be part of this cloth */
|
||||
int m_maxVertices;
|
||||
/** Current number of triangles that are part of this cloth */
|
||||
int m_numTriangles;
|
||||
/** Maximum number of triangles allocated to be part of this cloth */
|
||||
int m_maxTriangles;
|
||||
/** Index of first vertex in the world allocated to this cloth */
|
||||
int m_firstVertex;
|
||||
/** Index of first triangle in the world allocated to this cloth */
|
||||
int m_firstTriangle;
|
||||
/** Index of first link in the world allocated to this cloth */
|
||||
int m_firstLink;
|
||||
/** Maximum number of links allocated to this cloth */
|
||||
int m_maxLinks;
|
||||
/** Current number of links allocated to this cloth */
|
||||
int m_numLinks;
|
||||
|
||||
/** The actual soft body this data represents */
|
||||
btSoftBody *m_softBody;
|
||||
|
||||
|
||||
public:
|
||||
btAcceleratedSoftBodyInterface( btSoftBody *softBody ) :
|
||||
m_softBody( softBody )
|
||||
{
|
||||
m_numVertices = 0;
|
||||
m_maxVertices = 0;
|
||||
m_numTriangles = 0;
|
||||
m_maxTriangles = 0;
|
||||
m_firstVertex = 0;
|
||||
m_firstTriangle = 0;
|
||||
m_firstLink = 0;
|
||||
m_maxLinks = 0;
|
||||
m_numLinks = 0;
|
||||
}
|
||||
int getNumVertices()
|
||||
{
|
||||
return m_numVertices;
|
||||
}
|
||||
|
||||
int getNumTriangles()
|
||||
{
|
||||
return m_numTriangles;
|
||||
}
|
||||
|
||||
int getMaxVertices()
|
||||
{
|
||||
return m_maxVertices;
|
||||
}
|
||||
|
||||
int getMaxTriangles()
|
||||
{
|
||||
return m_maxTriangles;
|
||||
}
|
||||
|
||||
int getFirstVertex()
|
||||
{
|
||||
return m_firstVertex;
|
||||
}
|
||||
|
||||
int getFirstTriangle()
|
||||
{
|
||||
return m_firstTriangle;
|
||||
}
|
||||
|
||||
// TODO: All of these set functions will have to do checks and
|
||||
// update the world because restructuring of the arrays will be necessary
|
||||
// Reasonable use of "friend"?
|
||||
void setNumVertices( int numVertices )
|
||||
{
|
||||
m_numVertices = numVertices;
|
||||
}
|
||||
|
||||
void setNumTriangles( int numTriangles )
|
||||
{
|
||||
m_numTriangles = numTriangles;
|
||||
}
|
||||
|
||||
void setMaxVertices( int maxVertices )
|
||||
{
|
||||
m_maxVertices = maxVertices;
|
||||
}
|
||||
|
||||
void setMaxTriangles( int maxTriangles )
|
||||
{
|
||||
m_maxTriangles = maxTriangles;
|
||||
}
|
||||
|
||||
void setFirstVertex( int firstVertex )
|
||||
{
|
||||
m_firstVertex = firstVertex;
|
||||
}
|
||||
|
||||
void setFirstTriangle( int firstTriangle )
|
||||
{
|
||||
m_firstTriangle = firstTriangle;
|
||||
}
|
||||
|
||||
void setMaxLinks( int maxLinks )
|
||||
{
|
||||
m_maxLinks = maxLinks;
|
||||
}
|
||||
|
||||
void setNumLinks( int numLinks )
|
||||
{
|
||||
m_numLinks = numLinks;
|
||||
}
|
||||
|
||||
void setFirstLink( int firstLink )
|
||||
{
|
||||
m_firstLink = firstLink;
|
||||
}
|
||||
|
||||
int getMaxLinks()
|
||||
{
|
||||
return m_maxLinks;
|
||||
}
|
||||
|
||||
int getNumLinks()
|
||||
{
|
||||
return m_numLinks;
|
||||
}
|
||||
|
||||
int getFirstLink()
|
||||
{
|
||||
return m_firstLink;
|
||||
}
|
||||
|
||||
btSoftBody* getSoftBody()
|
||||
{
|
||||
return m_softBody;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void setAcceleration( Vectormath::Aos::Vector3 acceleration )
|
||||
{
|
||||
m_currentSolver->setPerClothAcceleration( m_clothIdentifier, acceleration );
|
||||
}
|
||||
|
||||
void setWindVelocity( Vectormath::Aos::Vector3 windVelocity )
|
||||
{
|
||||
m_currentSolver->setPerClothWindVelocity( m_clothIdentifier, windVelocity );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the density of the air in which the cloth is situated.
|
||||
*/
|
||||
void setAirDensity( btScalar density )
|
||||
{
|
||||
m_currentSolver->setPerClothMediumDensity( m_clothIdentifier, static_cast<float>(density) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a collision object to this soft body.
|
||||
*/
|
||||
void addCollisionObject( btCollisionObject *collisionObject )
|
||||
{
|
||||
m_currentSolver->addCollisionObjectForSoftBody( m_clothIdentifier, collisionObject );
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
class KernelDesc
|
||||
{
|
||||
protected:
|
||||
|
||||
|
||||
public:
|
||||
ID3D11ComputeShader* kernel;
|
||||
ID3D11Buffer* constBuffer;
|
||||
|
||||
KernelDesc()
|
||||
{
|
||||
kernel = 0;
|
||||
constBuffer = 0;
|
||||
}
|
||||
|
||||
virtual ~KernelDesc()
|
||||
{
|
||||
// TODO: this should probably destroy its kernel but we need to be careful
|
||||
// in case KernelDescs are copied
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct PrepareLinksCB
|
||||
{
|
||||
int numLinks;
|
||||
int padding0;
|
||||
int padding1;
|
||||
int padding2;
|
||||
};
|
||||
|
||||
struct SolvePositionsFromLinksKernelCB
|
||||
{
|
||||
int startLink;
|
||||
int numLinks;
|
||||
float kst;
|
||||
float ti;
|
||||
};
|
||||
|
||||
struct IntegrateCB
|
||||
{
|
||||
int numNodes;
|
||||
float solverdt;
|
||||
int padding1;
|
||||
int padding2;
|
||||
};
|
||||
|
||||
struct UpdatePositionsFromVelocitiesCB
|
||||
{
|
||||
int numNodes;
|
||||
float solverSDT;
|
||||
int padding1;
|
||||
int padding2;
|
||||
};
|
||||
|
||||
struct UpdateVelocitiesFromPositionsWithoutVelocitiesCB
|
||||
{
|
||||
int numNodes;
|
||||
float isolverdt;
|
||||
int padding1;
|
||||
int padding2;
|
||||
};
|
||||
|
||||
struct UpdateVelocitiesFromPositionsWithVelocitiesCB
|
||||
{
|
||||
int numNodes;
|
||||
float isolverdt;
|
||||
int padding1;
|
||||
int padding2;
|
||||
};
|
||||
|
||||
struct UpdateSoftBodiesCB
|
||||
{
|
||||
int numNodes;
|
||||
int startFace;
|
||||
int numFaces;
|
||||
float epsilon;
|
||||
};
|
||||
|
||||
|
||||
struct OutputToVertexArrayCB
|
||||
{
|
||||
int startNode;
|
||||
int numNodes;
|
||||
int positionOffset;
|
||||
int positionStride;
|
||||
|
||||
int normalOffset;
|
||||
int normalStride;
|
||||
int padding1;
|
||||
int padding2;
|
||||
};
|
||||
|
||||
|
||||
struct ApplyForcesCB
|
||||
{
|
||||
unsigned int numNodes;
|
||||
float solverdt;
|
||||
float epsilon;
|
||||
int padding3;
|
||||
};
|
||||
|
||||
struct AddVelocityCB
|
||||
{
|
||||
int startNode;
|
||||
int lastNode;
|
||||
float velocityX;
|
||||
float velocityY;
|
||||
float velocityZ;
|
||||
int padding1;
|
||||
int padding2;
|
||||
int padding3;
|
||||
};
|
||||
|
||||
struct VSolveLinksCB
|
||||
{
|
||||
int startLink;
|
||||
int numLinks;
|
||||
float kst;
|
||||
int padding;
|
||||
};
|
||||
|
||||
|
||||
private:
|
||||
ID3D11Device * m_dx11Device;
|
||||
ID3D11DeviceContext* m_dx11Context;
|
||||
|
||||
|
||||
/** Link data for all cloths. Note that this will be sorted batch-wise for efficient computation and m_linkAddresses will maintain the addressing. */
|
||||
btSoftBodyLinkDataDX11 m_linkData;
|
||||
btSoftBodyVertexDataDX11 m_vertexData;
|
||||
btSoftBodyTriangleDataDX11 m_triangleData;
|
||||
|
||||
/** Variable to define whether we need to update solver constants on the next iteration */
|
||||
bool m_updateSolverConstants;
|
||||
|
||||
bool m_shadersInitialized;
|
||||
|
||||
/**
|
||||
* Cloths owned by this solver.
|
||||
* Only our cloths are in this array.
|
||||
*/
|
||||
btAlignedObjectArray< btAcceleratedSoftBodyInterface * > m_softBodySet;
|
||||
|
||||
/** Acceleration value to be applied to all non-static vertices in the solver.
|
||||
* Index n is cloth n, array sized by number of cloths in the world not the solver.
|
||||
*/
|
||||
btAlignedObjectArray< Vectormath::Aos::Vector3 > m_perClothAcceleration;
|
||||
btDX11Buffer<Vectormath::Aos::Vector3> m_dx11PerClothAcceleration;
|
||||
|
||||
/** Wind velocity to be applied normal to all non-static vertices in the solver.
|
||||
* Index n is cloth n, array sized by number of cloths in the world not the solver.
|
||||
*/
|
||||
btAlignedObjectArray< Vectormath::Aos::Vector3 > m_perClothWindVelocity;
|
||||
btDX11Buffer<Vectormath::Aos::Vector3> m_dx11PerClothWindVelocity;
|
||||
|
||||
/** Velocity damping factor */
|
||||
btAlignedObjectArray< float > m_perClothDampingFactor;
|
||||
btDX11Buffer<float> m_dx11PerClothDampingFactor;
|
||||
|
||||
/** Velocity correction coefficient */
|
||||
btAlignedObjectArray< float > m_perClothVelocityCorrectionCoefficient;
|
||||
btDX11Buffer<float> m_dx11PerClothVelocityCorrectionCoefficient;
|
||||
|
||||
/** Lift parameter for wind effect on cloth. */
|
||||
btAlignedObjectArray< float > m_perClothLiftFactor;
|
||||
btDX11Buffer<float> m_dx11PerClothLiftFactor;
|
||||
|
||||
/** Drag parameter for wind effect on cloth. */
|
||||
btAlignedObjectArray< float > m_perClothDragFactor;
|
||||
btDX11Buffer<float> m_dx11PerClothDragFactor;
|
||||
|
||||
/** Density of the medium in which each cloth sits */
|
||||
btAlignedObjectArray< float > m_perClothMediumDensity;
|
||||
btDX11Buffer<float> m_dx11PerClothMediumDensity;
|
||||
|
||||
KernelDesc prepareLinksKernel;
|
||||
KernelDesc solvePositionsFromLinksKernel;
|
||||
KernelDesc vSolveLinksKernel;
|
||||
KernelDesc integrateKernel;
|
||||
KernelDesc addVelocityKernel;
|
||||
KernelDesc updatePositionsFromVelocitiesKernel;
|
||||
KernelDesc updateVelocitiesFromPositionsWithoutVelocitiesKernel;
|
||||
KernelDesc updateVelocitiesFromPositionsWithVelocitiesKernel;
|
||||
KernelDesc resetNormalsAndAreasKernel;
|
||||
KernelDesc normalizeNormalsAndAreasKernel;
|
||||
KernelDesc updateSoftBodiesKernel;
|
||||
KernelDesc outputToVertexArrayWithNormalsKernel;
|
||||
KernelDesc outputToVertexArrayWithoutNormalsKernel;
|
||||
|
||||
KernelDesc outputToVertexArrayKernel;
|
||||
KernelDesc applyForcesKernel;
|
||||
KernelDesc collideSphereKernel;
|
||||
KernelDesc collideCylinderKernel;
|
||||
|
||||
|
||||
/**
|
||||
* Integrate motion on the solver.
|
||||
*/
|
||||
virtual void integrate( float solverdt );
|
||||
float computeTriangleArea(
|
||||
const Vectormath::Aos::Point3 &vertex0,
|
||||
const Vectormath::Aos::Point3 &vertex1,
|
||||
const Vectormath::Aos::Point3 &vertex2 );
|
||||
|
||||
|
||||
/**
|
||||
* Compile a compute shader kernel from a string and return the appropriate KernelDesc object.
|
||||
*/
|
||||
KernelDesc compileComputeShaderFromString( const char* shaderString, const char* shaderName, int constBufferSize );
|
||||
|
||||
bool buildShaders();
|
||||
|
||||
void resetNormalsAndAreas( int numVertices );
|
||||
|
||||
void normalizeNormalsAndAreas( int numVertices );
|
||||
|
||||
void executeUpdateSoftBodies( int firstTriangle, int numTriangles );
|
||||
|
||||
Vectormath::Aos::Vector3 ProjectOnAxis( const Vectormath::Aos::Vector3 &v, const Vectormath::Aos::Vector3 &a );
|
||||
|
||||
void ApplyClampedForce( float solverdt, const Vectormath::Aos::Vector3 &force, const Vectormath::Aos::Vector3 &vertexVelocity, float inverseMass, Vectormath::Aos::Vector3 &vertexForce );
|
||||
|
||||
virtual void applyForces( float solverdt );
|
||||
|
||||
void updateConstants( float timeStep );
|
||||
|
||||
btAcceleratedSoftBodyInterface *findSoftBodyInterface( const btSoftBody* const softBody );
|
||||
|
||||
//////////////////////////////////////
|
||||
// Kernel dispatches
|
||||
void prepareLinks();
|
||||
|
||||
void updatePositionsFromVelocities( float solverdt );
|
||||
void solveLinksForPosition( int startLink, int numLinks, float kst, float ti );
|
||||
void solveLinksForVelocity( int startLink, int numLinks, float kst );
|
||||
|
||||
void updateVelocitiesFromPositionsWithVelocities( float isolverdt );
|
||||
void updateVelocitiesFromPositionsWithoutVelocities( float isolverdt );
|
||||
|
||||
// End kernel dispatches
|
||||
/////////////////////////////////////
|
||||
|
||||
public:
|
||||
btDX11SoftBodySolver(ID3D11Device * dx11Device, ID3D11DeviceContext* dx11Context);
|
||||
|
||||
virtual ~btDX11SoftBodySolver();
|
||||
|
||||
|
||||
virtual btSoftBodyLinkData &getLinkData();
|
||||
|
||||
virtual btSoftBodyVertexData &getVertexData();
|
||||
|
||||
virtual btSoftBodyTriangleData &getTriangleData();
|
||||
|
||||
|
||||
|
||||
|
||||
virtual bool checkInitialized();
|
||||
|
||||
virtual void updateSoftBodies( );
|
||||
|
||||
virtual void optimize( btAlignedObjectArray< btSoftBody * > &softBodies );
|
||||
|
||||
virtual void solveConstraints( float solverdt );
|
||||
|
||||
virtual void predictMotion( float solverdt );
|
||||
|
||||
virtual void copySoftBodyToVertexBuffer( const btSoftBody *const softBody, btVertexBufferDescriptor *vertexBuffer );
|
||||
|
||||
};
|
||||
|
||||
#endif // #ifndef BT_ACCELERATED_SOFT_BODY_DX11_SOLVER_H
|
||||
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/src
|
||||
)
|
||||
|
||||
|
||||
SET(OPENCL_DIR $ENV{ATISTREAMSDKROOT})
|
||||
SET(OPENCL_INCLUDE_PATH "${ATISTREAMSDKROOT}/include" CACHE DOCSTRING "OpenCL SDK include path")
|
||||
|
||||
INCLUDE_DIRECTORIES(${OPENCL_INCLUDE_PATH} "../cpu/")
|
||||
|
||||
SET(BulletSoftBodyOpenCLSolvers_SRCS
|
||||
btSoftBodySolver_OpenCL.cpp
|
||||
)
|
||||
|
||||
SET(BulletSoftBodyOpenCLSolvers_HDRS
|
||||
btSoftBodySolver_OpenCL.h
|
||||
../cpu/btSoftBodySolverData.h
|
||||
btSoftBodySolverVertexData_OpenCL.h
|
||||
btSoftBodySolverTriangleData_OpenCL.h
|
||||
btSoftBodySolverLinkData_OpenCL.h
|
||||
btSoftBodySolverBuffer_OpenCL.h
|
||||
)
|
||||
|
||||
# OpenCL and HLSL Shaders.
|
||||
# Build rules generated to stringify these into headers
|
||||
# which are needed by some of the sources
|
||||
SET(BulletSoftBodyOpenCLSolvers_Shaders
|
||||
# OutputToVertexArray
|
||||
UpdateNormals
|
||||
Integrate
|
||||
UpdatePositions
|
||||
UpdateNodes
|
||||
SolvePositions
|
||||
UpdatePositionsFromVelocities
|
||||
ApplyForces
|
||||
PrepareLinks
|
||||
VSolveLinks
|
||||
)
|
||||
|
||||
foreach(f ${BulletSoftBodyOpenCLSolvers_Shaders})
|
||||
LIST(APPEND BulletSoftBodyOpenCLSolvers_OpenCLC "OpenCLC/${f}.cl")
|
||||
endforeach(f)
|
||||
|
||||
|
||||
|
||||
ADD_LIBRARY(BulletSoftBodySolvers_OpenCL ${BulletSoftBodyOpenCLSolvers_SRCS} ${BulletSoftBodyOpenCLSolvers_HDRS} ${BulletSoftBodyOpenCLSolvers_OpenCLC})
|
||||
SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL PROPERTIES VERSION ${BULLET_VERSION})
|
||||
SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL PROPERTIES SOVERSION ${BULLET_VERSION})
|
||||
IF (BUILD_SHARED_LIBS)
|
||||
TARGET_LINK_LIBRARIES(BulletSoftBody BulletDynamics)
|
||||
ENDIF (BUILD_SHARED_LIBS)
|
||||
|
||||
|
||||
IF (INSTALL_LIBS)
|
||||
IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES)
|
||||
IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5)
|
||||
IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
INSTALL(TARGETS BulletSoftBodySolvers_OpenCL DESTINATION .)
|
||||
ELSE (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
INSTALL(TARGETS BulletSoftBodySolvers_OpenCL DESTINATION lib${LIB_SUFFIX})
|
||||
INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DESTINATION include FILES_MATCHING PATTERN "*.h")
|
||||
ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5)
|
||||
|
||||
IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL PROPERTIES FRAMEWORK true)
|
||||
SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL PROPERTIES PUBLIC_HEADER "${BulletSoftBodyOpenCLSolvers_HDRS}")
|
||||
ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES)
|
||||
ENDIF (INSTALL_LIBS)
|
||||
@@ -0,0 +1,91 @@
|
||||
MSTRINGIFY(
|
||||
|
||||
/*#define float3 float4
|
||||
float dot3(float3 a, float3 b)
|
||||
{
|
||||
return a.x*b.x + a.y*b.y + a.z*b.z;
|
||||
}*/
|
||||
|
||||
float3 projectOnAxis( float3 v, float3 a )
|
||||
{
|
||||
return (a*dot(v, a));
|
||||
}
|
||||
|
||||
__kernel void
|
||||
ApplyForcesKernel(
|
||||
const uint numNodes,
|
||||
const float solverdt,
|
||||
const float epsilon,
|
||||
__global int * g_vertexClothIdentifier,
|
||||
__global float4 * g_vertexNormal,
|
||||
__global float * g_vertexArea,
|
||||
__global float * g_vertexInverseMass,
|
||||
__global float * g_clothLiftFactor,
|
||||
__global float * g_clothDragFactor,
|
||||
__global float4 * g_clothWindVelocity,
|
||||
__global float4 * g_clothAcceleration,
|
||||
__global float * g_clothMediumDensity,
|
||||
__global float4 * g_vertexForceAccumulator,
|
||||
__global float4 * g_vertexVelocity)
|
||||
{
|
||||
unsigned int nodeID = get_global_id(0);
|
||||
if( nodeID < numNodes )
|
||||
{
|
||||
int clothId = g_vertexClothIdentifier[nodeID];
|
||||
float nodeIM = g_vertexInverseMass[nodeID];
|
||||
|
||||
if( nodeIM > 0.0f )
|
||||
{
|
||||
float3 nodeV = g_vertexVelocity[nodeID].xyz;
|
||||
float3 normal = g_vertexNormal[nodeID].xyz;
|
||||
float area = g_vertexArea[nodeID];
|
||||
float3 nodeF = g_vertexForceAccumulator[nodeID].xyz;
|
||||
|
||||
// Read per-cloth values
|
||||
float3 clothAcceleration = g_clothAcceleration[clothId].xyz;
|
||||
float3 clothWindVelocity = g_clothWindVelocity[clothId].xyz;
|
||||
float liftFactor = g_clothLiftFactor[clothId];
|
||||
float dragFactor = g_clothDragFactor[clothId];
|
||||
float mediumDensity = g_clothMediumDensity[clothId];
|
||||
|
||||
// Apply the acceleration to the cloth rather than do this via a force
|
||||
nodeV += (clothAcceleration*solverdt);
|
||||
|
||||
g_vertexVelocity[nodeID] = (float4)(nodeV, 0.f);
|
||||
|
||||
float3 relativeWindVelocity = nodeV - clothWindVelocity;
|
||||
float relativeSpeedSquared = dot(relativeWindVelocity, relativeWindVelocity);
|
||||
|
||||
if( relativeSpeedSquared > epsilon )
|
||||
{
|
||||
// Correct direction of normal relative to wind direction and get dot product
|
||||
normal = normal * (dot(normal, relativeWindVelocity) < 0 ? -1.f : 1.f);
|
||||
float dvNormal = dot(normal, relativeWindVelocity);
|
||||
if( dvNormal > 0 )
|
||||
{
|
||||
float3 force = (float3)(0.f, 0.f, 0.f);
|
||||
float c0 = area * dvNormal * relativeSpeedSquared / 2.f;
|
||||
float c1 = c0 * mediumDensity;
|
||||
force += normal * (-c1 * liftFactor);
|
||||
force += normalize(relativeWindVelocity)*(-c1 * dragFactor);
|
||||
|
||||
float dtim = solverdt * nodeIM;
|
||||
float3 forceDTIM = force * dtim;
|
||||
|
||||
float3 nodeFPlusForce = nodeF + force;
|
||||
|
||||
// m_nodesf[i] -= ProjectOnAxis(m_nodesv[i], force.normalized())/dtim;
|
||||
float3 nodeFMinus = nodeF - (projectOnAxis(nodeV, normalize(force))/dtim);
|
||||
|
||||
nodeF = nodeFPlusForce;
|
||||
if( dot(forceDTIM, forceDTIM) > dot(nodeV, nodeV) )
|
||||
nodeF = nodeFMinus;
|
||||
|
||||
g_vertexForceAccumulator[nodeID] = (float4)(nodeF, 0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
@@ -0,0 +1,35 @@
|
||||
MSTRINGIFY(
|
||||
|
||||
// Node indices for each link
|
||||
|
||||
//#define float3 float4
|
||||
|
||||
__kernel void
|
||||
IntegrateKernel(
|
||||
const int numNodes,
|
||||
const float solverdt,
|
||||
__global float * g_vertexInverseMasses,
|
||||
__global float4 * g_vertexPositions,
|
||||
__global float4 * g_vertexVelocity,
|
||||
__global float4 * g_vertexPreviousPositions,
|
||||
__global float4 * g_vertexForceAccumulator)
|
||||
{
|
||||
int nodeID = get_global_id(0);
|
||||
if( nodeID < numNodes )
|
||||
{
|
||||
float3 position = g_vertexPositions[nodeID].xyz;
|
||||
float3 velocity = g_vertexVelocity[nodeID].xyz;
|
||||
float3 force = g_vertexForceAccumulator[nodeID].xyz;
|
||||
float inverseMass = g_vertexInverseMasses[nodeID];
|
||||
|
||||
g_vertexPreviousPositions[nodeID] = (float4)(position, 0.f);
|
||||
velocity += force * inverseMass * solverdt;
|
||||
position += velocity * solverdt;
|
||||
|
||||
g_vertexForceAccumulator[nodeID] = (float4)(0.f, 0.f, 0.f, 0.0f);
|
||||
g_vertexPositions[nodeID] = (float4)(position, 0.f);
|
||||
g_vertexVelocity[nodeID] = (float4)(velocity, 0.f);
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
@@ -0,0 +1,34 @@
|
||||
MSTRINGIFY(
|
||||
|
||||
__kernel void
|
||||
PrepareLinksKernel(
|
||||
const int numLinks,
|
||||
__global int2 * g_linksVertexIndices,
|
||||
__global float * g_linksMassLSC,
|
||||
__global float4 * g_nodesPreviousPosition,
|
||||
__global float * g_linksLengthRatio,
|
||||
__global float4 * g_linksCurrentLength)
|
||||
{
|
||||
int linkID = get_global_id(0);
|
||||
if( linkID < numLinks )
|
||||
{
|
||||
int2 nodeIndices = g_linksVertexIndices[linkID];
|
||||
int node0 = nodeIndices.x;
|
||||
int node1 = nodeIndices.y;
|
||||
|
||||
float4 nodePreviousPosition0 = g_nodesPreviousPosition[node0];
|
||||
float4 nodePreviousPosition1 = g_nodesPreviousPosition[node1];
|
||||
|
||||
float massLSC = g_linksMassLSC[linkID];
|
||||
|
||||
float4 linkCurrentLength = nodePreviousPosition1 - nodePreviousPosition0;
|
||||
|
||||
float linkLengthRatio = dot(linkCurrentLength, linkCurrentLength)*massLSC;
|
||||
linkLengthRatio = 1.0f/linkLengthRatio;
|
||||
|
||||
g_linksCurrentLength[linkID] = linkCurrentLength;
|
||||
g_linksLengthRatio[linkID] = linkLengthRatio;
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
@@ -0,0 +1,55 @@
|
||||
|
||||
MSTRINGIFY(
|
||||
|
||||
/*#define float3 float4
|
||||
|
||||
float dot3(float3 a, float3 b)
|
||||
{
|
||||
return a.x*b.x + a.y*b.y + a.z*b.z;
|
||||
}*/
|
||||
|
||||
__kernel void
|
||||
SolvePositionsFromLinksKernel(
|
||||
const int startLink,
|
||||
const int numLinks,
|
||||
const float kst,
|
||||
const float ti,
|
||||
__global int2 * g_linksVertexIndices,
|
||||
__global float * g_linksMassLSC,
|
||||
__global float * g_linksRestLengthSquared,
|
||||
__global float * g_verticesInverseMass,
|
||||
__global float4 * g_vertexPositions)
|
||||
|
||||
{
|
||||
int linkID = get_global_id(0) + startLink;
|
||||
if( get_global_id(0) < numLinks )
|
||||
{
|
||||
float massLSC = g_linksMassLSC[linkID];
|
||||
float restLengthSquared = g_linksRestLengthSquared[linkID];
|
||||
|
||||
if( massLSC > 0.0f )
|
||||
{
|
||||
int2 nodeIndices = g_linksVertexIndices[linkID];
|
||||
int node0 = nodeIndices.x;
|
||||
int node1 = nodeIndices.y;
|
||||
|
||||
float3 position0 = g_vertexPositions[node0].xyz;
|
||||
float3 position1 = g_vertexPositions[node1].xyz;
|
||||
|
||||
float inverseMass0 = g_verticesInverseMass[node0];
|
||||
float inverseMass1 = g_verticesInverseMass[node1];
|
||||
|
||||
float3 del = position1 - position0;
|
||||
float len = dot(del, del);
|
||||
float k = ((restLengthSquared - len)/(massLSC*(restLengthSquared+len)))*kst;
|
||||
position0 = position0 - del*(k*inverseMass0);
|
||||
position1 = position1 + del*(k*inverseMass1);
|
||||
|
||||
g_vertexPositions[node0] = (float4)(position0, 0.f);
|
||||
g_vertexPositions[node1] = (float4)(position1, 0.f);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
@@ -0,0 +1,44 @@
|
||||
MSTRINGIFY(
|
||||
|
||||
/*#define float3 float4
|
||||
|
||||
float dot3(float3 a, float3 b)
|
||||
{
|
||||
return a.x*b.x + a.y*b.y + a.z*b.z;
|
||||
}*/
|
||||
|
||||
__kernel void
|
||||
UpdateConstantsKernel(
|
||||
const int numLinks,
|
||||
__global int2 * g_linksVertexIndices,
|
||||
__global float4 * g_vertexPositions,
|
||||
__global float * g_vertexInverseMasses,
|
||||
__global float * g_linksMaterialLSC,
|
||||
__global float * g_linksMassLSC,
|
||||
__global float * g_linksRestLengthSquared,
|
||||
__global float * g_linksRestLengths)
|
||||
{
|
||||
int linkID = get_global_id(0);
|
||||
if( linkID < numLinks )
|
||||
{
|
||||
int2 nodeIndices = g_linksVertexIndices[linkID];
|
||||
int node0 = nodeIndices.x;
|
||||
int node1 = nodeIndices.y;
|
||||
float linearStiffnessCoefficient = g_linksMaterialLSC[ linkID ];
|
||||
|
||||
float3 position0 = g_vertexPositions[node0].xyz;
|
||||
float3 position1 = g_vertexPositions[node1].xyz;
|
||||
float inverseMass0 = g_vertexInverseMasses[node0];
|
||||
float inverseMass1 = g_vertexInverseMasses[node1];
|
||||
|
||||
float3 difference = position0 - position1;
|
||||
float length2 = dot(difference, difference);
|
||||
float length = sqrt(length2);
|
||||
|
||||
g_linksRestLengths[linkID] = length;
|
||||
g_linksMassLSC[linkID] = (inverseMass0 + inverseMass1)/linearStiffnessCoefficient;
|
||||
g_linksRestLengthSquared[linkID] = length*length;
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
@@ -0,0 +1,40 @@
|
||||
MSTRINGIFY(
|
||||
|
||||
//#define float3 float4
|
||||
|
||||
__kernel void
|
||||
updateVelocitiesFromPositionsWithVelocitiesKernel(
|
||||
int numNodes,
|
||||
float isolverdt,
|
||||
__global float4 * g_vertexPositions,
|
||||
__global float4 * g_vertexPreviousPositions,
|
||||
__global int * g_vertexClothIndices,
|
||||
__global float *g_clothVelocityCorrectionCoefficients,
|
||||
__global float * g_clothDampingFactor,
|
||||
__global float4 * g_vertexVelocities,
|
||||
__global float4 * g_vertexForces)
|
||||
{
|
||||
int nodeID = get_global_id(0);
|
||||
if( nodeID < numNodes )
|
||||
{
|
||||
float3 position = g_vertexPositions[nodeID].xyz;
|
||||
float3 previousPosition = g_vertexPreviousPositions[nodeID].xyz;
|
||||
float3 velocity = g_vertexVelocities[nodeID].xyz;
|
||||
int clothIndex = g_vertexClothIndices[nodeID];
|
||||
float velocityCorrectionCoefficient = g_clothVelocityCorrectionCoefficients[clothIndex];
|
||||
float dampingFactor = g_clothDampingFactor[clothIndex];
|
||||
float velocityCoefficient = (1.f - dampingFactor);
|
||||
|
||||
float3 difference = position - previousPosition;
|
||||
|
||||
velocity += difference*velocityCorrectionCoefficient*isolverdt;
|
||||
|
||||
// Damp the velocity
|
||||
velocity *= velocityCoefficient;
|
||||
|
||||
g_vertexVelocities[nodeID] = (float4)(velocity, 0.f);
|
||||
g_vertexForces[nodeID] = (float4)(0.f, 0.f, 0.f, 0.f);
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
@@ -0,0 +1,103 @@
|
||||
MSTRINGIFY(
|
||||
|
||||
//#define float3 float4
|
||||
|
||||
/*float length3(float3 a)
|
||||
{
|
||||
a.w = 0;
|
||||
return length(a);
|
||||
}
|
||||
|
||||
float normalize3(float3 a)
|
||||
{
|
||||
a.w = 0;
|
||||
return normalize(a);
|
||||
}*/
|
||||
|
||||
__kernel void
|
||||
ResetNormalsAndAreasKernel(
|
||||
const unsigned int numNodes,
|
||||
__global float4 * g_vertexNormals,
|
||||
__global float * g_vertexArea)
|
||||
{
|
||||
if( get_global_id(0) < numNodes )
|
||||
{
|
||||
g_vertexNormals[get_global_id(0)] = (float4)(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
g_vertexArea[get_global_id(0)] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
__kernel void
|
||||
UpdateSoftBodiesKernel(
|
||||
const unsigned int startFace,
|
||||
const unsigned int numFaces,
|
||||
__global int4 * g_triangleVertexIndexSet,
|
||||
__global float4 * g_vertexPositions,
|
||||
__global float4 * g_vertexNormals,
|
||||
__global float * g_vertexArea,
|
||||
__global float4 * g_triangleNormals,
|
||||
__global float * g_triangleArea)
|
||||
{
|
||||
int faceID = get_global_id(0) + startFace;
|
||||
if( get_global_id(0) < numFaces )
|
||||
{
|
||||
int4 triangleIndexSet = g_triangleVertexIndexSet[ faceID ];
|
||||
int nodeIndex0 = triangleIndexSet.x;
|
||||
int nodeIndex1 = triangleIndexSet.y;
|
||||
int nodeIndex2 = triangleIndexSet.z;
|
||||
|
||||
float3 node0 = g_vertexPositions[nodeIndex0].xyz;
|
||||
float3 node1 = g_vertexPositions[nodeIndex1].xyz;
|
||||
float3 node2 = g_vertexPositions[nodeIndex2].xyz;
|
||||
float3 nodeNormal0 = g_vertexNormals[nodeIndex0].xyz;
|
||||
float3 nodeNormal1 = g_vertexNormals[nodeIndex1].xyz;
|
||||
float3 nodeNormal2 = g_vertexNormals[nodeIndex2].xyz;
|
||||
float vertexArea0 = g_vertexArea[nodeIndex0];
|
||||
float vertexArea1 = g_vertexArea[nodeIndex1];
|
||||
float vertexArea2 = g_vertexArea[nodeIndex2];
|
||||
|
||||
float3 vector0 = node1 - node0;
|
||||
float3 vector1 = node2 - node0;
|
||||
|
||||
float3 faceNormal = cross(vector0.xyz, vector1.xyz);
|
||||
float triangleArea = length(faceNormal);
|
||||
|
||||
nodeNormal0 = nodeNormal0 + faceNormal;
|
||||
nodeNormal1 = nodeNormal1 + faceNormal;
|
||||
nodeNormal2 = nodeNormal2 + faceNormal;
|
||||
vertexArea0 = vertexArea0 + triangleArea;
|
||||
vertexArea1 = vertexArea1 + triangleArea;
|
||||
vertexArea2 = vertexArea2 + triangleArea;
|
||||
|
||||
g_triangleNormals[faceID] = (float4)(normalize(faceNormal), 0.f);
|
||||
g_vertexNormals[nodeIndex0] = (float4)(nodeNormal0, 0.f);
|
||||
g_vertexNormals[nodeIndex1] = (float4)(nodeNormal1, 0.f);
|
||||
g_vertexNormals[nodeIndex2] = (float4)(nodeNormal2, 0.f);
|
||||
g_triangleArea[faceID] = triangleArea;
|
||||
g_vertexArea[nodeIndex0] = vertexArea0;
|
||||
g_vertexArea[nodeIndex1] = vertexArea1;
|
||||
g_vertexArea[nodeIndex2] = vertexArea2;
|
||||
}
|
||||
}
|
||||
|
||||
__kernel void
|
||||
NormalizeNormalsAndAreasKernel(
|
||||
const unsigned int numNodes,
|
||||
__global int * g_vertexTriangleCount,
|
||||
__global float4 * g_vertexNormals,
|
||||
__global float * g_vertexArea)
|
||||
{
|
||||
if( get_global_id(0) < numNodes )
|
||||
{
|
||||
float4 normal = g_vertexNormals[get_global_id(0)];
|
||||
float area = g_vertexArea[get_global_id(0)];
|
||||
int numTriangles = g_vertexTriangleCount[get_global_id(0)];
|
||||
|
||||
float vectorLength = length(normal);
|
||||
|
||||
g_vertexNormals[get_global_id(0)] = normalize(normal);
|
||||
g_vertexArea[get_global_id(0)] = area/(float)(numTriangles);
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
@@ -0,0 +1,36 @@
|
||||
MSTRINGIFY(
|
||||
|
||||
//#define float3 float4
|
||||
|
||||
__kernel void
|
||||
updateVelocitiesFromPositionsWithoutVelocitiesKernel(
|
||||
const int numNodes,
|
||||
const float isolverdt,
|
||||
__global float4 * g_vertexPositions,
|
||||
__global float4 * g_vertexPreviousPositions,
|
||||
__global int * g_vertexClothIndices,
|
||||
__global float * g_clothDampingFactor,
|
||||
__global float4 * g_vertexVelocities,
|
||||
__global float4 * g_vertexForces)
|
||||
|
||||
{
|
||||
int nodeID = get_global_id(0);
|
||||
if( nodeID < numNodes )
|
||||
{
|
||||
float3 position = g_vertexPositions[nodeID].xyz;
|
||||
float3 previousPosition = g_vertexPreviousPositions[nodeID].xyz;
|
||||
float3 velocity = g_vertexVelocities[nodeID].xyz;
|
||||
int clothIndex = g_vertexClothIndices[nodeID];
|
||||
float dampingFactor = g_clothDampingFactor[clothIndex];
|
||||
float velocityCoefficient = (1.f - dampingFactor);
|
||||
|
||||
float3 difference = position - previousPosition;
|
||||
|
||||
velocity = difference*velocityCoefficient*isolverdt;
|
||||
|
||||
g_vertexVelocities[nodeID] = (float4)(velocity, 0.f);
|
||||
g_vertexForces[nodeID] = (float4)(0.f, 0.f, 0.f, 0.f);
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
@@ -0,0 +1,26 @@
|
||||
MSTRINGIFY(
|
||||
|
||||
//#define float3 float4
|
||||
|
||||
__kernel void
|
||||
UpdatePositionsFromVelocitiesKernel(
|
||||
const int numNodes,
|
||||
const float solverSDT,
|
||||
__global float4 * g_vertexVelocities,
|
||||
__global float4 * g_vertexPreviousPositions,
|
||||
__global float4 * g_vertexCurrentPosition)
|
||||
{
|
||||
int vertexID = get_global_id(0);
|
||||
if( vertexID < numNodes )
|
||||
{
|
||||
float3 previousPosition = g_vertexPreviousPositions[vertexID].xyz;
|
||||
float3 velocity = g_vertexVelocities[vertexID].xyz;
|
||||
|
||||
float3 newPosition = previousPosition + velocity*solverSDT;
|
||||
|
||||
g_vertexCurrentPosition[vertexID] = (float4)(newPosition, 0.f);
|
||||
g_vertexPreviousPositions[vertexID] = (float4)(newPosition, 0.f);
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
@@ -0,0 +1,45 @@
|
||||
MSTRINGIFY(
|
||||
|
||||
__kernel void
|
||||
VSolveLinksKernel(
|
||||
int startLink,
|
||||
int numLinks,
|
||||
float kst,
|
||||
__global int2 * g_linksVertexIndices,
|
||||
__global float * g_linksLengthRatio,
|
||||
__global float4 * g_linksCurrentLength,
|
||||
__global float * g_vertexInverseMass,
|
||||
__global float4 * g_vertexVelocity)
|
||||
{
|
||||
int linkID = get_global_id(0) + startLink;
|
||||
if( get_global_id(0) < numLinks )
|
||||
{
|
||||
int2 nodeIndices = g_linksVertexIndices[linkID];
|
||||
int node0 = nodeIndices.x;
|
||||
int node1 = nodeIndices.y;
|
||||
|
||||
float linkLengthRatio = g_linksLengthRatio[linkID];
|
||||
float3 linkCurrentLength = g_linksCurrentLength[linkID].xyz;
|
||||
|
||||
float3 vertexVelocity0 = g_vertexVelocity[node0].xyz;
|
||||
float3 vertexVelocity1 = g_vertexVelocity[node1].xyz;
|
||||
|
||||
float vertexInverseMass0 = g_vertexInverseMass[node0];
|
||||
float vertexInverseMass1 = g_vertexInverseMass[node1];
|
||||
|
||||
float3 nodeDifference = vertexVelocity0 - vertexVelocity1;
|
||||
float dotResult = dot(linkCurrentLength, nodeDifference);
|
||||
float j = -dotResult*linkLengthRatio*kst;
|
||||
|
||||
float3 velocityChange0 = linkCurrentLength*(j*vertexInverseMass0);
|
||||
float3 velocityChange1 = linkCurrentLength*(j*vertexInverseMass1);
|
||||
|
||||
vertexVelocity0 += velocityChange0;
|
||||
vertexVelocity1 -= velocityChange1;
|
||||
|
||||
g_vertexVelocity[node0] = (float4)(vertexVelocity0, 0.f);
|
||||
g_vertexVelocity[node1] = (float4)(vertexVelocity1, 0.f);
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef BT_SOFT_BODY_SOLVER_BUFFER_OPENCL_H
|
||||
#define BT_SOFT_BODY_SOLVER_BUFFER_OPENCL_H
|
||||
|
||||
// OpenCL support
|
||||
#include <CL/cl.hpp>
|
||||
|
||||
#ifndef SAFE_RELEASE
|
||||
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
|
||||
#endif
|
||||
|
||||
template <typename ElementType> class btOpenCLBuffer
|
||||
{
|
||||
protected:
|
||||
cl::CommandQueue m_queue;
|
||||
btAlignedObjectArray< ElementType > * m_CPUBuffer;
|
||||
cl::Buffer m_buffer;
|
||||
|
||||
int m_gpuSize;
|
||||
bool m_onGPU;
|
||||
|
||||
bool m_readOnlyOnGPU;
|
||||
|
||||
bool m_allocated;
|
||||
// TODO: Remove this once C++ bindings are fixed
|
||||
cl::Context context;
|
||||
|
||||
bool createBuffer( cl::Buffer *preexistingBuffer = 0)
|
||||
{
|
||||
cl_int err;
|
||||
|
||||
|
||||
if( preexistingBuffer )
|
||||
{
|
||||
m_buffer = *preexistingBuffer;
|
||||
}
|
||||
else {
|
||||
m_buffer = cl::Buffer(
|
||||
context,
|
||||
m_readOnlyOnGPU ? CL_MEM_READ_ONLY : CL_MEM_READ_WRITE,
|
||||
m_CPUBuffer->size() * sizeof(ElementType),
|
||||
0,
|
||||
&err);
|
||||
if( err != CL_SUCCESS )
|
||||
{
|
||||
btAssert( "Buffer::Buffer(m_buffer)");
|
||||
}
|
||||
}
|
||||
|
||||
m_gpuSize = m_CPUBuffer->size();
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
btOpenCLBuffer(
|
||||
cl::CommandQueue queue,
|
||||
btAlignedObjectArray< ElementType > *CPUBuffer,
|
||||
bool readOnly) :
|
||||
m_queue(queue),
|
||||
m_CPUBuffer(CPUBuffer),
|
||||
m_gpuSize(0),
|
||||
m_onGPU(false),
|
||||
m_readOnlyOnGPU(readOnly),
|
||||
m_allocated(false)
|
||||
{
|
||||
context = m_queue.getInfo<CL_QUEUE_CONTEXT>();
|
||||
}
|
||||
|
||||
~btOpenCLBuffer()
|
||||
{
|
||||
}
|
||||
|
||||
cl::Buffer getBuffer()
|
||||
{
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
bool moveToGPU()
|
||||
{
|
||||
cl_int err;
|
||||
|
||||
if( (m_CPUBuffer->size() != m_gpuSize) )
|
||||
{
|
||||
m_onGPU = false;
|
||||
}
|
||||
|
||||
if( !m_onGPU && m_CPUBuffer->size() > 0 )
|
||||
{
|
||||
if (!m_allocated || (m_CPUBuffer->size() != m_gpuSize)) {
|
||||
if (!createBuffer()) {
|
||||
return false;
|
||||
}
|
||||
m_allocated = true;
|
||||
}
|
||||
|
||||
err = m_queue.enqueueWriteBuffer(
|
||||
m_buffer,
|
||||
CL_FALSE,
|
||||
0,
|
||||
m_CPUBuffer->size() * sizeof(ElementType),
|
||||
&((*m_CPUBuffer)[0]));
|
||||
if( err != CL_SUCCESS )
|
||||
{
|
||||
btAssert( "CommandQueue::enqueueWriteBuffer(m_buffer)" );
|
||||
}
|
||||
|
||||
m_onGPU = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool moveFromGPU()
|
||||
{
|
||||
cl_int err;
|
||||
|
||||
if (m_CPUBuffer->size() > 0) {
|
||||
if (m_onGPU && !m_readOnlyOnGPU) {
|
||||
err = m_queue.enqueueReadBuffer(
|
||||
m_buffer,
|
||||
CL_TRUE,
|
||||
0,
|
||||
m_CPUBuffer->size() * sizeof(ElementType),
|
||||
&((*m_CPUBuffer)[0]));
|
||||
|
||||
if( err != CL_SUCCESS )
|
||||
{
|
||||
btAssert( "CommandQueue::enqueueReadBuffer(m_buffer)" );
|
||||
}
|
||||
|
||||
m_onGPU = false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool copyFromGPU()
|
||||
{
|
||||
cl_int err;
|
||||
|
||||
if (m_CPUBuffer->size() > 0) {
|
||||
if (m_onGPU && !m_readOnlyOnGPU) {
|
||||
err = m_queue.enqueueReadBuffer(
|
||||
m_buffer,
|
||||
CL_TRUE,
|
||||
0,
|
||||
m_CPUBuffer->size() * sizeof(ElementType),
|
||||
&((*m_CPUBuffer)[0]));
|
||||
|
||||
if( err != CL_SUCCESS )
|
||||
{
|
||||
btAssert( "CommandQueue::enqueueReadBuffer(m_buffer)");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void changedOnCPU()
|
||||
{
|
||||
m_onGPU = false;
|
||||
}
|
||||
}; // class btOpenCLBuffer
|
||||
|
||||
|
||||
#endif // #ifndef BT_SOFT_BODY_SOLVER_BUFFER_OPENCL_H
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "BulletSoftBody/Solvers/CPU/btSoftBodySolverData.h"
|
||||
#include "BulletSoftBody/Solvers/OpenCL/btSoftBodySolverBuffer_OpenCL.h"
|
||||
|
||||
|
||||
#ifndef BT_SOFT_BODY_SOLVER_LINK_DATA_OPENCL_H
|
||||
#define BT_SOFT_BODY_SOLVER_LINK_DATA_OPENCL_H
|
||||
|
||||
|
||||
class btSoftBodyLinkDataOpenCL : public btSoftBodyLinkData
|
||||
{
|
||||
public:
|
||||
bool m_onGPU;
|
||||
cl::CommandQueue m_queue;
|
||||
|
||||
btOpenCLBuffer<LinkNodePair> m_clLinks;
|
||||
btOpenCLBuffer<float> m_clLinkStrength;
|
||||
btOpenCLBuffer<float> m_clLinksMassLSC;
|
||||
btOpenCLBuffer<float> m_clLinksRestLengthSquared;
|
||||
btOpenCLBuffer<Vectormath::Aos::Vector3> m_clLinksCLength;
|
||||
btOpenCLBuffer<float> m_clLinksLengthRatio;
|
||||
btOpenCLBuffer<float> m_clLinksRestLength;
|
||||
btOpenCLBuffer<float> m_clLinksMaterialLinearStiffnessCoefficient;
|
||||
|
||||
/**
|
||||
* Link addressing information for each cloth.
|
||||
* Allows link locations to be computed independently of data batching.
|
||||
*/
|
||||
btAlignedObjectArray< int > m_linkAddresses;
|
||||
|
||||
/**
|
||||
* Start and length values for computation batches over link data.
|
||||
*/
|
||||
btAlignedObjectArray< std::pair< int, int > > m_batchStartLengths;
|
||||
|
||||
btSoftBodyLinkDataOpenCL(cl::CommandQueue queue);
|
||||
|
||||
virtual ~btSoftBodyLinkDataOpenCL();
|
||||
|
||||
/** Allocate enough space in all link-related arrays to fit numLinks links */
|
||||
virtual void createLinks( int numLinks );
|
||||
|
||||
/** Insert the link described into the correct data structures assuming space has already been allocated by a call to createLinks */
|
||||
virtual void setLinkAt(
|
||||
const LinkDescription &link,
|
||||
int linkIndex );
|
||||
|
||||
virtual bool onAccelerator();
|
||||
|
||||
virtual bool moveToAccelerator();
|
||||
|
||||
virtual bool moveFromAccelerator();
|
||||
|
||||
/**
|
||||
* Generate (and later update) the batching for the entire link set.
|
||||
* This redoes a lot of work because it batches the entire set when each cloth is inserted.
|
||||
* In theory we could delay it until just before we need the cloth.
|
||||
* It's a one-off overhead, though, so that is a later optimisation.
|
||||
*/
|
||||
void generateBatches();
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // #ifndef BT_SOFT_BODY_SOLVER_LINK_DATA_OPENCL_H
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#include "BulletSoftBody/Solvers/CPU/btSoftBodySolverData.h"
|
||||
#include "BulletSoftBody/Solvers/OpenCL/btSoftBodySolverBuffer_OpenCL.h"
|
||||
|
||||
|
||||
#ifndef BT_SOFT_BODY_SOLVER_TRIANGLE_DATA_OPENCL_H
|
||||
#define BT_SOFT_BODY_SOLVER_TRIANGLE_DATA_OPENCL_H
|
||||
|
||||
|
||||
class btSoftBodyTriangleDataOpenCL : public btSoftBodyTriangleData
|
||||
{
|
||||
public:
|
||||
bool m_onGPU;
|
||||
cl::CommandQueue m_queue;
|
||||
|
||||
btOpenCLBuffer<btSoftBodyTriangleData::TriangleNodeSet> m_clVertexIndices;
|
||||
btOpenCLBuffer<float> m_clArea;
|
||||
btOpenCLBuffer<Vectormath::Aos::Vector3> m_clNormal;
|
||||
|
||||
/**
|
||||
* Link addressing information for each cloth.
|
||||
* Allows link locations to be computed independently of data batching.
|
||||
*/
|
||||
btAlignedObjectArray< int > m_triangleAddresses;
|
||||
|
||||
/**
|
||||
* Start and length values for computation batches over link data.
|
||||
*/
|
||||
btAlignedObjectArray< std::pair< int, int > > m_batchStartLengths;
|
||||
|
||||
public:
|
||||
btSoftBodyTriangleDataOpenCL( cl::CommandQueue queue );
|
||||
|
||||
virtual ~btSoftBodyTriangleDataOpenCL();
|
||||
|
||||
/** Allocate enough space in all link-related arrays to fit numLinks links */
|
||||
virtual void createTriangles( int numTriangles );
|
||||
|
||||
/** Insert the link described into the correct data structures assuming space has already been allocated by a call to createLinks */
|
||||
virtual void setTriangleAt( const btSoftBodyTriangleData::TriangleDescription &triangle, int triangleIndex );
|
||||
|
||||
virtual bool onAccelerator();
|
||||
|
||||
virtual bool moveToAccelerator();
|
||||
|
||||
virtual bool moveFromAccelerator();
|
||||
|
||||
/**
|
||||
* Generate (and later update) the batching for the entire triangle set.
|
||||
* This redoes a lot of work because it batches the entire set when each cloth is inserted.
|
||||
* In theory we could delay it until just before we need the cloth.
|
||||
* It's a one-off overhead, though, so that is a later optimisation.
|
||||
*/
|
||||
void generateBatches();
|
||||
}; // class btSoftBodyTriangleDataOpenCL
|
||||
|
||||
|
||||
#endif // #ifndef BT_SOFT_BODY_SOLVER_TRIANGLE_DATA_OPENCL_H
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "BulletSoftBody/Solvers/CPU/btSoftBodySolverData.h"
|
||||
#include "BulletSoftBody/Solvers/OpenCL/btSoftBodySolverBuffer_OpenCL.h"
|
||||
|
||||
#ifndef BT_SOFT_BODY_SOLVER_VERTEX_DATA_OPENCL_H
|
||||
#define BT_SOFT_BODY_SOLVER_VERTEX_DATA_OPENCL_H
|
||||
|
||||
|
||||
class btSoftBodyVertexDataOpenCL : public btSoftBodyVertexData
|
||||
{
|
||||
protected:
|
||||
bool m_onGPU;
|
||||
cl::CommandQueue m_queue;
|
||||
|
||||
public:
|
||||
btOpenCLBuffer<int> m_clClothIdentifier;
|
||||
btOpenCLBuffer<Vectormath::Aos::Point3> m_clVertexPosition;
|
||||
btOpenCLBuffer<Vectormath::Aos::Point3> m_clVertexPreviousPosition;
|
||||
btOpenCLBuffer<Vectormath::Aos::Vector3> m_clVertexVelocity;
|
||||
btOpenCLBuffer<Vectormath::Aos::Vector3> m_clVertexForceAccumulator;
|
||||
btOpenCLBuffer<Vectormath::Aos::Vector3> m_clVertexNormal;
|
||||
btOpenCLBuffer<float> m_clVertexInverseMass;
|
||||
btOpenCLBuffer<float> m_clVertexArea;
|
||||
btOpenCLBuffer<int> m_clVertexTriangleCount;
|
||||
public:
|
||||
btSoftBodyVertexDataOpenCL( cl::CommandQueue queue);
|
||||
|
||||
virtual ~btSoftBodyVertexDataOpenCL();
|
||||
|
||||
virtual bool onAccelerator();
|
||||
|
||||
virtual bool moveToAccelerator();
|
||||
|
||||
virtual bool moveFromAccelerator();
|
||||
};
|
||||
|
||||
|
||||
#endif // #ifndef BT_SOFT_BODY_SOLVER_VERTEX_DATA_OPENCL_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,377 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef BT_SOFT_BODY_SOLVER_OPENCL_H
|
||||
#define BT_SOFT_BODY_SOLVER_OPENCL_H
|
||||
|
||||
#include "BulletMultiThreaded/vectormath/scalar/cpp/vectormath_aos.h"
|
||||
#include "BulletMultiThreaded/vectormath/scalar/cpp/mat_aos.h"
|
||||
#include "BulletMultiThreaded/vectormath/scalar/cpp/vec_aos.h"
|
||||
|
||||
#include "BulletSoftBody/btSoftBodySolvers.h"
|
||||
#include "BulletSoftBody/solvers/OpenCL/btSoftBodySolverBuffer_OpenCL.h"
|
||||
#include "BulletSoftBody/solvers/OpenCL/btSoftBodySolverLinkData_OpenCL.h"
|
||||
#include "BulletSoftBody/solvers/OpenCL/btSoftBodySolverVertexData_OpenCL.h"
|
||||
#include "BulletSoftBody/solvers/OpenCL/btSoftBodySolverTriangleData_OpenCL.h"
|
||||
|
||||
|
||||
class btOpenCLSoftBodySolver : public btSoftBodySolver
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* SoftBody class to maintain information about a soft body instance
|
||||
* within a solver.
|
||||
* This data addresses the main solver arrays.
|
||||
*/
|
||||
class btAcceleratedSoftBodyInterface
|
||||
{
|
||||
protected:
|
||||
/** Current number of vertices that are part of this cloth */
|
||||
int m_numVertices;
|
||||
/** Maximum number of vertices allocated to be part of this cloth */
|
||||
int m_maxVertices;
|
||||
/** Current number of triangles that are part of this cloth */
|
||||
int m_numTriangles;
|
||||
/** Maximum number of triangles allocated to be part of this cloth */
|
||||
int m_maxTriangles;
|
||||
/** Index of first vertex in the world allocated to this cloth */
|
||||
int m_firstVertex;
|
||||
/** Index of first triangle in the world allocated to this cloth */
|
||||
int m_firstTriangle;
|
||||
/** Index of first link in the world allocated to this cloth */
|
||||
int m_firstLink;
|
||||
/** Maximum number of links allocated to this cloth */
|
||||
int m_maxLinks;
|
||||
/** Current number of links allocated to this cloth */
|
||||
int m_numLinks;
|
||||
|
||||
/** The actual soft body this data represents */
|
||||
btSoftBody *m_softBody;
|
||||
|
||||
|
||||
public:
|
||||
btAcceleratedSoftBodyInterface( btSoftBody *softBody ) :
|
||||
m_softBody( softBody )
|
||||
{
|
||||
m_numVertices = 0;
|
||||
m_maxVertices = 0;
|
||||
m_numTriangles = 0;
|
||||
m_maxTriangles = 0;
|
||||
m_firstVertex = 0;
|
||||
m_firstTriangle = 0;
|
||||
m_firstLink = 0;
|
||||
m_maxLinks = 0;
|
||||
m_numLinks = 0;
|
||||
}
|
||||
int getNumVertices()
|
||||
{
|
||||
return m_numVertices;
|
||||
}
|
||||
|
||||
int getNumTriangles()
|
||||
{
|
||||
return m_numTriangles;
|
||||
}
|
||||
|
||||
int getMaxVertices()
|
||||
{
|
||||
return m_maxVertices;
|
||||
}
|
||||
|
||||
int getMaxTriangles()
|
||||
{
|
||||
return m_maxTriangles;
|
||||
}
|
||||
|
||||
int getFirstVertex()
|
||||
{
|
||||
return m_firstVertex;
|
||||
}
|
||||
|
||||
int getFirstTriangle()
|
||||
{
|
||||
return m_firstTriangle;
|
||||
}
|
||||
|
||||
// TODO: All of these set functions will have to do checks and
|
||||
// update the world because restructuring of the arrays will be necessary
|
||||
// Reasonable use of "friend"?
|
||||
void setNumVertices( int numVertices )
|
||||
{
|
||||
m_numVertices = numVertices;
|
||||
}
|
||||
|
||||
void setNumTriangles( int numTriangles )
|
||||
{
|
||||
m_numTriangles = numTriangles;
|
||||
}
|
||||
|
||||
void setMaxVertices( int maxVertices )
|
||||
{
|
||||
m_maxVertices = maxVertices;
|
||||
}
|
||||
|
||||
void setMaxTriangles( int maxTriangles )
|
||||
{
|
||||
m_maxTriangles = maxTriangles;
|
||||
}
|
||||
|
||||
void setFirstVertex( int firstVertex )
|
||||
{
|
||||
m_firstVertex = firstVertex;
|
||||
}
|
||||
|
||||
void setFirstTriangle( int firstTriangle )
|
||||
{
|
||||
m_firstTriangle = firstTriangle;
|
||||
}
|
||||
|
||||
void setMaxLinks( int maxLinks )
|
||||
{
|
||||
m_maxLinks = maxLinks;
|
||||
}
|
||||
|
||||
void setNumLinks( int numLinks )
|
||||
{
|
||||
m_numLinks = numLinks;
|
||||
}
|
||||
|
||||
void setFirstLink( int firstLink )
|
||||
{
|
||||
m_firstLink = firstLink;
|
||||
}
|
||||
|
||||
int getMaxLinks()
|
||||
{
|
||||
return m_maxLinks;
|
||||
}
|
||||
|
||||
int getNumLinks()
|
||||
{
|
||||
return m_numLinks;
|
||||
}
|
||||
|
||||
int getFirstLink()
|
||||
{
|
||||
return m_firstLink;
|
||||
}
|
||||
|
||||
btSoftBody* getSoftBody()
|
||||
{
|
||||
return m_softBody;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void setAcceleration( Vectormath::Aos::Vector3 acceleration )
|
||||
{
|
||||
m_currentSolver->setPerClothAcceleration( m_clothIdentifier, acceleration );
|
||||
}
|
||||
|
||||
void setWindVelocity( Vectormath::Aos::Vector3 windVelocity )
|
||||
{
|
||||
m_currentSolver->setPerClothWindVelocity( m_clothIdentifier, windVelocity );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the density of the air in which the cloth is situated.
|
||||
*/
|
||||
void setAirDensity( btScalar density )
|
||||
{
|
||||
m_currentSolver->setPerClothMediumDensity( m_clothIdentifier, static_cast<float>(density) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a collision object to this soft body.
|
||||
*/
|
||||
void addCollisionObject( btCollisionObject *collisionObject )
|
||||
{
|
||||
m_currentSolver->addCollisionObjectForSoftBody( m_clothIdentifier, collisionObject );
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
class KernelDesc
|
||||
{
|
||||
protected:
|
||||
public:
|
||||
cl::Kernel kernel;
|
||||
|
||||
KernelDesc()
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~KernelDesc()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
btSoftBodyLinkDataOpenCL m_linkData;
|
||||
btSoftBodyVertexDataOpenCL m_vertexData;
|
||||
btSoftBodyTriangleDataOpenCL m_triangleData;
|
||||
|
||||
/** Variable to define whether we need to update solver constants on the next iteration */
|
||||
bool m_updateSolverConstants;
|
||||
|
||||
bool m_shadersInitialized;
|
||||
|
||||
/**
|
||||
* Cloths owned by this solver.
|
||||
* Only our cloths are in this array.
|
||||
*/
|
||||
btAlignedObjectArray< btAcceleratedSoftBodyInterface * > m_softBodySet;
|
||||
|
||||
/** Acceleration value to be applied to all non-static vertices in the solver.
|
||||
* Index n is cloth n, array sized by number of cloths in the world not the solver.
|
||||
*/
|
||||
btAlignedObjectArray< Vectormath::Aos::Vector3 > m_perClothAcceleration;
|
||||
btOpenCLBuffer<Vectormath::Aos::Vector3> m_clPerClothAcceleration;
|
||||
|
||||
/** Wind velocity to be applied normal to all non-static vertices in the solver.
|
||||
* Index n is cloth n, array sized by number of cloths in the world not the solver.
|
||||
*/
|
||||
btAlignedObjectArray< Vectormath::Aos::Vector3 > m_perClothWindVelocity;
|
||||
btOpenCLBuffer<Vectormath::Aos::Vector3> m_clPerClothWindVelocity;
|
||||
|
||||
/** Velocity damping factor */
|
||||
btAlignedObjectArray< float > m_perClothDampingFactor;
|
||||
btOpenCLBuffer<float> m_clPerClothDampingFactor;
|
||||
|
||||
/** Velocity correction coefficient */
|
||||
btAlignedObjectArray< float > m_perClothVelocityCorrectionCoefficient;
|
||||
btOpenCLBuffer<float> m_clPerClothVelocityCorrectionCoefficient;
|
||||
|
||||
/** Lift parameter for wind effect on cloth. */
|
||||
btAlignedObjectArray< float > m_perClothLiftFactor;
|
||||
btOpenCLBuffer<float> m_clPerClothLiftFactor;
|
||||
|
||||
/** Drag parameter for wind effect on cloth. */
|
||||
btAlignedObjectArray< float > m_perClothDragFactor;
|
||||
btOpenCLBuffer<float> m_clPerClothDragFactor;
|
||||
|
||||
/** Density of the medium in which each cloth sits */
|
||||
btAlignedObjectArray< float > m_perClothMediumDensity;
|
||||
btOpenCLBuffer<float> m_clPerClothMediumDensity;
|
||||
|
||||
KernelDesc prepareLinksKernel;
|
||||
KernelDesc solvePositionsFromLinksKernel;
|
||||
KernelDesc updateConstantsKernel;
|
||||
KernelDesc integrateKernel;
|
||||
KernelDesc addVelocityKernel;
|
||||
KernelDesc updatePositionsFromVelocitiesKernel;
|
||||
KernelDesc updateVelocitiesFromPositionsWithoutVelocitiesKernel;
|
||||
KernelDesc updateVelocitiesFromPositionsWithVelocitiesKernel;
|
||||
KernelDesc vSolveLinksKernel;
|
||||
KernelDesc resetNormalsAndAreasKernel;
|
||||
KernelDesc normalizeNormalsAndAreasKernel;
|
||||
KernelDesc updateSoftBodiesKernel;
|
||||
KernelDesc outputToVertexArrayWithNormalsKernel;
|
||||
KernelDesc outputToVertexArrayWithoutNormalsKernel;
|
||||
|
||||
KernelDesc outputToVertexArrayKernel;
|
||||
KernelDesc applyForcesKernel;
|
||||
KernelDesc collideSphereKernel;
|
||||
KernelDesc collideCylinderKernel;
|
||||
|
||||
static const int workGroupSize = 128;
|
||||
|
||||
cl::CommandQueue m_queue;
|
||||
cl::Context context;
|
||||
cl::Device device;
|
||||
|
||||
|
||||
/**
|
||||
* Compile a compute shader kernel from a string and return the appropriate KernelDesc object.
|
||||
*/
|
||||
KernelDesc compileCLKernelFromString( const char *shaderString, const char *shaderName );
|
||||
|
||||
bool buildShaders();
|
||||
|
||||
void resetNormalsAndAreas( int numVertices );
|
||||
|
||||
void normalizeNormalsAndAreas( int numVertices );
|
||||
|
||||
void executeUpdateSoftBodies( int firstTriangle, int numTriangles );
|
||||
|
||||
Vectormath::Aos::Vector3 ProjectOnAxis( const Vectormath::Aos::Vector3 &v, const Vectormath::Aos::Vector3 &a );
|
||||
|
||||
void ApplyClampedForce( float solverdt, const Vectormath::Aos::Vector3 &force, const Vectormath::Aos::Vector3 &vertexVelocity, float inverseMass, Vectormath::Aos::Vector3 &vertexForce );
|
||||
|
||||
btAcceleratedSoftBodyInterface *findSoftBodyInterface( const btSoftBody* const softBody );
|
||||
|
||||
virtual void applyForces( float solverdt );
|
||||
|
||||
/**
|
||||
* Integrate motion on the solver.
|
||||
*/
|
||||
virtual void integrate( float solverdt );
|
||||
|
||||
void updateConstants( float timeStep );
|
||||
|
||||
float computeTriangleArea(
|
||||
const Vectormath::Aos::Point3 &vertex0,
|
||||
const Vectormath::Aos::Point3 &vertex1,
|
||||
const Vectormath::Aos::Point3 &vertex2 );
|
||||
|
||||
|
||||
//////////////////////////////////////
|
||||
// Kernel dispatches
|
||||
void prepareLinks();
|
||||
|
||||
void solveLinksForVelocity( int startLink, int numLinks, float kst );
|
||||
|
||||
void updatePositionsFromVelocities( float solverdt );
|
||||
|
||||
void solveLinksForPosition( int startLink, int numLinks, float kst, float ti );
|
||||
|
||||
void updateVelocitiesFromPositionsWithVelocities( float isolverdt );
|
||||
|
||||
void updateVelocitiesFromPositionsWithoutVelocities( float isolverdt );
|
||||
|
||||
// End kernel dispatches
|
||||
/////////////////////////////////////
|
||||
|
||||
|
||||
public:
|
||||
btOpenCLSoftBodySolver(const cl::CommandQueue &queue);
|
||||
|
||||
virtual ~btOpenCLSoftBodySolver();
|
||||
|
||||
|
||||
|
||||
|
||||
virtual btSoftBodyLinkData &getLinkData();
|
||||
|
||||
virtual btSoftBodyVertexData &getVertexData();
|
||||
|
||||
virtual btSoftBodyTriangleData &getTriangleData();
|
||||
|
||||
|
||||
|
||||
|
||||
virtual bool checkInitialized();
|
||||
|
||||
virtual void updateSoftBodies( );
|
||||
|
||||
virtual void optimize( btAlignedObjectArray< btSoftBody * > &softBodies );
|
||||
|
||||
virtual void solveConstraints( float solverdt );
|
||||
|
||||
virtual void predictMotion( float solverdt );
|
||||
|
||||
virtual void copySoftBodyToVertexBuffer( const btSoftBody *const softBody, btVertexBufferDescriptor *vertexBuffer );
|
||||
}; // btOpenCLSoftBodySolver
|
||||
|
||||
#endif #ifndef BT_SOFT_BODY_SOLVER_OPENCL_H
|
||||
Reference in New Issue
Block a user