aboutsummaryrefslogtreecommitdiff
path: root/APEX_1.4/samples_v2/SampleBase
diff options
context:
space:
mode:
authorgit perforce import user <a@b>2016-10-25 12:29:14 -0600
committerSheikh Dawood Abdul Ajees <Sheikh Dawood Abdul Ajees>2016-10-25 18:56:37 -0500
commit3dfe2108cfab31ba3ee5527e217d0d8e99a51162 (patch)
treefa6485c169e50d7415a651bf838f5bcd0fd3bfbd /APEX_1.4/samples_v2/SampleBase
downloadphysx-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')
-rw-r--r--APEX_1.4/samples_v2/SampleBase/ApexController.cpp577
-rw-r--r--APEX_1.4/samples_v2/SampleBase/ApexController.h192
-rw-r--r--APEX_1.4/samples_v2/SampleBase/ApexRenderMaterial.cpp288
-rw-r--r--APEX_1.4/samples_v2/SampleBase/ApexRenderMaterial.h123
-rw-r--r--APEX_1.4/samples_v2/SampleBase/ApexRenderResourceManager.cpp52
-rw-r--r--APEX_1.4/samples_v2/SampleBase/ApexRenderResourceManager.h107
-rw-r--r--APEX_1.4/samples_v2/SampleBase/ApexRenderResources.cpp814
-rw-r--r--APEX_1.4/samples_v2/SampleBase/ApexRenderResources.h250
-rw-r--r--APEX_1.4/samples_v2/SampleBase/ApexRenderer.cpp512
-rw-r--r--APEX_1.4/samples_v2/SampleBase/ApexRenderer.h183
-rw-r--r--APEX_1.4/samples_v2/SampleBase/ApexResourceCallback.cpp342
-rw-r--r--APEX_1.4/samples_v2/SampleBase/ApexResourceCallback.h77
-rw-r--r--APEX_1.4/samples_v2/SampleBase/CommonUIController.cpp404
-rw-r--r--APEX_1.4/samples_v2/SampleBase/CommonUIController.h110
-rw-r--r--APEX_1.4/samples_v2/SampleBase/PhysXPrimitive.cpp241
-rw-r--r--APEX_1.4/samples_v2/SampleBase/PhysXPrimitive.h54
-rw-r--r--APEX_1.4/samples_v2/SampleBase/SampleManager.cpp78
-rw-r--r--APEX_1.4/samples_v2/SampleBase/SampleManager.h45
-rw-r--r--APEX_1.4/samples_v2/SampleBase/Utils.cpp13
-rw-r--r--APEX_1.4/samples_v2/SampleBase/Utils.h179
-rw-r--r--APEX_1.4/samples_v2/SampleBase/shaders/clothing_asset_skinned.hlsl73
-rw-r--r--APEX_1.4/samples_v2/SampleBase/shaders/clothing_asset_static.hlsl47
-rw-r--r--APEX_1.4/samples_v2/SampleBase/shaders/common_buffers.hlsl29
-rw-r--r--APEX_1.4/samples_v2/SampleBase/shaders/debug_primitive.hlsl31
-rw-r--r--APEX_1.4/samples_v2/SampleBase/shaders/destruction_asset.hlsl56
-rw-r--r--APEX_1.4/samples_v2/SampleBase/shaders/lighting.hlsl48
-rw-r--r--APEX_1.4/samples_v2/SampleBase/shaders/mesh_particle.hlsl53
-rw-r--r--APEX_1.4/samples_v2/SampleBase/shaders/physx_primitive.hlsl39
-rw-r--r--APEX_1.4/samples_v2/SampleBase/shaders/pointsprite.hlsl107
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