diff options
| author | git perforce import user <a@b> | 2016-10-25 12:29:14 -0600 |
|---|---|---|
| committer | Sheikh Dawood Abdul Ajees <Sheikh Dawood Abdul Ajees> | 2016-10-25 18:56:37 -0500 |
| commit | 3dfe2108cfab31ba3ee5527e217d0d8e99a51162 (patch) | |
| tree | fa6485c169e50d7415a651bf838f5bcd0fd3bfbd /APEX_1.4/samples_v2/SampleBase | |
| download | physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.tar.xz physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.zip | |
Initial commit:
PhysX 3.4.0 Update @ 21294896
APEX 1.4.0 Update @ 21275617
[CL 21300167]
Diffstat (limited to 'APEX_1.4/samples_v2/SampleBase')
29 files changed, 5124 insertions, 0 deletions
diff --git a/APEX_1.4/samples_v2/SampleBase/ApexController.cpp b/APEX_1.4/samples_v2/SampleBase/ApexController.cpp new file mode 100644 index 00000000..d8c7eb67 --- /dev/null +++ b/APEX_1.4/samples_v2/SampleBase/ApexController.cpp @@ -0,0 +1,577 @@ +/* + * Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. + * + * NVIDIA CORPORATION and its licensors retain all intellectual property + * and proprietary rights in and to this software, related documentation + * and any modifications thereto. Any use, reproduction, disclosure or + * distribution of this software and related documentation without an express + * license agreement from NVIDIA CORPORATION is strictly prohibited. + */ + +#include "ApexController.h" +#include "ApexRenderResourceManager.h" +#include "ApexResourceCallback.h" +#include "ApexRenderer.h" +#include "ApexRenderMaterial.h" +#include "PhysXPrimitive.h" +#include "legacy/ModuleIofxLegacy.h" + +#include "XInput.h" +#include "DXUTMisc.h" +#include "DXUTCamera.h" + +#define PVD_TO_FILE 0 + +#define USE_GPU_RB_SIMULATION 1 + +const DirectX::XMFLOAT3 PLANE_COLOR(0.25f, 0.25f, 0.25f); + +ApexController::ApexController(PxSimulationFilterShader filterShader, CFirstPersonCamera* camera) +: mCamera(camera) +, mApexRenderDebug(NULL) +, mFilterShader(filterShader) +, mLastSimulationTime(0) +, mPaused(false) +{ + QueryPerformanceFrequency(&mPerformanceFreq); +} + +ApexController::~ApexController() +{ +} + +void ApexController::onInitialize() +{ + initPhysX(); + initApex(); + initPhysXPrimitives(); +} + +void ApexController::onTerminate() +{ + releaseApex(); + releasePhysX(); + releasePhysXPrimitives(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// PhysX init/release +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + +void ApexController::initPhysX() +{ + mFoundation = PxCreateFoundation(PX_FOUNDATION_VERSION, mAllocator, mErrorCallback); + + mPvd = PxCreatePvd(*mFoundation); + + PxTolerancesScale scale; + + mPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *mFoundation, scale, true, mPvd); + + PxCookingParams cookingParams(scale); +#if USE_GPU_RB_SIMULATION + cookingParams.buildGPUData = true; +#endif + mCooking = PxCreateCooking(PX_PHYSICS_VERSION, mPhysics->getFoundation(), cookingParams); + + PxSceneDesc sceneDesc(mPhysics->getTolerancesScale()); + sceneDesc.gravity = PxVec3(0.0f, -9.81f, 0.0f); + mDispatcher = PxDefaultCpuDispatcherCreate(2); + sceneDesc.cpuDispatcher = mDispatcher; + sceneDesc.filterShader = mFilterShader; + sceneDesc.flags |= PxSceneFlag::eENABLE_STABILIZATION; + sceneDesc.flags |= PxSceneFlag::eENABLE_PCM; + +#if APEX_CUDA_SUPPORT + PxCudaContextManagerDesc ctxMgrDesc; + mCudaContext = CreateCudaContextManager(ctxMgrDesc, mErrorCallback); + if (mCudaContext && !mCudaContext->contextIsValid()) + { + mCudaContext->release(); + mCudaContext = NULL; + } + sceneDesc.gpuDispatcher = mCudaContext != NULL ? mCudaContext->getGpuDispatcher() : NULL; +#if USE_GPU_RB_SIMULATION + sceneDesc.flags |= PxSceneFlag::eENABLE_GPU_DYNAMICS; + sceneDesc.broadPhaseType = PxBroadPhaseType::eGPU; +#endif +#endif + mPhysicsScene = mPhysics->createScene(sceneDesc); + + mDefaultMaterial = mPhysics->createMaterial(0.8f, 0.7f, 0.1f); + + PxPvdSceneClient* pvdClient = mPhysicsScene->getScenePvdClient(); + if(pvdClient) + { + pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONSTRAINTS, true); + pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONTACTS, true); + pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_SCENEQUERIES, true); + } + + mPhysicsScene->setVisualizationParameter(PxVisualizationParameter::eSCALE, 1); +} + +void ApexController::releasePhysX() +{ + mDefaultMaterial->release(); + mPhysicsScene->release(); +#if APEX_CUDA_SUPPORT + if (mCudaContext) + mCudaContext->release(); +#endif + mDispatcher->release(); + mPhysics->release(); + PxPvdTransport* transport = mPvd->getTransport(); + mPvd->release(); + transport->release(); + mCooking->release(); + mFoundation->release(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// APEX SDK init/release +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void ApexController::initApex() +{ + // Fill out the Apex SDKriptor + ApexSDKDesc apexDesc; + + // Apex needs an allocator and error stream. By default it uses those of the PhysX SDK. + + // Let Apex know about our PhysX SDK and cooking library + apexDesc.physXSDK = mPhysics; + apexDesc.cooking = mCooking; + apexDesc.pvd = mPvd; + + // Our custom dummy render resource manager + mApexRenderResourceManager = new ApexRenderResourceManager(GetDeviceManager()->GetDevice()); + apexDesc.renderResourceManager = mApexRenderResourceManager; + + // Our custom named resource handler + mApexResourceCallback = new ApexResourceCallback(); + apexDesc.resourceCallback = mApexResourceCallback; + apexDesc.foundation = mFoundation; + + // Finally, create the Apex SDK + ApexCreateError error; + mApexSDK = CreateApexSDK(apexDesc, &error); + PX_ASSERT(mApexSDK); + + // Initialize destructible module + mModuleDestructible = static_cast<ModuleDestructible*>(mApexSDK->createModule("Destructible")); + NvParameterized::Interface* params = mModuleDestructible->getDefaultModuleDesc(); + mModuleDestructible->init(*params); + + // Initialize particles module + mModuleParticles = static_cast<ModuleParticles*>(mApexSDK->createModule("Particles")); + mModuleParticles->init(*mModuleParticles->getDefaultModuleDesc()); + mModuleLegacy = mApexSDK->createModule("Legacy"); + mModuleTurbulenceFS = mApexSDK->createModule("TurbulenceFS"); + mModuleIofx = static_cast<ModuleIofx*>(mModuleParticles->getModule("IOFX")); + + // Initialize clothing module + mModuleClothing = static_cast<ModuleClothing*>(mApexSDK->createModule("Clothing")); + mModuleClothing->init(*mModuleClothing->getDefaultModuleDesc()); + + mApexResourceCallback->setApexSDK(mApexSDK); + mApexResourceCallback->setModuleParticles(mModuleParticles); + + // render debug + PX_ASSERT(mApexRenderDebug == NULL); + mApexRenderDebug = mApexSDK->createApexRenderDebug(mRenderDebugInterface, false); + + // Create Apex scene + SceneDesc sceneDesc; + sceneDesc.scene = mPhysicsScene; + sceneDesc.debugInterface = mApexRenderDebug; + mApexScene = mApexSDK->createScene(sceneDesc); + mApexScene->allocViewMatrix(ViewMatrixType::LOOK_AT_LH); + mApexScene->allocProjMatrix(ProjMatrixType::USER_CUSTOMIZED); + + // IofxLegacy render callback + ModuleIofxLegacy* iofxLegacyModule = static_cast<ModuleIofxLegacy*>(mApexSDK->createModule("IOFX_Legacy")); + if (iofxLegacyModule) + { + IofxRenderCallback* iofxLegacyRCB = iofxLegacyModule->getIofxLegacyRenderCallback(*mApexScene); + mModuleIofx->setIofxRenderCallback(*mApexScene, iofxLegacyRCB); + } + + // render volume + nvidia::PxBounds3 infBounds; + infBounds.setMaximal(); + mRenderVolume = mModuleIofx->createRenderVolume(*mApexScene, infBounds, 0, true); + + // connect pvd +#if PVD_TO_FILE + PxPvdTransport* transport = PxDefaultPvdFileTransportCreate("d:\\snippet.pxd2"); +#else + PxPvdTransport* transport = PxDefaultPvdSocketTransportCreate("127.0.0.1", 5425, 10); +#endif + if (transport) + mPvd->connect(*transport, PxPvdInstrumentationFlag::eALL); +} + +void ApexController::releaseApex() +{ + if (mRenderVolume) + { + mModuleIofx->releaseRenderVolume(*mRenderVolume); + mRenderVolume = NULL; + } + + for (std::map<DestructibleActor*, DestructibleRenderable*>::iterator it = mDestructibleActors.begin(); it != mDestructibleActors.end(); + it++) + { + (*it).first->release(); + (*it).second->release(); + } + mDestructibleActors.clear(); + + for (std::set<ClothingActor*>::iterator it = mClothingActors.begin(); it != mClothingActors.end(); + it++) + { + (*it)->release(); + } + mClothingActors.clear(); + + + for (std::set<EffectPackageActor*>::iterator it = mEffectPackageActors.begin(); it != mEffectPackageActors.end(); it++) + { + (*it)->release(); + } + mEffectPackageActors.clear(); + + for(std::set<Asset*>::iterator it = mAssets.begin(); it != mAssets.end(); it++) + { + (*it)->release(); + } + mAssets.clear(); + + if (mApexRenderDebug) + { + mApexSDK->releaseApexRenderDebug(*mApexRenderDebug); + } + + mApexScene->release(); + mApexSDK->release(); + + delete mApexRenderResourceManager; + delete mApexResourceCallback; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Controller events +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void ApexController::Animate(double dt) +{ + if (mPaused) + return; + + // slower physics if fps is too low + dt = PxClamp(dt, 0.001, 0.33); + + LARGE_INTEGER time0; + QueryPerformanceCounter(&time0); + + + mApexScene->setViewMatrix(XMMATRIXToPxMat44(mCamera->GetViewMatrix())); + mApexScene->setProjMatrix(XMMATRIXToPxMat44(mCamera->GetProjMatrix())); + mApexScene->simulate(dt); + PxU32 errorState; + mApexScene->fetchResults(true, &errorState); + + LARGE_INTEGER time1; + QueryPerformanceCounter(&time1); + mLastSimulationTime = static_cast<float>(time1.QuadPart - time0.QuadPart) / static_cast<float>(mPerformanceFreq.QuadPart); + + if (mApexRenderDebug != NULL) + { + const physx::PxRenderBuffer & renderBuffer = mPhysicsScene->getRenderBuffer(); + mApexRenderDebug->addDebugRenderable(renderBuffer); + } + + mModuleIofx->prepareRenderables(*mApexScene); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Destructible actor spawn/remove +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +DestructibleActor* ApexController::spawnDestructibleActor(const char* assetPath) +{ + Asset* asset = static_cast<Asset*>( + mApexSDK->getNamedResourceProvider()->getResource(DESTRUCTIBLE_AUTHORING_TYPE_NAME, assetPath)); + + DestructibleAsset* destructibleAsset = static_cast<DestructibleAsset*>(asset); + + NvParameterized::Interface* actorDesc = destructibleAsset->getDefaultActorDesc(); + + nvidia::PxMat44 globalPose = nvidia::PxMat44(nvidia::PxIdentity); + PxBounds3 b = destructibleAsset->getRenderMeshAsset()->getBounds(); + globalPose.setPosition(PxVec3(0, -destructibleAsset->getRenderMeshAsset()->getBounds().minimum.z, 0)); + globalPose.column1 = nvidia::PxVec4(0.0f, 0.0f, -1.0f, 0.0f); + globalPose.column2 = nvidia::PxVec4(0.0f, 1.0f, 0.0f, 0.0f); + + NvParameterized::setParamTransform(*actorDesc, "globalPose", nvidia::PxTransform(globalPose)); + + NvParameterized::setParamBool(*actorDesc, "dynamic", false); + NvParameterized::setParamBool(*actorDesc, "formExtendedStructures", true); + NvParameterized::setParamF32(*actorDesc, "supportStrength", 1.9f); + + NvParameterized::setParamF32(*actorDesc, "defaultBehaviorGroup.damageThreshold", 5.0f); + NvParameterized::setParamI32(*actorDesc, "destructibleParameters.impactDamageDefaultDepth", 2); + NvParameterized::setParamBool(*actorDesc, "structureSettings.useStressSolver", true); + + DestructibleActor* actor = + static_cast<DestructibleActor*>(destructibleAsset->createApexActor(*actorDesc, *mApexScene)); + + while (asset->forceLoadAssets() > 0) {} + + mDestructibleActors[actor] = actor->acquireRenderableReference(); + mAssets.emplace(destructibleAsset); + + return actor; +} + +void ApexController::removeActor(DestructibleActor* actor) +{ + if (mDestructibleActors.find(actor) == mDestructibleActors.end()) + return; + + mDestructibleActors.at(actor)->release(); + actor->release(); + mDestructibleActors.erase(actor); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Clothing actor spawn/remove +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +ClothingActor* ApexController::spawnClothingActor(const char* assetPath) +{ + Asset* asset = static_cast<Asset*>( + mApexSDK->getNamedResourceProvider()->getResource(CLOTHING_AUTHORING_TYPE_NAME, assetPath)); + + ClothingAsset* clothingAsset = static_cast<ClothingAsset*>(asset); + + NvParameterized::Interface* actorDesc = clothingAsset->getDefaultActorDesc(); + + //NvParameterized::setParamF32(*actorDesc, "actorScale", 0.1f); + + ClothingActor* actor = + static_cast<ClothingActor*>(clothingAsset->createApexActor(*actorDesc, *mApexScene)); + + while (asset->forceLoadAssets() > 0) {} + + mClothingActors.emplace(actor); + mAssets.emplace(clothingAsset); + + return actor; +} + +void ApexController::removeActor(ClothingActor* actor) +{ + if (mClothingActors.find(actor) == mClothingActors.end()) + return; + + actor->release(); + mClothingActors.erase(actor); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Effect package actor spawn/remove +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +EffectPackageActor* ApexController::spawnEffectPackageActor(const char* assetPath) +{ + + PxTransform globalPose = PxTransform(nvidia::PxIdentity); + globalPose.p = PxVec3(0, 10, 0); + + nvidia::apex::Asset *asset = (nvidia::apex::Asset *)mApexSDK->getNamedResourceProvider()->getResource(PARTICLES_EFFECT_PACKAGE_AUTHORING_TYPE_NAME, assetPath); + NvParameterized::Interface *defaultActorDesc = asset->getDefaultActorDesc(); + NvParameterized::setParamTransform(*defaultActorDesc, "InitialPose", globalPose); + nvidia::apex::Actor *effectPackageActor = asset->createApexActor(*defaultActorDesc, *mApexScene); + EffectPackageActor* actor = static_cast<EffectPackageActor *>(effectPackageActor); + + while (asset->forceLoadAssets() > 0) {} + + mEffectPackageActors.emplace(actor); + mAssets.emplace(asset); + + return actor; +} + +void ApexController::removeActor(EffectPackageActor* actor) +{ + if (mEffectPackageActors.find(actor) == mEffectPackageActors.end()) + return; + + actor->release(); + mEffectPackageActors.erase(actor); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// PhysX Primitive +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void ApexController::initPhysXPrimitives() +{ + // create plane + PhysXPrimitive* plane = spawnPhysXPrimitivePlane(nvidia::PxPlane(PxVec3(0, 1, 0).getNormalized(), 0)); + plane->setColor(PLANE_COLOR); +} + +void ApexController::releasePhysXPrimitives() +{ + for(std::set<PhysXPrimitive*>::iterator it = mPrimitives.begin(); it != mPrimitives.end(); it++) + { + delete (*it); + } + mPrimitives.clear(); +} + +PhysXPrimitive* ApexController::spawnPhysXPrimitiveBox(const nvidia::PxTransform& position, float density) +{ + PxBoxGeometry geom = PxBoxGeometry(PxVec3(1, 1, 1)); + PxRigidDynamic* actor = PxCreateDynamic(*mPhysics, position, geom, *mDefaultMaterial, density); + + return spawnPhysXPrimitive(actor, PxVec3(1, 1, 1)); +} + +PhysXPrimitive* ApexController::spawnPhysXPrimitivePlane(const nvidia::PxPlane& plane) +{ + PxRigidStatic* actor = PxCreatePlane(*mPhysics, plane, *mDefaultMaterial); + return spawnPhysXPrimitive(actor, PxVec3(500)); +} + +PhysXPrimitive* ApexController::spawnPhysXPrimitive(PxRigidActor* actor, PxVec3 scale) +{ + mPhysicsScene->addActor(*actor); + + PhysXPrimitive* p = new PhysXPrimitive(actor, scale); + + mPrimitives.emplace(p); + + return p; +} + +void ApexController::removePhysXPrimitive(PhysXPrimitive* primitive) +{ + if(mPrimitives.find(primitive) == mPrimitives.end()) + return; + + mPrimitives.erase(primitive); + delete primitive; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Render +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void ApexController::renderOpaque(ApexRenderer* renderer) +{ + for (std::map<DestructibleActor*, DestructibleRenderable*>::iterator it = mDestructibleActors.begin(); it != mDestructibleActors.end(); + it++) + { + (*it).first->lockRenderResources(); + (*it).first->updateRenderResources(false); + (*it).first->dispatchRenderResources(*renderer); + (*it).first->unlockRenderResources(); + + (*it).second->lockRenderResources(); + (*it).second->updateRenderResources(false); + (*it).second->dispatchRenderResources(*renderer); + (*it).second->unlockRenderResources(); + } + + for (std::set<ClothingActor*>::iterator it = mClothingActors.begin(); it != mClothingActors.end(); + it++) + { + (*it)->lockRenderResources(); + (*it)->updateRenderResources(false); + (*it)->dispatchRenderResources(*renderer); + (*it)->unlockRenderResources(); + } + + mApexScene->lockRenderResources(); + mApexScene->updateRenderResources(false); + mApexScene->dispatchRenderResources(*renderer); + mApexScene->unlockRenderResources(); + + renderParticles(renderer, IofxRenderable::MESH); + + for (std::set<PhysXPrimitive*>::iterator it = mPrimitives.begin(); it != mPrimitives.end(); it++) + { + renderer->renderResource(*it); + } + + mApexRenderDebug->lockRenderResources(); + mApexRenderDebug->updateRenderResources(0); + mApexRenderDebug->dispatchRenderResources(*renderer); + mApexRenderDebug->unlockRenderResources(); +} + +void ApexController::renderTransparency(ApexRenderer* renderer) +{ + renderParticles(renderer, IofxRenderable::SPRITE); +} + +void ApexController::renderParticles(ApexRenderer* renderer, IofxRenderable::Type type) +{ + uint32_t numActors; + IofxActor* const* actors = mRenderVolume->lockIofxActorList(numActors); + for (uint32_t j = 0; j < numActors; j++) + { + IofxRenderable* iofxRenderable = actors[j]->acquireRenderableReference(); + if (iofxRenderable) + { + if (iofxRenderable->getType() == type) + { + Renderable* apexRenderable = static_cast<Renderable*>(iofxRenderable->userData); + if (apexRenderable && !apexRenderable->getBounds().isEmpty()) + { + apexRenderable->lockRenderResources(); + apexRenderable->updateRenderResources(false); + apexRenderable->dispatchRenderResources(*renderer); + apexRenderable->unlockRenderResources(); + } + } + iofxRenderable->release(); + } + } + mRenderVolume->unlockIofxActorList(); +} + + +PxVec3 unproject(PxMat44& proj, PxMat44& view, float x, float y) +{ + PxVec4 screenPoint(x, y, 0, 1); + PxVec4 viewPoint = PxVec4(x / proj[0][0], y / proj[1][1], 1, 1); + PxVec4 nearPoint = view.inverseRT().transform(viewPoint); + if (nearPoint.w) + nearPoint *= 1.0f / nearPoint.w; + return PxVec3(nearPoint.x, nearPoint.y, nearPoint.z); +} + + +void ApexController::getEyePoseAndPickDir(float mouseX, float mouseY, PxVec3& eyePos, PxVec3& pickDir) +{ + PxMat44 view = XMMATRIXToPxMat44(mCamera->GetViewMatrix()); + PxMat44 proj = XMMATRIXToPxMat44(mCamera->GetProjMatrix()); + + PxMat44 eyeTransform = view.inverseRT(); + eyePos = eyeTransform.getPosition(); + PxVec3 nearPos = unproject(proj, view, mouseX * 2 - 1, 1 - mouseY * 2); + pickDir = nearPos - eyePos; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/APEX_1.4/samples_v2/SampleBase/ApexController.h b/APEX_1.4/samples_v2/SampleBase/ApexController.h new file mode 100644 index 00000000..15ecaf64 --- /dev/null +++ b/APEX_1.4/samples_v2/SampleBase/ApexController.h @@ -0,0 +1,192 @@ +/* +* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. +* +* NVIDIA CORPORATION and its licensors retain all intellectual property +* and proprietary rights in and to this software, related documentation +* and any modifications thereto. Any use, reproduction, disclosure or +* distribution of this software and related documentation without an express +* license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#ifndef APEX_CONTROLLER_H +#define APEX_CONTROLLER_H + +#include "SampleManager.h" +#include <DirectXMath.h> + +#include "ApexCudaContextManager.h" +#include "ModuleClothing.h" +#include "ClothingActor.h" +#include "ClothingAsset.h" +#include "ClothingRenderProxy.h" +#include "DestructibleAsset.h" +#include "DestructibleActor.h" +#include "DestructibleRenderable.h" +#include "ModuleParticles.h" +#include "ModuleIofx.h" +#include "IofxActor.h" +#include "RenderVolume.h" +#include "EffectPackageActor.h" +#include "EffectPackageAsset.h" +#include "nvparameterized/NvParameterized.h" +#include "nvparameterized/NvParamUtils.h" +#include "PxPhysicsAPI.h" +#include "Apex.h" +#include "PxMat44.h" + +#pragma warning(push) +#pragma warning(disable : 4350) +#include <set> +#include <map> +#pragma warning(pop) + +using namespace physx; +using namespace nvidia; +using namespace nvidia::apex; + +class ApexRenderResourceManager; +class ApexResourceCallback; +class CFirstPersonCamera; +class PhysXPrimitive; +class ApexRenderer; + +class ApexController : public ISampleController +{ + public: + ApexController(PxSimulationFilterShader filterShader, CFirstPersonCamera* camera); + virtual ~ApexController(); + + virtual void onInitialize(); + virtual void onTerminate(); + + virtual void Animate(double dt); + + void renderOpaque(ApexRenderer* renderer); + void renderTransparency(ApexRenderer* renderer); + + void getEyePoseAndPickDir(float mouseX, float mouseY, PxVec3& eyePos, PxVec3& pickDir); + + DestructibleActor* spawnDestructibleActor(const char* assetPath); + void removeActor(DestructibleActor* actor); + + ClothingActor* spawnClothingActor(const char* assetPath); + void removeActor(ClothingActor* actor); + + EffectPackageActor* spawnEffectPackageActor(const char* assetPath); + void removeActor(EffectPackageActor* actor); + + PhysXPrimitive* spawnPhysXPrimitiveBox(const nvidia::PxTransform& position, float density = 2000.0f); + PhysXPrimitive* spawnPhysXPrimitivePlane(const nvidia::PxPlane& plane); + void removePhysXPrimitive(PhysXPrimitive*); + + + void setRenderDebugInterface(RENDER_DEBUG::RenderDebugInterface* iFace) + { + mRenderDebugInterface = iFace; + } + + + ApexResourceCallback* getResourceCallback() + { + return mApexResourceCallback; + }; + + ResourceProvider* getResourceProvider() + { + return mApexSDK->getNamedResourceProvider(); + } + + ModuleDestructible* getModuleDestructible() + { + return mModuleDestructible; + } + + ModuleParticles* getModuleParticles() + { + return mModuleParticles; + } + + ApexSDK* getApexSDK() + { + return mApexSDK; + } + + Scene* getApexScene() + { + return mApexScene; + } + + float getLastSimulationTime() + { + return mLastSimulationTime; + } + + void togglePlayPause() + { + mPaused = !mPaused; + } + + private: + void initPhysX(); + void releasePhysX(); + + void initApex(); + void releaseApex(); + + void initPhysXPrimitives(); + void releasePhysXPrimitives(); + + void renderParticles(ApexRenderer* renderer, IofxRenderable::Type type); + + PhysXPrimitive* spawnPhysXPrimitive(PxRigidActor* position, PxVec3 scale); + + PxSimulationFilterShader mFilterShader; +#if APEX_CUDA_SUPPORT + PxCudaContextManager* mCudaContext; +#endif + ApexSDK* mApexSDK; + ApexRenderResourceManager* mApexRenderResourceManager; + ApexResourceCallback* mApexResourceCallback; + + ModuleDestructible* mModuleDestructible; + ModuleParticles* mModuleParticles; + ModuleIofx* mModuleIofx; + Module* mModuleTurbulenceFS; + Module* mModuleLegacy; + ModuleClothing* mModuleClothing; + RenderVolume* mRenderVolume; + + Scene* mApexScene; + + PxDefaultAllocator mAllocator; + PxDefaultErrorCallback mErrorCallback; + + PxFoundation* mFoundation; + PxPhysics* mPhysics; + PxCooking* mCooking; + + PxDefaultCpuDispatcher* mDispatcher; + PxScene* mPhysicsScene; + + PxMaterial* mDefaultMaterial; + + PxPvd* mPvd; + + RenderDebugInterface* mApexRenderDebug; + RENDER_DEBUG::RenderDebugInterface* mRenderDebugInterface; + + std::set<Asset*> mAssets; + std::map<DestructibleActor*, DestructibleRenderable*> mDestructibleActors; + std::set<ClothingActor*> mClothingActors; + std::set<EffectPackageActor*> mEffectPackageActors; + std::set<PhysXPrimitive*> mPrimitives; + + CFirstPersonCamera* mCamera; + + float mLastSimulationTime; + LARGE_INTEGER mPerformanceFreq; + + bool mPaused; +}; + +#endif diff --git a/APEX_1.4/samples_v2/SampleBase/ApexRenderMaterial.cpp b/APEX_1.4/samples_v2/SampleBase/ApexRenderMaterial.cpp new file mode 100644 index 00000000..9e6eaa2d --- /dev/null +++ b/APEX_1.4/samples_v2/SampleBase/ApexRenderMaterial.cpp @@ -0,0 +1,288 @@ +/* +* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. +* +* NVIDIA CORPORATION and its licensors retain all intellectual property +* and proprietary rights in and to this software, related documentation +* and any modifications thereto. Any use, reproduction, disclosure or +* distribution of this software and related documentation without an express +* license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#include "ApexRenderMaterial.h" +#include <DirectXMath.h> +#include "ApexResourceCallback.h" +#include "Utils.h" +#include "PsFastXml.h" + +#include "PsFileBuffer.h" +#include "PxInputDataFromPxFileBuf.h" +#include "nvparameterized/NvParamUtils.h" + + +const char* DEFAULT_SPRITE_PARTICLE_SHADER = "pointsprite.hlsl"; +const char* DEFAULT_MESH_PARTICLE_SHADER = "pointsprite.hlsl"; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Material .xml files parser +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class MaterialXmlParser : public nvidia::shdfnd::FastXml::Callback +{ +public: + MaterialXmlParser() : + blendMode(ApexRenderMaterial::BLEND_NONE) + { + } + virtual ~MaterialXmlParser() + { + } + + string textureFile; + vector<string> shaderFiles; + ApexRenderMaterial::BlendMode blendMode; + +protected: + // encountered a comment in the XML + virtual bool processComment(const char* /*comment*/) + { + return true; + } + + virtual bool processClose(const char* /*element*/, unsigned int /*depth*/, bool& /*isError*/) + { + return true; + } + + // return true to continue processing the XML document, false to skip. + virtual bool processElement(const char* elementName, // name of the element + const char* elementData, // element data, null if none + const nvidia::shdfnd::FastXml::AttributePairs& attr, + int /*lineno*/) // line number in the source XML file + { + PX_UNUSED(attr); + if (::strcmp(elementName, "texture") == 0) + { + textureFile = elementData; + } + else if (::strcmp(elementName, "shader") == 0) + { + shaderFiles.push_back(elementData); + } + else if (::strcmp(elementName, "blending") == 0) + { + blendMode = (::stricmp(elementData, "additive") == 0) ? ApexRenderMaterial::BLEND_ADDITIVE : + ApexRenderMaterial::BLEND_ALPHA_BLENDING; + } + + return true; + } +}; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// ApexRenderMaterial +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +ApexRenderMaterial::ApexRenderMaterial(ApexResourceCallback* resourceProvider, const char* xmlFilePath) +{ + PsFileBuffer theBuffer(xmlFilePath, nvidia::general_PxIOStream2::PxFileBuf::OPEN_READ_ONLY); + PxInputDataFromPxFileBuf id(theBuffer); + MaterialXmlParser parser; + nvidia::shdfnd::FastXml* xml = nvidia::shdfnd::createFastXml(&parser); + xml->processXml(id, false); + + this->initialize(resourceProvider, parser.shaderFiles, parser.textureFile.c_str(), parser.blendMode); + + xml->release(); +} + +ApexRenderMaterial::ApexRenderMaterial(ApexResourceCallback* resourceCallback, const NvParameterized::Interface *graphicMaterialData) +{ + const char* textureFileName = NULL; + NvParameterized::getParamString(*graphicMaterialData, "DiffuseTexture", textureFileName); + + BlendMode blendMode = BLEND_NONE; + + const char *technique = "SPRITE_ONE"; + NvParameterized::getParamEnum(*graphicMaterialData, "RenderTechnique", technique); + if (technique) + { + if (::strcmp(technique, "SPRITE_ONE") == 0) + { + blendMode = BLEND_ADDITIVE; + } + else if (::strcmp(technique, "SPRITE_ALPHA") == 0) + { + blendMode = BLEND_ALPHA_BLENDING; + } + } + + this->initialize(resourceCallback, blendMode == BLEND_NONE ? DEFAULT_MESH_PARTICLE_SHADER : DEFAULT_SPRITE_PARTICLE_SHADER, textureFileName, blendMode); +} + +ApexRenderMaterial::ApexRenderMaterial(ApexResourceCallback* resourceCallback, const char* shaderFileName, + const char* textureFileName, BlendMode blendMode) +{ + this->initialize(resourceCallback, shaderFileName, textureFileName, blendMode); +} + +void ApexRenderMaterial::initialize(ApexResourceCallback* resourceCallback, const char* shaderFileName, const char* textureFileName, BlendMode blendMode) +{ + vector<string> v; + v.push_back(shaderFileName); + initialize(resourceCallback, v, textureFileName, blendMode); +} + +void ApexRenderMaterial::initialize(ApexResourceCallback* resourceCallback, vector<string> shaderFileNames, const char* textureFileName, BlendMode blendMode) +{ + mTextureSRV = nullptr; + mTexture = nullptr; + mBlendState = nullptr; + mTextureFileName = textureFileName; + + for (uint32_t i = 0; i < shaderFileNames.size(); i++) + { + string shaderFilePath = ((char*)resourceCallback->requestResourceCustom(ApexResourceCallback::eSHADER_FILE_PATH, shaderFileNames[i].c_str())); + mShaderFilePathes.push_back(shaderFilePath); + } + mShaderGroups.reserve(mShaderFilePathes.size()); + + if (!mTextureFileName.empty()) + { + mTexture = + (TextureResource*)resourceCallback->requestResourceCustom(ApexResourceCallback::eTEXTURE_RESOURCE, mTextureFileName.c_str()); + } + + setBlending(blendMode); + + reload(); +} + +void ApexRenderMaterial::releaseReloadableResources() +{ + for (vector<ShaderGroup*>::iterator it = mShaderGroups.begin(); it != mShaderGroups.end(); it++) + { + delete *it; + } + mShaderGroups.clear(); + + SAFE_RELEASE(mTextureSRV); +} + +ApexRenderMaterial::~ApexRenderMaterial() +{ + releaseReloadableResources(); + SAFE_RELEASE(mBlendState); + + for (list<Instance*>::iterator it = mInstances.begin(); it != mInstances.end(); it++) + { + delete *it; + } + mInstances.clear(); +} + +void ApexRenderMaterial::setBlending(BlendMode blendMode) +{ + SAFE_RELEASE(mBlendState); + + D3D11_BLEND_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + + switch (blendMode) + { + case BLEND_NONE: + desc.RenderTarget[0].BlendEnable = FALSE; + desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; + break; + case BLEND_ALPHA_BLENDING: + desc.AlphaToCoverageEnable = FALSE; + desc.IndependentBlendEnable = TRUE; + desc.RenderTarget[0].BlendEnable = TRUE; + desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; + desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; + desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; + desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; + desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; + desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA; + desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; + break; + case BLEND_ADDITIVE: // actually, is's additive by alpha + desc.AlphaToCoverageEnable = FALSE; + desc.IndependentBlendEnable = TRUE; + desc.RenderTarget[0].BlendEnable = TRUE; + desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; + desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; + desc.RenderTarget[0].DestBlend = D3D11_BLEND_ONE; + desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ONE; + desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; + desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA; + desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; + break; + default: + PX_ALWAYS_ASSERT_MESSAGE("Unknown blend mode"); + } + + ID3D11Device* device = GetDeviceManager()->GetDevice(); + V(device->CreateBlendState(&desc, &mBlendState)); +} + +void ApexRenderMaterial::reload() +{ + releaseReloadableResources(); + + // load shaders + ID3D11Device* device = GetDeviceManager()->GetDevice(); + + for (vector<string>::iterator it = mShaderFilePathes.begin(); it != mShaderFilePathes.end(); it++) + { + const char* shaderFilePath = (*it).c_str(); + ShaderGroup* shaderGroup = new ShaderGroup(); + V(createShaderFromFile(device, shaderFilePath, "VS", &(shaderGroup->vs), shaderGroup->buffer)); + V(createShaderFromFile(device, shaderFilePath, "PS", &shaderGroup->ps)); + createShaderFromFile(device, shaderFilePath, "GS", &shaderGroup->gs); + mShaderGroups.push_back(shaderGroup); + } + + // load texture + if (mTexture) + { + V(DirectX::CreateShaderResourceView(device, mTexture->image.GetImages(), mTexture->image.GetImageCount(), + mTexture->metaData, &mTextureSRV)); + } +} + +ApexRenderMaterial::Instance* ApexRenderMaterial::getMaterialInstance(const D3D11_INPUT_ELEMENT_DESC* elementDescs, uint32_t numElements) +{ + ID3D11InputLayout* inputLayout = NULL; + ID3D11Device* device = GetDeviceManager()->GetDevice(); + + for (uint32_t i = 0; i < mShaderGroups.size(); i++) + { + if (mShaderGroups[i]->buffer == NULL) + continue; + + device->CreateInputLayout(elementDescs, numElements, mShaderGroups[i]->buffer->GetBufferPointer(), mShaderGroups[i]->buffer->GetBufferSize(), &inputLayout); + + if (inputLayout) + { + Instance* materialInstance = new Instance(*this, inputLayout, i); + mInstances.push_back(materialInstance); + return materialInstance; + } + } + PX_ALWAYS_ASSERT(); + return NULL; +} + +void ApexRenderMaterial::Instance::bind(ID3D11DeviceContext& context, uint32_t slot) +{ + mMaterial.mShaderGroups[mShaderNum]->Set(&context); + + context.OMSetBlendState(mMaterial.mBlendState, nullptr, 0xFFFFFFFF); + context.PSSetShaderResources(slot, 1, &(mMaterial.mTextureSRV)); + context.IASetInputLayout(mInputLayout); +} + +bool ApexRenderMaterial::Instance::isValid() +{ + return mMaterial.mShaderGroups.size() > 0 && mMaterial.mShaderGroups[mShaderNum]->IsValid(); +} diff --git a/APEX_1.4/samples_v2/SampleBase/ApexRenderMaterial.h b/APEX_1.4/samples_v2/SampleBase/ApexRenderMaterial.h new file mode 100644 index 00000000..77d86eb6 --- /dev/null +++ b/APEX_1.4/samples_v2/SampleBase/ApexRenderMaterial.h @@ -0,0 +1,123 @@ +/* +* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. +* +* NVIDIA CORPORATION and its licensors retain all intellectual property +* and proprietary rights in and to this software, related documentation +* and any modifications thereto. Any use, reproduction, disclosure or +* distribution of this software and related documentation without an express +* license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#ifndef APEX_RENDER_MATERIAL_H +#define APEX_RENDER_MATERIAL_H + +#include "Apex.h" +#include "Utils.h" +#include "DirectXTex.h" + +#pragma warning(push) +#pragma warning(disable : 4350) +#include <string> +#include <vector> +#include <list> +#pragma warning(pop) + +#pragma warning(disable : 4512) + +using namespace nvidia; +using namespace nvidia::apex; +using namespace std; + +class ApexResourceCallback; + +struct TextureResource +{ + DirectX::TexMetadata metaData; + DirectX::ScratchImage image; +}; + +class ApexRenderMaterial +{ + public: + + enum BlendMode + { + BLEND_NONE, + BLEND_ALPHA_BLENDING, + BLEND_ADDITIVE + }; + + ApexRenderMaterial(ApexResourceCallback* resourceProvider, const char* xmlFilePath); + ApexRenderMaterial(ApexResourceCallback* resourceProvider, const NvParameterized::Interface *graphicMaterialData); + ApexRenderMaterial(ApexResourceCallback* resourceProvider, const char* shaderFileName, const char* textureFileName, BlendMode blendMode = BLEND_NONE); + ~ApexRenderMaterial(); + + void setBlending(BlendMode blendMode); + void reload(); + + class Instance + { + public: + Instance(ApexRenderMaterial& material, ID3D11InputLayout* inputLayout, uint32_t shaderNum = 0) : mMaterial(material), mInputLayout(inputLayout), mShaderNum(shaderNum) {} + ~Instance() { SAFE_RELEASE(mInputLayout); } + + bool isValid(); + void bind(ID3D11DeviceContext& context, uint32_t slot); + private: + ApexRenderMaterial& mMaterial; + ID3D11InputLayout* mInputLayout; + uint32_t mShaderNum; + }; + + Instance* getMaterialInstance(const D3D11_INPUT_ELEMENT_DESC* elementDescs, uint32_t numElements); + + private: + void initialize(ApexResourceCallback* resourceCallback, const char* shaderFileName, const char* textureFileName, BlendMode blendMode); + void initialize(ApexResourceCallback* resourceProvider, vector<string> shaderFileNames, const char* textureFileName, BlendMode blendMode); + + void releaseReloadableResources(); + + string mShaderFileName; + string mTextureFileName; + + struct ShaderGroup + { + ShaderGroup() : vs(NULL), gs(NULL), ps(NULL) + { + } + ~ShaderGroup() + { + Release(); + } + void Release() + { + SAFE_RELEASE(vs); + SAFE_RELEASE(gs); + SAFE_RELEASE(ps); + SAFE_RELEASE(buffer); + } + void Set(ID3D11DeviceContext* c) + { + c->VSSetShader(vs, nullptr, 0); + c->GSSetShader(gs, nullptr, 0); + c->PSSetShader(ps, nullptr, 0); + } + bool IsValid() + { + return vs != NULL && ps != NULL; + } + ID3D11VertexShader* vs; + ID3D11GeometryShader* gs; + ID3D11PixelShader* ps; + ID3DBlob* buffer; + }; + + list<Instance*> mInstances; + TextureResource* mTexture; + ID3D11ShaderResourceView* mTextureSRV; + ID3D11BlendState* mBlendState; + vector<string> mShaderFilePathes; + vector<ShaderGroup*> mShaderGroups; +}; + +#endif
\ No newline at end of file diff --git a/APEX_1.4/samples_v2/SampleBase/ApexRenderResourceManager.cpp b/APEX_1.4/samples_v2/SampleBase/ApexRenderResourceManager.cpp new file mode 100644 index 00000000..c0856ed0 --- /dev/null +++ b/APEX_1.4/samples_v2/SampleBase/ApexRenderResourceManager.cpp @@ -0,0 +1,52 @@ +/* +* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. +* +* NVIDIA CORPORATION and its licensors retain all intellectual property +* and proprietary rights in and to this software, related documentation +* and any modifications thereto. Any use, reproduction, disclosure or +* distribution of this software and related documentation without an express +* license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#include "ApexRenderResourceManager.h" +#include "ApexRenderResources.h" + + +bool ApexRenderResourceManager::getInstanceLayoutData(uint32_t particleCount, + uint32_t particleSemanticsBitmap, + nvidia::apex::UserRenderInstanceBufferDesc* bufferDesc) +{ + PX_UNUSED(particleSemanticsBitmap); + using namespace nvidia::apex; + RenderDataFormat::Enum positionFormat = RenderInstanceLayoutElement::getSemanticFormat(RenderInstanceLayoutElement::POSITION_FLOAT3); + RenderDataFormat::Enum rotationFormat = RenderInstanceLayoutElement::getSemanticFormat(RenderInstanceLayoutElement::ROTATION_SCALE_FLOAT3x3); + const uint32_t positionElementSize = RenderDataFormat::getFormatDataSize(positionFormat); + const uint32_t rotationElementSize = RenderDataFormat::getFormatDataSize(rotationFormat); + bufferDesc->semanticOffsets[RenderInstanceLayoutElement::POSITION_FLOAT3] = 0; + bufferDesc->semanticOffsets[RenderInstanceLayoutElement::ROTATION_SCALE_FLOAT3x3] = positionElementSize; + uint32_t strideInBytes = positionElementSize + rotationElementSize;; + bufferDesc->stride = strideInBytes; + bufferDesc->maxInstances = particleCount; + return true; +} + +bool ApexRenderResourceManager::getSpriteLayoutData(uint32_t spriteCount, + uint32_t spriteSemanticsBitmap, + nvidia::apex::UserRenderSpriteBufferDesc* bufferDesc) +{ + PX_UNUSED(spriteSemanticsBitmap); + RenderDataFormat::Enum positionFormat = RenderSpriteLayoutElement::getSemanticFormat(RenderSpriteLayoutElement::POSITION_FLOAT3); + RenderDataFormat::Enum colorFormat = RenderSpriteLayoutElement::getSemanticFormat(RenderSpriteLayoutElement::COLOR_BGRA8); + RenderDataFormat::Enum scaleFormat = RenderSpriteLayoutElement::getSemanticFormat(RenderSpriteLayoutElement::SCALE_FLOAT2); + const uint32_t positionElementSize = RenderDataFormat::getFormatDataSize(positionFormat); + const uint32_t colorElementSize = RenderDataFormat::getFormatDataSize(colorFormat); + const uint32_t scaleElementSize = RenderDataFormat::getFormatDataSize(scaleFormat); + bufferDesc->semanticOffsets[RenderSpriteLayoutElement::POSITION_FLOAT3] = 0; + bufferDesc->semanticOffsets[RenderSpriteLayoutElement::COLOR_BGRA8] = positionElementSize; + bufferDesc->semanticOffsets[RenderSpriteLayoutElement::SCALE_FLOAT2] = positionElementSize + colorElementSize; + uint32_t strideInBytes = positionElementSize + colorElementSize + scaleElementSize; + bufferDesc->stride = strideInBytes; + bufferDesc->maxSprites = spriteCount; + bufferDesc->textureCount = 0; + return true; +}
\ No newline at end of file diff --git a/APEX_1.4/samples_v2/SampleBase/ApexRenderResourceManager.h b/APEX_1.4/samples_v2/SampleBase/ApexRenderResourceManager.h new file mode 100644 index 00000000..2d6da7b2 --- /dev/null +++ b/APEX_1.4/samples_v2/SampleBase/ApexRenderResourceManager.h @@ -0,0 +1,107 @@ +/* +* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. +* +* NVIDIA CORPORATION and its licensors retain all intellectual property +* and proprietary rights in and to this software, related documentation +* and any modifications thereto. Any use, reproduction, disclosure or +* distribution of this software and related documentation without an express +* license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#ifndef APEX_RENDER_RESOURCE_MANAGER_H +#define APEX_RENDER_RESOURCE_MANAGER_H + +#include "Apex.h" +#include "ApexRenderResources.h" + +#include "PsString.h" + +#pragma warning(push) +#pragma warning(disable : 4917) +#pragma warning(disable : 4365) +#include <d3d11.h> +#pragma warning(pop) + +using namespace nvidia::apex; + +class ApexRenderResourceManager : public UserRenderResourceManager +{ + public: + ApexRenderResourceManager(ID3D11Device* d) : mDevice(d) {} + + virtual UserRenderVertexBuffer* createVertexBuffer(const UserRenderVertexBufferDesc& desc) + { + return new SampleApexRendererVertexBuffer(*mDevice, desc); + } + virtual void releaseVertexBuffer(UserRenderVertexBuffer& buffer) + { + delete &buffer; + } + + virtual UserRenderIndexBuffer* createIndexBuffer(const UserRenderIndexBufferDesc& desc) + { + return new SampleApexRendererIndexBuffer(*mDevice, desc); + } + virtual void releaseIndexBuffer(UserRenderIndexBuffer& buffer) + { + delete &buffer; + } + + virtual UserRenderBoneBuffer* createBoneBuffer(const UserRenderBoneBufferDesc& desc) + { + return new SampleApexRendererBoneBuffer(*mDevice, desc); + } + virtual void releaseBoneBuffer(UserRenderBoneBuffer& buffer) + { + delete &buffer; + } + + virtual UserRenderInstanceBuffer* createInstanceBuffer(const UserRenderInstanceBufferDesc& desc) + { + return new SampleApexRendererInstanceBuffer(*mDevice, desc); + } + virtual void releaseInstanceBuffer(UserRenderInstanceBuffer& buffer) + { + delete &buffer; + } + + virtual UserRenderSpriteBuffer* createSpriteBuffer(const UserRenderSpriteBufferDesc& desc) + { + return new SampleApexRendererSpriteBuffer(*mDevice, desc); + } + virtual void releaseSpriteBuffer(UserRenderSpriteBuffer& buffer) + { + delete &buffer; + } + + virtual UserRenderSurfaceBuffer* createSurfaceBuffer(const UserRenderSurfaceBufferDesc&) + { + physx::shdfnd::printString("createSurfaceBuffer"); + return NULL; + } + virtual void releaseSurfaceBuffer(UserRenderSurfaceBuffer&) + { + } + + virtual UserRenderResource* createResource(const UserRenderResourceDesc& desc) + { + return new SampleApexRendererMesh(*mDevice, desc); + } + virtual void releaseResource(UserRenderResource& buffer) + { + delete &buffer; + } + + virtual uint32_t getMaxBonesForMaterial(void*) + { + return 0; + } + + virtual bool getSpriteLayoutData(uint32_t spriteCount, uint32_t spriteSemanticsBitmap, UserRenderSpriteBufferDesc* vertexDescArray); + virtual bool getInstanceLayoutData(uint32_t spriteCount, uint32_t particleSemanticsBitmap, UserRenderInstanceBufferDesc* instanceDescArray); + + private: + ID3D11Device* mDevice; +}; + +#endif
\ No newline at end of file diff --git a/APEX_1.4/samples_v2/SampleBase/ApexRenderResources.cpp b/APEX_1.4/samples_v2/SampleBase/ApexRenderResources.cpp new file mode 100644 index 00000000..dddd0279 --- /dev/null +++ b/APEX_1.4/samples_v2/SampleBase/ApexRenderResources.cpp @@ -0,0 +1,814 @@ +/* +* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. +* +* NVIDIA CORPORATION and its licensors retain all intellectual property +* and proprietary rights in and to this software, related documentation +* and any modifications thereto. Any use, reproduction, disclosure or +* distribution of this software and related documentation without an express +* license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#include "ApexRenderResources.h" + +#include "RenderDataFormat.h" +#include <sstream> + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Helper functions +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +static DXGI_FORMAT getD3DFormat(RenderDataFormat::Enum format) +{ + DXGI_FORMAT d3dFormat; + switch(format) + { + case RenderDataFormat::FLOAT1: + d3dFormat = DXGI_FORMAT_R32_FLOAT; + break; + case RenderDataFormat::FLOAT2: + d3dFormat = DXGI_FORMAT_R32G32_FLOAT; + break; + case RenderDataFormat::FLOAT3: + d3dFormat = DXGI_FORMAT_R32G32B32_FLOAT; + break; + case RenderDataFormat::FLOAT4: + d3dFormat = DXGI_FORMAT_R32G32B32A32_FLOAT; + break; + case RenderDataFormat::B8G8R8A8: + d3dFormat = DXGI_FORMAT_B8G8R8A8_UNORM; + break; + case RenderDataFormat::UINT1: + case RenderDataFormat::UBYTE4: + case RenderDataFormat::R8G8B8A8: + d3dFormat = DXGI_FORMAT_R8G8B8A8_UNORM; + break; + case RenderDataFormat::USHORT1: + d3dFormat = DXGI_FORMAT_R16_UINT; + break; + case RenderDataFormat::USHORT2: + d3dFormat = DXGI_FORMAT_R16G16_UINT; + break; + case RenderDataFormat::USHORT3: + case RenderDataFormat::USHORT4: + d3dFormat = DXGI_FORMAT_R16G16B16A16_UINT; + break; + default: + d3dFormat = DXGI_FORMAT_UNKNOWN; + } + PX_ASSERT((d3dFormat != DXGI_FORMAT_UNKNOWN) && "Invalid DIRECT3D11 vertex type."); + return d3dFormat; +} + +static void getD3DUsage(RenderVertexSemantic::Enum semantic, LPCSTR& usageName, uint8_t& usageIndex) +{ + usageIndex = 0; + if(semantic >= RenderVertexSemantic::TEXCOORD0 && semantic <= RenderVertexSemantic::TEXCOORD3) + { + usageName = "TEXCOORD"; + usageIndex = (uint8_t)(semantic - RenderVertexSemantic::TEXCOORD0); + } + else + { + switch(semantic) + { + case RenderVertexSemantic::POSITION: + usageName = "POSITION"; + break; + case RenderVertexSemantic::NORMAL: + usageName = "NORMAL"; + break; + case RenderVertexSemantic::TANGENT: + usageName = "TANGENT"; + break; + case RenderVertexSemantic::COLOR: + usageName = "COLOR"; + break; + case RenderVertexSemantic::BONE_INDEX: + usageName = "TEXCOORD"; + usageIndex = 5; + break; + case RenderVertexSemantic::BONE_WEIGHT: + usageName = "TEXCOORD"; + usageIndex = 6; + break; + case RenderVertexSemantic::DISPLACEMENT_TEXCOORD: + usageName = "TEXCOORD"; + usageIndex = 7; + break; + case RenderVertexSemantic::DISPLACEMENT_FLAGS: + usageName = "TEXCOORD"; + usageIndex = 8; + break; + default: + usageName = "POSITION"; + } + } +} + +static void getD3DUsage(RenderSpriteSemantic::Enum semantic, LPCSTR& usageName, uint8_t& usageIndex) +{ + usageIndex = 0; + switch (semantic) + { + case RenderSpriteSemantic::POSITION: + usageName = "POSITION"; + break; + case RenderSpriteSemantic::COLOR: + usageName = "COLOR"; + break; + case RenderSpriteSemantic::VELOCITY: + usageName = "NORMAL"; + break; + case RenderSpriteSemantic::SCALE: + usageName = "TANGENT"; + break; + case RenderSpriteSemantic::LIFE_REMAIN: + usageName = "TEXCOORD"; + usageIndex = 0; + break; + case RenderSpriteSemantic::DENSITY: + usageName = "TEXCOORD"; + usageIndex = 1; + break; + case RenderSpriteSemantic::SUBTEXTURE: + usageName = "TEXCOORD"; + usageIndex = 2; + break; + case RenderSpriteSemantic::ORIENTATION: + usageName = "TEXCOORD"; + usageIndex = 3; + break; + default: + PX_ALWAYS_ASSERT(); + usageName = "POSITION"; + break; + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// SampleApexRendererVertexBuffer +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +SampleApexRendererVertexBuffer::SampleApexRendererVertexBuffer(ID3D11Device& d3dDevice, + const apex::UserRenderVertexBufferDesc& desc) +: mDevice(d3dDevice) +{ + uint32_t stride = 0; + uint8_t pointer = 0; + for(uint32_t i = 0; i < apex::RenderVertexSemantic::NUM_SEMANTICS; i++) + { + apex::RenderDataFormat::Enum apexFormat = desc.buffersRequest[i]; + + mDataFormat[i] = apexFormat; + stride += RenderDataFormat::getFormatDataSize(apexFormat); + + mPointers[i] = pointer; + pointer += (uint8_t)RenderDataFormat::getFormatDataSize(apexFormat); + } + + mStride = stride; + mVerticesCount = desc.maxVerts; + + D3D11_BUFFER_DESC bufferDesc; + + memset(&bufferDesc, 0, sizeof(D3D11_BUFFER_DESC)); + bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bufferDesc.ByteWidth = (UINT)(desc.maxVerts * mStride); + bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + bufferDesc.Usage = D3D11_USAGE_DYNAMIC; + + V(mDevice.CreateBuffer(&bufferDesc, NULL, &mVertexBuffer)); +} + +SampleApexRendererVertexBuffer::~SampleApexRendererVertexBuffer(void) +{ + if(mVertexBuffer) + { + mVertexBuffer->Release(); + mVertexBuffer = NULL; + } +} + +void SampleApexRendererVertexBuffer::addVertexElements(uint32_t streamIndex, + std::vector<D3D11_INPUT_ELEMENT_DESC>& vertexElements) const +{ + uint32_t offset = 0; + + for(uint32_t i = 0; i < apex::RenderVertexSemantic::NUM_SEMANTICS; i++) + { + apex::RenderVertexSemantic::Enum semantic = (apex::RenderVertexSemantic::Enum)i; + + if(mDataFormat[i] != RenderDataFormat::UNSPECIFIED) + { + uint8_t d3dUsageIndex = 0; + LPCSTR d3dUsageName = ""; + getD3DUsage(semantic, d3dUsageName, d3dUsageIndex); + + D3D11_INPUT_ELEMENT_DESC element; + element.SemanticName = d3dUsageName; + element.SemanticIndex = d3dUsageIndex; + element.Format = getD3DFormat(mDataFormat[i]); + element.InputSlot = streamIndex; + element.AlignedByteOffset = offset; + element.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; + element.InstanceDataStepRate = 0; + + vertexElements.push_back(element); + + offset += (uint32_t)RenderDataFormat::getFormatDataSize(mDataFormat[i]); + } + } +} + +void SampleApexRendererVertexBuffer::writeBuffer(const apex::RenderVertexBufferData& data, uint32_t firstVertex, + uint32_t numVerts) +{ + ID3D11DeviceContext* context; + mDevice.GetImmediateContext(&context); + + D3D11_MAPPED_SUBRESOURCE mappedRead; + V(context->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, NULL, &mappedRead)); + + for(uint32_t i = 0; i < apex::RenderVertexSemantic::NUM_SEMANTICS; i++) + { + apex::RenderVertexSemantic::Enum apexSemantic = (apex::RenderVertexSemantic::Enum)i; + const apex::RenderSemanticData& semanticData = data.getSemanticData(apexSemantic); + if(semanticData.data) + { + const void* srcData = semanticData.data; + const uint32_t srcStride = semanticData.stride; + + void* dstData = ((uint8_t*)mappedRead.pData) + firstVertex * mStride + mPointers[i]; + + for(uint32_t j = 0; j < numVerts; j++) + { + memcpy(dstData, srcData, srcStride); + dstData = ((uint8_t*)dstData) + mStride; + srcData = ((uint8_t*)srcData) + srcStride; + } + } + } + + context->Unmap(mVertexBuffer, 0); +} + +void SampleApexRendererVertexBuffer::bind(ID3D11DeviceContext& context, uint32_t streamID, uint32_t firstVertex) +{ + ID3D11Buffer* pBuffers[1] = { mVertexBuffer }; + UINT strides[1] = { mStride }; + UINT offsets[1] = { firstVertex * mStride }; + context.IASetVertexBuffers(streamID, 1, pBuffers, strides, offsets); +} + +void SampleApexRendererVertexBuffer::unbind(ID3D11DeviceContext& context, uint32_t streamID) +{ + ID3D11Buffer* pBuffers[1] = { NULL }; + UINT strides[1] = { 0 }; + UINT offsets[1] = { 0 }; + context.IASetVertexBuffers(streamID, 1, pBuffers, strides, offsets); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// SampleApexRendererIndexBuffer +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +SampleApexRendererIndexBuffer::SampleApexRendererIndexBuffer(ID3D11Device& d3dDevice, + const apex::UserRenderIndexBufferDesc& desc) +: mDevice(d3dDevice) +{ + mIndicesCount = desc.maxIndices; + mStride = RenderDataFormat::getFormatDataSize(desc.format); + + D3D11_BUFFER_DESC bufferDesc; + + memset(&bufferDesc, 0, sizeof(D3D11_BUFFER_DESC)); + bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; + bufferDesc.ByteWidth = (UINT)(RenderDataFormat::getFormatDataSize(desc.format) * desc.maxIndices); + bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + bufferDesc.Usage = D3D11_USAGE_DYNAMIC; + + V(mDevice.CreateBuffer(&bufferDesc, NULL, &mIndexBuffer)); + + mFormat = (desc.format == RenderDataFormat::USHORT1 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT); +} + +SampleApexRendererIndexBuffer::~SampleApexRendererIndexBuffer(void) +{ + if(mIndexBuffer) + { + mIndexBuffer->Release(); + mIndexBuffer = NULL; + } +} + +void SampleApexRendererIndexBuffer::writeBuffer(const void* srcData, uint32_t srcStride, uint32_t firstDestElement, + uint32_t numElements) +{ + ID3D11DeviceContext* context; + mDevice.GetImmediateContext(&context); + + D3D11_MAPPED_SUBRESOURCE mappedRead; + V(context->Map(mIndexBuffer, 0, D3D11_MAP_WRITE_DISCARD, NULL, &mappedRead)); + + ::memcpy(static_cast<char*>(mappedRead.pData) + firstDestElement * mStride, srcData, mStride * numElements); + + context->Unmap(mIndexBuffer, 0); +} + +void SampleApexRendererIndexBuffer::bind(ID3D11DeviceContext& context) +{ + context.IASetIndexBuffer(mIndexBuffer, mFormat, 0); +} + +void SampleApexRendererIndexBuffer::unbind(ID3D11DeviceContext& context) +{ + context.IASetIndexBuffer(NULL, DXGI_FORMAT(), 0); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// SampleApexRendererBoneBuffer +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +SampleApexRendererBoneBuffer::SampleApexRendererBoneBuffer(ID3D11Device& d3dDevice, + const apex::UserRenderBoneBufferDesc& desc) +: mDevice(d3dDevice) +{ + mMaxBones = desc.maxBones; + mBones = NULL; + mBones = new PxMat44[mMaxBones]; + + { + D3D11_TEXTURE2D_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.Width = 4; + desc.Height = mMaxBones; + desc.MipLevels = 1; + desc.ArraySize = 1; + desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.CPUAccessFlags = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + + D3D11_SUBRESOURCE_DATA subData; + memset(&subData, 0, sizeof(D3D11_SUBRESOURCE_DATA)); + subData.pSysMem = mBones; + subData.SysMemPitch = desc.Width * sizeof(unsigned int); + subData.SysMemSlicePitch = 0; + + V(mDevice.CreateTexture2D(&desc, &subData, &mTexture)); + } + + { + D3D11_SHADER_RESOURCE_VIEW_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; + desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + desc.Texture2D.MipLevels = 1; + desc.Texture2D.MostDetailedMip = 0; + V(mDevice.CreateShaderResourceView(mTexture, &desc, &mShaderResourceView)); + } +} + +SampleApexRendererBoneBuffer::~SampleApexRendererBoneBuffer(void) +{ + if(mBones) + { + delete[] mBones; + } + + if(mTexture) + { + mTexture->Release(); + } + + if(mShaderResourceView) + { + mShaderResourceView->Release(); + } +} + +void SampleApexRendererBoneBuffer::writeBuffer(const apex::RenderBoneBufferData& data, uint32_t firstBone, + uint32_t numBones) +{ + const apex::RenderSemanticData& semanticData = data.getSemanticData(apex::RenderBoneSemantic::POSE); + if(!semanticData.data) + return; + + const void* srcData = semanticData.data; + const uint32_t srcStride = semanticData.stride; + for(uint32_t i = 0; i < numBones; i++) + { + mBones[firstBone + i] = PxMat44(*((const PxMat44*)srcData)); + srcData = ((uint8_t*)srcData) + srcStride; + } + + ID3D11DeviceContext* context; + mDevice.GetImmediateContext(&context); + + CD3D11_BOX box(0, (LONG)firstBone, 0, 4, (LONG)(firstBone + numBones), 1); + context->UpdateSubresource(mTexture, 0, &box, mBones, 16 * 4, 16 * 4 * mMaxBones); +} + +void SampleApexRendererBoneBuffer::bind(uint32_t slot) +{ + ID3D11DeviceContext* context; + mDevice.GetImmediateContext(&context); + + context->VSSetShaderResources(slot, 1, &mShaderResourceView); + context->PSSetShaderResources(slot, 1, &mShaderResourceView); +} + +void SampleApexRendererBoneBuffer::unbind() +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// SampleApexRendererSpriteBuffer +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +SampleApexRendererSpriteBuffer::SampleApexRendererSpriteBuffer(ID3D11Device& d3dDevice, const nvidia::apex::UserRenderSpriteBufferDesc& desc) +: mDevice(d3dDevice) +{ + for (uint32_t i = 0; i < apex::RenderSpriteLayoutElement::NUM_SEMANTICS; i++) + { + if (desc.semanticOffsets[i] != static_cast<uint32_t>(-1)) + { + mDataFormat[i] = RenderSpriteLayoutElement::getSemanticFormat((apex::RenderSpriteLayoutElement::Enum)i); + } + else + { + mDataFormat[i] = RenderDataFormat::UNSPECIFIED; + } + } + + mStride = desc.stride; + + D3D11_BUFFER_DESC bufferDesc; + + memset(&bufferDesc, 0, sizeof(D3D11_BUFFER_DESC)); + bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bufferDesc.ByteWidth = (UINT)(desc.maxSprites * mStride); + bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + bufferDesc.Usage = D3D11_USAGE_DYNAMIC; + + V(mDevice.CreateBuffer(&bufferDesc, NULL, &mVertexBuffer)); +} + +SampleApexRendererSpriteBuffer::~SampleApexRendererSpriteBuffer(void) +{ + if (mVertexBuffer) + { + mVertexBuffer->Release(); + mVertexBuffer = NULL; + } +} + +void SampleApexRendererSpriteBuffer::addVertexElements(uint32_t streamIndex, + std::vector<D3D11_INPUT_ELEMENT_DESC>& vertexElements) const +{ + uint32_t offset = 0; + + for (uint32_t i = 0; i < apex::RenderSpriteLayoutElement::NUM_SEMANTICS; i++) + { + apex::RenderSpriteSemantic::Enum semantic = RenderSpriteLayoutElement::getSemantic((apex::RenderSpriteLayoutElement::Enum)i); + + if (mDataFormat[i] != RenderDataFormat::UNSPECIFIED) + { + uint8_t d3dUsageIndex = 0; + LPCSTR d3dUsageName = ""; + getD3DUsage(semantic, d3dUsageName, d3dUsageIndex); + + D3D11_INPUT_ELEMENT_DESC element; + element.SemanticName = d3dUsageName; + element.SemanticIndex = d3dUsageIndex; + element.Format = getD3DFormat(mDataFormat[i]); + element.InputSlot = streamIndex; + element.AlignedByteOffset = offset; + element.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; + element.InstanceDataStepRate = 0; + + vertexElements.push_back(element); + + offset += (uint32_t)RenderDataFormat::getFormatDataSize(mDataFormat[i]); + } + } +} + +void SampleApexRendererSpriteBuffer::writeBuffer(const void* srcData, uint32_t firstSprite, uint32_t numSprites) +{ + ID3D11DeviceContext* context; + mDevice.GetImmediateContext(&context); + + D3D11_MAPPED_SUBRESOURCE mappedRead; + V(context->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, NULL, &mappedRead)); + + ::memcpy(static_cast<char*>(mappedRead.pData) + firstSprite * mStride, srcData, mStride * numSprites); + + context->Unmap(mVertexBuffer, 0); +} + +void SampleApexRendererSpriteBuffer::writeTexture(uint32_t textureId, uint32_t numSprites, const void* srcData, size_t srcSize) +{ + PX_ALWAYS_ASSERT(); + PX_UNUSED(textureId); + PX_UNUSED(numSprites); + PX_UNUSED(srcData); + PX_UNUSED(srcSize); +} + +void SampleApexRendererSpriteBuffer::bind(ID3D11DeviceContext& context, uint32_t streamID, uint32_t firstVertex) +{ + ID3D11Buffer* pBuffers[1] = { mVertexBuffer }; + UINT strides[1] = { mStride }; + UINT offsets[1] = { firstVertex * mStride }; + context.IASetVertexBuffers(streamID, 1, pBuffers, strides, offsets); +} + +void SampleApexRendererSpriteBuffer::unbind(ID3D11DeviceContext& context, uint32_t streamID) +{ + ID3D11Buffer* pBuffers[1] = { NULL }; + UINT strides[1] = { 0 }; + UINT offsets[1] = { 0 }; + context.IASetVertexBuffers(streamID, 1, pBuffers, strides, offsets); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// SampleApexRendererInstanceBuffer +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +SampleApexRendererInstanceBuffer::SampleApexRendererInstanceBuffer(ID3D11Device& d3dDevice, const nvidia::apex::UserRenderInstanceBufferDesc& desc) + : mDevice(d3dDevice) +{ + for (uint32_t i = 0; i < apex::RenderInstanceLayoutElement::NUM_SEMANTICS; i++) + { + if (desc.semanticOffsets[i] != static_cast<uint32_t>(-1)) + { + RenderDataFormat::Enum dataFormat = RenderInstanceLayoutElement::getSemanticFormat((apex::RenderInstanceLayoutElement::Enum)i); + if (dataFormat == RenderDataFormat::FLOAT3x3) + { + mDataFormat.push_back(RenderDataFormat::FLOAT3); + mDataFormat.push_back(RenderDataFormat::FLOAT3); + mDataFormat.push_back(RenderDataFormat::FLOAT3); + } + else + { + mDataFormat.push_back(dataFormat); + } + } + else + { + } + } + + mStride = desc.stride; + + D3D11_BUFFER_DESC bufferDesc; + + memset(&bufferDesc, 0, sizeof(D3D11_BUFFER_DESC)); + bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bufferDesc.ByteWidth = (UINT)(desc.maxInstances * mStride); + bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + bufferDesc.Usage = D3D11_USAGE_DYNAMIC; + + V(mDevice.CreateBuffer(&bufferDesc, NULL, &mInstanceBuffer)); +} + +SampleApexRendererInstanceBuffer::~SampleApexRendererInstanceBuffer(void) +{ + if (mInstanceBuffer) + { + mInstanceBuffer->Release(); + mInstanceBuffer = NULL; + } +} + +void SampleApexRendererInstanceBuffer::addVertexElements(uint32_t streamIndex, + std::vector<D3D11_INPUT_ELEMENT_DESC>& vertexElements) const +{ + uint32_t offset = 0; + + for (uint32_t i = 0; i < mDataFormat.size(); i++) + { + RenderDataFormat::Enum dataFormat = mDataFormat[i]; + + D3D11_INPUT_ELEMENT_DESC element; + element.SemanticName = "TEXCOORD"; + element.SemanticIndex = 9 + i; + element.Format = getD3DFormat(dataFormat); + element.InputSlot = streamIndex; + element.AlignedByteOffset = offset; + element.InputSlotClass = D3D11_INPUT_PER_INSTANCE_DATA; + element.InstanceDataStepRate = 1; + + vertexElements.push_back(element); + + offset += (uint32_t)RenderDataFormat::getFormatDataSize(dataFormat); + } +} + +void SampleApexRendererInstanceBuffer::writeBuffer(const void* srcData, uint32_t firstInstance, uint32_t numInstances) +{ + ID3D11DeviceContext* context; + mDevice.GetImmediateContext(&context); + + D3D11_MAPPED_SUBRESOURCE mappedRead; + V(context->Map(mInstanceBuffer, 0, D3D11_MAP_WRITE_DISCARD, NULL, &mappedRead)); + + ::memcpy(static_cast<char*>(mappedRead.pData) + firstInstance * mStride, srcData, mStride * numInstances); + + context->Unmap(mInstanceBuffer, 0); +} + +void SampleApexRendererInstanceBuffer::bind(ID3D11DeviceContext& context, uint32_t streamID, uint32_t firstVertex) +{ + ID3D11Buffer* pBuffers[1] = { mInstanceBuffer }; + UINT strides[1] = { mStride }; + UINT offsets[1] = { firstVertex * mStride }; + context.IASetVertexBuffers(streamID, 1, pBuffers, strides, offsets); +} + +void SampleApexRendererInstanceBuffer::unbind(ID3D11DeviceContext& context, uint32_t streamID) +{ + ID3D11Buffer* pBuffers[1] = { NULL }; + UINT strides[1] = { 0 }; + UINT offsets[1] = { 0 }; + context.IASetVertexBuffers(streamID, 1, pBuffers, strides, offsets); +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// SampleApexRendererMesh +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +SampleApexRendererMesh::SampleApexRendererMesh(ID3D11Device& d3dDevice, const apex::UserRenderResourceDesc& desc) +: mDevice(d3dDevice) +{ + mVertexBuffers = NULL; + mNumVertexBuffers = 0; + mIndexBuffer = NULL; + mSpriteBuffer = NULL; + mInstanceBuffer = NULL; + mMaterialInstance = NULL; + + mBoneBuffer = NULL; + + mNumVertexBuffers = desc.numVertexBuffers; + if(mNumVertexBuffers > 0) + { + mVertexBuffers = new SampleApexRendererVertexBuffer* [mNumVertexBuffers]; + for(uint32_t i = 0; i < mNumVertexBuffers; i++) + { + mVertexBuffers[i] = static_cast<SampleApexRendererVertexBuffer*>(desc.vertexBuffers[i]); + } + } + + if (desc.indexBuffer) + mIndexBuffer = static_cast<SampleApexRendererIndexBuffer*>(desc.indexBuffer); + + if (desc.boneBuffer) + mBoneBuffer = static_cast<SampleApexRendererBoneBuffer*>(desc.boneBuffer); + + if (desc.spriteBuffer) + mSpriteBuffer = static_cast<SampleApexRendererSpriteBuffer*>(desc.spriteBuffer); + + if (desc.instanceBuffer) + mInstanceBuffer = static_cast<SampleApexRendererInstanceBuffer*>(desc.instanceBuffer); + + mCullMode = desc.cullMode; + mPrimitiveTopology = desc.primitives == RenderPrimitiveType::POINT_SPRITES ? D3D_PRIMITIVE_TOPOLOGY_POINTLIST : + D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + + setVertexBufferRange(desc.firstVertex, desc.numVerts); + setIndexBufferRange(desc.firstIndex, desc.numIndices); + setBoneBufferRange(desc.firstBone, desc.numBones); + setSpriteBufferRange(desc.firstSprite, desc.numSprites); + setInstanceBufferRange(desc.firstInstance, desc.numInstances); + + if (desc.material) + setMaterial(desc.material); +} + +void SampleApexRendererMesh::setMaterial(void* material) +{ + ApexRenderMaterial* renderMaterial = static_cast<ApexRenderMaterial*>(material); + if (mMaterial != renderMaterial) + { + mMaterial = renderMaterial; + + std::vector<D3D11_INPUT_ELEMENT_DESC> descs; + + for (uint32_t i = 0; i < mNumVertexBuffers; i++) + { + mVertexBuffers[i]->addVertexElements(i, descs); + } + + if (mSpriteBuffer) + mSpriteBuffer->addVertexElements(0, descs); + + if (mInstanceBuffer) + mInstanceBuffer->addVertexElements(mNumVertexBuffers, descs); + + mMaterialInstance = renderMaterial->getMaterialInstance(&descs[0], (uint32_t)descs.size()); + } +} + +SampleApexRendererMesh::~SampleApexRendererMesh(void) +{ + if(mVertexBuffers) + { + delete[] mVertexBuffers; + } +} + +void SampleApexRendererMesh::setVertexBufferRange(uint32_t firstVertex, uint32_t numVerts) +{ + mFirstVertex = firstVertex; + mNumVertices = numVerts; +} + +void SampleApexRendererMesh::setIndexBufferRange(uint32_t firstIndex, uint32_t numIndices) +{ + mFirstIndex = firstIndex; + mNumIndices = numIndices; +} + +void SampleApexRendererMesh::setBoneBufferRange(uint32_t firstBone, uint32_t numBones) +{ + mFirstBone = firstBone; + mNumBones = numBones; +} + +void SampleApexRendererMesh::setInstanceBufferRange(uint32_t firstInstance, uint32_t numInstances) +{ + mFirstInstance = firstInstance; + mNumInstances = numInstances; +} + +void SampleApexRendererMesh::setSpriteBufferRange(uint32_t firstSprite, uint32_t numSprites) +{ + mFirstSprite = firstSprite; + mNumSprites = numSprites; +} + +void SampleApexRendererMesh::render(const apex::RenderContext& c) +{ + PX_UNUSED(c); + if (mMaterialInstance == NULL || !mMaterialInstance->isValid()) + return; + + ID3D11DeviceContext* context; + mDevice.GetImmediateContext(&context); + + for(uint32_t i = 0; i < mNumVertexBuffers; i++) + { + mVertexBuffers[i]->bind(*context, i, 0); + } + + if (mIndexBuffer) + mIndexBuffer->bind(*context); + + mMaterialInstance->bind(*context, 0); + + if (mBoneBuffer) + mBoneBuffer->bind(1); + + if (mSpriteBuffer) + mSpriteBuffer->bind(*context, mNumVertexBuffers, mFirstSprite); + + if (mInstanceBuffer) + mInstanceBuffer->bind(*context, mNumVertexBuffers, mFirstInstance); + + context->IASetPrimitiveTopology(mPrimitiveTopology); + + if (mIndexBuffer && mInstanceBuffer) + context->DrawIndexedInstanced(mNumIndices, mNumInstances, mFirstIndex, 0, mFirstInstance); + else if (mIndexBuffer) + context->DrawIndexed(mNumIndices, mFirstIndex, 0); + else if (mInstanceBuffer) + context->DrawInstanced(mNumVertices, mNumInstances, mFirstVertex, mFirstInstance); + else if (mSpriteBuffer) + context->Draw(mNumSprites, mFirstSprite); + + for(uint32_t i = 0; i < mNumVertexBuffers; i++) + { + mVertexBuffers[i]->unbind(*context, i); + } + + if (mIndexBuffer) + mIndexBuffer->unbind(*context); + + if (mInstanceBuffer) + mInstanceBuffer->unbind(*context, 0); + + if (mSpriteBuffer) + mSpriteBuffer->unbind(*context, 0); + + if (mBoneBuffer != NULL) + mBoneBuffer->unbind(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/APEX_1.4/samples_v2/SampleBase/ApexRenderResources.h b/APEX_1.4/samples_v2/SampleBase/ApexRenderResources.h new file mode 100644 index 00000000..957c5798 --- /dev/null +++ b/APEX_1.4/samples_v2/SampleBase/ApexRenderResources.h @@ -0,0 +1,250 @@ +/* +* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. +* +* NVIDIA CORPORATION and its licensors retain all intellectual property +* and proprietary rights in and to this software, related documentation +* and any modifications thereto. Any use, reproduction, disclosure or +* distribution of this software and related documentation without an express +* license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#ifndef APEX_RENDER_RESOURCES_H +#define APEX_RENDER_RESOURCES_H + +#include "ApexRenderMaterial.h" + +#include "Apex.h" +#include "Utils.h" + +#include <vector> + +using namespace physx; +using namespace nvidia; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class SampleApexRendererVertexBuffer : public apex::UserRenderVertexBuffer +{ + public: + SampleApexRendererVertexBuffer(ID3D11Device& d3dDevice, const apex::UserRenderVertexBufferDesc& desc); + virtual ~SampleApexRendererVertexBuffer(void); + + void bind(ID3D11DeviceContext& context, uint32_t streamID, uint32_t firstVertex); + void unbind(ID3D11DeviceContext& context, uint32_t streamID); + void addVertexElements(uint32_t streamIndex, std::vector<D3D11_INPUT_ELEMENT_DESC>& vertexElements) const; + + protected: + virtual void writeBuffer(const apex::RenderVertexBufferData& data, uint32_t firstVertex, uint32_t numVerts); + + private: + uint32_t mStride; + uint32_t mVerticesCount; + uint8_t mPointers[RenderVertexSemantic::NUM_SEMANTICS]; + RenderDataFormat::Enum mDataFormat[RenderVertexSemantic::NUM_SEMANTICS]; + + ID3D11Device& mDevice; + ID3D11Buffer* mVertexBuffer; +}; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class SampleApexRendererIndexBuffer : public apex::UserRenderIndexBuffer +{ + public: + SampleApexRendererIndexBuffer(ID3D11Device& d3dDevice, const apex::UserRenderIndexBufferDesc& desc); + virtual ~SampleApexRendererIndexBuffer(void); + + void bind(ID3D11DeviceContext& context); + void unbind(ID3D11DeviceContext& context); + + uint32_t GetIndicesCount() + { + return mIndicesCount; + } + + private: + virtual void writeBuffer(const void* srcData, uint32_t srcStride, uint32_t firstDestElement, uint32_t numElements); + + private: + uint32_t mIndicesCount; + uint32_t mStride; + + ID3D11Device& mDevice; + ID3D11Buffer* mIndexBuffer; + DXGI_FORMAT mFormat; +}; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class SampleApexRendererBoneBuffer : public apex::UserRenderBoneBuffer +{ + public: + SampleApexRendererBoneBuffer(ID3D11Device& d3dDevice, const apex::UserRenderBoneBufferDesc& desc); + virtual ~SampleApexRendererBoneBuffer(void); + + void bind(uint32_t slot); + void unbind(); + + public: + virtual void writeBuffer(const apex::RenderBoneBufferData& data, uint32_t firstBone, uint32_t numBones); + + private: + uint32_t mMaxBones; + PxMat44* mBones; + + ID3D11Device& mDevice; + + ID3D11Texture2D* mTexture; + ID3D11ShaderResourceView* mShaderResourceView; +}; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class SampleApexRendererSpriteBuffer : public apex::UserRenderSpriteBuffer +{ +public: + SampleApexRendererSpriteBuffer(ID3D11Device& d3dDevice, const apex::UserRenderSpriteBufferDesc& desc); + virtual ~SampleApexRendererSpriteBuffer(void); + + void addVertexElements(uint32_t streamIndex, std::vector<D3D11_INPUT_ELEMENT_DESC>& vertexElements) const; + + void bind(ID3D11DeviceContext& context, uint32_t streamID, uint32_t firstVertex); + void unbind(ID3D11DeviceContext& context, uint32_t streamID); + + virtual void writeBuffer(const void* data, uint32_t firstSprite, uint32_t numSprites); + virtual void writeTexture(uint32_t textureId, uint32_t numSprites, const void* srcData, size_t srcSize); + +private: + ID3D11Device& mDevice; + + uint32_t mStride; + RenderDataFormat::Enum mDataFormat[RenderVertexSemantic::NUM_SEMANTICS]; + + ID3D11Buffer* mVertexBuffer; +}; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class SampleApexRendererInstanceBuffer : public apex::UserRenderInstanceBuffer +{ +public: + SampleApexRendererInstanceBuffer(ID3D11Device& d3dDevice, const apex::UserRenderInstanceBufferDesc& desc); + virtual ~SampleApexRendererInstanceBuffer(void); + + void addVertexElements(uint32_t streamIndex, std::vector<D3D11_INPUT_ELEMENT_DESC>& vertexElements) const; + + void bind(ID3D11DeviceContext& context, uint32_t streamID, uint32_t firstVertex); + void unbind(ID3D11DeviceContext& context, uint32_t streamID); + + virtual void writeBuffer(const void* data, uint32_t firstInstance, uint32_t numInstances); + +private: + ID3D11Device& mDevice; + + uint32_t mStride; + vector<RenderDataFormat::Enum> mDataFormat; + + ID3D11Buffer* mInstanceBuffer; +}; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class SampleApexRendererMesh : public apex::UserRenderResource +{ + public: + SampleApexRendererMesh(ID3D11Device& d3dDevice, const apex::UserRenderResourceDesc& desc); + virtual ~SampleApexRendererMesh(); + + public: + virtual void setVertexBufferRange(uint32_t firstVertex, uint32_t numVerts); + virtual void setIndexBufferRange(uint32_t firstIndex, uint32_t numIndices); + virtual void setBoneBufferRange(uint32_t firstBone, uint32_t numBones); + virtual void setInstanceBufferRange(uint32_t firstInstance, uint32_t numInstances); + virtual void setSpriteBufferRange(uint32_t firstSprite, uint32_t numSprites); + + virtual void setMaterial(void* material); + + uint32_t getNbVertexBuffers() const + { + return mNumVertexBuffers; + } + + apex::UserRenderVertexBuffer* getVertexBuffer(uint32_t index) const + { + apex::UserRenderVertexBuffer* buffer = 0; + PX_ASSERT(index < mNumVertexBuffers); + if(index < mNumVertexBuffers) + { + buffer = mVertexBuffers[index]; + } + return buffer; + } + + apex::UserRenderIndexBuffer* getIndexBuffer() const + { + return mIndexBuffer; + } + + apex::UserRenderBoneBuffer* getBoneBuffer() const + { + return mBoneBuffer; + } + + apex::UserRenderInstanceBuffer* getInstanceBuffer() const + { + return NULL; + } + + apex::UserRenderSpriteBuffer* getSpriteBuffer() const + { + return mSpriteBuffer; + } + + void render(const apex::RenderContext& context); + + private: + SampleApexRendererVertexBuffer** mVertexBuffers; + uint32_t mNumVertexBuffers; + uint32_t mFirstVertex; + uint32_t mNumVertices; + + SampleApexRendererIndexBuffer* mIndexBuffer; + uint32_t mFirstIndex; + uint32_t mNumIndices; + + SampleApexRendererBoneBuffer* mBoneBuffer; + uint32_t mFirstBone; + uint32_t mNumBones; + + SampleApexRendererSpriteBuffer* mSpriteBuffer; + uint32_t mFirstSprite; + uint32_t mNumSprites; + + SampleApexRendererInstanceBuffer* mInstanceBuffer; + uint32_t mFirstInstance; + uint32_t mNumInstances; + + PxMat44 mMeshTransform; + apex::RenderCullMode::Enum mCullMode; + + ApexRenderMaterial* mMaterial; + ApexRenderMaterial::Instance* mMaterialInstance; + + D3D11_PRIMITIVE_TOPOLOGY mPrimitiveTopology; + + ID3D11Device& mDevice; +}; + +#endif
\ No newline at end of file diff --git a/APEX_1.4/samples_v2/SampleBase/ApexRenderer.cpp b/APEX_1.4/samples_v2/SampleBase/ApexRenderer.cpp new file mode 100644 index 00000000..54328c65 --- /dev/null +++ b/APEX_1.4/samples_v2/SampleBase/ApexRenderer.cpp @@ -0,0 +1,512 @@ +/* +* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. +* +* NVIDIA CORPORATION and its licensors retain all intellectual property +* and proprietary rights in and to this software, related documentation +* and any modifications thereto. Any use, reproduction, disclosure or +* distribution of this software and related documentation without an express +* license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#include "ApexRenderer.h" +#include "ApexRenderResources.h" + + +#include "XInput.h" +#include "DXUTMisc.h" +#include "DXUTCamera.h" + +#include "PhysXPrimitive.h" + +#include "ApexResourceCallback.h" + +using namespace physx; +using namespace nvidia; + +const float CAMERA_CLIP_NEAR = 1.0f; +const float CAMERA_CLIP_FAR = 10000.00f; + +const float CLEAR_SCENE_COLOR[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// RenderDebugInterface implementation wrapper +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class RenderDebugImpl : public RENDER_DEBUG::RenderDebugInterface +{ +public: + RenderDebugImpl(ApexRenderer* renderer) : mRenderer(renderer) {} + + virtual void debugRenderLines(uint32_t lcount, const RENDER_DEBUG::RenderDebugVertex *vertices, + bool useZ, bool isScreenSpace) + { + PX_UNUSED(useZ); + PX_UNUSED(isScreenSpace); + mRenderer->renderDebugPrimitive(vertices, lcount * 2, D3D11_PRIMITIVE_TOPOLOGY_LINELIST); + } + + virtual void debugRenderTriangles(uint32_t tcount, const RENDER_DEBUG::RenderDebugSolidVertex *vertices, + bool useZ, bool isScreenSpace) + { + PX_UNUSED(useZ); + PX_UNUSED(isScreenSpace); + RENDER_DEBUG::RenderDebugVertex* verts = new RENDER_DEBUG::RenderDebugVertex[tcount * 3 * 2]; + + for (uint32_t i = 0; i < tcount * 3 * 2; ++i) + { + verts[i].mPos[0] = vertices[i].mPos[0]; + verts[i].mPos[1] = vertices[i].mPos[1]; + verts[i].mPos[2] = vertices[i].mPos[2]; + verts[i].mColor = vertices[i].mColor; + } + + mRenderer->renderDebugPrimitive(verts, tcount * 3 * 2, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + delete[] verts; + } + + // unused API: + virtual void debugMessage(const char * /* msg */) {} + virtual void renderTriangleMeshInstances(uint32_t, uint32_t, float, uint32_t, float, uint32_t, const RENDER_DEBUG::RenderDebugInstance*) {} + virtual void createTriangleMesh(uint32_t, uint32_t, const RENDER_DEBUG::RenderDebugMeshVertex*, uint32_t, const uint32_t*) {} + virtual void refreshTriangleMeshVertices(uint32_t, uint32_t, const RENDER_DEBUG::RenderDebugMeshVertex*, const uint32_t*) {} + virtual void releaseTriangleMesh(uint32_t) {} + virtual void debugText2D(float, float, float, float, bool, uint32_t, const char*) {} + virtual void createCustomTexture(uint32_t, const char*) {} + virtual void debugPoints(RENDER_DEBUG::PointRenderMode, uint32_t, uint32_t, float, uint32_t, float, uint32_t, float, uint32_t, const float*) {} + virtual void registerDigitalInputEvent(RENDER_DEBUG::InputEventIds::Enum, RENDER_DEBUG::InputIds::Enum) {} + virtual void registerAnalogInputEvent(RENDER_DEBUG::InputEventIds::Enum, float, RENDER_DEBUG::InputIds::Enum) {} + virtual void unregisterInputEvent(RENDER_DEBUG::InputEventIds::Enum) {} + virtual void resetInputEvents(void) {} + +private: + ApexRenderer* mRenderer; +}; + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Apex Renderer +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +ApexRenderer::ApexRenderer(CFirstPersonCamera* cam, ApexController& apex) +: mApex(apex) +, mCamera(cam) +, mCameraCB(nullptr) +, mWorldCB(nullptr) +, mObjectCB(nullptr) +, mRSState(nullptr) +, mDSState(nullptr) +, mDSTexture(nullptr) +, mDSView(nullptr) +, mDSTextureSRV(nullptr) +, mPointSampler(nullptr) +, mLinearSampler(nullptr) +, mWireframeMode(false) +, mDebugPrimitiveVB(nullptr) +, mDebugPrimitiveVBVerticesCount(0) +{ + mCBWorldData.ambientColor = DirectX::XMFLOAT3(0.1f, 0.1f, 0.1f); + mCBWorldData.pointLightColor = DirectX::XMFLOAT3(1.0f, 1.0f, 1.0f); + mCBWorldData.pointLightPos = DirectX::XMFLOAT3(-6.5f, 13.0f, 12.0f); + mCBWorldData.dirLightColor = DirectX::XMFLOAT3(0.21f, 0.21f, 0.21f); + mCBWorldData.dirLightDir = DirectX::XMFLOAT3(-0.08f, -0.34f, -0.91f); + mCBWorldData.specularPower = 140.0f; + mCBWorldData.specularIntensity = 0.4f; + + // render debug interface + mRenderDebugImpl = new (RenderDebugImpl)(this); + mApex.setRenderDebugInterface(mRenderDebugImpl); +} + +ApexRenderer::~ApexRenderer() +{ + delete mRenderDebugImpl; +} + +void ApexRenderer::initializeDefaultRSState() +{ + SAFE_RELEASE(mRSState); + D3D11_RASTERIZER_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.CullMode = D3D11_CULL_NONE; + desc.FillMode = mWireframeMode ? D3D11_FILL_WIREFRAME : D3D11_FILL_SOLID; + desc.AntialiasedLineEnable = FALSE; + desc.DepthBias = 0; + desc.DepthBiasClamp = 0; + desc.DepthClipEnable = TRUE; + desc.FrontCounterClockwise = FALSE; + desc.MultisampleEnable = TRUE; + desc.ScissorEnable = FALSE; + desc.SlopeScaledDepthBias = 0; + + V(mDevice->CreateRasterizerState(&desc, &mRSState)); +} + +HRESULT ApexRenderer::DeviceCreated(ID3D11Device* device) +{ + mDevice = device; + + // Camera constant buffer + { + D3D11_BUFFER_DESC buffer_desc; + ZeroMemory(&buffer_desc, sizeof(buffer_desc)); + buffer_desc.Usage = D3D11_USAGE_DYNAMIC; + buffer_desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + buffer_desc.ByteWidth = sizeof(CBCamera); + _ASSERT((buffer_desc.ByteWidth % 16) == 0); + + V(device->CreateBuffer(&buffer_desc, nullptr, &mCameraCB)); + } + + // World constant buffer + { + D3D11_BUFFER_DESC buffer_desc; + ZeroMemory(&buffer_desc, sizeof(buffer_desc)); + buffer_desc.Usage = D3D11_USAGE_DYNAMIC; + buffer_desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + buffer_desc.ByteWidth = sizeof(CBWorld); + _ASSERT((buffer_desc.ByteWidth % 16) == 0); + + V(device->CreateBuffer(&buffer_desc, nullptr, &mWorldCB)); + } + + // Object constant buffer + { + D3D11_BUFFER_DESC buffer_desc; + ZeroMemory(&buffer_desc, sizeof(buffer_desc)); + buffer_desc.Usage = D3D11_USAGE_DYNAMIC; + buffer_desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + buffer_desc.ByteWidth = sizeof(CBObject); + _ASSERT((buffer_desc.ByteWidth % 16) == 0); + + V(device->CreateBuffer(&buffer_desc, nullptr, &mObjectCB)); + } + + // Depth-Stencil state + { + D3D11_DEPTH_STENCIL_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.StencilEnable = FALSE; + desc.DepthEnable = TRUE; + desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; + desc.DepthFunc = D3D11_COMPARISON_LESS_EQUAL; + + V(device->CreateDepthStencilState(&desc, &mDSState)); + } + + // Linear sampler + { + D3D11_SAMPLER_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; + desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; + desc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; + desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; + desc.MaxAnisotropy = 1; + desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS; + desc.MinLOD = 0; + desc.MaxLOD = D3D11_FLOAT32_MAX; + V(device->CreateSamplerState(&desc, &mLinearSampler)); + } + + // Point sampler + { + D3D11_SAMPLER_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; + desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; + desc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; + desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; + desc.MaxAnisotropy = 1; + desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS; + desc.MinLOD = 0; + desc.MaxLOD = D3D11_FLOAT32_MAX; + V(device->CreateSamplerState(&desc, &mPointSampler)); + } + + // Rasterizer state + initializeDefaultRSState(); + + return S_OK; +} + +void ApexRenderer::DeviceDestroyed() +{ + SAFE_RELEASE(mCameraCB); + SAFE_RELEASE(mWorldCB); + SAFE_RELEASE(mObjectCB); + SAFE_RELEASE(mRSState); + SAFE_RELEASE(mDSState); + SAFE_RELEASE(mPointSampler); + SAFE_RELEASE(mLinearSampler); + SAFE_RELEASE(mDebugPrimitiveVB); + SAFE_RELEASE(mDSTexture); + SAFE_RELEASE(mDSView); + SAFE_RELEASE(mDSTextureSRV); +} + +#include "Shlwapi.h" + +void ApexRenderer::onInitialize() +{ + std::stringstream ss; + ss << GetCommandLineA(); + char buf[256]; + ss >> &buf[0]; + + PathRemoveFileSpecA(&buf[0]); + + ss.clear(); + ss << buf << "/../../samples_v2/"; + ss >> buf; + + mApex.getResourceCallback()->addSearchDir(&buf[1]); + + // physx primitive render material and input layout + { + mPhysXPrimitiveRenderMaterial = new ApexRenderMaterial(mApex.getResourceCallback(), "physx_primitive", ""); + + D3D11_INPUT_ELEMENT_DESC layout[] = { + { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 } + }; + + mPhysXPrimitiveRenderMaterialInstance = mPhysXPrimitiveRenderMaterial->getMaterialInstance(layout, ARRAYSIZE(layout)); + } + + // debug primitive render material and input layout + { + mDebugPrimitiveRenderMaterial = new ApexRenderMaterial(mApex.getResourceCallback(), "debug_primitive", ""); + + D3D11_INPUT_ELEMENT_DESC layout[] = { + { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 } + }; + + mDebugPrimitiveRenderMaterialInstance = mDebugPrimitiveRenderMaterial->getMaterialInstance(layout, ARRAYSIZE(layout)); + } +} + +void ApexRenderer::onTerminate() +{ + SAFE_DELETE(mPhysXPrimitiveRenderMaterial); + SAFE_DELETE(mDebugPrimitiveRenderMaterial); +} + +void ApexRenderer::BackBufferResized(ID3D11Device* /*device*/, const DXGI_SURFACE_DESC* sd) +{ + // Setup the camera's projection parameters + float fAspectRatio = sd->Width / (FLOAT)sd->Height; + mCamera->SetProjParams(DirectX::XM_PIDIV4, fAspectRatio, CAMERA_CLIP_NEAR, CAMERA_CLIP_FAR); + + SAFE_RELEASE(mDSTexture); + SAFE_RELEASE(mDSView); + SAFE_RELEASE(mDSTextureSRV); + + // create a new Depth-Stencil texture + { + D3D11_TEXTURE2D_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.Width = sd->Width; + desc.Height = sd->Height; + desc.MipLevels = 1; + desc.ArraySize = 1; + desc.Format = DXGI_FORMAT_R32_TYPELESS; // Use a typeless type here so that it can be both depth-stencil and shader resource. + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE; + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + V(mDevice->CreateTexture2D(&desc, NULL, &mDSTexture)); + } + + // create Depth-Stencil view + { + D3D11_DEPTH_STENCIL_VIEW_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; + desc.Format = DXGI_FORMAT_D32_FLOAT; // Make the view see this as D32_FLOAT instead of typeless + desc.Texture2D.MipSlice = 0; + V(mDevice->CreateDepthStencilView(mDSTexture, &desc, &mDSView)); + } + + // create Depth-Stencil shader resource view + { + D3D11_SHADER_RESOURCE_VIEW_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.Format = DXGI_FORMAT_R32_FLOAT; // Make the shaders see this as R32_FLOAT instead of typeless + desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + desc.Texture2D.MipLevels = 1; + desc.Texture2D.MostDetailedMip = 0; + V(mDevice->CreateShaderResourceView(mDSTexture, &desc, &mDSTextureSRV)); + } +} + +void ApexRenderer::Render(ID3D11Device* /*device*/, ID3D11DeviceContext* ctx, ID3D11RenderTargetView* pRTV, + ID3D11DepthStencilView*) +{ + mCurrentContext = ctx; + + ctx->ClearRenderTargetView(pRTV, CLEAR_SCENE_COLOR); + ctx->ClearDepthStencilView(mDSView, D3D11_CLEAR_DEPTH, 1.0, 0); + + // Fill Camera constant buffer + { + DirectX::XMMATRIX viewMatrix = mCamera->GetViewMatrix(); + DirectX::XMMATRIX projMatrix = mCamera->GetProjMatrix(); + DirectX::XMMATRIX projMatrixInv = DirectX::XMMatrixInverse(NULL, projMatrix); + + D3D11_MAPPED_SUBRESOURCE mappedResource; + ctx->Map(mCameraCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + CBCamera* cameraBuffer = (CBCamera*)mappedResource.pData; + cameraBuffer->projection = projMatrix; + cameraBuffer->projectionInv = projMatrixInv; + cameraBuffer->view = viewMatrix; + DirectX::XMStoreFloat3(&(cameraBuffer->viewPos), mCamera->GetEyePt()); + ctx->Unmap(mCameraCB, 0); + } + + // Fill World constant buffer + { + D3D11_MAPPED_SUBRESOURCE mappedResource; + ctx->Map(mWorldCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + CBWorld* worldBuffer = (CBWorld*)mappedResource.pData; + worldBuffer->ambientColor = mCBWorldData.ambientColor; + worldBuffer->pointLightPos = mCBWorldData.pointLightPos; + worldBuffer->pointLightColor = mCBWorldData.pointLightColor; + worldBuffer->dirLightDir = mCBWorldData.dirLightDir; + worldBuffer->specularPower = mCBWorldData.specularPower; + worldBuffer->dirLightColor = mCBWorldData.dirLightColor; + worldBuffer->specularIntensity = mCBWorldData.specularIntensity; + ctx->Unmap(mWorldCB, 0); + } + + // set constants buffers + ID3D11Buffer* cbs[4] = { nullptr }; + cbs[0] = mCameraCB; + cbs[1] = mWorldCB; + cbs[2] = mObjectCB; + ctx->VSSetConstantBuffers(0, 3, cbs); + ctx->GSSetConstantBuffers(0, 3, cbs); + ctx->PSSetConstantBuffers(0, 3, cbs); + + ctx->RSSetState(mRSState); + ctx->PSSetSamplers(0, 1, &mLinearSampler); + ctx->PSSetSamplers(1, 1, &mPointSampler); + + // Opaque render + ctx->OMSetRenderTargets(1, &pRTV, mDSView); + ctx->OMSetDepthStencilState(mDSState, 0xFF); + + mApex.renderOpaque(this); + + // Transparency render + ctx->OMSetRenderTargets(1, &pRTV, NULL); + ctx->PSSetShaderResources(1, 1, &mDSTextureSRV); + + mApex.renderTransparency(this); + + // Reset RT and SRV state + ID3D11ShaderResourceView* nullAttach[16] = { nullptr }; + ctx->PSSetShaderResources(0, 16, nullAttach); + ctx->OMSetRenderTargets(0, nullptr, nullptr); + +} + +void ApexRenderer::renderResource(const RenderContext& context) +{ + if(context.renderResource) + { + // Fill Object constant buffer + { + D3D11_MAPPED_SUBRESOURCE mappedResource; + mCurrentContext->Map(mObjectCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + CBObject* objectBuffer = (CBObject*)mappedResource.pData; + + objectBuffer->world = PxMat44ToXMMATRIX(context.local2world); + + mCurrentContext->Unmap(mObjectCB, 0); + } + + static_cast<SampleApexRendererMesh*>(context.renderResource)->render(context); + } +} + +void ApexRenderer::renderResource(PhysXPrimitive* primitive) +{ + mPhysXPrimitiveRenderMaterialInstance->bind(*mCurrentContext, 0); + + D3D11_MAPPED_SUBRESOURCE mappedResource; + mCurrentContext->Map(mObjectCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + CBObject* objectBuffer = (CBObject*)mappedResource.pData; + + objectBuffer->world = PxMat44ToXMMATRIX(primitive->getModelMatrix()); + objectBuffer->color = primitive->getColor(); + + mCurrentContext->Unmap(mObjectCB, 0); + + primitive->render(*mCurrentContext); +} + +void ApexRenderer::renderDebugPrimitive(const RENDER_DEBUG::RenderDebugVertex *vertices, uint32_t verticesCount, D3D11_PRIMITIVE_TOPOLOGY topology) +{ + mCurrentContext->IASetPrimitiveTopology(topology); + + mDebugPrimitiveRenderMaterialInstance->bind(*mCurrentContext, 0); + + D3D11_MAPPED_SUBRESOURCE mappedResource; + mCurrentContext->Map(mObjectCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + CBObject* objectBuffer = (CBObject*)mappedResource.pData; + + objectBuffer->world = PxMat44ToXMMATRIX(PxMat44(PxIdentity)); + + mCurrentContext->Unmap(mObjectCB, 0); + + if (mDebugPrimitiveVBVerticesCount < verticesCount) + { + mDebugPrimitiveVBVerticesCount = verticesCount; + SAFE_RELEASE(mDebugPrimitiveVB); + + D3D11_BUFFER_DESC bufferDesc; + + memset(&bufferDesc, 0, sizeof(D3D11_BUFFER_DESC)); + bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bufferDesc.ByteWidth = sizeof(RENDER_DEBUG::RenderDebugVertex) * mDebugPrimitiveVBVerticesCount; + bufferDesc.CPUAccessFlags = 0; + bufferDesc.MiscFlags = 0; + bufferDesc.Usage = D3D11_USAGE_DEFAULT; + + V(mDevice->CreateBuffer(&bufferDesc, NULL, &mDebugPrimitiveVB)); + } + + CD3D11_BOX box(0, 0, 0, (LONG)(sizeof(RENDER_DEBUG::RenderDebugVertex) * verticesCount), 1, 1); + mCurrentContext->UpdateSubresource(mDebugPrimitiveVB, 0, &box, vertices, 0, 0); + + ID3D11Buffer* pBuffers[1] = { mDebugPrimitiveVB }; + UINT strides[1] = { sizeof(RENDER_DEBUG::RenderDebugVertex) }; + UINT offsets[1] = { 0 }; + mCurrentContext->IASetVertexBuffers(0, 1, pBuffers, strides, offsets); + + mCurrentContext->Draw(verticesCount, 0); +} + +void ApexRenderer::reloadShaders() +{ + uint32_t count; + void** materials = mApex.getResourceProvider()->findAllResources(APEX_MATERIALS_NAME_SPACE, count); + for (uint32_t i = 0; i < count; i++) + { + ApexRenderMaterial* a = ((ApexRenderMaterial**)materials)[i]; + a->reload(); + } + + mPhysXPrimitiveRenderMaterial->reload(); + mDebugPrimitiveRenderMaterial->reload(); +} + + diff --git a/APEX_1.4/samples_v2/SampleBase/ApexRenderer.h b/APEX_1.4/samples_v2/SampleBase/ApexRenderer.h new file mode 100644 index 00000000..b7fe8306 --- /dev/null +++ b/APEX_1.4/samples_v2/SampleBase/ApexRenderer.h @@ -0,0 +1,183 @@ +/* +* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. +* +* NVIDIA CORPORATION and its licensors retain all intellectual property +* and proprietary rights in and to this software, related documentation +* and any modifications thereto. Any use, reproduction, disclosure or +* distribution of this software and related documentation without an express +* license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#ifndef APEX_RENDERER_H +#define APEX_RENDERER_H + +#include "ApexRenderMaterial.h" +#include "Apex.h" +#include "ApexController.h" +#include <DirectXMath.h> +#include "SampleManager.h" + +using namespace nvidia::apex; + +class CFirstPersonCamera; +class PhysXPrimitive; +class RenderDebugImpl; + +class ApexRenderer : public ISampleController, public UserRenderer +{ + public: + ApexRenderer(CFirstPersonCamera* cam, ApexController& apex); + ~ApexRenderer(); + virtual void renderResource(const RenderContext& context); + void renderResource(PhysXPrimitive* primitive); + void renderDebugPrimitive(const RENDER_DEBUG::RenderDebugVertex *vertices, uint32_t verticesCount, D3D11_PRIMITIVE_TOPOLOGY topology); + + void reloadShaders(); + + bool getWireframeMode() + { + return mWireframeMode; + } + + void setWireframeMode(bool enabled) + { + if(mWireframeMode != enabled) + { + mWireframeMode = enabled; + initializeDefaultRSState(); + } + } + + DirectX::XMFLOAT3& getAmbientColor() + { + return mCBWorldData.ambientColor; + } + + DirectX::XMFLOAT3& getPointLightPos() + { + return mCBWorldData.pointLightPos; + } + + DirectX::XMFLOAT3& getPointLightColor() + { + return mCBWorldData.pointLightColor; + } + + DirectX::XMFLOAT3& getDirLightDir() + { + return mCBWorldData.dirLightDir; + } + + DirectX::XMFLOAT3& getDirLightColor() + { + return mCBWorldData.dirLightColor; + } + + float& getSpecularIntensity() + { + return mCBWorldData.specularIntensity; + } + + float& getSpecularPower() + { + return mCBWorldData.specularPower; + } + + protected: + // callbacks: + virtual HRESULT DeviceCreated(ID3D11Device* pDevice); + virtual void DeviceDestroyed(); + virtual void onInitialize(); + virtual void onTerminate(); + virtual void BackBufferResized(ID3D11Device* pDevice, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc); + virtual void Render(ID3D11Device* /*device*/, ID3D11DeviceContext* ctx, ID3D11RenderTargetView* pRTV, + ID3D11DepthStencilView* pDSV); + + private: + void initializeDefaultRSState(); + + ApexController& mApex; + struct CBCamera + { + DirectX::XMMATRIX projection; + DirectX::XMMATRIX projectionInv; + DirectX::XMMATRIX view; + DirectX::XMFLOAT3 viewPos; + float unusedPad; + }; + struct CBWorld + { + DirectX::XMFLOAT3 ambientColor; + float unusedPad1; + DirectX::XMFLOAT3 pointLightPos; + float unusedPad2; + DirectX::XMFLOAT3 pointLightColor; + float unusedPad3; + DirectX::XMFLOAT3 dirLightDir; + float specularPower; + DirectX::XMFLOAT3 dirLightColor; + float specularIntensity; // TODO: actually it's per object property + }; + struct CBObject + { + DirectX::XMMATRIX world; + DirectX::XMFLOAT3 color; + float unusedPad; + }; + + CBWorld mCBWorldData; + + ID3D11Device* mDevice; + ID3D11DeviceContext* mCurrentContext; + + CFirstPersonCamera* mCamera; + + ID3D11Buffer* mCameraCB; + ID3D11Buffer* mWorldCB; + ID3D11Buffer* mObjectCB; + + ID3D11RasterizerState* mRSState; + ID3D11DepthStencilState* mDSState; + + ID3D11Texture2D* mDSTexture; + ID3D11DepthStencilView* mDSView; + ID3D11ShaderResourceView* mDSTextureSRV; + + + ID3D11SamplerState* mPointSampler; + ID3D11SamplerState* mLinearSampler; + + ApexRenderMaterial* mPhysXPrimitiveRenderMaterial; + ApexRenderMaterial::Instance* mPhysXPrimitiveRenderMaterialInstance; + + ApexRenderMaterial* mDebugPrimitiveRenderMaterial; + ApexRenderMaterial::Instance* mDebugPrimitiveRenderMaterialInstance;; + + ID3D11Buffer* mDebugPrimitiveVB; + uint32_t mDebugPrimitiveVBVerticesCount; + + RenderDebugImpl* mRenderDebugImpl; + + bool mWireframeMode; +}; + +static nvidia::PxMat44 XMMATRIXToPxMat44(const DirectX::XMMATRIX& mat) +{ + nvidia::PxMat44 m; + memcpy(const_cast<float*>(m.front()), &mat.r[0], 4 * 4 * sizeof(float)); + return m; +} + +static DirectX::XMMATRIX PxMat44ToXMMATRIX(const nvidia::PxMat44& mat) +{ + return DirectX::XMMATRIX(mat.front()); +} + +static nvidia::PxVec4 XMVECTORToPxVec4(const DirectX::XMVECTOR& vec) +{ + DirectX::XMFLOAT4 f; + DirectX::XMStoreFloat4(&f, vec); + return nvidia::PxVec4(f.x, f.y, f.z, f.w); +} + +#endif
\ No newline at end of file diff --git a/APEX_1.4/samples_v2/SampleBase/ApexResourceCallback.cpp b/APEX_1.4/samples_v2/SampleBase/ApexResourceCallback.cpp new file mode 100644 index 00000000..690c65ad --- /dev/null +++ b/APEX_1.4/samples_v2/SampleBase/ApexResourceCallback.cpp @@ -0,0 +1,342 @@ +/* +* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. +* +* NVIDIA CORPORATION and its licensors retain all intellectual property +* and proprietary rights in and to this software, related documentation +* and any modifications thereto. Any use, reproduction, disclosure or +* distribution of this software and related documentation without an express +* license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#include "ApexResourceCallback.h" + +#include "DestructibleAsset.h" +#include "ClothingAsset.h" +#include "EffectPackageAsset.h" + +#include "EmitterAsset.h" +#include "ImpactEmitterAsset.h" +#include "IofxAsset.h" +#include "BasicIosAsset.h" +#include "RenderMeshAsset.h" +#include "ParticleIosAsset.h" + +#include <windows.h> +#include "Utils.h" + +#include "UserOpaqueMesh.h" + +#include "ApexRenderMaterial.h" + +#include "PsString.h" + +using namespace physx; +using namespace nvidia; + +#define PATH_MAX_LEN 512 + + +ApexResourceCallback::ApexResourceCallback() +{ + // search for root folder by default + addSearchDir("."); +} + +void* ApexResourceCallback::requestResource(const char* nameSpace, const char* name) +{ + Asset* asset = 0; + + if(!shdfnd::strcmp(nameSpace, DESTRUCTIBLE_AUTHORING_TYPE_NAME) + || !shdfnd::strcmp(nameSpace, CLOTHING_AUTHORING_TYPE_NAME) + || !shdfnd::strcmp(nameSpace, EMITTER_AUTHORING_TYPE_NAME) + || !shdfnd::strcmp(nameSpace, IMPACT_EMITTER_AUTHORING_TYPE_NAME) + || !shdfnd::strcmp(nameSpace, IOFX_AUTHORING_TYPE_NAME) + || !shdfnd::strcmp(nameSpace, BASIC_IOS_AUTHORING_TYPE_NAME) + || !shdfnd::strcmp(nameSpace, PARTICLE_IOS_AUTHORING_TYPE_NAME) + || !shdfnd::strcmp(nameSpace, RENDER_MESH_AUTHORING_TYPE_NAME)) + { + NvParameterized::Interface* params = deserializeFromFile(name); + if (params != NULL) + { + asset = mApexSDK->createAsset(params, name); + PX_ASSERT(asset && "ERROR Creating NvParameterized Asset"); + } + } + else if (!shdfnd::strcmp(nameSpace, APEX_OPAQUE_MESH_NAME_SPACE)) + { + NvParameterized::Interface* params = deserializeFromFile("woodChunkMesh"); + if (params != NULL) + { + asset = mApexSDK->createAsset(params, "woodChunkMesh"); + PX_ASSERT(asset && "ERROR Creating NvParameterized Asset"); + } + } + else if(!shdfnd::strcmp(nameSpace, APEX_MATERIALS_NAME_SPACE)) + { + // try load as GraphicMaterial first + if (mModuleParticles) + { + const NvParameterized::Interface *graphicMaterialData = mModuleParticles->locateGraphicsMaterialData(name); + if (graphicMaterialData) + { + ApexRenderMaterial* material = new ApexRenderMaterial(this, graphicMaterialData); + return material; + } + } + + // try load from xml file then + char path[PATH_MAX_LEN]; + const char* exts[] = { "xml" }; + if (findFile(name, std::vector<const char*>(exts, exts + sizeof(exts) / sizeof(exts[0])), path)) + { + ApexRenderMaterial* material = new ApexRenderMaterial(this, path); + return material; + } + } + else if (!shdfnd::strcmp(nameSpace, APEX_COLLISION_GROUP_128_NAME_SPACE)) + { + return NULL; + } + else if (!shdfnd::strcmp(nameSpace, APEX_CUSTOM_VB_NAME_SPACE)) + { + return NULL; + } + + // try load from particles DB + if (asset == NULL && mModuleParticles) + { + // mModuleParticles + NvParameterized::Interface *iface = mModuleParticles->locateResource(name, nameSpace); + if (iface) + { + NvParameterized::Interface *copyInterface = NULL; + iface->clone(copyInterface); // Create a copy of the parameterize data. + PX_ASSERT(copyInterface); + if (copyInterface) + { + asset = mApexSDK->createAsset(copyInterface, name); // Create the asset using this NvParameterized::Inteface data + PX_ASSERT(asset); + } + } + } + + PX_ASSERT_WITH_MESSAGE(asset, name); + return asset; +} + +NvParameterized::Interface* ApexResourceCallback::deserializeFromFile(const char* name) +{ + NvParameterized::Interface* params = NULL; + + char path[PATH_MAX_LEN]; + const char* exts[] = { "apb", "apx" }; + if (findFile(name, std::vector<const char*>(exts, exts + sizeof(exts) / sizeof(exts[0])), path)) + { + PxFileBuf* stream = mApexSDK->createStream(path, PxFileBuf::OPEN_READ_ONLY); + + if (stream) + { + NvParameterized::Serializer::SerializeType serType = mApexSDK->getSerializeType(*stream); + NvParameterized::Serializer::ErrorType serError; + NvParameterized::Serializer* ser = mApexSDK->createSerializer(serType); + PX_ASSERT(ser); + + NvParameterized::Serializer::DeserializedData data; + serError = ser->deserialize(*stream, data); + + if (serError == NvParameterized::Serializer::ERROR_NONE && data.size() == 1) + { + params = data[0]; + } + else + { + PX_ASSERT(0 && "ERROR Deserializing NvParameterized Asset"); + } + + stream->release(); + ser->release(); + } + } + + return params; +} + + +void ApexResourceCallback::releaseResource(const char* nameSpace, const char*, void* resource) +{ + if (!shdfnd::strcmp(nameSpace, DESTRUCTIBLE_AUTHORING_TYPE_NAME) || + !shdfnd::strcmp(nameSpace, CLOTHING_AUTHORING_TYPE_NAME)) + { + Asset* asset = (Asset*)resource; + mApexSDK->releaseAsset(*asset); + } + else if (!shdfnd::strcmp(nameSpace, APEX_MATERIALS_NAME_SPACE)) + { + delete (ApexRenderMaterial*)resource; + } +} + +void* ApexResourceCallback::requestResourceCustom(CustomResourceNameSpace customNameSpace, const char* name) +{ + std::pair<CustomResourceNameSpace, std::string> key(customNameSpace, name); + if (mCustomResources.find(key) == mCustomResources.end()) + { + void *resource = NULL; + if (customNameSpace == eSHADER_FILE_PATH) + { + char* path = new char[PATH_MAX_LEN]; + const char* exts[] = { "hlsl" }; + if (findFile(name, std::vector<const char*>(exts, exts + sizeof(exts) / sizeof(exts[0])), path)) + { + resource = path; + } + else + { + PX_ALWAYS_ASSERT_MESSAGE(name); + delete[] path; + } + } + else if (customNameSpace == eTEXTURE_RESOURCE) + { + char path[PATH_MAX_LEN]; + const char* exts[] = { "dds", "tga" }; + if (findFile(name, std::vector<const char*>(exts, exts + sizeof(exts) / sizeof(exts[0])), path)) + { + TextureResource* textureResource = new TextureResource(); + WCHAR wPath[MAX_PATH]; + MultiByteToWideChar(CP_ACP, 0, path, -1, wPath, MAX_PATH); + wPath[MAX_PATH - 1] = 0; + + const char* ext = strext(path); + if (::strcmp(ext, "dds") == 0) + { + V(DirectX::LoadFromDDSFile(wPath, DirectX::DDS_FLAGS_NONE, &textureResource->metaData, + textureResource->image)); + } + else if (::strcmp(ext, "tga") == 0) + { + V(DirectX::LoadFromTGAFile(wPath, &textureResource->metaData, + textureResource->image)); + } + else + { + PX_ALWAYS_ASSERT_MESSAGE("Unsupported texture extension"); + } + resource = textureResource; + } + } + + if (resource != NULL) + { + mCustomResources.emplace(key, resource); + } + else + { + PX_ALWAYS_ASSERT_MESSAGE(name); + } + } + return mCustomResources.at(key); +} + +void ApexResourceCallback::addSearchDir(const char* dir, bool recursive) +{ + uint32_t len = dir && *dir ? (uint32_t)strlen(dir) : 0; + if(len) + { + len++; + char* searchPath = new char[len]; + shdfnd::strlcpy(searchPath, len, dir); + SearchDir searcDir = { searchPath, recursive }; + mSearchDirs.push_back(searcDir); + } +} + +ApexResourceCallback::~ApexResourceCallback() +{ + // release search dirs + for(size_t i = 0; i < mSearchDirs.size(); i++) + { + delete[] mSearchDirs[i].path; + } + mSearchDirs.clear(); + + // release custom resources map + for (std::map<std::pair<CustomResourceNameSpace, std::string>, void*>::iterator it = mCustomResources.begin(); it != mCustomResources.end(); it++) + { + switch ((*it).first.first) + { + case eSHADER_FILE_PATH: + delete (char*)((*it).second); + break; + case eTEXTURE_RESOURCE: + delete (TextureResource*)((*it).second); + break; + default: + PX_ALWAYS_ASSERT(); + break; + } + } + mCustomResources.clear(); +} + +bool ApexResourceCallback::findFileInDir(const char* fileNameFull, const char* path, bool recursive, char* foundPath) +{ + WIN32_FIND_DATA ffd; + char tmp[PATH_MAX_LEN]; + shdfnd::snprintf(tmp, sizeof(tmp), "%s\\*", path); + HANDLE hFind = FindFirstFile(tmp, &ffd); + + if(INVALID_HANDLE_VALUE == hFind) + { + return NULL; + } + + do + { + if(0 == nvidia::strcmp(".", ffd.cFileName) || 0 == nvidia::strcmp("..", ffd.cFileName)) + continue; + + if(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + char tmp[PATH_MAX_LEN]; + shdfnd::snprintf(tmp, sizeof(tmp), "%s\\%s", path, ffd.cFileName); + if(findFileInDir(fileNameFull, tmp, recursive, foundPath)) + return true; + } + else if(nvidia::stricmp(ffd.cFileName, fileNameFull) == 0) + { + shdfnd::snprintf(foundPath, PATH_MAX_LEN, "%s\\%s", path, ffd.cFileName); + return true; + } + } while(FindNextFile(hFind, &ffd) != 0); + + return false; +} + +bool ApexResourceCallback::findFile(const char* fileName, std::vector<const char*> exts, char* foundPath) +{ + std::string fileNameOnly = fileName; + size_t ind = fileNameOnly.find_last_of('/'); + if (ind > 0) + fileNameOnly = fileNameOnly.substr(ind + 1); + + for(size_t i = 0; i < mSearchDirs.size(); i++) + { + const SearchDir& searchDir = mSearchDirs[i]; + + for(size_t j = 0; j < exts.size(); j++) + { + const char* ext = exts[j]; + const uint32_t fileMaxLen = 128; + char fileNameFull[fileMaxLen] = { 0 }; + + nvidia::shdfnd::snprintf(fileNameFull, fileMaxLen, "%s.%s", fileNameOnly.c_str(), ext); + if(findFileInDir(fileNameFull, searchDir.path, searchDir.recursive, foundPath)) + return true; + } + + if (findFileInDir(fileNameOnly.c_str(), searchDir.path, searchDir.recursive, foundPath)) + return true; + } + return false; +} diff --git a/APEX_1.4/samples_v2/SampleBase/ApexResourceCallback.h b/APEX_1.4/samples_v2/SampleBase/ApexResourceCallback.h new file mode 100644 index 00000000..4e4dbfaf --- /dev/null +++ b/APEX_1.4/samples_v2/SampleBase/ApexResourceCallback.h @@ -0,0 +1,77 @@ +/* +* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. +* +* NVIDIA CORPORATION and its licensors retain all intellectual property +* and proprietary rights in and to this software, related documentation +* and any modifications thereto. Any use, reproduction, disclosure or +* distribution of this software and related documentation without an express +* license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#ifndef APEX_RESOURCE_CALLBACK_H +#define APEX_RESOURCE_CALLBACK_H + +#include "Apex.h" +#include "ModuleParticles.h" + +#pragma warning(push) +#pragma warning(disable : 4350) +#include <vector> +#include <string> +#include <map> +#pragma warning(pop) + +using namespace nvidia::apex; + +class physx::PxFileBuf; + +class ApexResourceCallback : public ResourceCallback +{ + public: + ApexResourceCallback(); + ~ApexResourceCallback(); + + void setApexSDK(ApexSDK* apexSDK) + { + mApexSDK = apexSDK; + } + + void setModuleParticles(ModuleParticles* moduleParticles) + { + mModuleParticles = moduleParticles; + } + + // ResourceCallback API: + virtual void* requestResource(const char* nameSpace, const char* name); + virtual void releaseResource(const char* nameSpace, const char*, void* resource); + + // Internal samples API: + void addSearchDir(const char* dir, bool recursive = true); + NvParameterized::Interface* deserializeFromFile(const char* path); + + enum CustomResourceNameSpace + { + eSHADER_FILE_PATH, + eTEXTURE_RESOURCE + }; + + void* requestResourceCustom(CustomResourceNameSpace customNameSpace, const char* name); + + private: + ApexSDK* mApexSDK; + ModuleParticles* mModuleParticles; + + bool findFile(const char* fileName, std::vector<const char*> exts, char* foundPath); + bool findFileInDir(const char* fileNameFull, const char* path, bool recursive, char* foundPath); + + struct SearchDir + { + char* path; + bool recursive; + }; + + std::vector<SearchDir> mSearchDirs; + std::map<std::pair<CustomResourceNameSpace, std::string>, void*> mCustomResources; +}; + +#endif
\ No newline at end of file diff --git a/APEX_1.4/samples_v2/SampleBase/CommonUIController.cpp b/APEX_1.4/samples_v2/SampleBase/CommonUIController.cpp new file mode 100644 index 00000000..08be4392 --- /dev/null +++ b/APEX_1.4/samples_v2/SampleBase/CommonUIController.cpp @@ -0,0 +1,404 @@ +/* +* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. +* +* NVIDIA CORPORATION and its licensors retain all intellectual property +* and proprietary rights in and to this software, related documentation +* and any modifications thereto. Any use, reproduction, disclosure or +* distribution of this software and related documentation without an express +* license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#include "CommonUIController.h" + +#include <DirectXMath.h> + +#include "XInput.h" +#include "DXUTMisc.h" +#pragma warning(push) +#pragma warning(disable : 4481) // Suppress "nonstandard extension used" warning +#include "DXUTCamera.h" +#pragma warning(pop) + +#include "ApexRenderer.h" +#include "ApexController.h" + +using namespace std; + +CommonUIController::CommonUIController(CFirstPersonCamera* cam, ApexRenderer* r, ApexController* a) +: mCamera(cam) +, mApexRenderer(r) +, mApexController(a) +, mShowHint(false) +{ + mHintOffLines.push_back("Press F1 to toggle hint"); +} + +HRESULT CommonUIController::DeviceCreated(ID3D11Device* pDevice) +{ + TwInit(TW_DIRECT3D11, pDevice); + TwDefine("GLOBAL fontstyle=fixed contained=true"); + + mSettingsBar = TwNewBar("Settings"); + TwDefine( + "Settings color='19 25 19' alpha=128 text=light size='380 350' iconified=true valueswidth=65 position='12 80'"); + + TwAddVarCB(mSettingsBar, "WireFrame", TW_TYPE_BOOLCPP, CommonUIController::setWireframeEnabled, + CommonUIController::getWireframeEnabled, this, "group=Main key=o"); + TwAddButton(mSettingsBar, "Reload Shaders", CommonUIController::onReloadShadersButton, this, "group=Main key=f5"); + TwAddVarRW(mSettingsBar, "Ambient Color", TW_TYPE_COLOR3F, &(mApexRenderer->getAmbientColor()), "group='Scene'"); + TwAddVarRW(mSettingsBar, "Point Light Color", TW_TYPE_COLOR3F, &(mApexRenderer->getPointLightColor()), "group='Scene'"); + TwAddVarRW(mSettingsBar, "Point Light Pos", TW_TYPE_DIR3F, &(mApexRenderer->getPointLightPos()), "group='Scene'"); + TwAddVarRW(mSettingsBar, "Dir Light Color", TW_TYPE_COLOR3F, &(mApexRenderer->getDirLightColor()), "group='Scene'"); + TwAddVarRW(mSettingsBar, "Dir Light Dir", TW_TYPE_DIR3F, &(mApexRenderer->getDirLightDir()), "group='Scene'"); + TwAddVarRW(mSettingsBar, "Specular Power", TW_TYPE_FLOAT, &(mApexRenderer->getSpecularPower()), "group='Scene' min=1 max=500 step=1"); + TwAddVarRW(mSettingsBar, "Specular Intensity", TW_TYPE_FLOAT, &(mApexRenderer->getSpecularIntensity()), "group='Scene' min=0 max=2 step=0.05"); + + addPhysXDebugRenderParam(PxVisualizationParameter::eWORLD_AXES); + addPhysXDebugRenderParam(PxVisualizationParameter::eBODY_AXES); + addPhysXDebugRenderParam(PxVisualizationParameter::eACTOR_AXES); + + addHintLine("Rotate camera - RMB"); + addHintLine("Move camera - WASDQE(SHIFT)"); + addHintLine("Play/Pause - P"); + addHintLine("Reload shaders - F5"); + addHintLine("Wireframe - O"); + + + toggleCameraSpeed(false); + + return S_OK; +} + +void CommonUIController::DeviceDestroyed() +{ + TwTerminate(); + + for (std::list<IDebugRenderParam*>::iterator it = mDebugRenderParams.begin(); it != mDebugRenderParams.end(); it++) + { + delete (*it); + } + mDebugRenderParams.clear(); +} + +LRESULT CommonUIController::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + PX_UNUSED(hWnd); + PX_UNUSED(wParam); + PX_UNUSED(lParam); + + if(uMsg == WM_KEYDOWN || uMsg == WM_KEYUP) + { + // Camera overspeed event + int iKeyPressed = static_cast<int>(wParam); + if(iKeyPressed == VK_SHIFT) + { + toggleCameraSpeed(uMsg == WM_KEYDOWN); + } + + // Play/Pause + if (iKeyPressed == 'P' && uMsg == WM_KEYDOWN) + { + mApexController->togglePlayPause(); + } + + // Hint show/hide + if (iKeyPressed == VK_F1 && uMsg == WM_KEYDOWN) + { + mShowHint = !mShowHint; + } + } + + // TW events capture + if(TwEventWin(hWnd, uMsg, wParam, lParam)) + { + return 0; // Event has been handled by AntTweakBar + } + + // Camera events + mCamera->HandleMessages(hWnd, uMsg, wParam, lParam); + + return 1; +} + +void CommonUIController::Animate(double fElapsedTimeSeconds) +{ + mCamera->FrameMove((float)fElapsedTimeSeconds); +} + +void CommonUIController::Render(ID3D11Device*, ID3D11DeviceContext*, ID3D11RenderTargetView*, ID3D11DepthStencilView*) +{ + // Render stats text + TwBeginText(2, 0, 0, 0); + char msg[256]; + double averageTime = GetDeviceManager()->GetAverageFrameTime(); + double fps = (averageTime > 0) ? 1.0 / averageTime : 0.0; + sprintf_s(msg, "FPS: %.1f", fps); + TwAddTextLine(msg, 0xFF9BD839, 0xFF000000); + sprintf_s(msg, "Simulation Time: %.5fs ", mApexController->getLastSimulationTime()); + TwAddTextLine(msg, 0xFF9BD839, 0xFF000000); + TwEndText(); + + // Render hint text + list<string> lines = mShowHint ? mHintOnLines : mHintOffLines; + uint32_t lineNum = 0; + for (list<string>::iterator it = lines.begin(); it != lines.end(); it++) + { + int tw, th; + TwMeasureTextLine(it->c_str(), &tw, &th); + TwBeginText((int32_t)mWidth - tw - 2, th * (int32_t)lineNum, 0, 0); + TwAddTextLine(it->c_str(), 0xFFFFFF99, 0xFF000000); + TwEndText(); + + lineNum++; + } + + TwDraw(); +} + +void CommonUIController::BackBufferResized(ID3D11Device* pDevice, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc) +{ + PX_UNUSED(pDevice); + + mWidth = pBackBufferSurfaceDesc->Width; + mHeight = pBackBufferSurfaceDesc->Height; + + TwWindowSize((int32_t)mWidth, (int32_t)mHeight); +} + +void CommonUIController::toggleCameraSpeed(bool overspeed) +{ + mCamera->SetScalers(0.002f, overspeed ? 150.f : 25.f); +} + +void CommonUIController::addHintLine(std::string hintLine) +{ + mHintOnLines.push_back(hintLine); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// UI Callbacks +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void TW_CALL CommonUIController::setDebugRenderParam(const void* value, void* clientData) +{ + IDebugRenderParam* param = static_cast<IDebugRenderParam*>(clientData); + param->setParamEnabled(*static_cast<const bool*>(value)); +} + +void TW_CALL CommonUIController::getDebugRenderParam(void* value, void* clientData) +{ + IDebugRenderParam* param = static_cast<IDebugRenderParam*>(clientData); + *static_cast<bool*>(value) = param->isParamEnabled(); +} + + +void TW_CALL CommonUIController::setWireframeEnabled(const void* value, void* clientData) +{ + CommonUIController* controller = static_cast<CommonUIController*>(clientData); + controller->mApexRenderer->setWireframeMode(*static_cast<const bool*>(value)); +} + +void TW_CALL CommonUIController::getWireframeEnabled(void* value, void* clientData) +{ + CommonUIController* controller = static_cast<CommonUIController*>(clientData); + *static_cast<bool*>(value) = controller->mApexRenderer->getWireframeMode(); +} + + +void TW_CALL CommonUIController::onReloadShadersButton(void* clientData) +{ + CommonUIController* controller = static_cast<CommonUIController*>(clientData); + controller->mApexRenderer->reloadShaders(); +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Debug Render Params +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +bool CommonUIController::ApexDebugRenderParam::isParamEnabled() +{ + Scene* scene = mController->mApexController->getApexScene(); + + NvParameterized::Interface* debugRenderInterface = scene->getDebugRenderParams(); + if (!mModule.empty()) + { + debugRenderInterface = scene->getModuleDebugRenderParams(mModule.c_str()); + } + + NvParameterized::Handle handle(*debugRenderInterface, mName.c_str()); + PX_ASSERT(handle.isValid()); + + if (handle.parameterDefinition()->type() == NvParameterized::TYPE_F32) + { + float v; + handle.getParamF32(v); + return v == mValue; + } + else if (handle.parameterDefinition()->type() == NvParameterized::TYPE_U32) + { + uint32_t v; + handle.getParamU32(v); + return v == uint32_t(mValue); + } + else if (handle.parameterDefinition()->type() == NvParameterized::TYPE_BOOL) + { + bool v; + handle.getParamBool(v); + return v; + } + else + { + PX_ALWAYS_ASSERT(); + return false; + } +} + +void CommonUIController::ApexDebugRenderParam::setParamEnabled(bool enabled) +{ + Scene* scene = mController->mApexController->getApexScene(); + + NvParameterized::Interface* debugRenderInterface = scene->getDebugRenderParams(); + NvParameterized::setParamBool(*debugRenderInterface, "Enable", true); + NvParameterized::setParamF32(*debugRenderInterface, "Scale", 1.0f); + + if (!mModule.empty()) + { + debugRenderInterface = scene->getModuleDebugRenderParams(mModule.c_str()); + } + + NvParameterized::Handle handle(*debugRenderInterface, mName.c_str()); + PX_ASSERT(handle.isValid()); + + if (handle.parameterDefinition()->type() == NvParameterized::TYPE_F32) + { + handle.setParamF32(enabled ? mValue : 0); + } + else if (handle.parameterDefinition()->type() == NvParameterized::TYPE_U32) + { + handle.setParamU32(mValue ? uint32_t(mValue) : 0); + } + else if (handle.parameterDefinition()->type() == NvParameterized::TYPE_BOOL) + { + handle.setParamBool(enabled); + } +} + +bool CommonUIController::PhysXDebugRenderParam::isParamEnabled() +{ + Scene* scene = mController->mApexController->getApexScene(); + return scene->getPhysXScene()->getVisualizationParameter(mParameter) != 0; +} + +void CommonUIController::PhysXDebugRenderParam::setParamEnabled(bool enabled) +{ + Scene* scene = mController->mApexController->getApexScene(); + scene->getPhysXScene()->setVisualizationParameter(mParameter, enabled ? 1.0f : 0.0f); +} + +static const char* getUINameForPhysXParam(physx::PxVisualizationParameter::Enum param) +{ + using physx::PxVisualizationParameter; + + switch (param) + { + case PxVisualizationParameter::eSCALE: + return "Scale"; + case PxVisualizationParameter::eBODY_AXES: + return "Body Axes"; + case PxVisualizationParameter::eWORLD_AXES: + return "World Axes"; + case PxVisualizationParameter::eBODY_MASS_AXES: + return "Body Mass Axes"; + case PxVisualizationParameter::eBODY_LIN_VELOCITY: + return "Body Lin Velocity"; + case PxVisualizationParameter::eBODY_ANG_VELOCITY: + return "Body Ang Velocity"; + case PxVisualizationParameter::eBODY_JOINT_GROUPS: + return "Body Joint"; + case PxVisualizationParameter::eCONTACT_POINT: + return "Contact Point"; + case PxVisualizationParameter::eCONTACT_NORMAL: + return "Contact Normal"; + case PxVisualizationParameter::eCONTACT_ERROR: + return "Contact Error"; + case PxVisualizationParameter::eCONTACT_FORCE: + return "Contact Force"; + case PxVisualizationParameter::eACTOR_AXES: + return "Actor Axes"; + case PxVisualizationParameter::eCOLLISION_AABBS: + return "Collision AABBs"; + case PxVisualizationParameter::eCOLLISION_SHAPES: + return "Collision Shapes"; + case PxVisualizationParameter::eCOLLISION_AXES: + return "Collision Axes"; + case PxVisualizationParameter::eCOLLISION_COMPOUNDS: + return "Collision Compounds"; + case PxVisualizationParameter::eCOLLISION_FNORMALS: + return "Collision FNormals"; + case PxVisualizationParameter::eCOLLISION_EDGES: + return "Collision Edges"; + case PxVisualizationParameter::eCOLLISION_STATIC: + return "Collision Static"; + case PxVisualizationParameter::eCOLLISION_DYNAMIC: + return "Collision Dynamic"; + case PxVisualizationParameter::eJOINT_LOCAL_FRAMES: + return "Joint Local Frames"; + case PxVisualizationParameter::eJOINT_LIMITS: + return "Joint Limits"; + case PxVisualizationParameter::ePARTICLE_SYSTEM_POSITION: + return "PS Position"; + case PxVisualizationParameter::ePARTICLE_SYSTEM_VELOCITY: + return "PS Velocity"; + case PxVisualizationParameter::ePARTICLE_SYSTEM_COLLISION_NORMAL: + return "PS Collision Normal"; + case PxVisualizationParameter::ePARTICLE_SYSTEM_BOUNDS: + return "PS Bounds"; + case PxVisualizationParameter::ePARTICLE_SYSTEM_GRID: + return "PS Grid"; + case PxVisualizationParameter::ePARTICLE_SYSTEM_BROADPHASE_BOUNDS: + return "PS Broadphase Bounds"; + case PxVisualizationParameter::ePARTICLE_SYSTEM_MAX_MOTION_DISTANCE: + return "PS Max Motion Distance"; + case PxVisualizationParameter::eCULL_BOX: + return "Cull Box"; + case PxVisualizationParameter::eCLOTH_VERTICAL: + return "Cloth Vertical"; + case PxVisualizationParameter::eCLOTH_HORIZONTAL: + return "Cloth Horizontal"; + case PxVisualizationParameter::eCLOTH_BENDING: + return "Cloth Bending"; + case PxVisualizationParameter::eCLOTH_SHEARING: + return "Cloth Shearing"; + case PxVisualizationParameter::eCLOTH_VIRTUAL_PARTICLES: + return "Cloth Virtual Particles"; + case PxVisualizationParameter::eMBP_REGIONS: + return "MBP Regions"; + default: + PX_ALWAYS_ASSERT(); + return ""; + } +} + +void CommonUIController::addApexDebugRenderParam(std::string name, std::string module, float value, std::string uiName) +{ + PX_ASSERT(mSettingsBar); + + IDebugRenderParam* param = new ApexDebugRenderParam(this, name, module, value); + mDebugRenderParams.push_back(param); + + TwAddVarCB(mSettingsBar, uiName.empty() ? name.c_str() : uiName.c_str(), TW_TYPE_BOOLCPP, CommonUIController::setDebugRenderParam, + CommonUIController::getDebugRenderParam, param, "group='Debug Render'"); +} + +void CommonUIController::addPhysXDebugRenderParam(physx::PxVisualizationParameter::Enum parameter) +{ + PX_ASSERT(mSettingsBar); + + IDebugRenderParam* param = new PhysXDebugRenderParam(this, parameter); + mDebugRenderParams.push_back(param); + + TwAddVarCB(mSettingsBar, getUINameForPhysXParam(parameter), TW_TYPE_BOOLCPP, CommonUIController::setDebugRenderParam, + CommonUIController::getDebugRenderParam, param, "group='Debug Render'"); +}
\ No newline at end of file diff --git a/APEX_1.4/samples_v2/SampleBase/CommonUIController.h b/APEX_1.4/samples_v2/SampleBase/CommonUIController.h new file mode 100644 index 00000000..9790957f --- /dev/null +++ b/APEX_1.4/samples_v2/SampleBase/CommonUIController.h @@ -0,0 +1,110 @@ +/* +* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. +* +* NVIDIA CORPORATION and its licensors retain all intellectual property +* and proprietary rights in and to this software, related documentation +* and any modifications thereto. Any use, reproduction, disclosure or +* distribution of this software and related documentation without an express +* license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#ifndef COMMON_UI_CONTROLLER_H +#define COMMON_UI_CONTROLLER_H + +#include "SampleManager.h" +#include <DirectXMath.h> +#include "AntTweakBar.h" +#pragma warning(push) +#pragma warning(disable : 4350) +#include <string> +#include <list> +#pragma warning(pop) +#include "PxPhysicsAPI.h" + +class CFirstPersonCamera; +class ApexRenderer; +class ApexController; + +class CommonUIController : public ISampleController +{ + public: + CommonUIController(CFirstPersonCamera* cam, ApexRenderer* r, ApexController* a); + virtual ~CommonUIController() {}; + + virtual HRESULT DeviceCreated(ID3D11Device* pDevice); + virtual void DeviceDestroyed(); + virtual LRESULT MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + virtual void Animate(double fElapsedTimeSeconds); + virtual void Render(ID3D11Device*, ID3D11DeviceContext*, ID3D11RenderTargetView*, ID3D11DepthStencilView*); + virtual void BackBufferResized(ID3D11Device* pDevice, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc); + + void addHintLine(std::string hintLine); + + void addApexDebugRenderParam(std::string name, std::string module = "", float value = 1.0f, std::string uiName = ""); + void addPhysXDebugRenderParam(physx::PxVisualizationParameter::Enum parameter); + + static void TW_CALL setWireframeEnabled(const void* value, void* clientData); + static void TW_CALL getWireframeEnabled(void* value, void* clientData); + + static void TW_CALL setDebugRenderParam(const void* value, void* clientData); + static void TW_CALL getDebugRenderParam(void* value, void* clientData); + + static void TW_CALL onReloadShadersButton(void* clientData); + + private: + void toggleCameraSpeed(bool overspeed); + + CFirstPersonCamera* mCamera; + ApexRenderer* mApexRenderer; + ApexController* mApexController; + TwBar* mSettingsBar; + + UINT mWidth; + UINT mHeight; + + std::list<std::string> mHintOnLines; + std::list<std::string> mHintOffLines; + bool mShowHint; + + class IDebugRenderParam + { + public: + virtual ~IDebugRenderParam() {} + virtual bool isParamEnabled() = 0; + virtual void setParamEnabled(bool) = 0; + }; + + class ApexDebugRenderParam : public IDebugRenderParam + { + public: + ApexDebugRenderParam(CommonUIController* controller, std::string name, std::string module, float value) + : mController(controller), mName(name), mModule(module), mValue(value) {} + + virtual bool isParamEnabled(); + virtual void setParamEnabled(bool); + + private: + CommonUIController* mController; + std::string mName; + std::string mModule; + float mValue; + }; + + class PhysXDebugRenderParam : public IDebugRenderParam + { + public: + PhysXDebugRenderParam(CommonUIController* controller, physx::PxVisualizationParameter::Enum parameter) + : mController(controller), mParameter(parameter) {} + + virtual bool isParamEnabled(); + virtual void setParamEnabled(bool); + + private: + CommonUIController* mController; + physx::PxVisualizationParameter::Enum mParameter; + }; + + std::list<IDebugRenderParam*> mDebugRenderParams; +}; + +#endif
\ No newline at end of file diff --git a/APEX_1.4/samples_v2/SampleBase/PhysXPrimitive.cpp b/APEX_1.4/samples_v2/SampleBase/PhysXPrimitive.cpp new file mode 100644 index 00000000..b6eac540 --- /dev/null +++ b/APEX_1.4/samples_v2/SampleBase/PhysXPrimitive.cpp @@ -0,0 +1,241 @@ +/* +* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. +* +* NVIDIA CORPORATION and its licensors retain all intellectual property +* and proprietary rights in and to this software, related documentation +* and any modifications thereto. Any use, reproduction, disclosure or +* distribution of this software and related documentation without an express +* license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + + +#include "PhysXPrimitive.h" +#include <DirectXMath.h> +#include "ApexRenderMaterial.h" + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Base Mesh internal class +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +class Mesh +{ +public: + Mesh(const float v[], UINT numVertices) + { + ID3D11Device* device = GetDeviceManager()->GetDevice(); + + ID3D11DeviceContext* context; + device->GetImmediateContext(&context); + + mNumVertices = numVertices; + + D3D11_SUBRESOURCE_DATA vertexBufferData; + + ZeroMemory(&vertexBufferData, sizeof(vertexBufferData)); + vertexBufferData.pSysMem = v; + + D3D11_BUFFER_DESC bufferDesc; + + memset(&bufferDesc, 0, sizeof(D3D11_BUFFER_DESC)); + bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bufferDesc.ByteWidth = sizeof(float) * 6 * mNumVertices; + bufferDesc.CPUAccessFlags = 0; + bufferDesc.MiscFlags = 0; + bufferDesc.Usage = D3D11_USAGE_IMMUTABLE; + + V(device->CreateBuffer(&bufferDesc, &vertexBufferData, &mVertexBuffer)); + } + + ~Mesh() + { + SAFE_RELEASE(mVertexBuffer); + } + + void render(ID3D11DeviceContext& context) + { + ID3D11Buffer* pBuffers[1] = { mVertexBuffer }; + UINT strides[1] = { 6 * sizeof(float) }; + UINT offsets[1] = { 0 }; + context.IASetVertexBuffers(0, 1, pBuffers, strides, offsets); + + context.Draw(mNumVertices, 0); + } +private: + UINT mNumVertices; + ID3D11Buffer* mVertexBuffer; + +}; + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Box Mesh +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +const float boxVertices[] = +{ + -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, + 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, + 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, + 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, + -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, + -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, + + -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, + 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, + -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, + -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, + + -1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, + -1.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, + -1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, + -1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, + -1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, + -1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, + + 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, + 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, + 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, + 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, + 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, + 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, + + -1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, + 1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, + 1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, + 1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, + -1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, + -1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, + + -1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, + -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, + -1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f +}; + +class BoxMesh : public Mesh +{ +public: + BoxMesh() : Mesh(boxVertices, sizeof(boxVertices) / (6 * sizeof(boxVertices[0]))) {} +}; + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Plane Mesh +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +const float planeSize = 0.5f; + +const float planeVertices[] = +{ + 0, planeSize, planeSize, 1.0f, 0.0f, 0.0f, + 0, planeSize, -planeSize, 1.0f, 0.0f, 0.0f, + 0, -planeSize, -planeSize, 1.0f, 0.0f, 0.0f, + 0, -planeSize, -planeSize, 1.0f, 0.0f, 0.0f, + 0, -planeSize, planeSize, 1.0f, 0.0f, 0.0f, + 0, planeSize, planeSize, 1.0f, 0.0f, 0.0f, +}; + +class PlaneMesh : public Mesh +{ +public: + PlaneMesh() : Mesh(planeVertices, sizeof(planeVertices) / (6 * sizeof(planeVertices[0]))) {} +}; + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Mesh Factory (Singleton) +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +class MeshFactory +{ +public: + ~MeshFactory() + { + for (int i = 0; i < PxGeometryType::eGEOMETRY_COUNT; i++) + { + if (_meshes[i]) + { + delete _meshes[i]; + } + } + } + + static MeshFactory& GetInstance() + { + static MeshFactory instance; + return instance; + } + + Mesh* GetMesh(PxGeometryType::Enum type) + { + if (_meshes[type] == NULL) + { + switch (type) + { + case PxGeometryType::eBOX: + _meshes[type] = new BoxMesh(); + break; + case PxGeometryType::ePLANE: + _meshes[type] = new PlaneMesh(); + break; + default: + PX_ALWAYS_ASSERT_MESSAGE("Unsupported PxGeometryType"); + return NULL; + } + } + + return _meshes[type]; + } + +private: + MeshFactory() {} + MeshFactory(const MeshFactory&); + MeshFactory& operator=(MeshFactory&); + + Mesh* _meshes[PxGeometryType::eGEOMETRY_COUNT]; +}; + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// PhysXPrimitive +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +PhysXPrimitive::PhysXPrimitive(PxRigidActor* actor, PxVec3 scale) : + mColor(1.0f, 1.0f, 1.0f) +{ + mActor = actor; + mScale = scale; + + PxShape* buffer[1]; + actor->getShapes(buffer, 1); + mMesh = MeshFactory::GetInstance().GetMesh(buffer[0]->getGeometryType()); + +} + + +PhysXPrimitive::~PhysXPrimitive() +{ +} + + +PxMat44 PhysXPrimitive::getModelMatrix() +{ + return PxMat44(mActor->getGlobalPose()) * PxMat44(PxVec4(mScale, 1)); +} + + +void PhysXPrimitive::render(ID3D11DeviceContext& context) +{ + context.IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + + mMesh->render(context); +}
\ No newline at end of file diff --git a/APEX_1.4/samples_v2/SampleBase/PhysXPrimitive.h b/APEX_1.4/samples_v2/SampleBase/PhysXPrimitive.h new file mode 100644 index 00000000..3094f224 --- /dev/null +++ b/APEX_1.4/samples_v2/SampleBase/PhysXPrimitive.h @@ -0,0 +1,54 @@ +/* +* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. +* +* NVIDIA CORPORATION and its licensors retain all intellectual property +* and proprietary rights in and to this software, related documentation +* and any modifications thereto. Any use, reproduction, disclosure or +* distribution of this software and related documentation without an express +* license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#ifndef PHYSX_PRIMITIVE_H +#define PHYSX_PRIMITIVE_H + +#include "Utils.h" +#include "PxPhysicsAPI.h" +#include <DirectXMath.h> + +using namespace physx; + +class ApexRenderMaterial; +class Mesh; + +class PhysXPrimitive +{ + public: + PhysXPrimitive(PxRigidActor* actor, PxVec3 scale); + ~PhysXPrimitive(); + + PxRigidActor* getActor() + { + return mActor; + } + + void setColor(DirectX::XMFLOAT3 color) + { + mColor = color; + } + DirectX::XMFLOAT3 getColor() + { + return mColor; + } + + PxMat44 getModelMatrix(); + + void render(ID3D11DeviceContext& context); + + private: + DirectX::XMFLOAT3 mColor; + PxRigidActor* mActor; + Mesh* mMesh; + PxVec3 mScale; +}; + +#endif
\ No newline at end of file diff --git a/APEX_1.4/samples_v2/SampleBase/SampleManager.cpp b/APEX_1.4/samples_v2/SampleBase/SampleManager.cpp new file mode 100644 index 00000000..0434053c --- /dev/null +++ b/APEX_1.4/samples_v2/SampleBase/SampleManager.cpp @@ -0,0 +1,78 @@ +/* +* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. +* +* NVIDIA CORPORATION and its licensors retain all intellectual property +* and proprietary rights in and to this software, related documentation +* and any modifications thereto. Any use, reproduction, disclosure or +* distribution of this software and related documentation without an express +* license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#include "SampleManager.h" + +#include "Utils.h" +#pragma warning(push) +#pragma warning(disable : 4917) +#pragma warning(disable : 4365) +#include "XInput.h" +#include "DXUTMisc.h" +#pragma warning(pop) + + +SampleManager::SampleManager(LPWSTR sampleName) +: mSampleName(sampleName) +{ + mDeviceManager = new DeviceManager(); +} + +void SampleManager::addControllerToFront(ISampleController* controller) +{ + mControllers.push_back(controller); +} + +int SampleManager::run() +{ + // FirstPersonCamera uses this timer, without it it will be FPS-dependent + DXUTGetGlobalTimer()->Start(); + + for (auto it = mControllers.begin(); it != mControllers.end(); it++) + mDeviceManager->AddControllerToFront(*it); + + DeviceCreationParameters deviceParams; + deviceParams.swapChainFormat = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; + deviceParams.swapChainSampleCount = 1; + deviceParams.startFullscreen = false; + deviceParams.backBufferWidth = 1280; + deviceParams.backBufferHeight = 720; +#if defined(DEBUG) | defined(_DEBUG) + deviceParams.createDeviceFlags = D3D11_CREATE_DEVICE_DEBUG; +#endif + deviceParams.featureLevel = D3D_FEATURE_LEVEL_11_0; + + if (FAILED(mDeviceManager->CreateWindowDeviceAndSwapChain(deviceParams, mSampleName))) + { + MessageBox(nullptr, "Cannot initialize the D3D11 device with the requested parameters", "Error", + MB_OK | MB_ICONERROR); + return 1; + } + + for (auto it = mControllers.begin(); it != mControllers.end(); it++) + (*it)->onInitialize(); + + for (auto it = mControllers.begin(); it != mControllers.end(); it++) + (*it)->onSampleStart(); + + mDeviceManager->SetVsyncEnabled(false); + mDeviceManager->MessageLoop(); + + for (auto it = mControllers.begin(); it != mControllers.end(); it++) + (*it)->onSampleStop(); + + for (auto it = mControllers.begin(); it != mControllers.end(); it++) + (*it)->onTerminate(); + + mDeviceManager->Shutdown(); + delete mDeviceManager; + + return 0; +} diff --git a/APEX_1.4/samples_v2/SampleBase/SampleManager.h b/APEX_1.4/samples_v2/SampleBase/SampleManager.h new file mode 100644 index 00000000..a04ece1e --- /dev/null +++ b/APEX_1.4/samples_v2/SampleBase/SampleManager.h @@ -0,0 +1,45 @@ +/* +* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. +* +* NVIDIA CORPORATION and its licensors retain all intellectual property +* and proprietary rights in and to this software, related documentation +* and any modifications thereto. Any use, reproduction, disclosure or +* distribution of this software and related documentation without an express +* license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#ifndef SAMPLE_MANAGER_H +#define SAMPLE_MANAGER_H + +#include "Utils.h" +#pragma warning(push) +#pragma warning(disable : 4350) +#include <list> +#include <string> + + +class ISampleController : public IVisualController +{ + public: + virtual void onInitialize() {} + virtual void onSampleStart() {} + virtual void onSampleStop() {} + virtual void onTerminate() {} +}; + + +class SampleManager +{ + public: + SampleManager(LPWSTR sampleName); + void addControllerToFront(ISampleController* controller); + int run(); + + private: + DeviceManager* mDeviceManager; + std::list<ISampleController*> mControllers; + LPWSTR mSampleName; +}; + + +#endif
\ No newline at end of file diff --git a/APEX_1.4/samples_v2/SampleBase/Utils.cpp b/APEX_1.4/samples_v2/SampleBase/Utils.cpp new file mode 100644 index 00000000..a271137d --- /dev/null +++ b/APEX_1.4/samples_v2/SampleBase/Utils.cpp @@ -0,0 +1,13 @@ +#include "Utils.h" + +#include <string> +#include <cstdarg> + +HRESULT messagebox_printf(const char* caption, UINT mb_type, const char* format, ...) +{ + va_list args; + va_start(args, format); + char formatted_text[512]; + _vsnprintf(formatted_text, 512, format, args); + return MessageBoxA(nullptr, formatted_text, caption, mb_type); +} diff --git a/APEX_1.4/samples_v2/SampleBase/Utils.h b/APEX_1.4/samples_v2/SampleBase/Utils.h new file mode 100644 index 00000000..d592b18b --- /dev/null +++ b/APEX_1.4/samples_v2/SampleBase/Utils.h @@ -0,0 +1,179 @@ +#ifndef UTILS_H +#define UTILS_H + +#pragma warning(push) +#pragma warning(disable : 4917) +#pragma warning(disable : 4365) +#pragma warning(disable : 4350) +#include <DeviceManager.h> +#include <d3dcompiler.h> +#include <assert.h> +#include <sstream> +#pragma warning(pop) + +#include "PxPreprocessor.h" + +#pragma warning(disable : 4505) + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// MACROS +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef V_RETURN +#define V_RETURN(x) \ + { \ + hr = (x); \ + if(FAILED(hr)) \ + { \ + return hr; \ + } \ + } +#endif + +#ifndef V +#define V(x) \ + { \ + HRESULT hr = (x); \ + _ASSERT(SUCCEEDED(hr)); \ + } +#endif + +#ifndef SAFE_RELEASE +#define SAFE_RELEASE(p) \ + { \ + if(p) \ + { \ + (p)->Release(); \ + (p) = NULL; \ + } \ + } +#endif + +#ifndef SAFE_DELETE +#define SAFE_DELETE(p) \ + { \ + if(p) \ + { \ + delete (p); \ + (p) = NULL; \ + } \ + } +#endif + +#define ASSERT_PRINT(cond, format, ...) \ + if(!(cond)) \ + { \ + messagebox_printf("Assertion Failed!", MB_OK | MB_ICONERROR, #cond "\n" format, __VA_ARGS__); \ + assert(cond); \ + } + +HRESULT messagebox_printf(const char* caption, UINT mb_type, const char* format, ...); + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// SHADER HELPERS +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +static HRESULT CompileShaderFromFile(const char* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, + ID3DBlob** ppBlobOut) +{ + HRESULT hr = S_OK; + ID3DBlob* pErrorBlob; + + WCHAR wFileName[MAX_PATH]; + MultiByteToWideChar(CP_ACP, 0, szFileName, -1, wFileName, MAX_PATH); + wFileName[MAX_PATH - 1] = 0; + hr = D3DCompileFromFile(wFileName, NULL, D3D_COMPILE_STANDARD_FILE_INCLUDE, szEntryPoint, szShaderModel, D3D10_SHADER_ENABLE_STRICTNESS, 0, + ppBlobOut, &pErrorBlob); + if(FAILED(hr)) + { + OutputDebugStringA((char*)pErrorBlob->GetBufferPointer()); + SAFE_RELEASE(pErrorBlob); + return hr; + } + SAFE_RELEASE(pErrorBlob); + + return S_OK; +} + +static HRESULT createShader(ID3D11Device* pDev, const void* pData, size_t len, ID3D11VertexShader** ppShd, bool) +{ + return pDev->CreateVertexShader(pData, len, nullptr, ppShd); +} + +static HRESULT createShader(ID3D11Device* pDev, const void* pData, size_t len, ID3D11GeometryShader** ppShd, + bool forceFast) +{ + PX_UNUSED(forceFast); + return pDev->CreateGeometryShader(pData, len, nullptr, ppShd); +} + +static HRESULT createShader(ID3D11Device* pDev, const void* pData, size_t len, ID3D11PixelShader** ppShd, bool) +{ + return pDev->CreatePixelShader(pData, len, nullptr, ppShd); +} + +static const char* shaderModel(ID3D11VertexShader**) +{ + return "vs_5_0"; +} + +static const char* shaderModel(ID3D11GeometryShader**) +{ + return "gs_5_0"; +} + +static const char* shaderModel(ID3D11PixelShader**) +{ + return "ps_5_0"; +} + +// Give back the shader buffer blob for use in CreateVertexLayout. Caller must release the blob. +template <class S> +static HRESULT createShaderFromFile(ID3D11Device* pDev, const char* szFileName, LPCSTR szEntryPoint, S** ppShd, + ID3DBlob*& pShaderBuffer, bool forceFast = false) +{ + HRESULT hr = CompileShaderFromFile(szFileName, szEntryPoint, shaderModel(ppShd), &pShaderBuffer); + if(SUCCEEDED(hr) && pShaderBuffer) + { + const void* shaderBufferData = pShaderBuffer->GetBufferPointer(); + const UINT shaderBufferSize = pShaderBuffer->GetBufferSize(); + createShader(pDev, shaderBufferData, shaderBufferSize, ppShd, forceFast); + } + return hr; +} + +// Overloaded, same as above but don't give back the shader buffer blob. +template <class S> +static HRESULT createShaderFromFile(ID3D11Device* pDev, const char* szFileName, LPCSTR szEntryPoint, S** ppShd, + bool forceFast = false) +{ + ID3DBlob* pShaderBuffer = NULL; + HRESULT hr = createShaderFromFile(pDev, szFileName, szEntryPoint, ppShd, pShaderBuffer, forceFast); + SAFE_RELEASE(pShaderBuffer); + return hr; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +static const char* strext(const char* str) +{ + const char* ext = NULL; // by default no extension found! + while (str) + { + str = strchr(str, '.'); + if (str) + { + str++; + ext = str; + } + } + return ext; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#endif
\ No newline at end of file diff --git a/APEX_1.4/samples_v2/SampleBase/shaders/clothing_asset_skinned.hlsl b/APEX_1.4/samples_v2/SampleBase/shaders/clothing_asset_skinned.hlsl new file mode 100644 index 00000000..0c5afca1 --- /dev/null +++ b/APEX_1.4/samples_v2/SampleBase/shaders/clothing_asset_skinned.hlsl @@ -0,0 +1,73 @@ +#include "common_buffers.hlsl" +#include "lighting.hlsl" + +SamplerState defaultSampler : register(s0); +Texture2D diffuseTexture : register(t0); +Texture2D bonesTexture : register(t1); + +struct VS_INPUT +{ + float3 position : POSITION0; + float3 normal : NORMAL0; + float2 uv : TEXCOORD0; + int3 boneIndices : TEXCOORD5; + float3 boneWeights : TEXCOORD6; +}; + +struct VS_OUTPUT +{ + float4 position : SV_POSITION; + float4 worldPos : POSITION0; + float2 uv : TEXCOORD0; + float3 normal : NORMAL0; +}; + +float4x4 getBoneMatrix(int boneIndex) +{ + float4x4 boneMatrix; + boneMatrix[0] = bonesTexture.Load(int3(0, boneIndex, 0)); + boneMatrix[1] = bonesTexture.Load(int3(1, boneIndex, 0)); + boneMatrix[2] = bonesTexture.Load(int3(2, boneIndex, 0)); + boneMatrix[3] = bonesTexture.Load(int3(3, boneIndex, 0)); + return boneMatrix; +} + +float4x4 accumulate_skin(float4 boneIndices0, float4 boneWeights0) +{ + float4x4 result = boneWeights0.x * getBoneMatrix(boneIndices0.x); + result = result + boneWeights0.y * getBoneMatrix(boneIndices0.y); + result = result + boneWeights0.z * getBoneMatrix(boneIndices0.z); + result = result + boneWeights0.w * getBoneMatrix(boneIndices0.w); + return result; +} + + +VS_OUTPUT VS(VS_INPUT iV) +{ + VS_OUTPUT oV; + + //float4x4 boneMatrix = accumulate_skin(iV.boneIndices, iV.boneWeights); + float4x4 boneMatrix = accumulate_skin(float4(iV.boneIndices, 0), float4(iV.boneWeights, 0)); + + float3 skinnedPos = mul(float4(iV.position, 1.0f), boneMatrix); + float4 worldSpacePos = mul(float4(skinnedPos, 1.0f), model); + float4 eyeSpacePos = mul(worldSpacePos, view); + oV.position = mul(eyeSpacePos, projection); + + oV.worldPos = worldSpacePos; + + // normals + float3 localNormal = mul(float4(skinnedPos, 0.0f), boneMatrix); + float3 worldNormal = mul(float4(localNormal, 0.0f), model); + oV.normal = worldNormal; + + oV.uv = iV.uv; + + return oV; +} + +float4 PS(VS_OUTPUT iV) : SV_Target0 +{ + float4 textureColor = diffuseTexture.Sample(defaultSampler, iV.uv); + return CalcPixelLight(textureColor, iV.worldPos, iV.normal); +}
\ No newline at end of file diff --git a/APEX_1.4/samples_v2/SampleBase/shaders/clothing_asset_static.hlsl b/APEX_1.4/samples_v2/SampleBase/shaders/clothing_asset_static.hlsl new file mode 100644 index 00000000..5a592d67 --- /dev/null +++ b/APEX_1.4/samples_v2/SampleBase/shaders/clothing_asset_static.hlsl @@ -0,0 +1,47 @@ +#include "common_buffers.hlsl" +#include "lighting.hlsl" + +SamplerState defaultSampler : register(s0); +Texture2D diffuseTexture : register(t0); +Texture2D bonesTexture : register(t1); + +struct VS_INPUT +{ + float3 position : POSITION0; + float3 normal : NORMAL0; + float2 uv : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 position : SV_POSITION; + float4 worldPos : POSITION0; + float2 uv : TEXCOORD0; + float3 normal : NORMAL0; +}; + +VS_OUTPUT VS(VS_INPUT iV) +{ + VS_OUTPUT oV; + + float4 worldSpacePos = mul(float4(iV.position, 1.0f), model); + float4 eyeSpacePos = mul(worldSpacePos, view); + oV.position = mul(eyeSpacePos, projection); + + oV.worldPos = worldSpacePos; + + // normals + float3 worldNormal = mul(float4(iV.normal, 0.0f), model); + oV.normal = worldNormal; + + oV.uv = iV.uv; + + return oV; +} + +float4 PS(VS_OUTPUT iV) : SV_Target0 +{ + float4 textureColor = diffuseTexture.Sample(defaultSampler, iV.uv); + + return CalcPixelLight(textureColor, iV.worldPos, iV.normal); +}
\ No newline at end of file diff --git a/APEX_1.4/samples_v2/SampleBase/shaders/common_buffers.hlsl b/APEX_1.4/samples_v2/SampleBase/shaders/common_buffers.hlsl new file mode 100644 index 00000000..62bf0776 --- /dev/null +++ b/APEX_1.4/samples_v2/SampleBase/shaders/common_buffers.hlsl @@ -0,0 +1,29 @@ +#ifndef COMMON_BUFFERS_HLSL +#define COMMON_BUFFERS_HLSL + +cbuffer Camera : register(b0) +{ + row_major matrix projection; + row_major matrix projectionInv; + row_major matrix view; + float3 viewPos; +}; + +cbuffer World : register(b1) +{ + float3 ambientColor; + float3 pointLightPos; + float3 pointLightColor; + float3 dirLightDir; + float specularPower; + float3 dirLightColor; + float specularIntensity; +}; + +cbuffer Object : register(b2) +{ + row_major matrix model; + float3 defaultColor; +}; + +#endif
\ No newline at end of file diff --git a/APEX_1.4/samples_v2/SampleBase/shaders/debug_primitive.hlsl b/APEX_1.4/samples_v2/SampleBase/shaders/debug_primitive.hlsl new file mode 100644 index 00000000..b96c53e3 --- /dev/null +++ b/APEX_1.4/samples_v2/SampleBase/shaders/debug_primitive.hlsl @@ -0,0 +1,31 @@ +#include "common_buffers.hlsl" + +struct VS_INPUT +{ + float3 position : POSITION0; + float3 color : COLOR0; +}; + +struct VS_OUTPUT +{ + float4 position : SV_POSITION; + float3 color : COLOR0; +}; + +VS_OUTPUT VS(VS_INPUT iV) +{ + VS_OUTPUT oV; + + float4 worldSpacePos = mul(float4(iV.position, 1.0f), model); + float4 eyeSpacePos = mul(worldSpacePos, view); + oV.position = mul(eyeSpacePos, projection); + + oV.color = iV.color; + + return oV; +} + +float4 PS(VS_OUTPUT iV) : SV_Target0 +{ + return float4(iV.color, 1); +}
\ No newline at end of file diff --git a/APEX_1.4/samples_v2/SampleBase/shaders/destruction_asset.hlsl b/APEX_1.4/samples_v2/SampleBase/shaders/destruction_asset.hlsl new file mode 100644 index 00000000..bb2ed1c1 --- /dev/null +++ b/APEX_1.4/samples_v2/SampleBase/shaders/destruction_asset.hlsl @@ -0,0 +1,56 @@ +#include "common_buffers.hlsl" +#include "lighting.hlsl" + +SamplerState defaultSampler : register(s0); +Texture2D diffuseTexture : register(t0); +Texture2D bonesTexture : register(t1); + +struct VS_INPUT +{ + float3 position : POSITION0; + float3 normal : NORMAL0; + float2 uv : TEXCOORD0; + int boneIndex : TEXCOORD5; +}; + +struct VS_OUTPUT +{ + float4 position : SV_POSITION; + float4 worldPos : POSITION0; + float2 uv : TEXCOORD0; + float3 normal : NORMAL0; +}; + +VS_OUTPUT VS(VS_INPUT iV) +{ + VS_OUTPUT oV; + + float4x4 boneMatrix; + boneMatrix[0] = bonesTexture.Load(int3(0, iV.boneIndex, 0)); + boneMatrix[1] = bonesTexture.Load(int3(1, iV.boneIndex, 0)); + boneMatrix[2] = bonesTexture.Load(int3(2, iV.boneIndex, 0)); + boneMatrix[3] = bonesTexture.Load(int3(3, iV.boneIndex, 0)); + + float3 skinnedPos = mul(float4(iV.position, 1.0f), boneMatrix); + float4 worldSpacePos = mul(float4(skinnedPos, 1.0f), model); + float4 eyeSpacePos = mul(worldSpacePos, view); + oV.position = mul(eyeSpacePos, projection); + + oV.worldPos = worldSpacePos; + + // normals + float3 localNormal = mul(float4(iV.normal, 0.0f), boneMatrix); + float3 worldNormal = mul(float4(localNormal, 0.0f), model); + oV.normal = worldNormal; + + oV.uv = iV.uv; + + return oV; +} + +float4 PS(VS_OUTPUT iV) : SV_Target0 +{ + float4 textureColor = diffuseTexture.Sample(defaultSampler, iV.uv); + + return CalcPixelLight(textureColor, iV.worldPos, iV.normal); +}
\ No newline at end of file diff --git a/APEX_1.4/samples_v2/SampleBase/shaders/lighting.hlsl b/APEX_1.4/samples_v2/SampleBase/shaders/lighting.hlsl new file mode 100644 index 00000000..6609dffa --- /dev/null +++ b/APEX_1.4/samples_v2/SampleBase/shaders/lighting.hlsl @@ -0,0 +1,48 @@ +#include "common_buffers.hlsl" + +static const float att_c = 1.0f; +static const float att_l = 0.014f; +static const float att_q = 0.0007f; + + +float CalcAttenuation(float distance) +{ + return 1 / (att_c + att_l * distance + att_q * distance * distance); +}; + + +float4 CalcLight(float4 textureColor, float3 lightDir, float3 viewDir, float3 normal, float3 lightColor, float specPower, float specIntensity, float attenuation) +{ + normal = normalize(normal); + + // diffuse + float3 dirToLight = normalize(-lightDir); + float diffuseFactor = max(dot(normal, dirToLight), 0.0); + float4 diffuse = float4(lightColor, 1) * textureColor * diffuseFactor * attenuation; + + // specular (Blinn-Phong) + float3 halfwayDir = normalize(dirToLight + viewDir); + float specFactor = pow(max(dot(viewDir, halfwayDir), 0.0), specPower); + float4 spec = float4(lightColor, 1) * specFactor * attenuation * specIntensity; + + return diffuse + spec; +}; + +float4 CalcPixelLight(float4 diffuseColor, float4 worldPos, float3 normal) +{ + float3 viewDir = normalize(viewPos - worldPos); + + // ambient + float4 ambient = float4(ambientColor, 1) * diffuseColor; + + // dir light + float4 dirLight = CalcLight(diffuseColor, dirLightDir, viewDir, normal, dirLightColor, specularPower, specularIntensity, 1); + + // point light + float3 pointLightDir = worldPos - pointLightPos; + float distance = length(pointLightDir); + float attenuation = CalcAttenuation(distance); + float4 pointLight = CalcLight(diffuseColor, pointLightDir, viewDir, normal, pointLightColor, specularPower, specularIntensity, attenuation); + + return ambient + dirLight + pointLight; +};
\ No newline at end of file diff --git a/APEX_1.4/samples_v2/SampleBase/shaders/mesh_particle.hlsl b/APEX_1.4/samples_v2/SampleBase/shaders/mesh_particle.hlsl new file mode 100644 index 00000000..615a1246 --- /dev/null +++ b/APEX_1.4/samples_v2/SampleBase/shaders/mesh_particle.hlsl @@ -0,0 +1,53 @@ +#include "common_buffers.hlsl" +#include "lighting.hlsl" + +SamplerState defaultSampler : register(s0); +Texture2D diffuseTexture : register(t0); + +static const float POINT_SIZE = 1.00f; + +struct VS_INPUT +{ + float3 position : POSITION0; + float3 normal : NORMAL; + float2 scale : TANGENT; + float2 uv : TEXCOORD0; + float3 instanceOffset : TEXCOORD9; + float3 instanceRotX : TEXCOORD10; + float3 instanceRotY : TEXCOORD11; + float3 instanceRotZ : TEXCOORD12; +}; + +struct VS_OUTPUT +{ + float4 position : SV_POSITION; + float4 worldPos : POSITION0; + float2 uv : TEXCOORD0; + float3 normal : NORMAL0; +}; + +VS_OUTPUT VS(VS_INPUT iV) +{ + VS_OUTPUT oV; + + float4x4 modelMatrix = mul(model, float4x4(float4(iV.instanceRotX, 0), float4(iV.instanceRotY, 0), float4(iV.instanceRotZ, 0), float4(iV.instanceOffset, 1))); + + float4 worldSpacePos = mul(float4(iV.position, 1.0f), modelMatrix); + float4 eyeSpacePos = mul(worldSpacePos, view); + oV.position = mul(eyeSpacePos, projection); + + oV.worldPos = worldSpacePos; + + oV.uv = iV.uv; + + float3 worldNormal = mul(float4(iV.normal, 0.0f), modelMatrix); + oV.normal = worldNormal; + + return oV; +} + +float4 PS(VS_OUTPUT iV) : SV_Target0 +{ + float4 textureColor = diffuseTexture.Sample(defaultSampler, iV.uv); + return CalcPixelLight(textureColor, iV.worldPos, iV.normal); +}
\ No newline at end of file diff --git a/APEX_1.4/samples_v2/SampleBase/shaders/physx_primitive.hlsl b/APEX_1.4/samples_v2/SampleBase/shaders/physx_primitive.hlsl new file mode 100644 index 00000000..80df4bf9 --- /dev/null +++ b/APEX_1.4/samples_v2/SampleBase/shaders/physx_primitive.hlsl @@ -0,0 +1,39 @@ +#include "common_buffers.hlsl" +#include "lighting.hlsl" + +struct VS_INPUT +{ + float3 position : POSITION0; + float3 normal : NORMAL0; +}; + +struct VS_OUTPUT +{ + float4 position : SV_POSITION; + float4 worldPos : POSITION0; + float3 normal : NORMAL0; +}; + +VS_OUTPUT VS(VS_INPUT iV) +{ + VS_OUTPUT oV; + + float4 worldSpacePos = mul(float4(iV.position, 1.0f), model); + float4 eyeSpacePos = mul(worldSpacePos, view); + oV.position = mul(eyeSpacePos, projection); + + oV.worldPos = worldSpacePos; + + // normals + float3 worldNormal = mul(float4(iV.normal, 0.0f), model); + oV.normal = worldNormal; + + return oV; +} + +float4 PS(VS_OUTPUT iV) : SV_Target0 +{ + float4 textureColor = float4(defaultColor, 1); + + return CalcPixelLight(textureColor, iV.worldPos, iV.normal); +}
\ No newline at end of file diff --git a/APEX_1.4/samples_v2/SampleBase/shaders/pointsprite.hlsl b/APEX_1.4/samples_v2/SampleBase/shaders/pointsprite.hlsl new file mode 100644 index 00000000..f36d1187 --- /dev/null +++ b/APEX_1.4/samples_v2/SampleBase/shaders/pointsprite.hlsl @@ -0,0 +1,107 @@ +#include "common_buffers.hlsl" +#include "lighting.hlsl" + +SamplerState linearSampler : register(s0); +SamplerState pointSampler : register(s1); +Texture2D diffuseTexture : register(t0); +Texture2D<float> depthTexture : register(t1); + +static const float POINT_SIZE = 1.00f; +static const float FADE_DISTANCE = 1.0f; + +struct VS_INPUT +{ + float3 position : POSITION0; + float4 color : COLOR0; + float2 scale : TANGENT; +}; + +struct VS_OUTPUT +{ + float4 position : SV_POSITION; + float4 color : COLOR0; + float2 uv : TEXCOORD0; + float2 screenPos : TEXCOORD1; + float2 depth : TEXCOORD2; + float2 pointSize : PSIZE; +}; + +VS_OUTPUT VS(VS_INPUT iV) +{ + VS_OUTPUT oV; + + float4 worldSpacePos = mul(float4(iV.position, 1.0f), model); + float4 eyeSpacePos = mul(worldSpacePos, view); + oV.position = mul(eyeSpacePos, projection); + + oV.color = iV.color; + oV.uv = float2(0, 0); + + // uncomment to use scale + //oV.pointSize = iV.scale * POINT_SIZE; + oV.pointSize = float2(1, 1) * POINT_SIZE; + + return oV; +} + +static const float4 SPRITE_VERTEX_POSITIONS[4] = +{ + float4( 0.5, -0.5, 0, 0), + float4( 0.5, 0.5, 0, 0), + float4( -0.5, -0.5, 0, 0), + float4( -0.5, 0.5, 0, 0), +}; + +static const float2 SPRITE_VERTEX_TEXCOORDS[4] = +{ + float2(1, 0), + float2(1, 1), + float2(0, 0), + float2(0, 1), +}; + +[maxvertexcount(4)] +void GS( point VS_OUTPUT sprite[1], inout TriangleStream<VS_OUTPUT> triStream ) +{ + VS_OUTPUT v; + + v.color = sprite[0].color; + v.pointSize = sprite[0].pointSize; + + float4 aspectFactor = float4((projection[0][0] / projection[1][1]) * v.pointSize.x, 1.0 * v.pointSize.y, 0, 0); + + [unroll] for(int i = 0; i < 4; ++i) + { + v.position = sprite[0].position + SPRITE_VERTEX_POSITIONS[i] * aspectFactor; + v.screenPos = v.position.xy / v.position.w; + v.depth = v.position.zw; + v.uv = SPRITE_VERTEX_TEXCOORDS[i]; + triStream.Append(v); + } + + triStream.RestartStrip(); +} + +float4 PS(VS_OUTPUT input) : SV_Target0 +{ + // soft particles fade: + float2 screenPos = 0.5*( (input.screenPos) + float2(1,1)); + screenPos.y = 1 - screenPos.y; + + float particleDepth = input.depth.x / input.depth.y; + + float depthSample = depthTexture.Sample(pointSampler, screenPos); + + float4 depthViewSample = mul(float4(input.screenPos, depthSample, 1), projectionInv ); + float4 depthViewParticle = mul(float4(input.screenPos, particleDepth, 1), projectionInv); + + float depthDiff = depthViewSample.z / depthViewSample.w - depthViewParticle.z / depthViewParticle.w; + if( depthDiff < 0 ) + discard; + + float depthFade = saturate( depthDiff / FADE_DISTANCE ); + + float4 textureColor = diffuseTexture.Sample(linearSampler, input.uv) * input.color; + textureColor.a *= depthFade; + return textureColor; +}
\ No newline at end of file |