diff options
| author | git perforce import user <a@b> | 2016-10-25 12:29:14 -0600 |
|---|---|---|
| committer | Sheikh Dawood Abdul Ajees <Sheikh Dawood Abdul Ajees> | 2016-10-25 18:56:37 -0500 |
| commit | 3dfe2108cfab31ba3ee5527e217d0d8e99a51162 (patch) | |
| tree | fa6485c169e50d7415a651bf838f5bcd0fd3bfbd /KaplaDemo/samples/sampleViewer3/HBAOHelper.cpp | |
| download | physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.tar.xz physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.zip | |
Initial commit:
PhysX 3.4.0 Update @ 21294896
APEX 1.4.0 Update @ 21275617
[CL 21300167]
Diffstat (limited to 'KaplaDemo/samples/sampleViewer3/HBAOHelper.cpp')
| -rw-r--r-- | KaplaDemo/samples/sampleViewer3/HBAOHelper.cpp | 289 |
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; +} |