aboutsummaryrefslogtreecommitdiff
path: root/KaplaDemo/samples/sampleViewer3/SampleViewer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'KaplaDemo/samples/sampleViewer3/SampleViewer.cpp')
-rw-r--r--KaplaDemo/samples/sampleViewer3/SampleViewer.cpp2527
1 files changed, 2527 insertions, 0 deletions
diff --git a/KaplaDemo/samples/sampleViewer3/SampleViewer.cpp b/KaplaDemo/samples/sampleViewer3/SampleViewer.cpp
new file mode 100644
index 00000000..96b395af
--- /dev/null
+++ b/KaplaDemo/samples/sampleViewer3/SampleViewer.cpp
@@ -0,0 +1,2527 @@
+// ===============================================================================
+// Title: Sample Viewer
+// Description: A Viewer for GRB Demo Scenes
+//
+// Written by: Matthias M�ller (23.11.11)
+// ===============================================================================
+
+#ifndef _SCL_SECURE_NO_WARNINGS
+#define _SCL_SECURE_NO_WARNINGS
+#endif
+
+#ifdef WIN32
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif
+#include <windows.h>
+#endif
+
+
+#undef random
+
+#include <stdio.h>
+#include <assert.h>
+
+#include "ShaderShadow.h"
+#include "ShadowMap.h"
+#include "RenderTarget.h"
+
+#include <GL/glut.h>
+
+#include "SampleViewer.h"
+#include "MediaPath.h"
+
+#include <task/PxTask.h>
+#include "cudamanager/PxCudaContextManager.h"
+
+#include "PxPhysics.h"
+#include "PxCooking.h"
+#include "PxDefaultAllocator.h"
+#include "PxDefaultErrorCallback.h"
+#include "PxDefaultCpuDispatcher.h"
+#include "PxExtensionsAPI.h"
+#include "PxPhysicsVersion.h"
+
+#include "PxScene.h"
+#include "PxGpu.h"
+
+#include "foundation/PxFoundationVersion.h"
+#include "foundation/PxProfiler.h"
+#include "pvd/PxPvd.h"
+
+//namespace PVD {
+// using namespace physx::debugger;
+// using namespace physx::debugger::comm;
+//}
+#include "Timing.h"
+#include "GLFontRenderer.h"
+#include "BmpFile.h"
+
+#include "SceneKaplaTower.h"
+#include "SceneKaplaArena.h"
+#include "SceneRagdollWashingMachine.h"
+#include "SceneVehicle.h"
+#include "SceneCrab.h"
+
+#include <string>
+#include <algorithm>
+//#include "fomHelper.h"
+#include <string>
+#include "MyShaders.h"
+#include "SimScene.h"
+#include "Texture.h"
+#include "AABox.h"
+#include "SSAOHelper.h"
+#include "HBAOHelper.h"
+#include "FXAAHelper.h"
+#include "IJGWin32/CPPJPEGWrapper.h"
+#include "HDRHelper.h"
+#include "SampleViewerGamepad.h"
+
+#include "PhysXMacros.h"
+
+#include "pvd/PxPvdTransport.h"
+#include "foundation/PxMat44.h"
+
+#define SCREEN_DUMP_PATH "C:\\Capture\\%05i.bmp"
+
+int DEFAULT_SOLVER_ITERATIONS = 8;
+
+
+#define WINDOW_WIDTH 1280
+#define WINDOW_HEIGHT 720
+
+#define ENABLE_PVD 1
+#define FULL_PVD 0
+
+// Globals -------------------------------------------------------------------------------------------
+
+int gPhysicsFrameNumber = 0; // different from gFrameNr since the latter is for graphics
+// ---------------------------------------------------------------------------------------------------
+float g_fogStart = 150.0f;
+float g_fogEnd = 350.0f;
+float shadowClipNear = 0.01f;
+float shadowClipFar = 80.0f;
+
+int gNrWorkerThreads = 4;
+
+
+extern float g_shadowAdd;
+const float zNear = 0.1f;
+const float zFar = 1000.0f;
+
+SSAOHelper* gSSAOHelper = NULL;
+HBAOHelper* gHBAOHelper = NULL;
+FXAAHelper* gFXAAHelper = NULL;
+HDRHelper* gHDRHelper = NULL;
+GLenum shadowMapType = GL_TEXTURE_2D_ARRAY_EXT;
+// PhysX
+PxPhysics* gPxPhysics = NULL;
+PxFoundation* gPxFoundation = NULL;
+PxCooking* gPxCooking = NULL;
+PxDefaultAllocator gAllocator;
+
+PxScene* gPxScene = NULL;
+PxDefaultCpuDispatcher* gPxDispatcher = NULL;
+
+PxCudaContextManager* gCudaContextManager;
+
+bool gUseGrb = true;
+bool gCurrentUsingGrb = gUseGrb;
+
+bool gForceSceneRecreate = false;
+int gCountdownToRecereate = 2;
+
+bool gShot = false;
+
+PxU32 gMaxSubSteps = 1u;
+
+// Physics param
+PxVec3 gDefaultGravity(0.0f ,-10.0f, 0.0f);
+float gTimeStepSize = 1.0f / 60.0f;
+float gSlowMotionFactor = 1.0f;
+
+// Scene
+bool gSceneRunning = false;
+float gTime = 0.0f;
+float gLastTime = 0.0f;
+bool gPause = false;
+bool gDisableRendering = false;
+bool gShowSplash = false;
+
+#ifdef USE_OPTIX
+int gNumScenes = 9;
+#else
+int gNumScenes = 5;
+#endif
+int gSceneNr = 0;
+
+float gGroundY = 0.0f;
+GLuint gGroundTexId = 0;
+
+GLuint gSplashScreenTexId = 0;
+int gSplashWidth = 0;
+int gSplashHeight = 0;
+char gResourcePath[512] = "../../../externalIP/resources";
+
+SampleViewerScene *gSampleScene = NULL;
+
+// Display
+GLFontRenderer *gFontRenderer = NULL;
+
+int gMainHandle;
+bool gHelp = false;
+bool gDisplay = true;
+char gDisplayString[512] = "";
+char gHelpString[2048] = "";
+char gDemoName[512] = "";
+float gFontSize = 0.02f;
+
+int gViewWidth = 0;
+int gViewHeight = 0;
+bool gShadows = false;
+bool gWireframeMode = false;
+bool gAdvancedRendering = true;
+bool gDebugRendering = true;
+bool gDrawGroundPlane = true;
+PxVec3 gGroupPlanePose = PxVec3(0.f);
+bool gDrawSkyBox = true;
+
+//bool gFXAAOn = true;
+//bool gDoSSAO = true;
+//bool gDoHDR = true;
+
+bool gFXAAOn = false;
+bool gDoSSAO = true;
+bool gDoHBAO = true;
+bool gDoHDR = true;
+bool gUseNormalMap = true;
+
+bool gDoDOF = false;
+
+// record movie
+int gPixelBufferSize = 0;
+GLbyte *gPixelBuffer = NULL;
+bool gRecordBMP = false;
+int gFrameNr = 0;
+int gMaxFrameNr = 0;
+
+// Shading
+int gNumShadows = 1;
+bool gShowReflections = false;
+
+static const int gNumLights = 1;
+PxVec3 gLightDirs[3];
+PxVec3 gLightPos[3];
+PxVec3 gBackLightDir;
+
+ShadowMap *gShadowMaps[4];
+ShaderShadow *gDefaultShader;
+RenderTarget *gReflectedSceneTarget = NULL;
+
+int gZval = 15;
+//FOMHelper* fom;
+Shader* gDisplayTexProg;
+Shader* gDisplayTexArrayProg;
+Shader* gDisplaySplashProg = 0;
+PxBounds3 sceneBounds;
+PxBounds3 fluidBounds;
+PxVec3 myDustColor;
+
+bool renderDust = true;
+
+#define MSAA_2x 2, 0, "MSAA_2x"
+#define CSAA_4x 2, 4, "CSAA_4x"
+#define CSAA_8x 4, 8, "CSAA_8x"
+#define CSAA_8xQ 8, 8, "CSAA_8xQ"
+#define CSAA_16x 4, 16, "CSAA_16x"
+#define CSAA_16xQ 8, 16, "CSAA_16xQ"
+
+AABox* g_pAABox = 0;
+int g_numAAModes = 5;
+//int fullW = 1900;
+//int fullH = 1200;
+
+int fullW = WINDOW_WIDTH;
+int fullH = WINDOW_HEIGHT;
+bool autoShoot = false;
+bool gForceReloadShader = false;
+bool gForceReloadDebugShader = false;
+
+using namespace std;
+
+struct SAAMode
+{
+ int ds;
+ int cs;
+ const char * name;
+};
+
+SAAMode g_aaModes[] = {
+ {MSAA_2x},
+ {CSAA_8x},
+ {CSAA_8xQ},
+ {CSAA_16x},
+ {CSAA_16xQ},
+ { CSAA_4x }
+};
+
+bool doFXAA = false;
+bool doAA = true;
+int g_curAA = 0;
+int g_curTech = 1;
+float g_curSSSize = 1.7f;
+
+bool gShowRayCast = false;
+bool fullScreen = false;
+
+// Camera
+struct Camera {
+ void init() {
+ fov = 40.0f;
+ pos = PxVec3(0.0f, 30.0f, 20.0f);
+ forward = PxVec3(0.0f,0.0f,-1.0f);
+ right = PxVec3(1.0f,0.0f,0.0f);
+
+ PxVec3 up(0, 1, 0);
+
+ PxQuat qy(3.14/4.f, right);
+ forward = qy.rotate(forward).getNormalized();
+ right = forward.cross(PxVec3(0, 1, 0)).getNormalized();
+
+
+ speed = 0.15f;
+ rotate = false;
+ translate = false;
+ zoom = false;
+
+ trackballMode = false;
+ trackballCenter = PxVec3(0.0f, 1.0f, 0.0f);
+ trackballRadius = 6.0f;
+ }
+ float fov;
+ PxVec3 pos, forward, right;
+ float speed;
+ bool rotate, translate, zoom;
+ bool trackballMode;
+ PxVec3 trackballCenter;
+ float trackballRadius;
+};
+
+Camera gCamera;
+
+// Mouse
+int gMouseX = 0;
+int gMouseY = 0;
+
+// keyboard
+#define MAX_KEYS 256
+bool gKeys[MAX_KEYS];
+
+// fps
+float curFPS = 0.0f;
+int gFrameCounter = 0;
+float gPreviousTime = getCurrentTime();
+
+volatile bool doneOneFrame = false;
+volatile bool doneInit = false;
+volatile bool doneRender = true;
+volatile bool shouldEndThread = false;
+volatile bool threadEnded = false;
+volatile int simulateDoneS = 0;
+bool renderEveryFrame = true;
+
+bool gParticlesTexOutdate = true;
+bool gConvexTexOutdate = true;
+
+
+//std::vector<Compound*> delCompoundList;
+
+SampleViewerGamepad sampleViewerGamepad;
+
+// ------------------------------------------------------------------------------------
+// This is needed to properly call cleanup routines when GLUT window is closed, as
+// there is no close callback routine, and the default way simply calls exit(0) thus
+// calling destructors w/o cleanups, leading to crash
+// (see atexit function that sets exit callback)
+// ------------------------------------------------------------------------------------
+bool gIsSampleCleanedUp = false;
+void ReleaseSDKs();
+void CleanupSample();
+// ------------------------------------------------------------------------------------
+
+physx::PxPvd* gPvd = NULL;
+physx::PxPvdTransport* gTransport = NULL;
+physx::PxPvdInstrumentationFlags gPvdFlags = physx::PxPvdInstrumentationFlag::eDEBUG;
+
+#include "PsString.h"
+#include "PsThread.h"
+
+//class SampleViewerPVDHandler : public PxPvd
+//{
+//public:
+//
+// void onPvdSendClassDescriptions(PVD::PvdConnection&) {}
+//
+// void onPvdConnected(PVD::PvdConnection& )
+// {
+// //setup joint visualization. This gets piped to pvd.
+// //gPxPhysics->getVisualDebugger()->setVisualDebuggerFlag(PxVisualDebuggerFlag::eTRANSMIT_CONSTRAINTS, true);
+// //gPxPhysics->getVisualDebugger()->setVisualDebuggerFlag(PxVisualDebuggerFlag::eTRANSMIT_CONTACTS, true);
+// //gPxPhysics->getVisualDebugger()->setVisualDebuggerFlag(PxVisualDebuggerFlag::eTRANSMIT_SCENEQUERIES, true);
+// }
+//
+// void onPvdDisconnected(PVD::PvdConnection& conn)
+// {
+// conn.release();
+// }
+//};
+//
+//SampleViewerPVDHandler gPVDConnectionHandler;
+
+class SampleViewerErrorCallback : public PxErrorCallback
+{
+public:
+ SampleViewerErrorCallback() {}
+ ~SampleViewerErrorCallback() {}
+
+ virtual void reportError(PxErrorCode::Enum code, const char* message, const char* file, int line)
+ {
+ if (code == PxErrorCode::eDEBUG_INFO)
+ {
+ char buffer[1024];
+ sprintf(buffer, "%s\n", message);
+ physx::shdfnd::printString(buffer);
+ }
+ else
+ {
+ const char* errorCode = NULL;
+
+ switch (code)
+ {
+ case PxErrorCode::eINVALID_PARAMETER:
+ errorCode = "invalid parameter";
+ break;
+ case PxErrorCode::eINVALID_OPERATION:
+ errorCode = "invalid operation";
+ break;
+ case PxErrorCode::eOUT_OF_MEMORY:
+ errorCode = "out of memory";
+ break;
+ case PxErrorCode::eDEBUG_INFO:
+ errorCode = "info";
+ break;
+ case PxErrorCode::eDEBUG_WARNING:
+ errorCode = "warning";
+ break;
+ case PxErrorCode::ePERF_WARNING:
+ errorCode = "performance warning";
+ break;
+ case PxErrorCode::eABORT:
+ errorCode = "abort";
+ break;
+ default:
+ errorCode = "unknown error";
+ break;
+ }
+
+ PX_ASSERT(errorCode);
+ if (errorCode)
+ {
+ char buffer[1024];
+ sprintf(buffer, "%s (%d) : %s : %s\n", file, line, errorCode, message);
+
+ physx::shdfnd::printString(buffer);
+
+ // in debug builds halt execution for abort codes
+ PX_ASSERT(code != PxErrorCode::eABORT);
+
+ // in release builds we also want to halt execution
+ // and make sure that the error message is flushed
+ while (code == PxErrorCode::eABORT)
+ {
+ physx::shdfnd::printString(buffer);
+ physx::shdfnd::Thread::sleep(1000);
+ }
+ }
+ }
+ }
+};
+
+SampleViewerErrorCallback gErrorCallback;
+// ------------------------------------------------------------------------------------
+#include <direct.h>
+
+// ------------------------------------------------------------------------------------
+bool LoadTexture(const char *filename, GLuint &texId, bool createMipmaps, GLuint type = GL_TEXTURE_2D, int *width = NULL, int *height = NULL)
+{
+ char path[512];
+ sprintf(path, "%s/%s", gResourcePath, filename);
+
+ // read out image data
+ int len = strlen(path);
+ unsigned char* ptr = 0, *ptrBegin;
+ int w, h;
+ BmpLoaderBuffer loader;
+ CPPJPEGWrapper jpg;
+ if (strcmp(&path[len-4], ".jpg") == 0) {
+ // jpg
+
+ if (!jpg.LoadJPEG(path, false)) {
+ printf("Error load jpg %s\n", path);
+ return false;
+ }
+ h = jpg.GetHeight();
+ w = jpg.GetWidth();
+ ptrBegin = ptr = jpg.GetData();
+ } else {
+ // bmp
+
+ if (!loader.loadFile(path)) {
+ fprintf(stderr, "Error loading bmp '%s'\n",path);
+ return false;
+ }
+ ptrBegin = ptr = loader.mRGB;
+ h = loader.mHeight;
+ w = loader.mWidth;
+
+ }
+
+ unsigned char *pColor = ptrBegin;
+
+ int lineLen = 3*w;
+ GLubyte *buffer = new GLubyte[w*h*3];
+ GLubyte *writePtr = &buffer[(h-1)*lineLen];
+
+ for (int i = 0; i < h; i++) {
+ GLubyte *writePtr = &buffer[i*lineLen];
+ GLubyte *readPtr = &pColor[i*lineLen];
+ for (int j = 0; j < w; j++) {
+ *writePtr++ = *readPtr++;
+ *writePtr++ = *readPtr++;
+ *writePtr++ = *readPtr++;
+ }
+ }
+
+ // ------ generate texture --------------------------------
+
+ glGenTextures(1, &texId);
+
+ glBindTexture(type, texId);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ glTexParameteri(type, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(type, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexParameteri(type, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(type, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexImage2D(type, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, buffer);
+ if (createMipmaps) {
+ glTexParameteri(type, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ gluBuild2DMipmaps(type, GL_RGB, w, h, GL_RGB, GL_UNSIGNED_BYTE, buffer);
+ }
+
+ delete[] buffer;
+
+ if (width)
+ *width = w;
+ if (height)
+ *height = h;
+ return true;
+}
+
+void displayTexture(GLuint tex)
+{
+ gDisplayTexProg->activate();
+ gDisplayTexProg->bindTexture("tex", tex, GL_TEXTURE_2D, 0);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f);
+ glTexCoord2f(1.0f, 0.0f); glVertex2f( 1.0f, -1.0f);
+ glTexCoord2f(1.0f, 1.0f); glVertex2f( 1.0f, 1.0f);
+ glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f, 1.0f);
+ glEnd();
+ gDisplayTexProg->deactivate();
+}
+void displayTextureArray(GLuint tex, int slice)
+{
+ gDisplayTexArrayProg->activate();
+ gDisplayTexArrayProg->bindTexture("tex", tex, GL_TEXTURE_2D_ARRAY_EXT, 0);
+ gDisplayTexArrayProg->setUniform1("slice", slice);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f);
+ glTexCoord2f(1.0f, 0.0f); glVertex2f(1.0f, -1.0f);
+ glTexCoord2f(1.0f, 1.0f); glVertex2f(1.0f, 1.0f);
+ glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f, 1.0f);
+ glEnd();
+ gDisplayTexArrayProg->deactivate();
+}
+const char *textureRECTPS = STRINGIFY(
+uniform sampler2DRect tex;
+void main()
+{
+gl_FragColor = texture2DRect(tex, gl_TexCoord[0].xy); \n
+//gl_FragColor = vec4(1,0,0,1);
+}
+);
+const char *texture2DArrayPS = STRINGIFY(
+ uniform sampler2DArray tex;
+void main()
+{
+ gl_FragColor = texture2DArray(tex, vec3(gl_TexCoord[0].xy,0.0f)); \n
+ //gl_FragColor = vec4(1,0,0,1);
+}
+);
+
+void displaySplashScreen()
+{
+ float as = (float)gSplashWidth/gSplashHeight;
+
+ float xv = 0.0f, yv = 0.0f;
+ float bs = gViewWidth / ((float)gViewHeight);
+ if (bs > as) {
+ // Too wide
+ // fit height
+ yv = 1.0f;
+ xv = (as*gViewHeight) / gViewWidth;
+ } else {
+ // Too Tall
+ xv = 1.0f;
+ yv = (gViewWidth/as) / gViewHeight;
+ }
+
+
+ gDisplaySplashProg->activate();
+ gDisplaySplashProg->bindTexture("tex", gSplashScreenTexId, GL_TEXTURE_RECTANGLE_ARB, 0);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0.0f, gSplashHeight); glVertex2f(-xv, -yv);
+ glTexCoord2f(gSplashWidth, gSplashHeight); glVertex2f( xv, -yv);
+ glTexCoord2f(gSplashWidth, 0.0f); glVertex2f( xv, yv);
+ glTexCoord2f(0.0f, 0.0f); glVertex2f(-xv, yv);
+ glEnd();
+ gDisplaySplashProg->deactivate();
+
+}
+
+// ------------------------------------------------------------------------------------
+void SaveFrameBuffer()
+{
+ char filename[256];
+ sprintf(filename, SCREEN_DUMP_PATH, gFrameNr);
+
+ int bufferSize = gViewWidth * gViewHeight * 3;
+ if (gPixelBufferSize != bufferSize) {
+ if (gPixelBuffer != NULL)
+ free(gPixelBuffer);
+ gPixelBuffer = (GLbyte *)malloc(bufferSize);
+ gPixelBufferSize = bufferSize;
+ }
+
+ glReadBuffer(GL_BACK);
+ glReadPixels(0,0, gViewWidth, gViewHeight, GL_RGB, GL_UNSIGNED_BYTE, gPixelBuffer);
+ saveBmpRBG(filename, gViewWidth, gViewHeight, gPixelBuffer);
+}
+
+// ------------------------------------------------------------------------------------
+void WaitForSim()
+{
+ if (gSceneRunning)
+ {
+ if (gSampleScene != NULL)
+ {
+ gSampleScene->syncAsynchronousWork();
+ }
+
+ PxU32 error;
+ gPxScene->fetchResults(true, &error);
+
+ assert(error == 0);
+ gSceneRunning = false;
+ }
+}
+
+// ------------------------------------------------------------------------------------
+PxFilterFlags contactReportFilterShader(PxFilterObjectAttributes attributes0, PxFilterData filterData0,
+ PxFilterObjectAttributes attributes1, PxFilterData filterData1,
+ PxPairFlags& pairFlags, const void* constantBlock, PxU32 constantBlockSize)
+{
+ PX_UNUSED((attributes0, attributes1, filterData0, filterData1, constantBlockSize, constantBlock));
+
+ // all initial and persisting reports for everything, with per-point data
+ pairFlags = PxPairFlag::eSOLVE_CONTACT | PxPairFlag::eDETECT_DISCRETE_CONTACT;
+ return PxFilterFlag::eDEFAULT;
+}
+
+// ------------------------------------------------------------------------------------
+
+
+void CreateSampleViewerScene();
+void InitSampleViewerScene();
+
+void RecreateSDKScenes()
+{
+ WaitForSim();
+
+ // physX
+ if (gPxScene != NULL)
+ gPxScene->release();
+
+ PxSceneDesc sceneDesc(gPxPhysics->getTolerancesScale());
+
+ sceneDesc.gravity = PxVec3(0.0f, -10.0f * gSlowMotionFactor * gSlowMotionFactor, 0.0f); // acceleration, factor squared
+ if (!gPxDispatcher)
+ gPxDispatcher = PxDefaultCpuDispatcherCreate(gNrWorkerThreads);
+
+ if(!gCudaContextManager)
+ {
+ PxCudaContextManagerDesc cudaContextManagerDesc;
+ gCudaContextManager = PxCreateCudaContextManager(*gPxFoundation, cudaContextManagerDesc);
+ }
+
+
+
+ sceneDesc.cpuDispatcher = gPxDispatcher;
+ sceneDesc.gpuDispatcher = gCudaContextManager->getGpuDispatcher();
+ sceneDesc.filterShader = contactReportFilterShader;
+ sceneDesc.flags |= PxSceneFlag::eENABLE_PCM;
+ sceneDesc.flags |= PxSceneFlag::eENABLE_STABILIZATION;
+ if (gUseGrb)
+ {
+ sceneDesc.flags |= PxSceneFlag::eENABLE_GPU_DYNAMICS;
+ sceneDesc.broadPhaseType = PxBroadPhaseType::eGPU;
+ }
+ sceneDesc.flags |= PxSceneFlag::eSUPPRESS_EAGER_SCENE_QUERY_REFIT;
+ sceneDesc.gpuDynamicsConfig.contactStreamSize *= 2;
+ sceneDesc.gpuDynamicsConfig.forceStreamCapacity *= 2;
+ sceneDesc.gpuDynamicsConfig.patchStreamSize *= 2;
+ sceneDesc.gpuDynamicsConfig.tempBufferCapacity *= 2;
+
+ gSampleScene->customizeSceneDesc(sceneDesc);
+
+ gPxScene = gPxPhysics->createScene(sceneDesc);
+
+ PxPvdSceneClient* pvdClient = gPxScene->getScenePvdClient();
+ if (pvdClient)
+ {
+ pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONSTRAINTS, false);
+ pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONTACTS, false);
+ pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_SCENEQUERIES, false);
+ }
+
+ if(gPxScene == NULL)
+ {
+ printf("\nError: Unable to create a PhysX scene, exiting the sample.\n\n");
+ exit(0);
+ }
+
+ gCurrentUsingGrb = gUseGrb;
+}
+
+//-----------------------------------------------------------------------------
+bool InitPhysX()
+{
+ // SDK
+ gPxFoundation = PxCreateFoundation(PX_FOUNDATION_VERSION, gAllocator, gErrorCallback);
+
+ gTransport = physx::PxDefaultPvdSocketTransportCreate("127.0.0.1", 5425, 10);
+
+ gPvd = NULL;
+
+#if ENABLE_PVD
+ gPvd = physx::PxCreatePvd(*gPxFoundation);
+ //gPvd->connect(*gTransport, physx::PxPvdInstrumentationFlag::eALL);
+ gPvd->connect(*gTransport, physx::PxPvdInstrumentationFlag::ePROFILE);
+#endif
+
+ gPxPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gPxFoundation, PxTolerancesScale(), false, gPvd);
+
+
+
+ if(gPxPhysics == NULL)
+ {
+ printf("\nPhysXSDK create error.\nUnable to initialize the PhysX SDK, exiting the sample.\n\n");
+ return false;
+ }
+ PxCookingParams params(gPxPhysics->getTolerancesScale());
+ params.buildGPUData = true;
+ gPxCooking = PxCreateCooking(PX_PHYSICS_VERSION, *gPxFoundation, params);
+
+ if (gPxCooking == NULL)
+ {
+ printf("\nError: Unable to initialize the cooking library, exiting the sample.\n\n");
+ return false;
+ }
+
+ PxInitExtensions(*gPxPhysics, gPvd);
+
+ UpdateTime();
+
+ return true;
+}
+
+// ------------------------------------------------------------------------------------
+void ReleaseSDKs()
+{
+ WaitForSim();
+
+ if(gPxPhysics != NULL)
+ {
+ PxCloseExtensions();
+
+ gPxScene->release();
+ gPxDispatcher->release();
+ gPxPhysics->release();
+ gPxCooking->release();
+ if (gPvd)
+ {
+ gPvd->release();
+ gPvd = NULL;
+ }
+
+ gCudaContextManager->release();
+
+ gPxFoundation->release();
+ gPxScene = NULL;
+ gPxDispatcher = NULL;
+ gPxPhysics = NULL;
+ gPxCooking = NULL;
+ gPxFoundation = NULL;
+ gCudaContextManager = NULL;
+ }
+}
+
+// ------------------------------------------------------------------------------------
+PxReal UpdateTime()
+{
+ PxReal deltaTime;
+ gTime = timeGetTime()*0.001f; // Get current time in seconds
+ deltaTime = gTime - gLastTime;
+ gLastTime = gTime;
+
+ return deltaTime;
+}
+
+#define OVERLAP_SIM_AND_RENDER 1
+
+// ------------------------------------------------------------------------------------
+static bool g_simulationRunning = false;
+static PxReal g_simulationDT = 0.0f;
+void BeginSimulation(void)
+{
+ assert(g_simulationRunning == false);
+ assert(g_simulationDT == 0.0f);
+ if(g_simulationRunning == false)
+ {
+ static float prevTime = getCurrentTime();
+ float currTime = getCurrentTime();
+
+ float elapsedTime = currTime - prevTime;
+
+ PxReal fSubsteps = elapsedTime / gTimeStepSize;
+ PxU32 iSubsteps = PxU32(fSubsteps);
+ PxU32 nbSubsteps = PxMax(1u, PxMin(iSubsteps, gMaxSubSteps));
+
+ prevTime += PxReal(iSubsteps)*gTimeStepSize;
+
+ for (PxU32 a = 0; a < nbSubsteps; ++a)
+ {
+
+
+#if OVERLAP_SIM_AND_RENDER
+ if (gSceneRunning)
+ {
+ //fetchResult
+
+ WaitForSim();
+ if (gSampleScene != NULL)
+ {
+ gSampleScene->postSim(gTimeStepSize);
+ }
+ }
+#endif
+
+ if (gForceSceneRecreate)
+ {
+ if (--gCountdownToRecereate)
+ {
+ CreateSampleViewerScene();
+ RecreateSDKScenes();
+ InitSampleViewerScene();
+
+ gForceSceneRecreate = false;
+ }
+ }
+ else if (gUseGrb != gCurrentUsingGrb)
+ {
+ PxScene* oldScene = gPxScene;
+ gPxScene = NULL;
+
+ RecreateSDKScenes(); //Create the PxScene...
+
+ const PxU32 nbRigidStatics = oldScene->getNbActors(PxActorTypeFlag::eRIGID_STATIC);
+ const PxU32 nbRigidDynamics = oldScene->getNbActors(PxActorTypeFlag::eRIGID_DYNAMIC);
+
+ Ps::Array<PxActor*> actors(nbRigidStatics + nbRigidDynamics);
+
+ oldScene->getActors(PxActorTypeFlag::eRIGID_STATIC, actors.begin(), nbRigidStatics);
+ oldScene->getActors(PxActorTypeFlag::eRIGID_DYNAMIC, actors.begin() + nbRigidStatics, nbRigidDynamics);
+
+
+ for (PxU32 a = 0; a < actors.size(); ++a)
+ {
+ oldScene->removeActor(*actors[a],false);
+ //gPxScene->addActor(*actors[a]);
+ }
+
+ for (PxU32 a = 0; a < actors.size(); ++a)
+ {
+ //oldScene->removeActor(*actors[a]);
+ gPxScene->addActor(*actors[a]);
+ }
+
+ oldScene->release();
+
+ gSampleScene->setScene(gPxScene);
+
+ gCurrentUsingGrb = gUseGrb;
+ }
+
+ {
+ if (gSampleScene != NULL)
+ gSampleScene->preSim(gTimeStepSize);
+
+ gPxScene->simulate(gTimeStepSize);
+
+ if (gSampleScene != NULL)
+ gSampleScene->duringSim(gTimeStepSize);
+
+ gSceneRunning = true;
+
+ g_simulationDT = gTimeStepSize;
+ g_simulationRunning = true;
+ }
+
+#if !OVERLAP_SIM_AND_RENDER
+ //if((a + 1) < nbSubsteps)
+ {
+ WaitForSim();
+ if (gSampleScene != NULL)
+ {
+ gSampleScene->postSim(gTimeStepSize);
+ }
+ }
+#endif
+ }
+
+
+ }
+}
+
+// ------------------------------------------------------------------------------------
+void EndSimulation(void)
+{
+ assert(g_simulationRunning == true);
+ assert(g_simulationDT != 0.0f);
+ if(g_simulationRunning == true)
+ {
+ PxReal dt = g_simulationDT;
+
+#if !OVERLAP_SIM_AND_RENDER
+ if (gSceneRunning)
+ {
+ //fetchResult
+ WaitForSim();
+ if (gSampleScene != NULL)
+ {
+ gSampleScene->postSim(gTimeStepSize);
+ }
+ }
+#endif
+
+ ++gPhysicsFrameNumber;
+
+ g_simulationDT = 0.0f;
+ g_simulationRunning = false;
+
+ gParticlesTexOutdate = true;
+ gConvexTexOutdate = true;
+ }
+}
+
+// ------------------------------------------------------------------------------------
+void RunPhysics()
+{
+ BeginSimulation();
+ EndSimulation();
+}
+
+// ------------------------------------------------------------------------------------
+
+void DisplayText()
+{
+ const char* aoString = gDoSSAO ? (gDoHBAO ? "(HBAO+)" : "(SSAO)"): "(NOAO)";
+ const char* normalString = gUseNormalMap ? "(NormalMap)" : "(NormalsFromDepth)";
+ sprintf(gDisplayString, "");
+ if (gDisplay)
+ sprintf(gDisplayString, "FPS = %0.2f\n Scene %i: %s %s%s %s %s", curFPS, gSceneNr + 1, gDemoName, gUseGrb ? "(GPU)" : "(CPU)", gHelp ? gHelpString : "", aoString, normalString);
+
+
+ float y = 0.95f;
+ int len = strlen(gDisplayString);
+ len = (len < 1024)?len:1023;
+ int start = 0;
+ char textBuffer[1024];
+ for(int i=0;i<len;i++)
+ {
+ if(gDisplayString[i] == '\n' || i == len-1)
+ {
+ int offset = i;
+ if(i == len-1) offset= i+1;
+ memcpy(textBuffer, gDisplayString+start, offset-start);
+ textBuffer[offset-start]=0;
+ gFontRenderer->print(0.01, y, gFontSize, textBuffer);
+ y -= 0.035f;
+ start = offset+1;
+ }
+ }
+}
+
+// ------------------------------------------------------------------------------------
+void SetHelpString()
+{
+ //char tempString[256];
+ sprintf(gHelpString, "\nGeneral:\n");
+ //sprintf(tempString, " 1-%d: choose scene\n", gNumScenes);
+
+ strcat(gHelpString, " F10: Reset scene\n");
+ strcat(gHelpString, " 1-5 or F10: Reset scene\n");
+ strcat(gHelpString, " F5: Toggle between CPU and GPU simulation\n");
+ strcat(gHelpString, " p: Pause\n");
+ strcat(gHelpString, " o: Single step\n");
+ if (gSceneNr == 2)
+ {
+ strcat(gHelpString, " F7: Detach/reattach camera\n");
+ strcat(gHelpString, " w,a,s,d,q,e: Drive car or move camera if camera is detached\n");
+ }
+
+ if (gSceneNr == 3)
+ {
+ strcat(gHelpString, " k: Spawn walker at mouse location\n");
+ }
+ strcat(gHelpString, " w,a,s,d,q,e: Camera\n");
+ strcat(gHelpString, " f: Toggle full screen mode\n");
+
+ strcat(gHelpString, " F1: Toggle help\n");
+
+ strcat(gHelpString, " F4: Change weapon: ");
+ if (gSampleScene != NULL)
+ strcat(gHelpString, gSampleScene->getWeaponName().c_str());
+ strcat(gHelpString, "\n");
+
+ strcat(gHelpString, " Shift-mouse: Drag objects\n");
+ strcat(gHelpString, " Space: Shoot\n");
+ if (gSceneNr == 0)
+ strcat(gHelpString, " b: Attack tower with random shapes\n");
+}
+
+// ------------------------------------------------------------------------------------
+void ProcessKeys()
+{
+ // Process keys
+ for (int i = 0; i < MAX_KEYS; i++)
+ {
+ if (!gKeys[i]) { continue; }
+
+ PxVec3 up;
+ up = PxVec3(0,1,0);
+ PxVec3 &pos = gCamera.trackballMode ? gCamera.trackballCenter : gCamera.pos;
+
+
+ if (!gSampleScene->isCameraDisable())
+ {
+ if (gCamera.trackballMode) {
+ switch (i)
+ {
+ // Camera controls
+ case 'W':
+ case 'w':{
+ gCamera.trackballRadius -= gCamera.speed;
+ if (gCamera.trackballRadius < 0.1f) gCamera.trackballRadius = 0.1f;
+ break;
+ }
+ case 'S':
+ case 's':{ gCamera.trackballRadius += gCamera.speed; break; }
+ case 'E':
+ case 'e':{ pos -= up * gCamera.speed; break; }
+ case 'Q':
+ case 'q':{ pos += up * gCamera.speed; break; }
+ }
+ }
+ else {
+ switch (i)
+ {
+ // Camera controls
+ case 'W':
+ case 'w':{ pos += gCamera.forward * gCamera.speed; break; }
+ case 'S':
+ case 's':{ pos -= gCamera.forward * gCamera.speed; break; }
+ case 'A':
+ case 'a':{ pos -= gCamera.right * gCamera.speed; break; }
+ case 'D':
+ case 'd':{ pos += gCamera.right * gCamera.speed; break; }
+ case 'E':
+ case 'e':{ pos -= up * gCamera.speed; break; }
+ case 'Q':
+ case 'q':{ pos += up * gCamera.speed; break; }
+ }
+ }
+ }
+
+ }
+}
+float XXX = 0.0f;
+ float modelMatrix[16];
+ float projMatrix[16];
+// ------------------------------------------------------------------------------------
+
+void SetupCamera(bool mirrored = false)
+{
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ float aspectRatio = ((float)glutGet(GLUT_WINDOW_WIDTH)/(float)glutGet(GLUT_WINDOW_HEIGHT));
+ gluPerspective(gCamera.fov, aspectRatio, zNear, zFar);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ if (gCamera.trackballMode) {
+ gCamera.trackballCenter.x = 0.0f;
+ gCamera.trackballCenter.z = 0.0f;
+ gCamera.pos = gCamera.trackballCenter - gCamera.forward * gCamera.trackballRadius;
+ }
+
+
+ gSampleScene->getCamera(gCamera.pos, gCamera.forward);
+
+ PxVec3 pos = gCamera.pos;
+ PxVec3 dir = gCamera.forward;
+ PxVec3 apos = gCamera.pos + dir;
+
+
+ gluLookAt(pos.x, pos.y, pos.z, pos.x + dir.x, pos.y + dir.y, pos.z + dir.z, 0.0f, 1.0f, 0.0f);
+
+ if (mirrored) {
+ PxTransform trans;
+
+ PxVec3 waterN(0.0f, 1.0f, 0.0f);
+ PxVec3 waterP(0.0f,gGroundY,0.0f);
+ float QQQ = 0.00f;
+ waterP.y += QQQ;
+ float np2 = 2.0f*waterN.dot(waterP);
+
+ PxVec3 r0 = PxVec3(1.0f, 0.0f, 0.0f) - 2*waterN.x*waterN;
+ PxVec3 r1 = PxVec3(0.0f, 1.0f, 0.0f) - 2*waterN.y*waterN;
+ PxVec3 r2 = PxVec3(0.0f, 0.0f, 1.0f) - 2*waterN.z*waterN;
+ PxVec3 t = np2*waterN;
+
+ float matGL[16] = {
+ r0.x, r1.x, r2.x, 0.0f,
+ r0.y, r1.y, r2.y, 0.0f,
+ r0.z, r1.z, r2.z, 0.0f,
+ t.x, t.y, t.z, 1.0f};
+
+ glMultMatrixf(matGL);
+
+ }
+
+
+ glGetFloatv(GL_MODELVIEW_MATRIX, modelMatrix);
+ glGetFloatv(GL_PROJECTION_MATRIX, projMatrix);
+
+ gDefaultShader->updateCamera(modelMatrix, projMatrix);
+ if (gSampleScene != NULL) {
+ for (int i = 0; i < (int)gSampleScene->getShaders().size(); i++)
+ gSampleScene->getShaders()[i]->updateCamera(modelMatrix, projMatrix);
+ gSampleScene->setCamera(gCamera.pos, gCamera.forward, PxVec3(0,1,0), gCamera.fov);
+ }
+
+ gCamera.right = gCamera.forward.cross(PxVec3(0,1,0)).getNormalized();
+ gCamera.forward.normalize();
+
+}
+
+// ------------------------------------------------------------------------------------
+void RenderObjects(bool useShader, bool reflectedOnly)
+{
+ ShaderMaterial mat;
+ mat.init();
+
+ // ground plane
+ if (!reflectedOnly && gDrawGroundPlane)
+ {
+ if (useShader) {
+ mat.init();
+ mat.reflectionCoeff = 0.2f;
+ if (gGroundTexId > 0) {
+ mat.texId = gGroundTexId;
+ }
+ }
+ if (useShader)
+ gDefaultShader->activate(mat);
+
+ const float size = 1000.0f;
+ const float y = -0.002f;
+
+
+ PxVec3 center = gGroupPlanePose;
+ PxVec3 p0 = center + PxVec3(-size, y, -size);
+ PxVec3 p1 = center + PxVec3( size, y, -size);
+ PxVec3 p2 = center + PxVec3( size, y, size);
+ PxVec3 p3 = center + PxVec3(-size, y, size);
+
+ float texScale = 300.0f;
+ PxVec3 t0(0.0f, 0.0f, 0.0f);
+ PxVec3 t1(texScale, 0.0f, 0.0f);
+ PxVec3 t2(texScale, texScale, 0.0f);
+ PxVec3 t3(0.0f, texScale, 0.0f);
+
+ glBegin(GL_TRIANGLES);
+ glNormal3f(0.0f, 1.0f, 0.0f);
+ glTexCoord2f(t0.x, t0.y); glVertex3f(p0.x, p0.y, p0.z);
+ glTexCoord2f(t2.x, t2.y); glVertex3f(p2.x, p2.y, p2.z);
+ glTexCoord2f(t1.x, t1.y); glVertex3f(p1.x, p1.y, p1.z);
+
+ glTexCoord2f(t0.x, t0.y); glVertex3f(p0.x, p0.y, p0.z);
+ glTexCoord2f(t3.x, t3.y); glVertex3f(p3.x, p3.y, p3.z);
+ glTexCoord2f(t2.x, t2.y); glVertex3f(p2.x, p2.y, p2.z);
+ glEnd();
+ if (useShader)
+ gDefaultShader->deactivate();
+ }
+
+ if (gSampleScene != NULL)
+ gSampleScene->render(useShader);
+
+/*
+ glDisable(GL_LIGHTING);
+
+
+ glBindBuffer(GL_ARRAY_BUFFER, gFluidSim.mistPS->glVB[currentBufMultiGPU]);
+ glVertexPointer(3, GL_FLOAT, sizeof(CUGLParticleInfo), (void*)0);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glColor3f(1.0f,1.0f,1.0f);
+ glDrawArrays(GL_POINTS, 0, gFluidSim.mistPS->numGLPars[currentBufMultiGPU]);
+
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ */
+
+//glDisable(GL_LIGHTING);
+
+ if (gShowRayCast) {
+
+ glDisable(GL_LIGHTING);
+ SimScene* simScene = ((SceneKapla*)gSampleScene)->getSimScene();
+ PxScene* scene = simScene->getScene();
+
+ PxVec3 start(-30.0f,0.0f,-30.0f);
+ PxVec3 xdir(1.0f,0.0f,0.0f);
+ PxVec3 zdir(0.0f,0.0f,1.0f);
+ PxVec3 castDir(0.0f, -1.0f, 0.0f);
+ PxVec3 castPos(0.0f, 100.0f, 0.0f);
+ float dist = 300.0f;
+ float dx = 0.3f;
+ int nx = 200;
+ int nz = 200;
+
+
+ glPointSize(10.0f);
+ glBegin(GL_POINTS);
+
+ PxHitFlags ff = PxHitFlag::ePOSITION | PxHitFlag::eNORMAL | PxHitFlag::eDISTANCE;
+ PxRaycastBuffer buf1;
+ PxRaycastHit hit;
+ for (int i = 0; i < nz; i++) {
+ for (int j = 0; j < nx; j++) {
+ PxVec3 startP = start + xdir*dx*j + zdir*dx*i + castPos;
+ scene->raycast(startP, castDir, dist, buf1, ff);
+ hit = buf1.block;
+ if (buf1.hasBlock) {
+ PxVec3 pos = startP + hit.distance * castDir;
+ glColor3f(1.0f,0.0f,0.0f);
+ glVertex3fv(&pos.x);
+ } else {
+ PxVec3 pos = startP;
+ pos.y = 0.0f;
+ glColor3f(0.0f,1.0f,0.0f);
+ glVertex3fv(&pos.x);
+
+ }
+
+ // scene->raycastSingle()
+
+ }
+ }
+
+ glEnd();
+ glEnable(GL_LIGHTING);
+ }
+}
+
+// ------------------------------------------------------------------------------------
+void RenderShadowCasters()
+{
+ RenderObjects(false, true);
+}
+
+inline void RenderDepthNormalInline(bool renderNormals){
+ if(renderNormals)
+ ShaderShadow::renderMode = ShaderShadow::RENDER_DEPTH_NORMAL;
+ else
+ ShaderShadow::renderMode = ShaderShadow::RENDER_DEPTH;
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ if (gCamera.trackballMode) {
+ gCamera.trackballCenter.x = 0.0f;
+ gCamera.trackballCenter.z = 0.0f;
+ gCamera.pos = gCamera.trackballCenter - gCamera.forward * gCamera.trackballRadius;
+ }
+
+ PxVec3 pos = gCamera.pos;
+ PxVec3 dir = gCamera.forward;
+ PxVec3 apos = gCamera.pos + dir;
+ gluLookAt(pos.x, pos.y, pos.z, pos.x + dir.x, pos.y + dir.y, pos.z + dir.z, 0.0f, 1.0f, 0.0f);
+ RenderObjects(true, false);
+
+ ShaderShadow::renderMode = ShaderShadow::RENDER_COLOR;
+
+}
+
+void RenderDepthNormal()
+{
+ RenderDepthNormalInline(true);
+}
+
+void RenderDepthOnly()
+{
+ RenderDepthNormalInline(false);
+}
+
+// ------------------------------------------------------------------------------------
+void RenderScene()
+{
+ // shadows
+ SetupCamera(false);
+
+ int numShadows = gNumShadows;
+ bool showReflections = gShowReflections;
+ if (SampleViewerScene::getRenderType() == SampleViewerScene::rtOPTIX) {
+ numShadows = 0;
+ showReflections = false;
+ }
+
+ if (numShadows > 0) {
+ ShaderShadow::renderMode = ShaderShadow::RENDER_DEPTH;
+ for (int i = 0; i < gNumLights; i++) {
+ if (gShadowMaps[i] == NULL)
+ //gShadowMaps[i] = new ShadowMap(gViewWidth, gViewHeight, gCamera.fov, i,12000);
+ //gShadowMaps[i] = new ShadowMap(gViewWidth, gViewHeight, gCamera.fov, i, 12000);
+ gShadowMaps[i] = new ShadowMap(gViewWidth, gViewHeight, gCamera.fov, i, 6144);
+
+ gDefaultShader->setShadowMap(i, gShadowMaps[i]);
+ if (gSampleScene != NULL) {
+ for (int j = 0; j < (int)gSampleScene->getShaders().size(); j++)
+ gSampleScene->getShaders()[j]->setShadowMap(i, gShadowMaps[i]);
+ }
+ if (i > numShadows)
+ continue;
+
+
+ if (gShadowMaps[i] != NULL)
+ gShadowMaps[i]->makeShadowMap(gCamera.pos, gCamera.forward, gLightDirs[i],
+ shadowClipNear, shadowClipFar, &RenderShadowCasters);
+ }
+ ShaderShadow::renderMode = ShaderShadow::RENDER_COLOR;
+ }
+
+ for (int i = 0; i < gNumLights; i++)
+ gDefaultShader->setSpotLight(i, gLightPos[i], gLightDirs[i]);
+ gDefaultShader->setBackLightDir(gBackLightDir);
+ gDefaultShader->setNumShadows(numShadows);
+ gDefaultShader->setShowReflection(showReflections);
+
+ if (gSampleScene != NULL) {
+ for (int i = 0; i < (int)gSampleScene->getShaders().size(); i++) {
+ ShaderShadow *s = gSampleScene->getShaders()[i];
+ for (int j = 0; j < gNumLights; j++)
+ s->setSpotLight(j, gLightPos[j], gLightDirs[j]);
+ s->setBackLightDir(gBackLightDir);
+ s->setNumShadows(numShadows);
+ s->setShowReflection(showReflections);
+ }
+ }
+
+ // reflection
+ if (showReflections) {
+
+ int reflectWidth = gViewWidth;
+ int reflectHeight = gViewHeight;
+
+ if (doAA) {
+ reflectWidth = g_pAABox->getBufW();
+ reflectHeight = g_pAABox->getBufH();
+ }
+ if (gReflectedSceneTarget == NULL) {
+
+ gReflectedSceneTarget = new RenderTarget(reflectWidth, reflectHeight);
+ gReflectedSceneTarget->beginCapture();
+ glViewport(0, 0, reflectWidth, reflectHeight);
+ gReflectedSceneTarget->endCapture();
+
+ gDefaultShader->setReflectionTexId(gReflectedSceneTarget->getColorTexId());
+ if (gSampleScene != NULL) {
+ for (int i = 0; i < (int)gSampleScene->getShaders().size(); i++)
+ gSampleScene->getShaders()[i]->setReflectionTexId(gReflectedSceneTarget->getColorTexId());
+ }
+ }
+
+ glViewport(0, 0, reflectWidth, reflectHeight);
+ gReflectedSceneTarget->beginCapture();
+
+ glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+// glClear(GL_DEPTH_BUFFER_BIT); // todo: why is this faster?
+
+ GLdouble clipEq[4];
+ clipEq[0] = 0.0f;
+ clipEq[1] = -1.0f;
+ clipEq[2] = 0.0f;
+ clipEq[3] = gGroundY;
+ glEnable(GL_CLIP_PLANE0);
+ glClipPlane(GL_CLIP_PLANE0, clipEq);
+
+ SetupCamera(true);
+ RenderObjects(true, true);
+
+ glDisable(GL_CLIP_PLANE0);
+ gReflectedSceneTarget->endCapture();
+ }
+ glViewport(0, 0, gViewWidth, gViewHeight);
+
+ SetupCamera();
+
+ bool useFXAA = doFXAA && gFXAAOn;
+
+ if (gDoHDR)
+ gHDRHelper->beginHDR(true);
+ else
+ {
+ if (useFXAA)
+ gFXAAHelper->StartFXAA();
+ }
+
+ if (doAA) {
+ if (gDoHDR) {
+ g_pAABox->oldFbo = gHDRHelper->mHDRFbo;
+
+ }
+ g_pAABox->Activate(0,0);
+ glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ }
+
+
+ RenderObjects(true, false);
+
+ //glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+ if (gDoSSAO) {
+ int oldFbo = (doAA)? (g_pAABox->fbms ? g_pAABox->fbms : g_pAABox->fb) : 0;
+
+ if (useFXAA) oldFbo = gFXAAHelper->FBO;
+ if (gDoHDR) {
+ if (!doAA) {
+ oldFbo = gHDRHelper->mHDRFbo;
+ }
+ }
+
+ if (gDoHBAO)
+ gHBAOHelper->renderAO(gUseNormalMap ? RenderDepthNormal : RenderDepthOnly, oldFbo, gUseNormalMap);
+ else
+ gSSAOHelper->DoSSAO(RenderDepthNormal, oldFbo);
+ }
+
+ if (doAA) {g_pAABox->Deactivate();}
+ if (doAA) g_pAABox->Draw(g_curTech);
+
+ if (gDoHDR)
+ {
+ if (useFXAA) gFXAAHelper->StartFXAA();
+ if (useFXAA) {
+ gHDRHelper->DoHDR(gFXAAHelper->FBO, gDoDOF);
+ } else {
+ gHDRHelper->DoHDR(0, gDoDOF);
+ }
+ }
+
+ if (useFXAA)
+ gFXAAHelper->EndFXAA(0);
+}
+
+// ------------------------------------------------------------------------------------
+void RenderCallback()
+{
+ if (gForceReloadShader) {
+ SceneKapla* scene = (SceneKapla*) gSampleScene;
+ scene->mSimSceneShader->loadShaders((string(gResourcePath) + string("\\shaders\\scene_vs.cpp")).c_str(), (string(gResourcePath) + string("\\shaders\\scene_fs.cpp")).c_str());
+ gForceReloadShader = false;
+ }
+ if (gForceReloadDebugShader) {
+ gDisplayTexArrayProg->loadShaders((string(gResourcePath) + string("\\shaders\\passthrough_vs.cpp")).c_str(), (string(gResourcePath) + string("\\shaders\\shadowdebug_fs.cpp")).c_str());
+ gDefaultShader->loadShaders((string(gResourcePath) + string("\\shaders\\default_vs.cpp")).c_str(), (string(gResourcePath) + string("\\shaders\\default_fs.cpp")).c_str());
+ gHDRHelper->mShaderDOF.loadShaders((string(gResourcePath) + string("\\shaders\\dof_vs.cpp")).c_str(), (string(gResourcePath) + string("\\shaders\\dof_fs.cpp")).c_str());
+ gHDRHelper->mShaderBloomH.loadShaders((string(gResourcePath) + string("\\shaders\\dof_vs.cpp")).c_str(), (string(gResourcePath) + string("\\shaders\\bloomH_fs.cpp")).c_str());
+ gHDRHelper->mShaderBloomV.loadShaders((string(gResourcePath) + string("\\shaders\\dof_vs.cpp")).c_str(), (string(gResourcePath) + string("\\shaders\\bloomV_fs.cpp")).c_str());
+ gSSAOHelper->SSAOFilterH.loadShaders((string(gResourcePath) + string("\\shaders\\filterv_vs.cpp")).c_str(), (string(gResourcePath) + string("\\shaders\\filterh_fs.cpp")).c_str());
+ gSSAOHelper->SSAOFilterV.loadShaders((string(gResourcePath) + string("\\shaders\\filterv_vs.cpp")).c_str(), (string(gResourcePath) + string("\\shaders\\filterv_fs.cpp")).c_str());
+
+ SceneKapla* scene = (SceneKapla*)gSampleScene;
+ if (!scene->mSimSceneShader->loadShaders((string(gResourcePath) + string("\\shaders\\combine_vs.cpp")).c_str(), (string(gResourcePath) + string("\\shaders\\combine_fs.cpp")).c_str())) {
+ printf("Can't load shader\n");
+ }
+ gForceReloadDebugShader = false;
+
+
+ }
+
+ static float first_frame_time = getCurrentTime();
+
+ ProcessKeys();
+ if (gDisableRendering)
+ {
+ if(!gPause)
+ {
+ BeginSimulation();
+ EndSimulation();
+ }
+ }
+ else
+ {
+ if (!gPause)
+ BeginSimulation();
+
+ // Clear buffers
+ // glClearColor(0.52f, 0.60f, 0.71f, 1.0f);
+ glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ if (SampleViewerScene::getRenderType() == SampleViewerScene::rtOPTIX) {
+ gSampleScene->render(true);
+ SetupCamera();
+ } else {
+ RenderScene();
+ }
+
+ DisplayText();
+
+ if(gSampleScene)
+ {
+ sampleViewerGamepad.processGamepads(*gSampleScene);
+ }
+
+ glutSwapBuffers();
+ glutReportErrors();
+
+ if (!gPause)
+ EndSimulation();
+
+ if (gRecordBMP)
+ SaveFrameBuffer();
+ }
+
+ gFrameNr++; // global frame nr
+ gFrameCounter++; // FPS
+
+ if (gMaxFrameNr > 0) { // benchmark mode
+ if (gFrameNr >= gMaxFrameNr) {
+ printf("Benchmark done %d frames: %g seconds.\n",
+ gMaxFrameNr, getCurrentTime() - first_frame_time );
+ SampleViewerScene::cleanupStaticResources();
+ exit(0);
+ }
+ }
+
+ if (gShot) {
+ }
+
+
+}
+
+// ------------------------------------------------------------------------------------
+void ReshapeCallback(int width, int height)
+{
+ gViewWidth = width;
+ gViewHeight = height;
+ glViewport(0, 0, width, height);
+
+ if (gDoHDR)
+ {
+ gHDRHelper->Resize(width, height);
+ }
+
+ if (doAA) {
+ if(g_pAABox) delete g_pAABox;
+ g_pAABox = new AABox(gResourcePath);
+ g_pAABox->Initialize(width, height, g_curSSSize, g_aaModes[g_curAA].ds, g_aaModes[g_curAA].cs);
+ gSSAOHelper->Resize(g_pAABox->bufw, g_pAABox->bufh);
+ gHBAOHelper->resize(g_pAABox->bufw, g_pAABox->bufh, width, height);
+ } else {
+ gSSAOHelper->Resize(width, height);
+ gHBAOHelper->resize(width, height, width, height);
+ }
+ if (doFXAA) {
+ gFXAAHelper->Resize(width, height);
+ }
+
+}
+
+// ------------------------------------------------------------------------------------
+void IdleCallback()
+{
+ glutPostRedisplay();
+
+ float time = getCurrentTime();
+ float elapsedTime = time - gPreviousTime;
+
+ if (elapsedTime > 1.0f) {
+ char title[30];
+ curFPS = (float)gFrameCounter / elapsedTime;
+ //
+ sprintf(title, "GRB Demo");
+ glutSetWindowTitle(title);
+ gPreviousTime = time;
+ gFrameCounter = 0;
+ }
+ getElapsedTime();
+}
+
+
+void CreateSampleViewerScene()
+{
+ if (gSampleScene != NULL)
+ delete gSampleScene;
+ gSampleScene = NULL;
+
+ if (gMaxFrameNr > 0) { // benchmark mode
+ gPause = false;
+ }
+ else {
+ gPause = false;
+ }
+
+
+ float sceneSize = 20.0f;
+ sceneBounds.minimum = PxVec3(-sceneSize, 0.0f, -sceneSize);
+ sceneBounds.maximum = PxVec3(sceneSize, sceneSize, sceneSize);
+
+ float fluidSize = 5.0f;
+
+
+ //printf("Scene B is %f %f %f --- %f %f %f\n", sceneBounds.minimum.x, sceneBounds.minimum.y, sceneBounds.minimum.z,
+ // sceneBounds.maximum.x, sceneBounds.maximum.y, sceneBounds.maximum.z);
+ //gForceReloadDebugShader = true;
+ PxVec3 target(0.0f, 0.0f, 0.0f);
+ g_fogStart = 50.0f;
+ g_fogEnd = 150.0f;
+ shadowClipNear = 0.2f;
+ shadowClipFar = 100.0f;
+
+ DEFAULT_SOLVER_ITERATIONS = 8;
+
+ g_shadowAdd = -0.001f;
+
+ switch (gSceneNr) {
+ case 0:
+ {
+ gSampleScene = new SceneKaplaTower(gPxPhysics, gPxCooking, gUseGrb, gDefaultShader, gResourcePath, gSlowMotionFactor);
+ gLightPos[0] = PxVec3(sceneBounds.maximum.x, sceneBounds.maximum.y*3.0f, sceneBounds.maximum.z*2.f)*5.0f;
+ //g_shadowAdd = 0.f;// -0.004054f;
+
+ sprintf(gDemoName, "GRB Kapla Tower");
+ break;
+ }
+ case 1:
+ {
+ gSampleScene = new SceneKaplaArena(gPxPhysics, gPxCooking, gUseGrb, gDefaultShader, gResourcePath, gSlowMotionFactor);
+ gLightPos[0] = PxVec3(sceneBounds.maximum.x, sceneBounds.maximum.y*3.0f, sceneBounds.maximum.z)*5.0f;
+ //g_shadowAdd = -0.003;
+ //g_shadowAdd = 0.f;
+ sprintf(gDemoName, "GRB Kapla Arena");
+ break;
+ }
+ case 2:
+ {
+ gSampleScene = new SceneVehicle(gPxPhysics, gPxCooking, gUseGrb, gDefaultShader, gResourcePath, gSlowMotionFactor);
+ gLightPos[0] = PxVec3(sceneBounds.maximum.x, sceneBounds.maximum.y*3.0f, -sceneBounds.maximum.z)*5.0f;
+ //g_shadowAdd = -0.003;
+ //g_shadowAdd = -0.001891;
+ //g_shadowAdd = 0.f;
+ sprintf(gDemoName, "GRB Vehicle Demo");
+ break;
+ }
+ case 3:
+ {
+ //DEFAULT_SOLVER_ITERATIONS = 4;
+ gSampleScene = new SceneCrab(gPxPhysics, gPxCooking, gUseGrb, gDefaultShader, gResourcePath, gSlowMotionFactor);
+ gLightPos[0] = PxVec3(-sceneBounds.maximum.x, sceneBounds.maximum.y*8.0f, sceneBounds.maximum.z)*8.0f;
+ //g_shadowAdd = -0.001891;
+ //g_shadowAdd = 0.f;
+ g_fogStart = 150.0f;
+ g_fogEnd = 350.0f;
+ //shadowClipFar = 100.0f;
+ sprintf(gDemoName, "GRB Walkers Demo ");
+
+ break;
+ }
+ default:
+ {
+ //DEFAULT_SOLVER_ITERATIONS = 4;
+ //g_shadowAdd = -0.004054f;
+ //g_shadowAdd = 0.f;
+ //shadowClipFar = 130.0f;
+ gLightPos[0] = PxVec3(0.f, 25.f, 150.f);
+ gSampleScene = new SceneRagdollWashingMachine(gPxPhysics, gPxCooking, gUseGrb, gDefaultShader, gResourcePath, gSlowMotionFactor);
+ sprintf(gDemoName, "GRB Ragdoll Demo ");
+ break;
+ }
+ }
+
+ SceneKapla* scene = (SceneKapla*)gSampleScene;
+
+ if (!scene->mSimSceneShader->loadShaders((string(gResourcePath) + string("\\shaders\\combine_vs.cpp")).c_str(), (string(gResourcePath) + string("\\shaders\\combine_fs.cpp")).c_str()))
+ {
+ printf("Can't load shader\n");
+ }
+
+ gSampleScene->getInitialCamera(gCamera.pos, gCamera.forward);
+ float fogColor[4] = { 0, 0, 0, 1 };
+ glFogf(GL_FOG_DENSITY, 0.0009f);
+ glFogf(GL_FOG_START, g_fogStart);
+ glFogf(GL_FOG_END, g_fogEnd);
+ glFogfv(GL_FOG_COLOR, fogColor);
+
+ gLightDirs[0] = gLightPos[0] - target;
+ gLightDirs[0].normalize();
+
+ if (gSceneNr == 4)
+ {
+ gLightDirs[0] = PxVec3(0.f, 0.2f, 1.f).getNormalized();
+ }
+
+ gLightPos[1] = PxVec3(sceneBounds.minimum.x, sceneBounds.maximum.y, sceneBounds.minimum.z);
+ gLightDirs[1] = gLightPos[1] - target;
+ gLightDirs[1].normalize();
+
+ gLightPos[2] = PxVec3((sceneBounds.minimum.x + sceneBounds.maximum.x) * 0.5f, sceneBounds.maximum.y, sceneBounds.minimum.z);
+ gLightDirs[2] = gLightPos[2] - target;
+ gLightDirs[2].normalize();
+
+ gBackLightDir = PxVec3(0.8f, -1.0f, -1.2f);
+ gBackLightDir.normalize();
+
+ myDustColor = ((SceneKapla*)gSampleScene)->getSimSceneShader()->getDustColor();
+ SetHelpString();
+
+}
+
+// ------------------------------------------------------------------------------------
+void InitSampleViewerScene()
+{
+ gSampleScene->onInit(gPxScene);
+}
+
+void InitGlutCallbacks(bool, int, int);
+
+//-----------------------------------------------------------------------------
+void ToggleFullscreen()
+{
+ static int window[4] = {-1, -1, -1, -1};
+
+ if ( window[0] == -1) { // We are in non-fullscreen mode
+ window[0] = glutGet(GLUT_WINDOW_WIDTH);
+ window[1] = glutGet(GLUT_WINDOW_HEIGHT);
+ window[2] = glutGet(GLUT_WINDOW_X);
+ window[3] = glutGet(GLUT_WINDOW_Y);
+ glutFullScreen();
+ }
+ else
+ { // We are in fullscreen mode
+ glutPositionWindow( window[2], window[3] );
+ glutReshapeWindow( window[0], window[1] );
+ window[0] = -1;
+ }
+
+
+
+ glutPostRedisplay();
+}
+
+
+// ------------------------------------------------------------------------------------
+void KeyboardCallback(unsigned char key, int x, int y)
+{
+ if (key != 'p' && key != 'w' && key != 'a' && key != 's' && key != 'd' && key != 'q' && key != 'e' && key != 'x' && key != 'v'
+ && key != 'u' && key != 'i' && key != 'k' && key != 'y' && key != 'b' && key != 'c' && key != 'h' && key != 'H' && key != 'n')
+ gPause = false;
+
+ if (key == ' ') {
+ gShot = true;
+ }
+
+ gKeys[key] = true;
+
+ if ('1' <= key && key <= '0' + gNumScenes)
+ {
+ gSceneNr = key - '0' - 1;
+
+ WaitForSim();
+
+ if (gSampleScene)
+ delete gSampleScene;
+ gSampleScene = NULL;
+
+ CreateSampleViewerScene();
+ RecreateSDKScenes();
+
+ InitSampleViewerScene();
+
+ }
+
+ switch (key)
+ {
+ case 'f' : ToggleFullscreen(); break;
+
+ case 27 : {
+ CleanupSample();
+ exit(0);
+ } break;
+ case 'p': { gPause = !gPause; UpdateTime(); break; }
+ case 'o': { if (!gPause) gPause = true; RunPhysics(); glutPostRedisplay(); break; }
+ case 'h': { gDoSSAO = !gDoSSAO; break; }
+ case 'H': { gDoHBAO = !gDoHBAO; break; }
+ //case 'n': { gUseNormalMap = !gUseNormalMap; break; }
+
+ default: ;
+ }
+
+ if (gSampleScene != NULL)
+ gSampleScene->handleKeyDown(key, x, y);
+}
+
+void CleanupSample()
+{
+ if (gIsSampleCleanedUp)
+ return;
+
+ WaitForSim();
+
+ if (gSampleScene != NULL) {
+ delete gSampleScene;
+ gSampleScene = 0;
+ }
+ SampleViewerScene::cleanupStaticResources();
+ ReleaseSDKs();
+
+ glutDestroyWindow(gMainHandle);
+
+ gIsSampleCleanedUp = true;
+}
+
+// ------------------------------------------------------------------------------------
+
+void KeyboardUpCallback(unsigned char key, int x, int y)
+{
+ gKeys[key] = false;
+ if (gSampleScene != NULL)
+ gSampleScene->handleKeyUp(key, x, y);
+}
+
+// ------------------------------------------------------------------------------------
+
+void SpecialCallback(int key, int x, int y)
+{
+ switch (key)
+ {
+ // Reset PhysX
+ case GLUT_KEY_F1:
+ gHelp = !gHelp;
+ break;
+ case GLUT_KEY_F2:
+ gDisplay = !gDisplay;
+ break;
+
+ case GLUT_KEY_F10:
+ {
+ WaitForSim();
+
+ if (gSampleScene)
+ delete gSampleScene;
+ gSampleScene = NULL;
+
+ CreateSampleViewerScene();
+ RecreateSDKScenes();
+
+ InitSampleViewerScene();
+ return;
+ }
+ case GLUT_KEY_F5:
+ {
+ gUseGrb = !gUseGrb;
+ }
+ }
+ if (gSampleScene != NULL)
+ gSampleScene->handleSpecialKey(key, x, y);
+
+ SetHelpString();
+}
+
+// ------------------------------------------------------------------------------------
+void MouseCallback(int button, int state, int x, int y)
+{
+ if (button != GLUT_LEFT_BUTTON || glutGetModifiers() != 0)
+ gPause = false;
+
+ gMouseX = x;
+ gMouseY = y;
+
+ if (!(glutGetModifiers() & GLUT_ACTIVE_SHIFT)) {
+
+ if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
+ {
+ gCamera.zoom = true;
+ }
+ else if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
+ {
+ gCamera.rotate = true;
+ }
+ else if (button == GLUT_MIDDLE_BUTTON && state == GLUT_DOWN)
+ {
+ gCamera.translate = true;
+ }
+ }
+ if (state == GLUT_UP)
+ {
+ gCamera.rotate = false;
+ gCamera.translate = false;
+ gCamera.zoom = false;
+ }
+
+ if (gSampleScene != NULL)
+ gSampleScene->handleMouseButton(button, state, x, y);
+}
+
+// ------------------------------------------------------------------------------------
+
+void MotionCallback(int x, int y)
+{
+
+ int dx = gMouseX - x;
+ int dy = gMouseY - y;
+
+ PxVec3 up;
+ up = PxVec3(0,1,0);
+
+ const float translateSpeed = 0.1f;
+
+ if (gCamera.translate)
+ {
+ PxVec3 &pos = gCamera.trackballMode ? gCamera.trackballCenter : gCamera.pos;
+ pos += gCamera.right * dx * translateSpeed;
+ pos -= up * dy * translateSpeed;
+ }
+ else if (gCamera.rotate)
+ {
+ const float rotationSpeed = 0.01f;
+ if (gCamera.trackballMode) {
+ gCamera.forward.normalize();
+ gCamera.right = gCamera.forward.cross(PxVec3(0,1,0));
+
+ PxQuat qy(dx * rotationSpeed, PxVec3(0.0f, 1.0f, 0.0f));
+ gCamera.forward = qy.rotate(gCamera.forward);
+ PxQuat qx(dy * rotationSpeed, gCamera.right);
+ gCamera.forward = qx.rotate(gCamera.forward);
+ gCamera.forward.y = PxClamp(gCamera.forward.y, 0.9f, -0.9f);
+ gCamera.forward.normalize();
+ gCamera.pos = gCamera.trackballCenter - gCamera.forward * gCamera.trackballRadius;
+ }
+ else {
+ PxQuat qx(dx * rotationSpeed, up);
+ gCamera.forward = qx.rotate(gCamera.forward);
+ PxQuat qy(dy * rotationSpeed, gCamera.right);
+ PxVec3 tempForward = gCamera.forward;
+ gCamera.forward = qy.rotate(gCamera.forward);
+ gCamera.forward.normalize();
+
+ if (PxAbs(gCamera.forward.y) > 0.98f)
+ {
+ //Clamp the axis...
+ gCamera.forward = tempForward;
+ gCamera.forward.normalize();
+ }
+ }
+ }
+ else if (gCamera.zoom) {
+ if (gCamera.trackballMode)
+ gCamera.trackballRadius *= 1.0f + 0.01f * dy;
+ else
+ gCamera.pos -= gCamera.forward * dy * translateSpeed;
+ }
+
+ gMouseX = x;
+ gMouseY = y;
+
+ if (gSampleScene != NULL)
+ gSampleScene->handleMouseMotion(x, y);
+}
+
+// ------------------------------------------------------------------------------------
+
+void InitGlutCallbacks(bool fullscreen, int width, int height)
+{
+ if (fullScreen) {
+ char modeS[500];
+ sprintf(modeS, "%dx%d:32@60", width, height);
+ glutGameModeString(modeS);
+ glutEnterGameMode();
+ }
+ else {
+ gMainHandle = glutCreateWindow("Sample Viewer");
+ glutSetWindow(gMainHandle);
+ }
+ glutDisplayFunc(RenderCallback);
+ glutReshapeFunc(ReshapeCallback);
+ glutIdleFunc(IdleCallback);
+ glutKeyboardFunc(KeyboardCallback);
+ glutKeyboardUpFunc(KeyboardUpCallback);
+ glutSpecialFunc(SpecialCallback);
+ glutMouseFunc(MouseCallback);
+ glutMotionFunc(MotionCallback);
+ glutPassiveMotionFunc(MotionCallback);
+ MotionCallback(0, 0);
+}
+
+void InitGlut(int argc, char **argv)
+{
+ //printf("glutInit\n");
+
+ glutInit(&argc, argv);
+ glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT);
+ glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
+
+ InitGlutCallbacks(fullScreen, WINDOW_WIDTH, WINDOW_HEIGHT);
+
+ sampleViewerGamepad.init();
+
+ // Setup default render states
+ glEnable(GL_DEPTH_TEST);
+ glEnable(GL_COLOR_MATERIAL);
+ //glEnable(GL_CULL_FACE);
+ glShadeModel(GL_SMOOTH);
+#ifdef WIN32
+ glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
+ glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
+#endif
+
+ // Setup lighting
+ glEnable(GL_LIGHTING);
+// float AmbientColor[] = { 0.0f, 0.1f, 0.2f, 0.0f }; glLightfv(GL_LIGHT0, GL_AMBIENT, AmbientColor);
+// float DiffuseColor[] = { 0.8f, 0.8f, 0.8f, 0.0f }; glLightfv(GL_LIGHT0, GL_DIFFUSE, DiffuseColor);
+// float SpecularColor[] = { 0.7f, 0.7f, 0.7f, 0.0f }; glLightfv(GL_LIGHT0, GL_SPECULAR, SpecularColor);
+
+ float AmbientColor[] = { 0.0f, 0.0f, 0.0f, 0.0f }; glLightfv(GL_LIGHT0, GL_AMBIENT, AmbientColor);
+ float DiffuseColor[] = { 0.6f, 0.6f, 0.6f, 0.0f }; glLightfv(GL_LIGHT0, GL_DIFFUSE, DiffuseColor);
+ float SpecularColor[] = { 0.7f, 0.7f, 0.7f, 0.0f }; glLightfv(GL_LIGHT0, GL_SPECULAR, SpecularColor);
+
+
+ // float Position[] = { 100.0f, 100.0f, -400.0f, 1.0f }; glLightfv(GL_LIGHT0, GL_POSITION, Position);
+ //float Position[] = { 10.0f, 200.0f, 15.0f, 0.0f }; glLightfv(GL_LIGHT0, GL_POSITION, Position);
+
+ //float Position[] = { -400,200,300, 0.0f }; glLightfv(GL_LIGHT0, GL_POSITION, Position);
+#if !TEST_ART_GALLERY_FLOOR
+ float Position[] = { -400,200,300, 0.0f }; glLightfv(GL_LIGHT0, GL_POSITION, Position);
+#else
+ float Position[] = { 674,-300,200, 0.0f }; glLightfv(GL_LIGHT0, GL_POSITION, Position);
+#endif
+ glEnable(GL_LIGHT0);
+ glEnable(GL_NORMALIZE); // so that lighting on scaled objects is correct
+
+
+ PxVec3 target = PxVec3(0.0f, 8.0f, -25.0f);
+ gCamera.forward = target - gCamera.pos;
+ gCamera.forward.normalize();
+
+ for (int i = 0; i < gNumLights; i++)
+ gShadowMaps[i] = NULL;
+
+ GLenum err = glewInit();
+ if (err != GLEW_OK) {
+ printf("glewInit() failed\n");
+ exit(0);
+ }
+
+ // Setup Fog
+ glEnable (GL_FOG);
+ float fogColor[4] = {180.0f/255.0f,182.0f/255.0f,202.0f/255.0f,1.0f};
+ glFogi (GL_FOG_MODE, GL_LINEAR);
+
+ glFogf(GL_FOG_DENSITY, 0.0009f);
+ glFogf(GL_FOG_START, g_fogStart);
+ glFogf(GL_FOG_END, g_fogEnd);
+ glFogfv (GL_FOG_COLOR, fogColor);
+
+ // Load ground texture
+ gSplashScreenTexId = 0;
+
+ gDisplayTexArrayProg = new Shader();
+ gDisplayTexArrayProg->loadShaderCode(passThruVS, texture2DArrayPS);
+
+ gDisplaySplashProg = new Shader();
+ gDisplaySplashProg->loadShaderCode(passThruVS, textureRECTPS);
+
+ if (doAA) {
+ g_pAABox = new AABox(gResourcePath);
+ g_pAABox->Initialize(WINDOW_WIDTH, WINDOW_HEIGHT, g_curSSSize, g_aaModes[g_curAA].ds, g_aaModes[g_curAA].cs);
+ }
+
+ if (gDoHDR)
+ {
+ ShaderShadow::hdrScale = 2.0f;
+ }
+
+ gDefaultShader = new ShaderShadow(ShaderShadow::VS_DEFAULT, ShaderShadow::PS_SHADE);
+ gDefaultShader->init();
+
+ /*
+ TCHAR pwd[500];
+ GetCurrentDirectory(500,pwd);
+ MessageBox(NULL,pwd,pwd,0);
+*/
+ gFXAAHelper = new FXAAHelper(gResourcePath);
+ gSSAOHelper = new SSAOHelper(gCamera.fov, 0.1f, zNear, zFar, gResourcePath, doAA ? (1.0f/g_curSSSize) : 1.0f);
+ gHBAOHelper = new HBAOHelper(gCamera.fov, zNear, zFar);
+ gHDRHelper = new HDRHelper(gCamera.fov, 0.1f, zNear, zFar, gResourcePath, doAA ? (1.0f/g_curSSSize) : 1.0f);
+
+ gDisplayTexArrayProg->loadShaders((string(gResourcePath) + string("\\shaders\\passthrough_vs.cpp")).c_str(), (string(gResourcePath) + string("\\shaders\\shadowdebug_fs.cpp")).c_str());
+ gDefaultShader->loadShaders((string(gResourcePath) + string("\\shaders\\default_vs.cpp")).c_str(), (string(gResourcePath) + string("\\shaders\\default_fs.cpp")).c_str());
+ gHDRHelper->mShaderDOF.loadShaders((string(gResourcePath) + string("\\shaders\\dof_vs.cpp")).c_str(), (string(gResourcePath) + string("\\shaders\\dof_fs.cpp")).c_str());
+ gHDRHelper->mShaderBloomH.loadShaders((string(gResourcePath) + string("\\shaders\\dof_vs.cpp")).c_str(), (string(gResourcePath) + string("\\shaders\\bloomH_fs.cpp")).c_str());
+ gHDRHelper->mShaderBloomV.loadShaders((string(gResourcePath) + string("\\shaders\\dof_vs.cpp")).c_str(), (string(gResourcePath) + string("\\shaders\\bloomV_fs.cpp")).c_str());
+ gSSAOHelper->SSAOFilterH.loadShaders((string(gResourcePath) + string("\\shaders\\filterv_vs.cpp")).c_str(), (string(gResourcePath) + string("\\shaders\\filterh_fs.cpp")).c_str());
+ gSSAOHelper->SSAOFilterV.loadShaders((string(gResourcePath) + string("\\shaders\\filterv_vs.cpp")).c_str(), (string(gResourcePath) + string("\\shaders\\filterv_fs.cpp")).c_str());
+ gForceReloadDebugShader = false;
+
+
+ if (gSceneNr == 7) {
+ gCamera.pos = PxVec3(0.0319193f,3.24621f, 3.47924f);
+ }
+}
+
+extern int numCylinderSeg ;
+// ------------------------------------------------------------------------------------
+static bool parse_value_arg( std::string const& arg, std::string const& name, int& value )
+{
+ if (arg.substr(0, name.length() + 1) == (name + "=")) {
+ value = atoi( arg.substr(name.length() + 1).c_str());
+ return true;
+ }
+ return false;
+}
+
+static bool starts_with( std::string const& arg, std::string const& text )
+{
+ return arg.find( text ) == 0;
+}
+
+#define SQR(x) ((x)*(x)) // x^2
+
+// Constants
+#define M_SQRT3 1.73205080756887729352744634151 // sqrt(3)
+ // x^2
+
+
+// ----------------------------------------------------------------------------
+int dsyevc3(float A[3][3], float w[3])
+// ----------------------------------------------------------------------------
+// Calculates the eigenvalues of a symmetric 3x3 matrix A using Cardano's
+// analytical algorithm.
+// Only the diagonal and upper triangular parts of A are accessed. The access
+// is read-only.
+// ----------------------------------------------------------------------------
+// Parameters:
+// A: The symmetric input matrix
+// w: Storage buffer for eigenvalues
+// ----------------------------------------------------------------------------
+// Return value:
+// 0: Success
+// -1: Error
+// ----------------------------------------------------------------------------
+{
+ float m, c1, c0;
+
+ // Determine coefficients of characteristic poynomial. We write
+ // | a d f |
+ // A = | d* b e |
+ // | f* e* c |
+ float de = A[0][1] * A[1][2]; // d * e
+ float dd = SQR(A[0][1]); // d^2
+ float ee = SQR(A[1][2]); // e^2
+ float ff = SQR(A[0][2]); // f^2
+ m = A[0][0] + A[1][1] + A[2][2];
+ c1 = (A[0][0]*A[1][1] + A[0][0]*A[2][2] + A[1][1]*A[2][2]) // a*b + a*c + b*c - d^2 - e^2 - f^2
+ - (dd + ee + ff);
+ c0 = A[2][2]*dd + A[0][0]*ee + A[1][1]*ff - A[0][0]*A[1][1]*A[2][2]
+ - 2.0 * A[0][2]*de; // c*d^2 + a*e^2 + b*f^2 - a*b*c - 2*f*d*e)
+
+ float p, sqrt_p, q, c, s, phi;
+ p = SQR(m) - 3.0*c1;
+ q = m*(p - (3.0/2.0)*c1) - (27.0/2.0)*c0;
+ sqrt_p = sqrtf(fabs(p));
+
+ phi = 27.0 * ( 0.25*SQR(c1)*(p - c1) + c0*(q + 27.0/4.0*c0));
+ phi = (1.0/3.0) * atan2(sqrt(fabs(phi)), q);
+
+ c = sqrt_p*cosf(phi);
+ s = (1.0/M_SQRT3)*sqrt_p*sinf(phi);
+
+ w[1] = (1.0/3.0)*(m - c);
+ w[2] = w[1] + s;
+ w[0] = w[1] + c;
+ w[1] -= s;
+
+ return 0;
+}
+
+// ----------------------------------------------------------------------------
+int dsyevv3(float A[3][3], float Q[3][3], float w[3])
+// ----------------------------------------------------------------------------
+// Calculates the eigenvalues and normalized eigenvectors of a symmetric 3x3
+// matrix A using Cardano's method for the eigenvalues and an analytical
+// method based on vector cross products for the eigenvectors.
+// Only the diagonal and upper triangular parts of A need to contain meaningful
+// values. However, all of A may be used as temporary storage and may hence be
+// destroyed.
+// ----------------------------------------------------------------------------
+// Parameters:
+// A: The symmetric input matrix
+// Q: Storage buffer for eigenvectors
+// w: Storage buffer for eigenvalues
+// ----------------------------------------------------------------------------
+// Return value:
+// 0: Success
+// -1: Error
+// ----------------------------------------------------------------------------
+// Dependencies:
+// dsyevc3()
+// ----------------------------------------------------------------------------
+// Version history:
+// v1.1 (12 Mar 2012): Removed access to lower triangualr part of A
+// (according to the documentation, only the upper triangular part needs
+// to be filled)
+// v1.0: First released version
+// ----------------------------------------------------------------------------
+{
+#ifndef EVALS_ONLY
+ float norm; // Squared norm or inverse norm of current eigenvector
+ float n0, n1; // Norm of first and second columns of A
+ float n0tmp, n1tmp; // "Templates" for the calculation of n0/n1 - saves a few FLOPS
+ float thresh; // Small number used as threshold for floating point comparisons
+ float error; // Estimated maximum roundoff error in some steps
+ float wmax; // The eigenvalue of maximum modulus
+ float f, t; // Intermediate storage
+ int i, j; // Loop counters
+#endif
+
+ // Calculate eigenvalues
+ dsyevc3(A, w);
+
+#ifndef EVALS_ONLY
+ wmax = fabs(w[0]);
+ if ((t=fabs(w[1])) > wmax)
+ wmax = t;
+ if ((t=fabs(w[2])) > wmax)
+ wmax = t;
+ thresh = SQR(8.0 * DBL_EPSILON * wmax);
+
+ // Prepare calculation of eigenvectors
+ n0tmp = SQR(A[0][1]) + SQR(A[0][2]);
+ n1tmp = SQR(A[0][1]) + SQR(A[1][2]);
+ Q[0][1] = A[0][1]*A[1][2] - A[0][2]*A[1][1];
+ Q[1][1] = A[0][2]*A[0][1] - A[1][2]*A[0][0];
+ Q[2][1] = SQR(A[0][1]);
+
+ // Calculate first eigenvector by the formula
+ // v[0] = (A - w[0]).e1 x (A - w[0]).e2
+ A[0][0] -= w[0];
+ A[1][1] -= w[0];
+ Q[0][0] = Q[0][1] + A[0][2]*w[0];
+ Q[1][0] = Q[1][1] + A[1][2]*w[0];
+ Q[2][0] = A[0][0]*A[1][1] - Q[2][1];
+ norm = SQR(Q[0][0]) + SQR(Q[1][0]) + SQR(Q[2][0]);
+ n0 = n0tmp + SQR(A[0][0]);
+ n1 = n1tmp + SQR(A[1][1]);
+ error = n0 * n1;
+
+ if (n0 <= thresh) // If the first column is zero, then (1,0,0) is an eigenvector
+ {
+ Q[0][0] = 1.0;
+ Q[1][0] = 0.0;
+ Q[2][0] = 0.0;
+ }
+ else if (n1 <= thresh) // If the second column is zero, then (0,1,0) is an eigenvector
+ {
+ Q[0][0] = 0.0;
+ Q[1][0] = 1.0;
+ Q[2][0] = 0.0;
+ }
+ else if (norm < SQR(64.0 * DBL_EPSILON) * error)
+ { // If angle between A[0] and A[1] is too small, don't use
+ t = SQR(A[0][1]); // cross product, but calculate v ~ (1, -A0/A1, 0)
+ f = -A[0][0] / A[0][1];
+ if (SQR(A[1][1]) > t)
+ {
+ t = SQR(A[1][1]);
+ f = -A[0][1] / A[1][1];
+ }
+ if (SQR(A[1][2]) > t)
+ f = -A[0][2] / A[1][2];
+ norm = 1.0/sqrt(1 + SQR(f));
+ Q[0][0] = norm;
+ Q[1][0] = f * norm;
+ Q[2][0] = 0.0;
+ }
+ else // This is the standard branch
+ {
+ norm = sqrt(1.0 / norm);
+ for (j=0; j < 3; j++)
+ Q[j][0] = Q[j][0] * norm;
+ }
+
+
+ // Prepare calculation of second eigenvector
+ t = w[0] - w[1];
+ if (fabs(t) > 8.0 * DBL_EPSILON * wmax)
+ {
+ // For non-degenerate eigenvalue, calculate second eigenvector by the formula
+ // v[1] = (A - w[1]).e1 x (A - w[1]).e2
+ A[0][0] += t;
+ A[1][1] += t;
+ Q[0][1] = Q[0][1] + A[0][2]*w[1];
+ Q[1][1] = Q[1][1] + A[1][2]*w[1];
+ Q[2][1] = A[0][0]*A[1][1] - Q[2][1];
+ norm = SQR(Q[0][1]) + SQR(Q[1][1]) + SQR(Q[2][1]);
+ n0 = n0tmp + SQR(A[0][0]);
+ n1 = n1tmp + SQR(A[1][1]);
+ error = n0 * n1;
+
+ if (n0 <= thresh) // If the first column is zero, then (1,0,0) is an eigenvector
+ {
+ Q[0][1] = 1.0;
+ Q[1][1] = 0.0;
+ Q[2][1] = 0.0;
+ }
+ else if (n1 <= thresh) // If the second column is zero, then (0,1,0) is an eigenvector
+ {
+ Q[0][1] = 0.0;
+ Q[1][1] = 1.0;
+ Q[2][1] = 0.0;
+ }
+ else if (norm < SQR(64.0 * DBL_EPSILON) * error)
+ { // If angle between A[0] and A[1] is too small, don't use
+ t = SQR(A[0][1]); // cross product, but calculate v ~ (1, -A0/A1, 0)
+ f = -A[0][0] / A[0][1];
+ if (SQR(A[1][1]) > t)
+ {
+ t = SQR(A[1][1]);
+ f = -A[0][1] / A[1][1];
+ }
+ if (SQR(A[1][2]) > t)
+ f = -A[0][2] / A[1][2];
+ norm = 1.0/sqrt(1 + SQR(f));
+ Q[0][1] = norm;
+ Q[1][1] = f * norm;
+ Q[2][1] = 0.0;
+ }
+ else
+ {
+ norm = sqrt(1.0 / norm);
+ for (j=0; j < 3; j++)
+ Q[j][1] = Q[j][1] * norm;
+ }
+ }
+ else
+ {
+ // For degenerate eigenvalue, calculate second eigenvector according to
+ // v[1] = v[0] x (A - w[1]).e[i]
+ //
+ // This would really get to complicated if we could not assume all of A to
+ // contain meaningful values.
+ A[1][0] = A[0][1];
+ A[2][0] = A[0][2];
+ A[2][1] = A[1][2];
+ A[0][0] += w[0];
+ A[1][1] += w[0];
+ for (i=0; i < 3; i++)
+ {
+ A[i][i] -= w[1];
+ n0 = SQR(A[0][i]) + SQR(A[1][i]) + SQR(A[2][i]);
+ if (n0 > thresh)
+ {
+ Q[0][1] = Q[1][0]*A[2][i] - Q[2][0]*A[1][i];
+ Q[1][1] = Q[2][0]*A[0][i] - Q[0][0]*A[2][i];
+ Q[2][1] = Q[0][0]*A[1][i] - Q[1][0]*A[0][i];
+ norm = SQR(Q[0][1]) + SQR(Q[1][1]) + SQR(Q[2][1]);
+ if (norm > SQR(256.0 * DBL_EPSILON) * n0) // Accept cross product only if the angle between
+ { // the two vectors was not too small
+ norm = sqrt(1.0 / norm);
+ for (j=0; j < 3; j++)
+ Q[j][1] = Q[j][1] * norm;
+ break;
+ }
+ }
+ }
+
+ if (i == 3) // This means that any vector orthogonal to v[0] is an EV.
+ {
+ for (j=0; j < 3; j++)
+ if (Q[j][0] != 0.0) // Find nonzero element of v[0] ...
+ { // ... and swap it with the next one
+ norm = 1.0 / sqrt(SQR(Q[j][0]) + SQR(Q[(j+1)%3][0]));
+ Q[j][1] = Q[(j+1)%3][0] * norm;
+ Q[(j+1)%3][1] = -Q[j][0] * norm;
+ Q[(j+2)%3][1] = 0.0;
+ break;
+ }
+ }
+ }
+
+
+ // Calculate third eigenvector according to
+ // v[2] = v[0] x v[1]
+ Q[0][2] = Q[1][0]*Q[2][1] - Q[2][0]*Q[1][1];
+ Q[1][2] = Q[2][0]*Q[0][1] - Q[0][0]*Q[2][1];
+ Q[2][2] = Q[0][0]*Q[1][1] - Q[1][0]*Q[0][1];
+#endif
+
+ return 0;
+}
+
+int main(int argc, char** argv)
+{
+ /*
+ float A[3][3] = {{-4,2,1},
+ {2,9,-3},
+ {1,-3,-7}};
+ float Q[3][3];
+ float w[3];
+
+ dsyevv3(A,Q,w);
+ printf("%f %f %f\n", w[0], w[1], w[2]);
+
+ return 0;
+ */
+ strcpy(gResourcePath, "../../../externalIP/resources");
+ gCamera.init();
+
+ FILE *f = fopen("resourcePath.txt", "r");
+ if (f != NULL) {
+ fgets(gResourcePath, 512, f);
+ fclose(f);
+ }
+
+ const char* usage = "Usage:\n"
+ " -msaa Do MSAA Antialiasing (Slower, but better quality). On by default. \n"
+ " -fxaa Do FXAA Antialiasing (Faster, but poorer quality)\n"
+ " -nbThreads n Use n worker threads in PhysX\n"
+ " -nossao Disable SSAO\n"
+ " -nhdr Disable HDR\n"
+ " -grb Use GRB (default is on)\n"
+ " -nogrb Use software PhysX\n"
+ " -maxSubSteps n Enable up to n sub-steps per-frame."
+ "\n"
+ ;
+ printf(usage);
+
+ std::string render_opts;
+ for (int i = 1; i < argc; i++) {
+ std::string arg = argv[i];
+ std::transform(&arg[0], &arg[0] + arg.length(), &arg[0], tolower);
+ if (arg == "-nogrb") { gUseGrb = false; gCurrentUsingGrb = false; }
+ else if (arg == "-grb") gUseGrb = true;
+ else if (arg == "-msaa") {
+ doAA = true;
+ doFXAA = false;
+ }
+ else if (arg == "-fxaa") {
+ doFXAA = true;
+ doAA = false;
+ }
+ else if (arg == "-maxsubsteps")
+ {
+ if (argc > (1 + i))
+ {
+ PxU32 substepCount = atoi(argv[i + 1]);
+ gMaxSubSteps = substepCount;
+ i++;
+ }
+ }
+ else if (arg == "-nbthreads")
+ {
+ if (argc > (1 + i))
+ {
+ PxU32 nbThreads = atoi(argv[i + 1]);
+ gNrWorkerThreads = nbThreads;
+ i++;
+ }
+ }
+ else if (arg == "-nossao")
+ {
+ gDoSSAO = false;
+ }
+ else if (arg == "-nohdr")
+ {
+ gDoHDR = false;
+ }
+
+ }
+
+ if (!InitPhysX()) {
+ ReleaseSDKs();
+ return 0;
+ }
+
+ InitGlut(argc, argv);
+
+ if (!render_opts.empty()) {
+ SampleViewerScene::setRendererOptions(render_opts.c_str());
+ }
+
+ // Initialize physics scene and start the application main loop if scene was created
+
+ SampleViewerScene::setRenderType(SampleViewerScene::rtOPENGL);
+
+ gFontRenderer = new GLFontRenderer();
+
+ CreateSampleViewerScene();
+
+ //Hack! When rendering the first frame of the demo, various extremely large graphics buffers are allocated. In GPUs with relatively small amount of memory,
+ //these allocations can fail. This seems to relate to CUDA allocations fragmenting the heap. Therefore, we initialize the first frame to use CPU simulation, scheduling a transition to
+ //GPU to ensure that these large allocations succeed. They'll never be reallocated again.
+ //Ideally, these allocations would just happen before the GRB scene was initialized but that would require some surgery to the sample framework.
+ //bool useGrb = gUseGrb;
+ //gUseGrb = false;
+ RecreateSDKScenes();
+ //gUseGrb = useGrb;
+
+ //gForceSceneRecreate = useGrb;
+
+ InitSampleViewerScene();
+
+ atexit(CleanupSample);
+
+ glutMainLoop();
+}