aboutsummaryrefslogtreecommitdiff
path: root/KaplaDemo/samples/sampleViewer3/HBAOHelper.cpp
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 /KaplaDemo/samples/sampleViewer3/HBAOHelper.cpp
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 'KaplaDemo/samples/sampleViewer3/HBAOHelper.cpp')
-rw-r--r--KaplaDemo/samples/sampleViewer3/HBAOHelper.cpp289
1 files changed, 289 insertions, 0 deletions
diff --git a/KaplaDemo/samples/sampleViewer3/HBAOHelper.cpp b/KaplaDemo/samples/sampleViewer3/HBAOHelper.cpp
new file mode 100644
index 00000000..661b8311
--- /dev/null
+++ b/KaplaDemo/samples/sampleViewer3/HBAOHelper.cpp
@@ -0,0 +1,289 @@
+#include <GL/glew.h>
+#include "HBAOHelper.h"
+#include "foundation/PxMat44.h"
+#include "stdio.h"
+
+using namespace physx;
+
+static PxMat44 PerspectiveProjectionMatrix(float fovy, float x, float y, float n, float f)
+{
+ float PPM[16];
+
+ float coty = 1.0f / tan(fovy * physx::PxPi / 360.0f);
+ float aspect = x / (y > 0.0f ? y : 1.0f);
+
+ PPM[0] = coty / aspect;
+ PPM[1] = 0.0f;
+ PPM[2] = 0.0f;
+ PPM[3] = 0.0f;
+
+ PPM[4] = 0.0f;
+ PPM[5] = coty;
+ PPM[6] = 0.0f;
+ PPM[7] = 0.0f;
+
+ PPM[8] = 0.0f;
+ PPM[9] = 0.0f;
+ PPM[10] = (n + f) / (n - f);
+ PPM[11] = -1.0f;
+
+ PPM[12] = 0.0f;
+ PPM[13] = 0.0f;
+ PPM[14] = 2.0f * n * f / (n - f);
+ PPM[15] = 0.0f;
+
+ return PxMat44(PPM);
+}
+
+#ifndef CHECK_GL_ERROR
+#define CHECK_GL_ERROR() checkGLError(__FILE__, __LINE__)
+#endif
+
+void checkGLError(const char* file, int32_t line)
+{
+#if defined(_DEBUG)
+ GLint error = glGetError();
+ if (error)
+ {
+ const char* errorString = 0;
+ switch (error)
+ {
+ case GL_INVALID_ENUM: errorString = "GL_INVALID_ENUM"; break;
+ case GL_INVALID_FRAMEBUFFER_OPERATION: errorString = "GL_INVALID_FRAMEBUFFER_OPERATION"; break;
+ case GL_INVALID_VALUE: errorString = "GL_INVALID_VALUE"; break;
+ case GL_INVALID_OPERATION: errorString = "GL_INVALID_OPERATION"; break;
+ case GL_OUT_OF_MEMORY: errorString = "GL_OUT_OF_MEMORY"; break;
+ default: errorString = "unknown error"; break;
+ }
+ printf("GL error: %s, line %d: %s\n", file, line, errorString);
+ error = 0; // nice place to hang a breakpoint in compiler... :)
+ }
+#endif
+}
+
+HBAOHelper::HBAOHelper(float fov, float zNear, float zFar)
+ : mHbaoGlContext(NULL)
+ , mFov(fov)
+ , mZnear(zNear)
+ , mZFar(zFar)
+ , mWidthAA(0)
+ , mHeightAA(0)
+ , mWidthReal(0)
+ , mHeightReal(0)
+ , mNormalTex(-1)
+ , mDepthTex(-1)
+ , mFBO(0)
+ , mDownScaledFBO(0)
+ , mColorTex(-1)
+{
+ init();
+}
+
+HBAOHelper::~HBAOHelper()
+{
+ if (mHbaoGlContext)
+ mHbaoGlContext->Release();
+
+ glDeleteTextures(1, &mNormalTex);
+ glDeleteTextures(1, &mDepthTex);
+ glDeleteTextures(1, &mColorTex);
+ glDeleteFramebuffers(1, &mFBO);
+ glDeleteFramebuffers(1, &mDownScaledFBO);
+
+ CHECK_GL_ERROR();
+}
+
+bool HBAOHelper::init()
+{
+ memset(mNormalMapTransform, 0, sizeof(float)*16);
+ mNormalMapTransform[0] = -1.0f;
+ mNormalMapTransform[5] = 1.0f;
+ mNormalMapTransform[10] = 1.0f;
+ mNormalMapTransform[15] = 1.0f;
+
+ glGenTextures(1, &mNormalTex);
+ glGenTextures(1, &mDepthTex);
+ glGenTextures(1, &mColorTex);
+ glGenFramebuffers(1, &mFBO);
+ glGenFramebuffers(1, &mDownScaledFBO);
+ CHECK_GL_ERROR();
+
+ GFSDK_SSAO_CustomHeap CustomHeap;
+ CustomHeap.new_ = ::operator new;
+ CustomHeap.delete_ = ::operator delete;
+
+ GFSDK_SSAO_INIT_GL_FUNCTIONS(mGLFunctions);
+
+ GFSDK_SSAO_Status status = GFSDK_SSAO_CreateContext_GL(&mHbaoGlContext, &mGLFunctions, &CustomHeap);
+ if (status != GFSDK_SSAO_OK)
+ return false;
+
+ GFSDK_SSAO_Version Version;
+ status = GFSDK_SSAO_GetVersion(&Version);
+
+ mAoParams.Radius = 1.0f;
+ mAoParams.Bias = 0.5f;
+ mAoParams.NearAO = 4.0f;
+ mAoParams.FarAO = 1.5f;
+
+ mAoParams.BackgroundAO.Enable = false;
+ mAoParams.BackgroundAO.BackgroundViewDepth = 1.f;
+
+ mAoParams.ForegroundAO.Enable = false;
+ mAoParams.ForegroundAO.ForegroundViewDepth = 1.0f;
+
+ mAoParams.DepthStorage = true ? GFSDK_SSAO_FP16_VIEW_DEPTHS : GFSDK_SSAO_FP32_VIEW_DEPTHS;
+ mAoParams.PowerExponent = 2.0f;
+ mAoParams.DepthClampMode = false ? GFSDK_SSAO_CLAMP_TO_BORDER : GFSDK_SSAO_CLAMP_TO_EDGE;
+ mAoParams.Blur.Enable = true;
+ mAoParams.Blur.Sharpness = 16.0f;
+ mAoParams.Blur.Radius = GFSDK_SSAO_BLUR_RADIUS_4;
+
+ return status == GFSDK_SSAO_OK;
+}
+
+void HBAOHelper::resize(int wAA, int hAA, int realw, int realH)
+{
+ mWidthAA = wAA;
+ mHeightAA = hAA;
+
+ mWidthReal = realw;
+ mHeightReal = realH;
+
+ glViewport(0, 0, mWidthReal, mHeightReal);
+ PxMat44 Projection = PerspectiveProjectionMatrix(mFov, float(mWidthReal), float(mHeightReal), mZnear, mZFar);
+ glMatrixMode(GL_PROJECTION);
+ glLoadMatrixf(&Projection.column0.x);
+
+ glBindTexture(GL_TEXTURE_2D, mNormalTex);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, mWidthReal, mHeightReal, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+
+ glBindTexture(GL_TEXTURE_2D, mDepthTex);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, mWidthReal, mHeightReal, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
+
+ GFSDK_SSAO_Status status = mHbaoGlContext->PreCreateFBOs(mAoParams, mWidthReal, mHeightReal);
+
+ glBindTexture(GL_TEXTURE_2D, mColorTex);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, mWidthReal, mHeightReal, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, mDownScaledFBO);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mColorTex, 0);
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+ CHECK_GL_ERROR();
+}
+
+bool HBAOHelper::renderAO(void(*renderScene)(), GLuint oldFBO, bool useNormalTexture)
+{
+ glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mNormalTex, 0);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, mDepthTex, 0);
+
+ glViewport(0, 0, mWidthReal, mHeightReal);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ PxMat44 Projection = PerspectiveProjectionMatrix(mFov, float(mWidthReal), float(mHeightReal), mZnear, mZFar);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadMatrixf(&Projection.column0.x);
+ glEnable(GL_DEPTH_TEST);
+ glEnable(GL_CULL_FACE);
+ renderScene();
+ glDisable(GL_CULL_FACE);
+ glDisable(GL_DEPTH_TEST);
+
+ CHECK_GL_ERROR();
+
+ //
+ // render AO
+ //
+
+ GFSDK_SSAO_InputData_GL Input;
+ Input.DepthData.DepthTextureType = GFSDK_SSAO_HARDWARE_DEPTHS;
+ Input.DepthData.FullResDepthTexture = GFSDK_SSAO_Texture_GL(GL_TEXTURE_2D, mDepthTex);
+ Input.DepthData.ProjectionMatrix.Data = GFSDK_SSAO_Float4x4(&Projection.column0.x);
+ Input.DepthData.ProjectionMatrix.Layout = GFSDK_SSAO_ROW_MAJOR_ORDER;
+ Input.DepthData.MetersToViewSpaceUnits = 1.0f;
+
+ if (useNormalTexture)
+ {
+ Input.NormalData.Enable = true;
+ Input.NormalData.FullResNormalTexture = GFSDK_SSAO_Texture_GL(GL_TEXTURE_2D, mNormalTex);
+ Input.NormalData.WorldToViewMatrix.Data = GFSDK_SSAO_Float4x4(mNormalMapTransform);
+ Input.NormalData.WorldToViewMatrix.Layout = GFSDK_SSAO_ROW_MAJOR_ORDER;
+ Input.NormalData.DecodeScale = -2.f;
+ Input.NormalData.DecodeBias = 1.0f;
+ }
+
+ bool renderDirectlyToOldFbo = ((mHeightReal == mHeightAA) && (mWidthReal == mWidthAA));
+ bool showDebugNormals = false;
+ bool showHBAO = false;
+
+ GFSDK_SSAO_RenderMask RenderMask = showDebugNormals ? GFSDK_SSAO_RENDER_DEBUG_NORMAL : GFSDK_SSAO_RENDER_AO;
+ GFSDK_SSAO_Output_GL Output;
+ Output.OutputFBO = renderDirectlyToOldFbo ? oldFBO : mDownScaledFBO;
+ Output.Blend.Mode = !renderDirectlyToOldFbo || showHBAO ? GFSDK_SSAO_OVERWRITE_RGB : GFSDK_SSAO_MULTIPLY_RGB;
+
+ GFSDK_SSAO_Status status;
+ status = mHbaoGlContext->RenderAO(Input, mAoParams, Output, RenderMask);
+
+ if (!renderDirectlyToOldFbo)
+ {
+ // upscale to oldFbo
+ glBindFramebuffer(GL_FRAMEBUFFER, oldFBO);
+
+ glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
+ glEnable(GL_BLEND);
+ glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
+ glBlendFuncSeparate(GL_ZERO, GL_SRC_COLOR, GL_ZERO, GL_ONE);
+
+ glViewport(0, 0, mWidthAA, mHeightAA);
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+ glOrtho(0, mWidthAA, 0, mHeightAA, -1, 1);
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+
+ glUseProgram(0);
+
+ glDisable(GL_LIGHTING);
+ glDisable(GL_DEPTH_TEST);
+ glEnable(GL_TEXTURE_2D);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, mColorTex);
+
+ glBegin(GL_QUADS);
+ glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0f, 0.0f);
+ glTexCoord2f(1.0f, 0.0f); glVertex2f(float(mWidthAA), 0.0f);
+ glTexCoord2f(1.0f, 1.0f); glVertex2f(float(mWidthAA), float(mHeightAA));
+ glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0f, float(mHeightAA));
+ glEnd();
+
+ glEnable(GL_LIGHTING);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glDisable(GL_BLEND);
+
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+ }
+
+ glEnable(GL_DEPTH_TEST);
+ glDepthMask(GL_TRUE);
+ CHECK_GL_ERROR();
+ return true;
+}