Init
This commit is contained in:
211
kaplademo/source/demoFramework/BmpFile.cpp
Normal file
211
kaplademo/source/demoFramework/BmpFile.cpp
Normal file
@ -0,0 +1,211 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "BmpFile.h"
|
||||
|
||||
static bool isBigEndian() { int i = 1; return *((char*)&i)==0; }
|
||||
|
||||
static unsigned short endianSwap(unsigned short nValue)
|
||||
{
|
||||
return (((nValue>> 8)) | (nValue << 8));
|
||||
|
||||
}
|
||||
|
||||
static unsigned int endianSwap(unsigned int i)
|
||||
{
|
||||
unsigned char b1, b2, b3, b4;
|
||||
|
||||
b1 = i & 255;
|
||||
b2 = ( i >> 8 ) & 255;
|
||||
b3 = ( i>>16 ) & 255;
|
||||
b4 = ( i>>24 ) & 255;
|
||||
|
||||
return ((unsigned int)b1 << 24) + ((unsigned int)b2 << 16) + ((unsigned int)b3 << 8) + b4;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
struct BMPHEADER {
|
||||
unsigned short Type;
|
||||
unsigned int Size;
|
||||
unsigned short Reserved1;
|
||||
unsigned short Reserved2;
|
||||
unsigned int OffBits;
|
||||
};
|
||||
|
||||
// Only Win3.0 BMPINFO (see later for OS/2)
|
||||
struct BMPINFO {
|
||||
unsigned int Size;
|
||||
unsigned int Width;
|
||||
unsigned int Height;
|
||||
unsigned short Planes;
|
||||
unsigned short BitCount;
|
||||
unsigned int Compression;
|
||||
unsigned int SizeImage;
|
||||
unsigned int XPelsPerMeter;
|
||||
unsigned int YPelsPerMeter;
|
||||
unsigned int ClrUsed;
|
||||
unsigned int ClrImportant;
|
||||
};
|
||||
|
||||
#pragma pack()
|
||||
|
||||
// Compression Type
|
||||
#define BI_RGB 0L
|
||||
#define BI_RLE8 1L
|
||||
#define BI_RLE4 2L
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
BmpLoaderBuffer::BmpLoaderBuffer()
|
||||
{
|
||||
mWidth = 0;
|
||||
mHeight = 0;
|
||||
mRGB = NULL;
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
BmpLoaderBuffer::~BmpLoaderBuffer()
|
||||
{
|
||||
if (mRGB) free(mRGB);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
bool BmpLoaderBuffer::loadFile(const char *filename)
|
||||
{
|
||||
if (mRGB) {
|
||||
free(mRGB);
|
||||
mRGB = NULL;
|
||||
}
|
||||
mWidth = 0;
|
||||
mHeight = 0;
|
||||
|
||||
FILE *f = fopen(filename, "rb");
|
||||
if (!f)
|
||||
return false;
|
||||
|
||||
size_t num;
|
||||
BMPHEADER header;
|
||||
num = fread(&header, sizeof(BMPHEADER), 1, f);
|
||||
if(isBigEndian()) header.Type = endianSwap(header.Type);
|
||||
if (num != 1) { fclose(f); return false; }
|
||||
if (header.Type != 'MB') { fclose(f); return false; }
|
||||
|
||||
BMPINFO info;
|
||||
num = fread(&info, sizeof(BMPINFO), 1, f);
|
||||
if (num != 1) { fclose(f); return false; }
|
||||
if(isBigEndian()) info.Size = endianSwap(info.Size);
|
||||
if(isBigEndian()) info.BitCount = endianSwap(info.BitCount);
|
||||
if(isBigEndian()) info.Compression = endianSwap(info.Compression);
|
||||
if(isBigEndian()) info.Width = endianSwap(info.Width);
|
||||
if(isBigEndian()) info.Height = endianSwap(info.Height);
|
||||
|
||||
if (info.Size != sizeof(BMPINFO)) { fclose(f); return false; }
|
||||
if (info.BitCount != 24) { fclose(f); return false; }
|
||||
if (info.Compression != BI_RGB) { fclose(f); return false; }
|
||||
|
||||
mWidth = info.Width;
|
||||
mHeight = info.Height;
|
||||
mRGB = (unsigned char*)malloc(mWidth * mHeight * 3);
|
||||
|
||||
int lineLen = (((info.Width * (info.BitCount>>3)) + 3)>>2)<<2;
|
||||
unsigned char *line = (unsigned char *)malloc(lineLen);
|
||||
|
||||
for(int i = info.Height-1; i >= 0; i--) {
|
||||
num = fread(line, lineLen, 1, f);
|
||||
if (num != 1) { fclose(f); return false; }
|
||||
unsigned char *src = line;
|
||||
unsigned char *dest = mRGB + i*info.Width*3;
|
||||
for(unsigned int j = 0; j < info.Width; j++) {
|
||||
unsigned char r,g,b;
|
||||
b = *src++; g = *src++; r = *src++;
|
||||
*dest++ = r; *dest++ = g; *dest++ = b;
|
||||
}
|
||||
}
|
||||
|
||||
free(line);
|
||||
fclose(f);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
bool saveBmpRBG(const char *filename, int width, int height, void *data)
|
||||
{
|
||||
FILE *f = fopen(filename, "wb");
|
||||
if (!f) return false;
|
||||
|
||||
// todo : works on pcs only, swap correctly if big endian
|
||||
BMPHEADER header;
|
||||
header.Type = 'MB';
|
||||
header.Size = sizeof(BMPINFO);
|
||||
header.Reserved1 = 0;
|
||||
header.Reserved2 = 0;
|
||||
header.OffBits = sizeof(BMPHEADER) + sizeof(BMPINFO);
|
||||
fwrite(&header, sizeof(BMPHEADER), 1, f);
|
||||
|
||||
BMPINFO info;
|
||||
info.Size = sizeof(BMPINFO);
|
||||
info.Width = width;
|
||||
info.Height = height;
|
||||
info.Planes = 1;
|
||||
info.BitCount = 24;
|
||||
info.Compression = BI_RGB;
|
||||
info.XPelsPerMeter = 4000;
|
||||
info.YPelsPerMeter = 4000;
|
||||
info.ClrUsed = 0;
|
||||
info.ClrImportant = 0;
|
||||
fwrite(&info, sizeof(info), 1, f);
|
||||
|
||||
// padded to multiple of 4
|
||||
int lineLen = (((info.Width * (info.BitCount>>3)) + 3)>>2)<<2;
|
||||
info.SizeImage = lineLen * height;
|
||||
|
||||
unsigned char *line = (unsigned char *)malloc(lineLen);
|
||||
|
||||
for(int i = 0; i < height; i++) {
|
||||
unsigned char *src = (unsigned char*)data + i*width*3;
|
||||
unsigned char *dest = line;
|
||||
for(int j = 0; j < width; j++) {
|
||||
unsigned char r,g,b;
|
||||
r = *src++; g = *src++; b = *src++;
|
||||
*dest++ = b; *dest++ = g; *dest++ = r;
|
||||
}
|
||||
for (int j = 3*width; j < lineLen; j++)
|
||||
*dest++ = 0;
|
||||
fwrite(line, lineLen, 1, f);
|
||||
}
|
||||
|
||||
free(line);
|
||||
fclose(f);
|
||||
|
||||
return true;
|
||||
}
|
||||
48
kaplademo/source/demoFramework/BmpFile.h
Normal file
48
kaplademo/source/demoFramework/BmpFile.h
Normal file
@ -0,0 +1,48 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#ifndef BMP_LOADER_H
|
||||
#define BMP_LOADER_H
|
||||
|
||||
class BmpLoaderBuffer
|
||||
{
|
||||
public:
|
||||
|
||||
BmpLoaderBuffer(void);
|
||||
~BmpLoaderBuffer(void);
|
||||
|
||||
// Data is persists until the class is destructed.
|
||||
bool loadFile(const char *filename);
|
||||
|
||||
int mWidth;
|
||||
int mHeight;
|
||||
unsigned char *mRGB;
|
||||
};
|
||||
|
||||
bool saveBmpRBG(const char *filename, int width, int height, void *data);
|
||||
|
||||
#endif
|
||||
175
kaplademo/source/demoFramework/FXAAHelper.cpp
Normal file
175
kaplademo/source/demoFramework/FXAAHelper.cpp
Normal file
@ -0,0 +1,175 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#include "FXAAHelper.h"
|
||||
#include "foundation/PxMat44.h"
|
||||
const char *computeLumaVS = STRINGIFY(
|
||||
void main(void)
|
||||
{
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
gl_Position = gl_Vertex * 2.0 - 1.0;
|
||||
}
|
||||
);
|
||||
|
||||
const char *computeLumaFS = STRINGIFY(
|
||||
uniform sampler2D imgTex;
|
||||
|
||||
void main (void)
|
||||
{
|
||||
vec4 col = texture2D(imgTex,gl_TexCoord[0].xy);
|
||||
gl_FragColor = vec4(col.xyz, sqrt(dot(col.rgb, vec3(0.299, 0.587, 0.114))));
|
||||
}
|
||||
);
|
||||
|
||||
FXAAHelper::FXAAHelper( const char* resourcePath) {
|
||||
|
||||
char fxaaVSF[5000];
|
||||
char fxaaFSF[5000];
|
||||
sprintf(fxaaVSF, "%s\\fxaa.vs", resourcePath);
|
||||
sprintf(fxaaFSF, "%s\\fxaa.fs", resourcePath);
|
||||
computeLuma.loadShaderCode(computeLumaVS,computeLumaFS);
|
||||
fxaa.loadShaders(fxaaVSF,fxaaFSF);
|
||||
|
||||
|
||||
glUseProgram(computeLuma);
|
||||
glUniform1i(glGetUniformLocation(computeLuma,"imgTex"),0);
|
||||
glUseProgram(0);
|
||||
|
||||
glUseProgram(fxaa);
|
||||
glUniform1i(glGetUniformLocation(fxaa,"imgWithLumaTex"),0);
|
||||
glUseProgram(0);
|
||||
|
||||
glGenTextures(1,&imgTex);
|
||||
glGenTextures(1,&imgWithLumaTex);
|
||||
glGenTextures(1,&depthTex);
|
||||
glGenFramebuffers(1,&FBO);
|
||||
}
|
||||
|
||||
void FXAAHelper::Resize(int w,int h) {
|
||||
|
||||
Width = w;
|
||||
Height = h;
|
||||
|
||||
glViewport(0,0,Width,Height);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D,imgTex);
|
||||
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,Width,Height,0,GL_RGBA,GL_UNSIGNED_BYTE,NULL);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D,imgWithLumaTex);
|
||||
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,Width,Height,0,GL_RGBA,GL_UNSIGNED_BYTE,NULL);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D,depthTex);
|
||||
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_COMPONENT32,Width,Height,0,GL_DEPTH_COMPONENT,GL_FLOAT,NULL);
|
||||
|
||||
|
||||
glUseProgram(fxaa);
|
||||
glUniform2f(glGetUniformLocation(fxaa,"rcpFrame"), 1.0f / ((float)Width), 1.0f / ((float)Height));
|
||||
|
||||
glUseProgram(0);
|
||||
|
||||
}
|
||||
void FXAAHelper::Destroy() {
|
||||
|
||||
computeLuma.deleteShaders();
|
||||
fxaa.deleteShaders();
|
||||
|
||||
glDeleteTextures(1,&imgTex);
|
||||
glDeleteTextures(1,&imgWithLumaTex);
|
||||
glDeleteTextures(1,&depthTex);
|
||||
glDeleteFramebuffers(1,&FBO);
|
||||
}
|
||||
|
||||
void FXAAHelper::StartFXAA() {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER,FBO);
|
||||
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D,imgTex,0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,GL_TEXTURE_2D,depthTex,0);
|
||||
|
||||
glViewport(0,0,Width,Height);
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
void FXAAHelper::EndFXAA(GLuint oldFBO) {
|
||||
|
||||
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_FALSE);
|
||||
// if(Blur)
|
||||
// {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER,FBO);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D,imgWithLumaTex,0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,GL_TEXTURE_2D,0,0);
|
||||
|
||||
glClearColor(0.0f,0.0f,0.0f,0.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D,imgTex);
|
||||
|
||||
glUseProgram(computeLuma);
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
glTexCoord2f(0.0f,0.0f); glVertex2f(0.0f,0.0f);
|
||||
glTexCoord2f(1.0f,0.0f); glVertex2f(1.0f,0.0f);
|
||||
glTexCoord2f(1.0f,1.0f); glVertex2f(1.0f,1.0f);
|
||||
glTexCoord2f(0.0f,1.0f); glVertex2f(0.0f,1.0f);
|
||||
glEnd();
|
||||
|
||||
glUseProgram(0);
|
||||
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER,oldFBO);
|
||||
glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D,imgWithLumaTex);
|
||||
glUseProgram(fxaa);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(0.0f,0.0f); glVertex2f(0.0f,0.0f);
|
||||
glTexCoord2f(1.0f,0.0f); glVertex2f(1.0f,0.0f);
|
||||
glTexCoord2f(1.0f,1.0f); glVertex2f(1.0f,1.0f);
|
||||
glTexCoord2f(0.0f,1.0f); glVertex2f(0.0f,1.0f);
|
||||
glEnd();
|
||||
|
||||
glUseProgram(0);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D,0);
|
||||
glDepthMask(GL_TRUE);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_CULL_FACE);
|
||||
|
||||
}
|
||||
42
kaplademo/source/demoFramework/FXAAHelper.h
Normal file
42
kaplademo/source/demoFramework/FXAAHelper.h
Normal file
@ -0,0 +1,42 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
#include <GL/glew.h>
|
||||
#include "Shader.h"
|
||||
|
||||
class FXAAHelper{
|
||||
public:
|
||||
int Width, Height;
|
||||
Shader computeLuma, fxaa;
|
||||
FXAAHelper(const char* resourcePath);
|
||||
void Resize(int w, int h);
|
||||
void StartFXAA(); // Call before rendering things
|
||||
void EndFXAA(GLuint oldFBO); // Compute luma and then do FXAA
|
||||
void Destroy();
|
||||
GLuint FBO, depthTex, imgTex, imgWithLumaTex;
|
||||
};
|
||||
405
kaplademo/source/demoFramework/FrameBufferObject.cpp
Normal file
405
kaplademo/source/demoFramework/FrameBufferObject.cpp
Normal file
@ -0,0 +1,405 @@
|
||||
//glew uses iostreams which uses exceptions, so we need to turn off the following warning
|
||||
//warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc
|
||||
#pragma warning( disable : 4530 )
|
||||
|
||||
/*
|
||||
Copyright (c) 2005,
|
||||
Aaron Lefohn (lefohn@cs.ucdavis.edu)
|
||||
Robert Strzodka (strzodka@stanford.edu)
|
||||
Adam Moerschell (atmoerschell@ucdavis.edu)
|
||||
All rights reserved.
|
||||
|
||||
This software is licensed under the BSD open-source license. See
|
||||
http://www.opensource.org/licenses/bsd-license.php for more detail.
|
||||
|
||||
*************************************************************
|
||||
Redistribution and use in source and binary forms, with or
|
||||
without modification, are permitted provided that the following
|
||||
conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the University of Californa, Davis nor the names of
|
||||
the contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "FrameBufferObject.h"
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
#define LOG_FBO_CALLS 0
|
||||
|
||||
FrameBufferObject::FrameBufferObject()
|
||||
: m_fboId(_GenerateFboId()),
|
||||
m_savedFboId(0)
|
||||
{
|
||||
// Bind this FBO so that it actually gets created now
|
||||
_GuardedBind();
|
||||
_GuardedUnbind();
|
||||
}
|
||||
|
||||
FrameBufferObject::~FrameBufferObject()
|
||||
{
|
||||
#if LOG_FBO_CALLS
|
||||
printf("deleting FBO %d\n",m_fboId);
|
||||
#endif
|
||||
|
||||
glDeleteFramebuffersEXT(1, &m_fboId);
|
||||
}
|
||||
|
||||
void FrameBufferObject::Bind()
|
||||
{
|
||||
#if LOG_FBO_CALLS
|
||||
printf("binding framebuffer %d\n",m_fboId);
|
||||
#endif
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fboId);
|
||||
}
|
||||
|
||||
void FrameBufferObject::Disable()
|
||||
{
|
||||
#if LOG_FBO_CALLS
|
||||
printf("binding window framebuffer \n");
|
||||
#endif
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
}
|
||||
|
||||
void
|
||||
FrameBufferObject::AttachTexture( GLenum texTarget, GLuint texId,
|
||||
GLenum attachment, int mipLevel, int zSlice )
|
||||
{
|
||||
_GuardedBind();
|
||||
|
||||
/*
|
||||
#ifndef NDEBUG
|
||||
if( GetAttachedId(attachment) != texId ) {
|
||||
#endif
|
||||
*/
|
||||
|
||||
_FramebufferTextureND( attachment, texTarget,
|
||||
texId, mipLevel, zSlice );
|
||||
|
||||
/*
|
||||
#ifndef NDEBUG
|
||||
}
|
||||
else {
|
||||
cerr << "FrameBufferObject::AttachTexture PERFORMANCE WARNING:\n"
|
||||
<< "\tRedundant bind of texture (id = " << texId << ").\n"
|
||||
<< "\tHINT : Compile with -DNDEBUG to remove this warning.\n";
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
|
||||
_GuardedUnbind();
|
||||
}
|
||||
|
||||
void
|
||||
FrameBufferObject::AttachTextures( int numTextures, GLenum texTarget[], GLuint texId[],
|
||||
GLenum attachment[], int mipLevel[], int zSlice[] )
|
||||
{
|
||||
for(int i = 0; i < numTextures; ++i) {
|
||||
AttachTexture( texTarget[i], texId[i],
|
||||
attachment ? attachment[i] : (GL_COLOR_ATTACHMENT0_EXT + i),
|
||||
mipLevel ? mipLevel[i] : 0,
|
||||
zSlice ? zSlice[i] : 0 );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
FrameBufferObject::AttachRenderBuffer( GLuint buffId, GLenum attachment )
|
||||
{
|
||||
_GuardedBind();
|
||||
|
||||
#ifndef NDEBUG
|
||||
if( GetAttachedId(attachment) != buffId ) {
|
||||
#endif
|
||||
|
||||
#if LOG_FBO_CALLS
|
||||
printf("fbo %d: attaching renderbuffer to attachment point %d\n",m_fboId,attachment);
|
||||
#endif
|
||||
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, attachment,
|
||||
GL_RENDERBUFFER_EXT, buffId);
|
||||
|
||||
#ifndef NDEBUG
|
||||
}
|
||||
else {
|
||||
cerr << "FrameBufferObject::AttachRenderBuffer PERFORMANCE WARNING:\n"
|
||||
<< "\tRedundant bind of Renderbuffer (id = " << buffId << ")\n"
|
||||
<< "\tHINT : Compile with -DNDEBUG to remove this warning.\n";
|
||||
}
|
||||
#endif
|
||||
|
||||
_GuardedUnbind();
|
||||
}
|
||||
|
||||
void
|
||||
FrameBufferObject::AttachRenderBuffers( int numBuffers, GLuint buffId[], GLenum attachment[] )
|
||||
{
|
||||
for(int i = 0; i < numBuffers; ++i) {
|
||||
AttachRenderBuffer( buffId[i],
|
||||
attachment ? attachment[i] : (GL_COLOR_ATTACHMENT0_EXT + i) );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
FrameBufferObject::Unattach( GLenum attachment )
|
||||
{
|
||||
_GuardedBind();
|
||||
GLenum type = GetAttachedType(attachment);
|
||||
|
||||
#if LOG_FBO_CALLS
|
||||
printf("fbo %d: detatching from attachment point %d\n",m_fboId,attachment);
|
||||
#endif
|
||||
|
||||
switch(type) {
|
||||
case GL_NONE:
|
||||
break;
|
||||
case GL_RENDERBUFFER_EXT:
|
||||
AttachRenderBuffer( 0, attachment );
|
||||
break;
|
||||
case GL_TEXTURE:
|
||||
AttachTexture( GL_TEXTURE_2D, 0, attachment );
|
||||
break;
|
||||
default:
|
||||
cerr << "FrameBufferObject::unbind_attachment ERROR: Unknown attached resource type\n";
|
||||
}
|
||||
_GuardedUnbind();
|
||||
}
|
||||
|
||||
void
|
||||
FrameBufferObject::UnattachAll()
|
||||
{
|
||||
int numAttachments = GetMaxColorAttachments();
|
||||
for(int i = 0; i < numAttachments; ++i) {
|
||||
Unattach( GL_COLOR_ATTACHMENT0_EXT + i );
|
||||
}
|
||||
}
|
||||
|
||||
GLint FrameBufferObject::GetMaxColorAttachments()
|
||||
{
|
||||
GLint maxAttach = 0;
|
||||
glGetIntegerv( GL_MAX_COLOR_ATTACHMENTS_EXT, &maxAttach );
|
||||
return maxAttach;
|
||||
}
|
||||
|
||||
GLuint FrameBufferObject::_GenerateFboId()
|
||||
{
|
||||
GLuint id = 0;
|
||||
glGenFramebuffersEXT(1, &id);
|
||||
|
||||
#if LOG_FBO_CALLS
|
||||
printf("created FBO %d\n",id);
|
||||
#endif
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
void FrameBufferObject::_GuardedBind()
|
||||
{
|
||||
// Only binds if m_fboId is different than the currently bound FBO
|
||||
glGetIntegerv( GL_FRAMEBUFFER_BINDING_EXT, &m_savedFboId );
|
||||
if (m_fboId != (GLuint)m_savedFboId) {
|
||||
|
||||
#if LOG_FBO_CALLS
|
||||
printf("binding framebuffer %d\n",m_fboId);
|
||||
#endif
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fboId);
|
||||
}
|
||||
}
|
||||
|
||||
void FrameBufferObject::_GuardedUnbind()
|
||||
{
|
||||
// Returns FBO binding to the previously enabled FBO
|
||||
if (m_fboId != (GLuint)m_savedFboId) {
|
||||
#if LOG_FBO_CALLS
|
||||
printf("binding framebuffer %d\n",m_savedFboId);
|
||||
#endif
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, (GLuint)m_savedFboId);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
FrameBufferObject::_FramebufferTextureND( GLenum attachment, GLenum texTarget,
|
||||
GLuint texId, int mipLevel,
|
||||
int zSlice )
|
||||
{
|
||||
#if LOG_FBO_CALLS
|
||||
printf("fbo %d: attaching texture %d to attachment point %d\n",m_fboId,texId,attachment);
|
||||
#endif
|
||||
|
||||
if (texTarget == GL_TEXTURE_1D) {
|
||||
glFramebufferTexture1DEXT( GL_FRAMEBUFFER_EXT, attachment,
|
||||
GL_TEXTURE_1D, texId, mipLevel );
|
||||
}
|
||||
else if (texTarget == GL_TEXTURE_3D) {
|
||||
glFramebufferTexture3DEXT( GL_FRAMEBUFFER_EXT, attachment,
|
||||
GL_TEXTURE_3D, texId, mipLevel, zSlice );
|
||||
}
|
||||
else {
|
||||
// Default is GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE_ARB, or cube faces
|
||||
glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, attachment,
|
||||
texTarget, texId, mipLevel );
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
bool FrameBufferObject::IsValid( ostream& ostr )
|
||||
{
|
||||
_GuardedBind();
|
||||
|
||||
#if LOG_FBO_CALLS
|
||||
printf("fbo %d: checking for FBO errors\n",m_fboId);
|
||||
#endif
|
||||
|
||||
bool isOK = false;
|
||||
|
||||
GLenum status;
|
||||
status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
||||
switch(status) {
|
||||
case GL_FRAMEBUFFER_COMPLETE_EXT: // Everything's OK
|
||||
isOK = true;
|
||||
break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
|
||||
ostr << "glift::CheckFramebufferStatus() ERROR:\n\t"
|
||||
<< "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT\n";
|
||||
isOK = false;
|
||||
break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
|
||||
ostr << "glift::CheckFramebufferStatus() ERROR:\n\t"
|
||||
<< "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT\n";
|
||||
isOK = false;
|
||||
break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
|
||||
ostr << "glift::CheckFramebufferStatus() ERROR:\n\t"
|
||||
<< "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT\n";
|
||||
isOK = false;
|
||||
break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
|
||||
ostr << "glift::CheckFramebufferStatus() ERROR:\n\t"
|
||||
<< "GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT\n";
|
||||
isOK = false;
|
||||
break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
|
||||
ostr << "glift::CheckFramebufferStatus() ERROR:\n\t"
|
||||
<< "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT\n";
|
||||
isOK = false;
|
||||
break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
|
||||
ostr << "glift::CheckFramebufferStatus() ERROR:\n\t"
|
||||
<< "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT\n";
|
||||
isOK = false;
|
||||
break;
|
||||
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
|
||||
ostr << "glift::CheckFramebufferStatus() ERROR:\n\t"
|
||||
<< "GL_FRAMEBUFFER_UNSUPPORTED_EXT\n";
|
||||
isOK = false;
|
||||
break;
|
||||
default:
|
||||
ostr << "glift::CheckFramebufferStatus() ERROR:\n\t"
|
||||
<< "Unknown ERROR\n";
|
||||
isOK = false;
|
||||
}
|
||||
|
||||
_GuardedUnbind();
|
||||
return isOK;
|
||||
}
|
||||
#endif // NDEBUG
|
||||
|
||||
/// Accessors
|
||||
GLenum FrameBufferObject::GetAttachedType( GLenum attachment )
|
||||
{
|
||||
#if LOG_FBO_CALLS
|
||||
printf("querying type of attachment at %d\n",attachment);
|
||||
#endif
|
||||
|
||||
// Returns GL_RENDERBUFFER_EXT or GL_TEXTURE
|
||||
_GuardedBind();
|
||||
GLint type = 0;
|
||||
glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT, attachment,
|
||||
GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT,
|
||||
&type);
|
||||
_GuardedUnbind();
|
||||
return GLenum(type);
|
||||
}
|
||||
|
||||
GLuint FrameBufferObject::GetAttachedId( GLenum attachment )
|
||||
{
|
||||
#if LOG_FBO_CALLS
|
||||
printf("getting id of attachment at %d\n",attachment);
|
||||
#endif
|
||||
|
||||
_GuardedBind();
|
||||
GLint id = 0;
|
||||
glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT, attachment,
|
||||
GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT,
|
||||
&id);
|
||||
_GuardedUnbind();
|
||||
return GLuint(id);
|
||||
}
|
||||
|
||||
GLint FrameBufferObject::GetAttachedMipLevel( GLenum attachment )
|
||||
{
|
||||
#if LOG_FBO_CALLS
|
||||
printf("getting mip level of attachment at %d\n",attachment);
|
||||
#endif
|
||||
|
||||
_GuardedBind();
|
||||
GLint level = 0;
|
||||
glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT, attachment,
|
||||
GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT,
|
||||
&level);
|
||||
_GuardedUnbind();
|
||||
return level;
|
||||
}
|
||||
|
||||
GLint FrameBufferObject::GetAttachedCubeFace( GLenum attachment )
|
||||
{
|
||||
#if LOG_FBO_CALLS
|
||||
printf("getting cube face id of attachment at %d\n",attachment);
|
||||
#endif
|
||||
|
||||
_GuardedBind();
|
||||
GLint level = 0;
|
||||
glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT, attachment,
|
||||
GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT,
|
||||
&level);
|
||||
_GuardedUnbind();
|
||||
return level;
|
||||
}
|
||||
|
||||
GLint FrameBufferObject::GetAttachedZSlice( GLenum attachment )
|
||||
{
|
||||
#if LOG_FBO_CALLS
|
||||
printf("querying z slice of attachment at %d\n",attachment);
|
||||
#endif
|
||||
_GuardedBind();
|
||||
GLint slice = 0;
|
||||
glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT, attachment,
|
||||
GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT,
|
||||
&slice);
|
||||
_GuardedUnbind();
|
||||
return slice;
|
||||
}
|
||||
|
||||
|
||||
|
||||
210
kaplademo/source/demoFramework/FrameBufferObject.h
Normal file
210
kaplademo/source/demoFramework/FrameBufferObject.h
Normal file
@ -0,0 +1,210 @@
|
||||
/*
|
||||
Copyright (c) 2005,
|
||||
Aaron Lefohn (lefohn@cs.ucdavis.edu)
|
||||
Robert Strzodka (strzodka@stanford.edu)
|
||||
Adam Moerschell (atmoerschell@ucdavis.edu)
|
||||
All rights reserved.
|
||||
|
||||
This software is licensed under the BSD open-source license. See
|
||||
http://www.opensource.org/licenses/bsd-license.php for more detail.
|
||||
|
||||
*************************************************************
|
||||
Redistribution and use in source and binary forms, with or
|
||||
without modification, are permitted provided that the following
|
||||
conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the University of Californa, Davis nor the names of
|
||||
the contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef UCDAVIS_FRAMEBUFFER_OBJECT_H
|
||||
#define UCDAVIS_FRAMEBUFFER_OBJECT_H
|
||||
|
||||
#include <GL/glew.h>
|
||||
#include <iostream>
|
||||
|
||||
/*!
|
||||
FramebufferObject Class. This class encapsulates the FramebufferObject
|
||||
(FBO) OpenGL spec. See the official spec at:
|
||||
http://oss.sgi.com/projects/ogl-sample/registry/EXT/framebuffer_object.txt
|
||||
|
||||
for details.
|
||||
|
||||
A framebuffer object (FBO) is conceptually a structure containing pointers
|
||||
to GPU memory. The memory pointed to is either an OpenGL texture or an
|
||||
OpenGL RenderBuffer. FBOs can be used to render to one or more textures,
|
||||
share depth buffers between multiple sets of color buffers/textures and
|
||||
are a complete replacement for pbuffers.
|
||||
|
||||
Performance Notes:
|
||||
1) It is more efficient (but not required) to call Bind()
|
||||
on an FBO before making multiple method calls. For example:
|
||||
|
||||
FramebufferObject fbo;
|
||||
fbo.Bind();
|
||||
fbo.AttachTexture(GL_TEXTURE_2D, texId0, GL_COLOR_ATTACHMENT0_EXT);
|
||||
fbo.AttachTexture(GL_TEXTURE_2D, texId1, GL_COLOR_ATTACHMENT1_EXT);
|
||||
fbo.IsValid();
|
||||
|
||||
To provide a complete encapsulation, the following usage
|
||||
pattern works correctly but is less efficient:
|
||||
|
||||
FramebufferObject fbo;
|
||||
// NOTE : No Bind() call
|
||||
fbo.AttachTexture(GL_TEXTURE_2D, texId0, GL_COLOR_ATTACHMENT0_EXT);
|
||||
fbo.AttachTexture(GL_TEXTURE_2D, texId1, GL_COLOR_ATTACHMENT1_EXT);
|
||||
fbo.IsValid();
|
||||
|
||||
The first usage pattern binds the FBO only once, whereas
|
||||
the second usage binds/unbinds the FBO for each method call.
|
||||
|
||||
2) Use FramebufferObject::Disable() sparingly. We have intentionally
|
||||
left out an "Unbind()" method because it is largely unnecessary
|
||||
and encourages rendundant Bind/Unbind coding. Binding an FBO is
|
||||
usually much faster than enabling/disabling a pbuffer, but is
|
||||
still a costly operation. When switching between multiple FBOs
|
||||
and a visible OpenGL framebuffer, the following usage pattern
|
||||
is recommended:
|
||||
|
||||
FramebufferObject fbo1, fbo2;
|
||||
fbo1.Bind();
|
||||
... Render ...
|
||||
// NOTE : No Unbind/Disable here...
|
||||
|
||||
fbo2.Bind();
|
||||
... Render ...
|
||||
|
||||
// Disable FBO rendering and return to visible window
|
||||
// OpenGL framebuffer.
|
||||
FramebufferObject::Disable();
|
||||
*/
|
||||
class FrameBufferObject
|
||||
{
|
||||
public:
|
||||
/// Ctor/Dtor
|
||||
FrameBufferObject();
|
||||
virtual ~FrameBufferObject();
|
||||
|
||||
/// Bind this FBO as current render target
|
||||
void Bind();
|
||||
|
||||
/// Bind a texture to the "attachment" point of this FBO
|
||||
virtual void AttachTexture( GLenum texTarget,
|
||||
GLuint texId,
|
||||
GLenum attachment = GL_COLOR_ATTACHMENT0_EXT,
|
||||
int mipLevel = 0,
|
||||
int zSlice = 0 );
|
||||
|
||||
/// Bind an array of textures to multiple "attachment" points of this FBO
|
||||
/// - By default, the first 'numTextures' attachments are used,
|
||||
/// starting with GL_COLOR_ATTACHMENT0_EXT
|
||||
virtual void AttachTextures( int numTextures,
|
||||
GLenum texTarget[],
|
||||
GLuint texId[],
|
||||
GLenum attachment[] = NULL,
|
||||
int mipLevel[] = NULL,
|
||||
int zSlice[] = NULL );
|
||||
|
||||
/// Bind a render buffer to the "attachment" point of this FBO
|
||||
virtual void AttachRenderBuffer( GLuint buffId,
|
||||
GLenum attachment = GL_COLOR_ATTACHMENT0_EXT );
|
||||
|
||||
/// Bind an array of render buffers to corresponding "attachment" points
|
||||
/// of this FBO.
|
||||
/// - By default, the first 'numBuffers' attachments are used,
|
||||
/// starting with GL_COLOR_ATTACHMENT0_EXT
|
||||
virtual void AttachRenderBuffers( int numBuffers, GLuint buffId[],
|
||||
GLenum attachment[] = NULL );
|
||||
|
||||
/// Free any resource bound to the "attachment" point of this FBO
|
||||
void Unattach( GLenum attachment );
|
||||
|
||||
/// Free any resources bound to any attachment points of this FBO
|
||||
void UnattachAll();
|
||||
|
||||
/// Is this FBO currently a valid render target?
|
||||
/// - Sends output to std::cerr by default but can
|
||||
/// be a user-defined C++ stream
|
||||
///
|
||||
/// NOTE : This function works correctly in debug build
|
||||
/// mode but always returns "true" if NDEBUG is
|
||||
/// is defined (optimized builds)
|
||||
#ifndef NDEBUG
|
||||
bool IsValid( std::ostream& ostr = std::cerr );
|
||||
#else
|
||||
bool IsValid( std::ostream& ostr = std::cerr ) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// BEGIN : Accessors
|
||||
/// Is attached type GL_RENDERBUFFER_EXT or GL_TEXTURE?
|
||||
GLenum GetAttachedType( GLenum attachment );
|
||||
|
||||
/// What is the Id of Renderbuffer/texture currently
|
||||
/// attached to "attachement?"
|
||||
GLuint GetAttachedId( GLenum attachment );
|
||||
|
||||
/// Which mipmap level is currently attached to "attachement?"
|
||||
GLint GetAttachedMipLevel( GLenum attachment );
|
||||
|
||||
/// Which cube face is currently attached to "attachment?"
|
||||
GLint GetAttachedCubeFace( GLenum attachment );
|
||||
|
||||
/// Which z-slice is currently attached to "attachment?"
|
||||
GLint GetAttachedZSlice( GLenum attachment );
|
||||
/// END : Accessors
|
||||
|
||||
|
||||
/// BEGIN : Static methods global to all FBOs
|
||||
/// Return number of color attachments permitted
|
||||
static int GetMaxColorAttachments();
|
||||
|
||||
/// Disable all FBO rendering and return to traditional,
|
||||
/// windowing-system controlled framebuffer
|
||||
/// NOTE:
|
||||
/// This is NOT an "unbind" for this specific FBO, but rather
|
||||
/// disables all FBO rendering. This call is intentionally "static"
|
||||
/// and named "Disable" instead of "Unbind" for this reason. The
|
||||
/// motivation for this strange semantic is performance. Providing
|
||||
/// "Unbind" would likely lead to a large number of unnecessary
|
||||
/// FBO enablings/disabling.
|
||||
static void Disable();
|
||||
/// END : Static methods global to all FBOs
|
||||
|
||||
protected:
|
||||
void _GuardedBind();
|
||||
void _GuardedUnbind();
|
||||
void _FramebufferTextureND( GLenum attachment, GLenum texTarget,
|
||||
GLuint texId, int mipLevel, int zSlice );
|
||||
static GLuint _GenerateFboId();
|
||||
|
||||
private:
|
||||
GLuint m_fboId;
|
||||
GLint m_savedFboId;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
1047
kaplademo/source/demoFramework/GLFontData.h
Normal file
1047
kaplademo/source/demoFramework/GLFontData.h
Normal file
File diff suppressed because it is too large
Load Diff
361
kaplademo/source/demoFramework/GLFontRenderer.cpp
Normal file
361
kaplademo/source/demoFramework/GLFontRenderer.cpp
Normal file
@ -0,0 +1,361 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#ifndef PHYSX_NO_RENDERER
|
||||
|
||||
#include "GLFontData.h"
|
||||
#include "GLFontRenderer.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <windows.h>
|
||||
#include <GL/gl.h>
|
||||
|
||||
using namespace physx;
|
||||
|
||||
bool GLFontRenderer::init()
|
||||
{
|
||||
m_isInit=false;
|
||||
m_textureObject=0;
|
||||
m_screenWidth=640;
|
||||
m_screenHeight=480;
|
||||
m_color = 0xffffffff;
|
||||
|
||||
glGenTextures(1, &m_textureObject);
|
||||
if(m_textureObject == 0)
|
||||
return false;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, m_textureObject);
|
||||
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
// expand to rgba
|
||||
unsigned char* pNewSource = new unsigned char[OGL_FONT_TEXTURE_WIDTH*OGL_FONT_TEXTURE_HEIGHT*4];
|
||||
for(int i=0;i<OGL_FONT_TEXTURE_WIDTH*OGL_FONT_TEXTURE_HEIGHT;i++)
|
||||
{
|
||||
pNewSource[i*4+0]=255;
|
||||
pNewSource[i*4+1]=255;
|
||||
pNewSource[i*4+2]=255;
|
||||
pNewSource[i*4+3]=OGLFontData[i];
|
||||
}
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, OGL_FONT_TEXTURE_WIDTH, OGL_FONT_TEXTURE_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, pNewSource);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
// delete[] pNewSource;
|
||||
|
||||
m_isInit=true;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline unsigned int safeStrlen( const char* pString )
|
||||
{
|
||||
return ( pString && *pString) ? (unsigned int)strlen(pString) : 0;
|
||||
}
|
||||
|
||||
template<typename TOperator>
|
||||
void GLFontRenderer::print( float fontSize, const char* pString, bool forceMonoSpace, int monoSpaceWidth, bool doOrthoProj, TOperator inOperator )
|
||||
{
|
||||
if ( !m_isInit )
|
||||
init();
|
||||
unsigned int num = safeStrlen( pString );
|
||||
if ( !m_isInit || !num )
|
||||
return;
|
||||
|
||||
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_LIGHTING);
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, m_textureObject);
|
||||
|
||||
if(doOrthoProj)
|
||||
{
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
glOrtho(0, m_screenWidth, 0, m_screenHeight, -1, 1);
|
||||
}
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
glColor4f((m_color&0xff) / float(0xff), ((m_color>>8)&0xff) / float(0xff),
|
||||
((m_color>>16)&0xff) / float(0xff), ((m_color>>24)&0xff) / float(0xff));
|
||||
|
||||
mVertList.resize( PxMax( num * 6 * 3, mVertList.size() ) );
|
||||
mTextureCoordList.resize( PxMax( num * 6 * 2, mTextureCoordList.size() ) );
|
||||
PxF32* pVertList = reinterpret_cast<PxF32*>( mVertList.begin() );
|
||||
PxF32* pTextureCoordList = reinterpret_cast<PxF32*>( mTextureCoordList.begin() );
|
||||
|
||||
int vertIndex = 0;
|
||||
int textureCoordIndex = 0;
|
||||
|
||||
float translateDown = 0.0f;
|
||||
float translate = 0.0f;
|
||||
unsigned int count = 0;
|
||||
|
||||
const float glyphHeightUV = ((float)OGL_FONT_CHARS_PER_COL)/OGL_FONT_TEXTURE_HEIGHT*2-0.01f;
|
||||
const float glyphWidthUV = ((float)OGL_FONT_CHARS_PER_ROW)/OGL_FONT_TEXTURE_WIDTH;
|
||||
|
||||
for(unsigned int i=0;i<num; i++)
|
||||
{
|
||||
if (pString[i] == '\n') {
|
||||
translateDown-=0.005f*m_screenHeight+fontSize;
|
||||
translate = 0.0f;
|
||||
continue;
|
||||
}
|
||||
|
||||
int c = pString[i]-OGL_FONT_CHAR_BASE;
|
||||
if (c < OGL_FONT_CHARS_PER_ROW*OGL_FONT_CHARS_PER_COL) {
|
||||
|
||||
count++;
|
||||
|
||||
float glyphWidth = (float)GLFontGlyphWidth[c];
|
||||
if(forceMonoSpace){
|
||||
glyphWidth = (float)monoSpaceWidth;
|
||||
}
|
||||
|
||||
glyphWidth = glyphWidth*(fontSize/(((float)OGL_FONT_TEXTURE_WIDTH)/OGL_FONT_CHARS_PER_ROW));
|
||||
|
||||
float cxUV = float((c)%OGL_FONT_CHARS_PER_ROW)/OGL_FONT_CHARS_PER_ROW+0.008f;
|
||||
float cyUV = float((c)/OGL_FONT_CHARS_PER_ROW)/OGL_FONT_CHARS_PER_COL+0.008f;
|
||||
inOperator( cxUV, cyUV, glyphWidthUV, glyphHeightUV
|
||||
, pVertList, pTextureCoordList, vertIndex, textureCoordIndex
|
||||
, translate, translateDown, glyphWidth );
|
||||
vertIndex += 6*3;
|
||||
textureCoordIndex += 6*2;
|
||||
|
||||
translate+=1.0f * glyphWidth;
|
||||
}
|
||||
}
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glVertexPointer(3, GL_FLOAT, 0, pVertList);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, pTextureCoordList);
|
||||
glDrawArrays(GL_TRIANGLES, 0, count*6);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
if(doOrthoProj)
|
||||
{
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
}
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_LIGHTING);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
struct TextPrintRender
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float fontSize;
|
||||
int screenHeight;
|
||||
|
||||
TextPrintRender( float _x, float _y, float _fontSize, int _screenWidth, int _screenHeight )
|
||||
: x( _x*_screenWidth )
|
||||
, y( _y*_screenHeight )
|
||||
, fontSize( _fontSize * _screenHeight )
|
||||
, screenHeight( _screenHeight )
|
||||
{
|
||||
}
|
||||
void operator()( float cxUV, float cyUV, float glyphWidthUV, float glyphHeightUV
|
||||
, float* pVertList, float* pTextureCoordList, int vertIndex, int textureCoordIndex
|
||||
, float translate, float translateDown, float glyphWidth )
|
||||
{
|
||||
translate *= screenHeight; //move translate to pixel space
|
||||
pTextureCoordList[textureCoordIndex++] = cxUV;
|
||||
pTextureCoordList[textureCoordIndex++] = cyUV+glyphHeightUV;
|
||||
|
||||
pVertList[vertIndex++] = x+0+translate;
|
||||
pVertList[vertIndex++] = y+0+translateDown;
|
||||
pVertList[vertIndex++] = 0;
|
||||
|
||||
pTextureCoordList[textureCoordIndex++] = cxUV+glyphWidthUV;
|
||||
pTextureCoordList[textureCoordIndex++] = cyUV;
|
||||
|
||||
pVertList[vertIndex++] = x+fontSize+translate;
|
||||
pVertList[vertIndex++] = y+fontSize+translateDown;
|
||||
pVertList[vertIndex++] = 0;
|
||||
|
||||
pTextureCoordList[textureCoordIndex++] = cxUV;
|
||||
pTextureCoordList[textureCoordIndex++] = cyUV;
|
||||
|
||||
pVertList[vertIndex++] = x+0+translate;
|
||||
pVertList[vertIndex++] = y+fontSize+translateDown;
|
||||
pVertList[vertIndex++] = 0;
|
||||
|
||||
pTextureCoordList[textureCoordIndex++] = cxUV;
|
||||
pTextureCoordList[textureCoordIndex++] = cyUV+glyphHeightUV;
|
||||
|
||||
pVertList[vertIndex++] = x+0+translate;
|
||||
pVertList[vertIndex++] = y+0+translateDown;
|
||||
pVertList[vertIndex++] = 0;
|
||||
|
||||
pTextureCoordList[textureCoordIndex++] = cxUV+glyphWidthUV;
|
||||
pTextureCoordList[textureCoordIndex++] = cyUV+glyphHeightUV;
|
||||
|
||||
pVertList[vertIndex++] = x+fontSize+translate;
|
||||
pVertList[vertIndex++] = y+0+translateDown;
|
||||
pVertList[vertIndex++] = 0;
|
||||
|
||||
pTextureCoordList[textureCoordIndex++] = cxUV+glyphWidthUV;
|
||||
pTextureCoordList[textureCoordIndex++] = cyUV;
|
||||
|
||||
pVertList[vertIndex++] = x+fontSize+translate;
|
||||
pVertList[vertIndex++] = y+fontSize+translateDown;
|
||||
pVertList[vertIndex++] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void GLFontRenderer::print(float x, float y, float fontSize, const char* pString, bool forceMonoSpace, int monoSpaceWidth, bool doOrthoProj)
|
||||
{
|
||||
print( fontSize, pString, forceMonoSpace, monoSpaceWidth, doOrthoProj, TextPrintRender( x, y, fontSize, m_screenWidth, m_screenHeight ) );
|
||||
}
|
||||
|
||||
GLFontMeasureResult GLFontRenderer::measure( float fontSize, const char* pString, bool forceMonoSpace, int monoSpaceWidth )
|
||||
{
|
||||
GLFontMeasureResult retval( 0, fontSize );
|
||||
if ( !m_isInit )
|
||||
init();
|
||||
unsigned int num( safeStrlen( pString ) );
|
||||
|
||||
for(unsigned int i=0;i<num; i++)
|
||||
{
|
||||
int c = pString[i]-OGL_FONT_CHAR_BASE;
|
||||
if (c < OGL_FONT_CHARS_PER_ROW*OGL_FONT_CHARS_PER_COL) {
|
||||
float glyphWidth = (float)GLFontGlyphWidth[c];
|
||||
if(forceMonoSpace){
|
||||
glyphWidth = (float)monoSpaceWidth;
|
||||
}
|
||||
|
||||
glyphWidth = glyphWidth*(fontSize/(((float)OGL_FONT_TEXTURE_WIDTH)/OGL_FONT_CHARS_PER_ROW));
|
||||
retval.width += glyphWidth;
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
struct TextPrint3DRender
|
||||
{
|
||||
PxVec3 pos;
|
||||
PxVec3 cameraDir;
|
||||
PxVec3 up;
|
||||
PxVec3 right;
|
||||
float fontSize;
|
||||
TextPrint3DRender( const PxVec3& _pos, const PxVec3& _cameraDir, const PxVec3& _up, float _fontSize )
|
||||
: pos( _pos )
|
||||
, cameraDir( _cameraDir )
|
||||
, up( _up )
|
||||
, fontSize( _fontSize )
|
||||
{
|
||||
}
|
||||
void operator()( float cxUV, float cyUV, float glyphWidthUV, float glyphHeightUV
|
||||
, float* pVertList, float* pTextureCoordList, int vertIndex, int textureCoordIndex
|
||||
, float translate, float translateDown, float glyphWidth )
|
||||
{
|
||||
pTextureCoordList[textureCoordIndex++] = cxUV;
|
||||
pTextureCoordList[textureCoordIndex++] = cyUV+glyphHeightUV;
|
||||
|
||||
PxVec3 v;
|
||||
v = pos + right * translate - up * (translateDown + fontSize);
|
||||
pVertList[vertIndex++] = v.x;
|
||||
pVertList[vertIndex++] = v.y;
|
||||
pVertList[vertIndex++] = v.z;
|
||||
|
||||
pTextureCoordList[textureCoordIndex++] = cxUV+glyphWidthUV;
|
||||
pTextureCoordList[textureCoordIndex++] = cyUV;
|
||||
|
||||
v = pos + right * (glyphWidth + translate) - up * translateDown;
|
||||
pVertList[vertIndex++] = v.x;
|
||||
pVertList[vertIndex++] = v.y;
|
||||
pVertList[vertIndex++] = v.z;
|
||||
|
||||
pTextureCoordList[textureCoordIndex++] = cxUV;
|
||||
pTextureCoordList[textureCoordIndex++] = cyUV;
|
||||
|
||||
v = pos + right * translate - up * translateDown;
|
||||
pVertList[vertIndex++] = v.x;
|
||||
pVertList[vertIndex++] = v.y;
|
||||
pVertList[vertIndex++] = v.z;
|
||||
|
||||
pTextureCoordList[textureCoordIndex++] = cxUV;
|
||||
pTextureCoordList[textureCoordIndex++] = cyUV+glyphHeightUV;
|
||||
|
||||
v = pos + right * translate - up * (fontSize + translateDown);
|
||||
pVertList[vertIndex++] = v.x;
|
||||
pVertList[vertIndex++] = v.y;
|
||||
pVertList[vertIndex++] = v.z;
|
||||
|
||||
pTextureCoordList[textureCoordIndex++] = cxUV+glyphWidthUV;
|
||||
pTextureCoordList[textureCoordIndex++] = cyUV+glyphHeightUV;
|
||||
|
||||
v = pos + right * (glyphWidth + translate) - up * (fontSize + translateDown);
|
||||
pVertList[vertIndex++] = v.x;
|
||||
pVertList[vertIndex++] = v.y;
|
||||
pVertList[vertIndex++] = v.z;
|
||||
|
||||
pTextureCoordList[textureCoordIndex++] = cxUV+glyphWidthUV;
|
||||
pTextureCoordList[textureCoordIndex++] = cyUV;
|
||||
|
||||
v = pos + right * (glyphWidth + translate) - up * translateDown;
|
||||
pVertList[vertIndex++] = v.x;
|
||||
pVertList[vertIndex++] = v.y;
|
||||
pVertList[vertIndex++] = v.z;
|
||||
}
|
||||
};
|
||||
|
||||
void GLFontRenderer::print3d(const PxVec3& pos, const PxVec3& cameraDir, const PxVec3& up, float fontSize, const char* pString, bool forceMonoSpace, int monoSpaceWidth)
|
||||
{
|
||||
print( fontSize, pString, forceMonoSpace, monoSpaceWidth, false, TextPrint3DRender( pos, cameraDir, up, fontSize ) );
|
||||
}
|
||||
|
||||
|
||||
void GLFontRenderer::setScreenResolution(int screenWidth, int screenHeight)
|
||||
{
|
||||
m_screenWidth = screenWidth;
|
||||
m_screenHeight = screenHeight;
|
||||
}
|
||||
|
||||
void GLFontRenderer::setColor(unsigned int abgr)
|
||||
{
|
||||
m_color = abgr;
|
||||
}
|
||||
|
||||
#endif //!PHYSX_NO_RENDERER
|
||||
92
kaplademo/source/demoFramework/GLFontRenderer.h
Normal file
92
kaplademo/source/demoFramework/GLFontRenderer.h
Normal file
@ -0,0 +1,92 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#ifndef __GL_FONT_RENDERER__
|
||||
#define __GL_FONT_RENDERER__
|
||||
|
||||
#include "foundation/PxVec3.h"
|
||||
#include "PsArray.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
enum FontColor
|
||||
{
|
||||
FNT_COLOR_BLUE = 0xffff0000,
|
||||
FNT_COLOR_GREEN = 0xff00ff00,
|
||||
FNT_COLOR_RED = 0xff0000ff,
|
||||
|
||||
FNT_COLOR_DARK_BLUE = 0xff800000,
|
||||
FNT_COLOR_DARK_GREEN = 0xff008000,
|
||||
FNT_COLOR_DARK_RED = 0xff000080,
|
||||
|
||||
FNT_COLOR_WHITE = 0xffffffff
|
||||
};
|
||||
|
||||
struct GLFontMeasureResult
|
||||
{
|
||||
float width;
|
||||
float height;
|
||||
GLFontMeasureResult( float w, float h )
|
||||
: width( w )
|
||||
, height( h )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class GLFontRenderer{
|
||||
|
||||
private:
|
||||
|
||||
bool m_isInit;
|
||||
unsigned int m_textureObject;
|
||||
int m_screenWidth;
|
||||
int m_screenHeight;
|
||||
unsigned int m_color;
|
||||
shdfnd::Array<PxF32> mVertList;
|
||||
shdfnd::Array<PxF32> mTextureCoordList;
|
||||
template<typename TOperator>
|
||||
void print( float fontSize, const char* pString, bool forceMonoSpace, int monoSpaceWidth, bool doOthoProj, TOperator inOperator );
|
||||
|
||||
public:
|
||||
GLFontRenderer() : m_isInit(false), m_textureObject(0), m_screenWidth(0), m_screenHeight(0) {}
|
||||
|
||||
bool init();
|
||||
void print(float x, float y, float fontSize, const char* pString, bool forceMonoSpace=false, int monoSpaceWidth=11, bool doOrthoProj=true);
|
||||
GLFontMeasureResult measure( float fontSize, const char* pString, bool forceMonoSpace=false, int monoSpaceWidth=11 );
|
||||
|
||||
void print3d(const physx::PxVec3& pos, const physx::PxVec3& cameraDir, const physx::PxVec3& up, float fontSize, const char* pString, bool forceMonoSpace=false, int monoSpaceWidth=11);
|
||||
void setScreenResolution(int screenWidth, int screenHeight);
|
||||
void getScreenResolution( int& screenWidth, int& screenHeight ) { screenWidth = m_screenWidth; screenHeight = m_screenHeight; }
|
||||
|
||||
// PT: contrary to what the comment said before the format is abgr:
|
||||
// 0xffff0000 = blue
|
||||
// 0xff00ff00 = green
|
||||
// 0xff0000ff = red
|
||||
void setColor(unsigned int abgr);
|
||||
};
|
||||
|
||||
#endif // __GL_FONT_RENDERER__
|
||||
316
kaplademo/source/demoFramework/HBAOHelper.cpp
Normal file
316
kaplademo/source/demoFramework/HBAOHelper.cpp
Normal file
@ -0,0 +1,316 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#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;
|
||||
}
|
||||
60
kaplademo/source/demoFramework/HBAOHelper.h
Normal file
60
kaplademo/source/demoFramework/HBAOHelper.h
Normal file
@ -0,0 +1,60 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "GFSDK_SSAO.h"
|
||||
#include "Shader.h"
|
||||
|
||||
class HBAOHelper
|
||||
{
|
||||
public:
|
||||
HBAOHelper(float fov, float zNear, float zFar);
|
||||
~HBAOHelper();
|
||||
|
||||
bool init();
|
||||
bool renderAO(void(*renderScene)(), GLuint oldFBO = 0, bool useNormalTexture = true);
|
||||
void resize(int wAA, int hAA, int realw, int realH);
|
||||
|
||||
private:
|
||||
GFSDK_SSAO_Parameters mAoParams;
|
||||
GFSDK_SSAO_GLFunctions mGLFunctions;
|
||||
GFSDK_SSAO_Context_GL* mHbaoGlContext;
|
||||
float mNormalMapTransform[16];
|
||||
float mFov;
|
||||
float mZnear;
|
||||
float mZFar;
|
||||
GLint mWidthAA;
|
||||
GLint mHeightAA;
|
||||
GLint mWidthReal;
|
||||
GLint mHeightReal;
|
||||
GLuint mNormalTex;
|
||||
GLuint mDepthTex;
|
||||
GLuint mFBO;
|
||||
GLuint mDownScaledFBO;
|
||||
GLuint mColorTex;
|
||||
};
|
||||
383
kaplademo/source/demoFramework/HDRHelper.cpp
Normal file
383
kaplademo/source/demoFramework/HDRHelper.cpp
Normal file
@ -0,0 +1,383 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#include "HDRHelper.h"
|
||||
#include "foundation/PxMat44.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
const char *HDRToneMappingVS = STRINGIFY(
|
||||
void main(void)
|
||||
{
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
gl_Position = gl_Vertex * 2.0 - 1.0;
|
||||
}
|
||||
);
|
||||
|
||||
const char *HDRBlurHFS = STRINGIFY(
|
||||
uniform sampler2D colorTex;
|
||||
uniform float sx;
|
||||
|
||||
void main (void)
|
||||
{
|
||||
vec3 bloom = vec3(0.0, 0.0, 0.0);
|
||||
const float hdrScale = 1.5;
|
||||
const int kernelSize = 10;
|
||||
const float invScale = 1.0 / (hdrScale * float(kernelSize));
|
||||
|
||||
for (int x = -kernelSize; x <= kernelSize; x++)
|
||||
{
|
||||
float s = gl_TexCoord[0].s + x * sx;
|
||||
float t = gl_TexCoord[0].t;
|
||||
vec3 color = texture2D(colorTex, vec2(s,t)).rgb;
|
||||
float luminance = dot(color, vec3(0.2125, 0.7154, 0.0721));
|
||||
if (luminance > 1.0)
|
||||
{
|
||||
bloom += color * ((kernelSize+1) - abs(float(x)));
|
||||
}
|
||||
}
|
||||
|
||||
gl_FragColor = vec4(bloom * invScale, 1.0);
|
||||
}
|
||||
);
|
||||
|
||||
const char *HDRBlurVFS = STRINGIFY(
|
||||
uniform sampler2D colorTex;
|
||||
uniform sampler2D blurTex;
|
||||
uniform float sy;
|
||||
|
||||
void main (void)
|
||||
{
|
||||
const float hdrScale = 1.5;
|
||||
const int kernelSize = 10;
|
||||
const float invScale = 1.0 / (hdrScale * float(kernelSize) * 100.0);
|
||||
|
||||
vec3 colorP = texture2D(colorTex, gl_TexCoord[0]).rgb;
|
||||
vec3 bloom = vec3(0.0, 0.0, 0.0);
|
||||
|
||||
for (int y = -kernelSize; y <= kernelSize; y++)
|
||||
{
|
||||
float s = gl_TexCoord[0].s;
|
||||
float t = gl_TexCoord[0].t + y * sy;
|
||||
vec3 color = texture2D(blurTex, vec2(s,t)).rgb;
|
||||
float luminance = dot(color, vec3(0.2125, 0.7154, 0.0721));
|
||||
if (luminance > 1.0)
|
||||
{
|
||||
bloom += color * ((kernelSize+1) - abs(float(y)));
|
||||
}
|
||||
}
|
||||
|
||||
vec3 hdrColor = invScale * bloom + colorP;
|
||||
|
||||
vec3 toneMappedColor = 2.0 * hdrColor / (hdrColor + vec3(1.0));
|
||||
gl_FragColor = vec4(toneMappedColor, 1.0);
|
||||
}
|
||||
);
|
||||
|
||||
const char *HDRDepthOfFieldFS = STRINGIFY(
|
||||
uniform sampler2D colorTex;
|
||||
uniform sampler2D depthTex;
|
||||
uniform float sx;
|
||||
uniform float sy;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
const float depthEnd = 0.993;
|
||||
const float depthSize = 0.01;
|
||||
|
||||
vec3 colorP = texture2D(colorTex, gl_TexCoord[0]).rgb;
|
||||
float depth = texture2D(depthTex, gl_TexCoord[0].st).r;
|
||||
|
||||
if ((depth - depthEnd) < depthSize)
|
||||
{
|
||||
const int depthKernelSize = 5;
|
||||
vec3 colorSum = vec3(0.0);
|
||||
float cnt = 0.0;
|
||||
for (int x = -depthKernelSize; x <= depthKernelSize; x++)
|
||||
for (int y = -depthKernelSize; y <= depthKernelSize; y++)
|
||||
{
|
||||
float s = gl_TexCoord[0].s + x * sy;
|
||||
float t = gl_TexCoord[0].t + y * sy;
|
||||
float scalex = ((depthKernelSize + 1) - abs(float(x))) / depthKernelSize;
|
||||
float scaley = ((depthKernelSize + 1) - abs(float(y))) / depthKernelSize;
|
||||
float scale = scalex * scaley;
|
||||
vec3 color = texture2D(colorTex, vec2(s, t)).rgb;
|
||||
colorSum += scale * color;
|
||||
cnt += scale;
|
||||
}
|
||||
|
||||
colorSum /= cnt;
|
||||
float depthScale = pow(max(0.0f, min(1.0, (abs(depth - depthEnd)) / depthSize)), 1.5);
|
||||
colorP = depthScale * colorSum + (1.0 - depthScale) * colorP;
|
||||
}
|
||||
|
||||
gl_FragColor = vec4(colorP, 1.0);
|
||||
}
|
||||
);
|
||||
|
||||
HDRHelper::HDRHelper(float fov,float padding,float zNear,float zFar, const char* resourcePath, float scale) : fov(fov),padding(padding),zNear(zNear),zFar(zFar), scale(scale)
|
||||
{
|
||||
mShaderBloomH.loadShaderCode(HDRToneMappingVS, HDRBlurHFS);
|
||||
mShaderBloomV.loadShaderCode(HDRToneMappingVS, HDRBlurVFS);
|
||||
mShaderDOF.loadShaderCode(HDRToneMappingVS, HDRDepthOfFieldFS);
|
||||
|
||||
glGenTextures(1,&mHDRColorTex);
|
||||
glGenTextures(1,&mHDRDepthTex);
|
||||
glGenTextures(1,&mHDRBlurTex);
|
||||
glGenTextures(1,&mHDRBloomTex);
|
||||
|
||||
glGenFramebuffers(1,&mHDRFbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mHDRFbo);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D,mHDRColorTex, 0);
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
||||
|
||||
glGenFramebuffers(1,&mHDRBlurFbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mHDRBlurFbo);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D,mHDRBlurTex, 0);
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
||||
|
||||
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
//printf("Frame buffer status %d\n\n\n",
|
||||
// (status == GL_FRAMEBUFFER_COMPLETE) ? 1 : 0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
void HDRHelper::Resize(int w,int h) {
|
||||
|
||||
realWidth = w;
|
||||
realHeight = h;
|
||||
Width = w*scale;
|
||||
Height = h*scale;
|
||||
|
||||
fovPad = 2.0f*atan(tan(fov*0.5f*physx::PxPi/180.0f)*(1.0f+padding))*180.0f/physx::PxPi;
|
||||
|
||||
glViewport(0,0,w,h);
|
||||
|
||||
// allocate HDR color buffer
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mHDRFbo);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D,mHDRColorTex);
|
||||
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_RGBA16F,w,h,0,GL_RGBA,GL_FLOAT,NULL);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D,mHDRDepthTex);
|
||||
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_COMPONENT24,w,h,0,GL_DEPTH_COMPONENT,GL_FLOAT,NULL);
|
||||
|
||||
// allocate HDR color buffer for blur operations
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mHDRBlurFbo);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D,mHDRBlurTex);
|
||||
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_RGBA16F,w,h,0,GL_RGBA,GL_FLOAT,NULL);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D,mHDRBloomTex);
|
||||
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_RGBA16F,w,h,0,GL_RGBA,GL_FLOAT,NULL);
|
||||
|
||||
// set program values
|
||||
glUseProgram(mShaderBloomH);
|
||||
glUniform1f(glGetUniformLocation(mShaderBloomH,"sx"),1.0f / (float)w);
|
||||
|
||||
glUseProgram(mShaderBloomV);
|
||||
glUniform1f(glGetUniformLocation(mShaderBloomV,"sy"),1.0f / (float)h);
|
||||
|
||||
glUseProgram(mShaderDOF);
|
||||
glUniform1f(glGetUniformLocation(mShaderDOF,"sx"),1.0f / (float)w);
|
||||
glUniform1f(glGetUniformLocation(mShaderDOF,"sy"),1.0f / (float)h);
|
||||
|
||||
glUseProgram(0);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
}
|
||||
|
||||
void HDRHelper::Destroy() {
|
||||
|
||||
mShaderBloomH.deleteShaders();
|
||||
mShaderBloomV.deleteShaders();
|
||||
|
||||
glDeleteTextures(1,&mHDRColorTex);
|
||||
glDeleteTextures(1,&mHDRDepthTex);
|
||||
glDeleteTextures(1,&mHDRBlurTex);
|
||||
glDeleteTextures(1,&mHDRBloomTex);
|
||||
|
||||
glDeleteFramebuffers(1,&mHDRFbo);
|
||||
glDeleteFramebuffers(1,&mHDRBlurFbo);
|
||||
}
|
||||
|
||||
void HDRHelper::beginHDR(bool useOwnFbo)
|
||||
{
|
||||
if (useOwnFbo)
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mHDRFbo);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D,mHDRColorTex, 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,GL_TEXTURE_2D,mHDRDepthTex,0);
|
||||
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
void HDRHelper::endHDR(bool useOwnFbo)
|
||||
{
|
||||
if (useOwnFbo)
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
void
|
||||
drawQuads(float s = 1.0f)
|
||||
{
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0f,0.0f);
|
||||
glTexCoord2f(1.0f, 0.0f); glVertex2f(s,0.0f);
|
||||
glTexCoord2f(1.0f, 1.0f); glVertex2f(s,s);
|
||||
glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0f,s);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
void HDRHelper::DoHDR(GLuint oldFBO, bool useDOF) {
|
||||
|
||||
PxMat44 Projection = PerspectiveProjectionMatrix(fov,Width,Height,zNear,zFar);
|
||||
|
||||
// render stored HDR fbo onto blur fbo, first with horizontal blur
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mHDRBlurFbo);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D,mHDRBlurTex,0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,GL_TEXTURE_2D,0,0);
|
||||
|
||||
glViewport(0,0,realWidth,realHeight);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadMatrixf(&Projection.column0.x);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, mHDRColorTex);
|
||||
|
||||
glUseProgram(mShaderBloomH);
|
||||
glUniform1f(glGetUniformLocation(mShaderBloomH, "sx"), 1.0f / (float)realWidth);
|
||||
glUniform1i(glGetUniformLocation(mShaderBloomH,"colorTex"),0);
|
||||
|
||||
drawQuads();
|
||||
|
||||
glUseProgram(0);
|
||||
glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D,0);
|
||||
|
||||
// now apply vertical blur for the bloom
|
||||
if (useDOF)
|
||||
{
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D,mHDRBloomTex,0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,GL_TEXTURE_2D,0,0);
|
||||
}
|
||||
else
|
||||
glBindFramebuffer(GL_FRAMEBUFFER,oldFBO);
|
||||
|
||||
glViewport(0,0,realWidth,realHeight);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadMatrixf(&Projection.column0.x);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D,mHDRColorTex);
|
||||
glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D,mHDRBlurTex);
|
||||
|
||||
glUseProgram(mShaderBloomV);
|
||||
glUniform1f(glGetUniformLocation(mShaderBloomV, "sy"), 1.0f / (float)realHeight);
|
||||
glUniform1i(glGetUniformLocation(mShaderBloomV,"colorTex"),0);
|
||||
glUniform1i(glGetUniformLocation(mShaderBloomV,"blurTex"),1);
|
||||
|
||||
drawQuads();
|
||||
|
||||
glUseProgram(0);
|
||||
glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D,0);
|
||||
glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D,0);
|
||||
|
||||
// now render the final image onto supplied fbo, apply DOF
|
||||
if (!useDOF) return;
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER,oldFBO);
|
||||
|
||||
glViewport(0,0,realWidth,realHeight);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadMatrixf(&Projection.column0.x);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D,mHDRBloomTex);
|
||||
glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D,mHDRDepthTex);
|
||||
|
||||
glUseProgram(mShaderDOF);
|
||||
glUniform1f(glGetUniformLocation(mShaderDOF, "sx"), 1.0f / (float)realWidth);
|
||||
glUniform1f(glGetUniformLocation(mShaderDOF, "sy"), 1.0f / (float)realHeight);
|
||||
glUniform1i(glGetUniformLocation(mShaderDOF,"colorTex"),0);
|
||||
glUniform1i(glGetUniformLocation(mShaderDOF,"depthTex"),1);
|
||||
|
||||
drawQuads();
|
||||
|
||||
glUseProgram(0);
|
||||
glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D,0);
|
||||
glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D,0);
|
||||
}
|
||||
64
kaplademo/source/demoFramework/HDRHelper.h
Normal file
64
kaplademo/source/demoFramework/HDRHelper.h
Normal file
@ -0,0 +1,64 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
#include <GL/glew.h>
|
||||
#include "Shader.h"
|
||||
|
||||
class HDRHelper{
|
||||
public:
|
||||
int Width, Height;
|
||||
int realWidth, realHeight;
|
||||
|
||||
float padding;
|
||||
float fov;
|
||||
float fovPad;
|
||||
float zNear, zFar;
|
||||
float scale;
|
||||
|
||||
Shader mShaderBloomH;
|
||||
Shader mShaderBloomV;
|
||||
Shader mShaderDOF;
|
||||
|
||||
HDRHelper(float fov, float padding, float zNear, float zFar, const char* resourcePath, float scale);
|
||||
|
||||
void beginHDR(bool useOwnFbo = true);
|
||||
void endHDR(bool useOwnFbo = true);
|
||||
|
||||
void Resize(int w, int h);
|
||||
|
||||
void DoHDR(GLuint oldFBO = 0, bool useDOF = true);
|
||||
void Destroy();
|
||||
|
||||
GLuint mHDRFbo;
|
||||
GLuint mHDRBlurFbo;
|
||||
|
||||
GLuint mHDRColorTex;
|
||||
GLuint mHDRDepthTex;
|
||||
GLuint mHDRBlurTex;
|
||||
GLuint mHDRBloomTex;
|
||||
};
|
||||
440
kaplademo/source/demoFramework/RawLoader.cpp
Normal file
440
kaplademo/source/demoFramework/RawLoader.cpp
Normal file
@ -0,0 +1,440 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2018 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
|
||||
// PT: this file is a loader for "raw" binary files. It should NOT create SDK objects directly.
|
||||
|
||||
#include <stdio.h>
|
||||
#include "foundation/PxPreprocessor.h"
|
||||
#include "foundation/PxAssert.h"
|
||||
#include "RawLoader.h"
|
||||
#include "PxTkFile.h"
|
||||
|
||||
typedef ::FILE File;
|
||||
|
||||
using namespace physx;
|
||||
|
||||
RAWObject::RAWObject() : mName(NULL)
|
||||
{
|
||||
mTransform = PxTransform(PxIdentity);
|
||||
}
|
||||
|
||||
RAWTexture::RAWTexture() :
|
||||
mID(0xffffffff),
|
||||
mWidth(0),
|
||||
mHeight(0),
|
||||
mHasAlpha(false)
|
||||
//mPixels(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
RAWMesh::RAWMesh() :
|
||||
mNbVerts(0),
|
||||
mNbFaces(0),
|
||||
mMaterialID(0xffffffff),
|
||||
mVerts(NULL),
|
||||
mVertexNormals(NULL),
|
||||
mVertexColors(NULL),
|
||||
mUVs(NULL),
|
||||
mIndices(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
RAWShape::RAWShape() :
|
||||
mNbVerts(0),
|
||||
mVerts(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
RAWHelper::RAWHelper()
|
||||
{
|
||||
}
|
||||
|
||||
RAWMaterial::RAWMaterial() :
|
||||
mID(0xffffffff),
|
||||
mDiffuseID(0xffffffff),
|
||||
mOpacity(1.0f),
|
||||
mDoubleSided(false)
|
||||
{
|
||||
mAmbientColor = PxVec3(0);
|
||||
mDiffuseColor = PxVec3(0);
|
||||
mSpecularColor = PxVec3(0);
|
||||
}
|
||||
|
||||
#if PX_INTEL_FAMILY
|
||||
static const bool gFlip = false;
|
||||
#elif PX_PPC
|
||||
static const bool gFlip = true;
|
||||
#elif PX_ARM_FAMILY
|
||||
static const bool gFlip = false;
|
||||
#else
|
||||
#error Unknown platform!
|
||||
#endif
|
||||
|
||||
PX_INLINE void Flip(PxU32& v)
|
||||
{
|
||||
PxU8* b = (PxU8*)&v;
|
||||
|
||||
PxU8 temp = b[0];
|
||||
b[0] = b[3];
|
||||
b[3] = temp;
|
||||
temp = b[1];
|
||||
b[1] = b[2];
|
||||
b[2] = temp;
|
||||
}
|
||||
|
||||
PX_INLINE void Flip(PxI32& v)
|
||||
{
|
||||
Flip((PxU32&)v);
|
||||
}
|
||||
|
||||
PX_INLINE void Flip(PxF32& v)
|
||||
{
|
||||
Flip((PxU32&)v);
|
||||
}
|
||||
|
||||
static PxU8 read8(File* fp)
|
||||
{
|
||||
PxU8 data;
|
||||
size_t numRead = fread(&data, 1, 1, fp);
|
||||
if (numRead != 1) { return 0; }
|
||||
return data;
|
||||
}
|
||||
|
||||
static PxU32 read32(File* fp)
|
||||
{
|
||||
PxU32 data;
|
||||
size_t numRead = fread(&data, 1, 4, fp);
|
||||
if (numRead != 4) { return 0; }
|
||||
if (gFlip)
|
||||
Flip(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
static PxF32 readFloat(File* fp)
|
||||
{
|
||||
PxF32 data;
|
||||
size_t numRead = fread(&data, 1, 4, fp);
|
||||
if (numRead != 4) { return 0; }
|
||||
if (gFlip)
|
||||
Flip(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
static PxTransform readTransform(File* fp, PxReal scale)
|
||||
{
|
||||
PxTransform tr;
|
||||
tr.p.x = scale * readFloat(fp);
|
||||
tr.p.y = scale * readFloat(fp);
|
||||
tr.p.z = scale * readFloat(fp);
|
||||
|
||||
tr.q.x = readFloat(fp);
|
||||
tr.q.y = readFloat(fp);
|
||||
tr.q.z = readFloat(fp);
|
||||
tr.q.w = readFloat(fp);
|
||||
|
||||
PX_ASSERT(tr.isValid());
|
||||
|
||||
return tr;
|
||||
}
|
||||
|
||||
static void readVertexArray(File* fp, PxVec3* verts, PxU32 nbVerts)
|
||||
{
|
||||
const size_t size = 4 * 3 * nbVerts;
|
||||
size_t numRead = fread(verts, 1, size, fp);
|
||||
if (numRead != size) { return; }
|
||||
|
||||
if (gFlip)
|
||||
{
|
||||
for (PxU32 j = 0; j<nbVerts; j++)
|
||||
{
|
||||
Flip(verts[j].x);
|
||||
Flip(verts[j].y);
|
||||
Flip(verts[j].z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void readUVs(File* fp, PxReal* uvs, PxU32 nbVerts)
|
||||
{
|
||||
const size_t size = 4 * 2 * nbVerts;
|
||||
size_t numRead = fread(uvs, 1, size, fp);
|
||||
if (numRead != size) { return; }
|
||||
|
||||
if (gFlip)
|
||||
{
|
||||
for (PxU32 j = 0; j<nbVerts * 2; j++)
|
||||
Flip(uvs[j]);
|
||||
}
|
||||
}
|
||||
|
||||
static void readVertices(File* fp, PxVec3* verts, PxU32 nbVerts, PxReal scale)
|
||||
{
|
||||
readVertexArray(fp, verts, nbVerts);
|
||||
|
||||
for (PxU32 j = 0; j<nbVerts; j++)
|
||||
verts[j] *= scale;
|
||||
}
|
||||
|
||||
static void readNormals(File* fp, PxVec3* verts, PxU32 nbVerts)
|
||||
{
|
||||
readVertexArray(fp, verts, nbVerts);
|
||||
}
|
||||
|
||||
static void readVertexColors(File* fp, PxVec3* colors, PxU32 nbVerts)
|
||||
{
|
||||
readVertexArray(fp, colors, nbVerts);
|
||||
}
|
||||
|
||||
static void readName(File* fp, char* objectName)
|
||||
{
|
||||
PxU32 offset = 0;
|
||||
char c;
|
||||
do
|
||||
{
|
||||
size_t numRead = fread(&c, 1, 1, fp);
|
||||
if (numRead != 1) { c = '\0'; }
|
||||
objectName[offset++] = c;
|
||||
} while (c);
|
||||
objectName[offset] = 0;
|
||||
}
|
||||
|
||||
|
||||
bool loadRAWfile(const char* filename, RAWImportCallback& cb, PxReal scale)
|
||||
{
|
||||
File* fp = NULL;
|
||||
fopen_s(&fp, filename, "rb");
|
||||
if (!fp)
|
||||
return false;
|
||||
|
||||
// General info
|
||||
const PxU32 tag = read32(fp);
|
||||
const PxU32 generalVersion = read32(fp);
|
||||
const PxU32 nbMaterials = read32(fp);
|
||||
const PxU32 nbTextures = read32(fp);
|
||||
const PxU32 nbMeshes = read32(fp);
|
||||
const PxU32 nbShapes = read32(fp);
|
||||
const PxU32 nbHelpers = read32(fp);
|
||||
|
||||
(void)tag;
|
||||
(void)generalVersion;
|
||||
char objectName[512];
|
||||
|
||||
// Textures
|
||||
for (PxU32 i = 0; i<nbTextures; i++)
|
||||
{
|
||||
RAWTexture data;
|
||||
|
||||
readName(fp, objectName);
|
||||
data.mName = objectName;
|
||||
data.mTransform = PxTransform(PxIdentity); // PT: texture transform not supported yet
|
||||
data.mID = read32(fp);
|
||||
|
||||
PxU32* pixels = NULL;
|
||||
PxU8 r, g, b, a;
|
||||
if (read8(fp))
|
||||
{
|
||||
data.mWidth = read32(fp);
|
||||
data.mHeight = read32(fp);
|
||||
data.mHasAlpha = read8(fp) != 0;
|
||||
const PxU32 nbPixels = data.mWidth*data.mHeight;
|
||||
pixels = new PxU32[nbPixels];
|
||||
data.mPixels = pixels;
|
||||
for (PxU32 i = 0; i<nbPixels; i++)
|
||||
{
|
||||
r = read8(fp);
|
||||
g = read8(fp);
|
||||
b = read8(fp);
|
||||
|
||||
if (data.mHasAlpha)
|
||||
a = read8(fp);
|
||||
else
|
||||
a = 0xff;
|
||||
|
||||
//b, g, r, a
|
||||
pixels[i] = b << 24 | g << 16 | r << 8 | a;
|
||||
/*pixels[i].r = read8(fp);
|
||||
pixels[i].g = read8(fp);
|
||||
pixels[i].b = read8(fp);
|
||||
if (data.mHasAlpha)
|
||||
pixels[i].a = read8(fp);
|
||||
else
|
||||
pixels[i].a = 0xff;*/
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
data.mWidth = 0;
|
||||
data.mHeight = 0;
|
||||
data.mHasAlpha = false;
|
||||
data.mPixels = NULL;
|
||||
}
|
||||
|
||||
cb.newTexture(data);
|
||||
delete[] pixels;
|
||||
}
|
||||
|
||||
// Materials
|
||||
for (PxU32 i = 0; i<nbMaterials; i++)
|
||||
{
|
||||
RAWMaterial data;
|
||||
data.mID = read32(fp);
|
||||
data.mDiffuseID = read32(fp);
|
||||
data.mOpacity = readFloat(fp);
|
||||
data.mDoubleSided = read32(fp) != 0;
|
||||
|
||||
data.mAmbientColor.x = readFloat(fp);
|
||||
data.mAmbientColor.y = readFloat(fp);
|
||||
data.mAmbientColor.z = readFloat(fp);
|
||||
|
||||
data.mDiffuseColor.x = readFloat(fp);
|
||||
data.mDiffuseColor.y = readFloat(fp);
|
||||
data.mDiffuseColor.z = readFloat(fp);
|
||||
|
||||
data.mSpecularColor.x = readFloat(fp);
|
||||
data.mSpecularColor.y = readFloat(fp);
|
||||
data.mSpecularColor.z = readFloat(fp);
|
||||
|
||||
cb.newMaterial(data);
|
||||
}
|
||||
|
||||
// Meshes
|
||||
for (PxU32 i = 0; i<nbMeshes; i++)
|
||||
{
|
||||
RAWMesh data;
|
||||
|
||||
readName(fp, objectName);
|
||||
data.mName = objectName;
|
||||
data.mTransform = readTransform(fp, scale);
|
||||
//
|
||||
data.mNbVerts = read32(fp);
|
||||
data.mNbFaces = read32(fp);
|
||||
const PxU32 hasVertexColors = read32(fp);
|
||||
const PxU32 hasUVs = read32(fp);
|
||||
data.mMaterialID = read32(fp);
|
||||
|
||||
PxVec3* tmpVerts = new PxVec3[data.mNbVerts];
|
||||
PxVec3* tmpNormals = new PxVec3[data.mNbVerts];
|
||||
PxVec3* tmpColors = NULL;
|
||||
PxReal* tmpUVs = NULL;
|
||||
|
||||
data.mVerts = tmpVerts;
|
||||
data.mVertexNormals = tmpNormals;
|
||||
data.mVertexColors = NULL;
|
||||
data.mUVs = NULL;
|
||||
|
||||
readVertices(fp, tmpVerts, data.mNbVerts, scale);
|
||||
readNormals(fp, tmpNormals, data.mNbVerts);
|
||||
|
||||
if (hasVertexColors)
|
||||
{
|
||||
tmpColors = new PxVec3[data.mNbVerts];
|
||||
data.mVertexColors = tmpColors;
|
||||
readVertexColors(fp, tmpColors, data.mNbVerts);
|
||||
}
|
||||
|
||||
if (hasUVs)
|
||||
{
|
||||
tmpUVs = new PxReal[(sizeof(PxReal)*data.mNbVerts * 2)];
|
||||
data.mUVs = tmpUVs;
|
||||
readUVs(fp, tmpUVs, data.mNbVerts);
|
||||
}
|
||||
|
||||
PxU32* tmpIndices = new PxU32[sizeof(PxU32)*data.mNbFaces * 3];
|
||||
data.mIndices = tmpIndices;
|
||||
const size_t size = 4 * 3 * data.mNbFaces;
|
||||
size_t numRead = fread(tmpIndices, 1, size, fp);
|
||||
if (numRead != size)
|
||||
{
|
||||
delete[] tmpIndices;
|
||||
delete[] tmpUVs;
|
||||
delete[] tmpColors;
|
||||
delete[] tmpNormals;
|
||||
delete[] tmpVerts;
|
||||
/*SAMPLE_FREE(tmpIndices);
|
||||
SAMPLE_FREE(tmpUVs);
|
||||
|
||||
DELETEARRAY(tmpColors);
|
||||
DELETEARRAY(tmpNormals);
|
||||
DELETEARRAY(tmpVerts);*/
|
||||
return false;
|
||||
}
|
||||
if (gFlip)
|
||||
{
|
||||
for (PxU32 j = 0; j<data.mNbFaces * 3; j++)
|
||||
{
|
||||
Flip(tmpIndices[j]);
|
||||
}
|
||||
}
|
||||
|
||||
cb.newMesh(data);
|
||||
|
||||
delete[] tmpIndices;
|
||||
delete[] tmpUVs;
|
||||
delete[] tmpColors;
|
||||
delete[] tmpNormals;
|
||||
delete[] tmpVerts;
|
||||
|
||||
/* SAMPLE_FREE(tmpIndices);
|
||||
SAMPLE_FREE(tmpUVs);
|
||||
DELETEARRAY(tmpColors);
|
||||
DELETEARRAY(tmpNormals);
|
||||
DELETEARRAY(tmpVerts);*/
|
||||
}
|
||||
|
||||
// Shapes
|
||||
for (PxU32 i = 0; i<nbShapes; i++)
|
||||
{
|
||||
RAWShape data;
|
||||
|
||||
readName(fp, objectName);
|
||||
data.mName = objectName;
|
||||
data.mTransform = readTransform(fp, scale);
|
||||
//
|
||||
data.mNbVerts = read32(fp);
|
||||
PxVec3* tmp = new PxVec3[data.mNbVerts];
|
||||
data.mVerts = tmp;
|
||||
readVertices(fp, tmp, data.mNbVerts, scale);
|
||||
|
||||
cb.newShape(data);
|
||||
|
||||
delete[] tmp;
|
||||
}
|
||||
|
||||
// Helpers
|
||||
for (PxU32 i = 0; i<nbHelpers; i++)
|
||||
{
|
||||
RAWHelper data;
|
||||
|
||||
readName(fp, objectName);
|
||||
data.mName = objectName;
|
||||
data.mTransform = readTransform(fp, scale);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
114
kaplademo/source/demoFramework/RawLoader.h
Normal file
114
kaplademo/source/demoFramework/RawLoader.h
Normal file
@ -0,0 +1,114 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2018 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
|
||||
#ifndef RAW_LOADER_H
|
||||
#define RAW_LOADER_H
|
||||
|
||||
#include "foundation/PxTransform.h"
|
||||
|
||||
class RAWObject
|
||||
{
|
||||
public:
|
||||
RAWObject();
|
||||
|
||||
const char* mName;
|
||||
physx::PxTransform mTransform;
|
||||
};
|
||||
|
||||
class RAWTexture : public RAWObject
|
||||
{
|
||||
public:
|
||||
RAWTexture();
|
||||
|
||||
physx::PxU32 mID;
|
||||
physx::PxU32 mWidth;
|
||||
physx::PxU32 mHeight;
|
||||
bool mHasAlpha;
|
||||
physx::PxU32* mPixels; //b, g, r, a(blue, green, red, alpha)
|
||||
};
|
||||
|
||||
class RAWMesh : public RAWObject
|
||||
{
|
||||
public:
|
||||
RAWMesh();
|
||||
|
||||
physx::PxU32 mNbVerts;
|
||||
physx::PxU32 mNbFaces;
|
||||
physx::PxU32 mMaterialID;
|
||||
const physx::PxVec3* mVerts;
|
||||
const physx::PxVec3* mVertexNormals;
|
||||
const physx::PxVec3* mVertexColors;
|
||||
const physx::PxReal* mUVs;
|
||||
const physx::PxU32* mIndices;
|
||||
};
|
||||
|
||||
class RAWShape : public RAWObject
|
||||
{
|
||||
public:
|
||||
RAWShape();
|
||||
|
||||
physx::PxU32 mNbVerts;
|
||||
const physx::PxVec3* mVerts;
|
||||
};
|
||||
|
||||
class RAWHelper : public RAWObject
|
||||
{
|
||||
public:
|
||||
RAWHelper();
|
||||
};
|
||||
|
||||
class RAWMaterial
|
||||
{
|
||||
public:
|
||||
RAWMaterial();
|
||||
|
||||
physx::PxU32 mID;
|
||||
physx::PxU32 mDiffuseID;
|
||||
physx::PxReal mOpacity;
|
||||
physx::PxVec3 mAmbientColor;
|
||||
physx::PxVec3 mDiffuseColor;
|
||||
physx::PxVec3 mSpecularColor;
|
||||
bool mDoubleSided;
|
||||
};
|
||||
|
||||
class RAWImportCallback
|
||||
{
|
||||
public:
|
||||
virtual ~RAWImportCallback() {}
|
||||
virtual void newMaterial(const RAWMaterial&) = 0;
|
||||
virtual void newMesh(const RAWMesh&) = 0;
|
||||
virtual void newShape(const RAWShape&) = 0;
|
||||
virtual void newHelper(const RAWHelper&) = 0;
|
||||
virtual void newTexture(const RAWTexture&) = 0;
|
||||
};
|
||||
|
||||
bool loadRAWfile(const char* filename, RAWImportCallback& cb, physx::PxReal scale);
|
||||
|
||||
#endif
|
||||
2905
kaplademo/source/demoFramework/Render/MyShaders.cpp
Normal file
2905
kaplademo/source/demoFramework/Render/MyShaders.cpp
Normal file
File diff suppressed because it is too large
Load Diff
48
kaplademo/source/demoFramework/Render/MyShaders.h
Normal file
48
kaplademo/source/demoFramework/Render/MyShaders.h
Normal file
@ -0,0 +1,48 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
extern const char *particleVS,*particleVSNoKill;
|
||||
extern const char *particleSpherePS, *particleDebugPS, *particleDensityPS, *particleFoamPS, *particleFoamVS, *particleBubblePS;
|
||||
extern const char *particleSurfacePS, *particleThicknessPS;
|
||||
extern const char *mblurVS, *mblurGS, *mblurGSNoKill, *particleSprayPS;
|
||||
extern const char *passThruVS;
|
||||
extern const char *depthBlurPS , *depthBlur2DPS, *depthBlurSymPS, *displaySurfacePS, *displaySurfaceNewPS, *displaySurfaceChromePS, *displaySurfaceSolidPS;
|
||||
extern const char *depthBlurViewIDPS, *depthBlurViewIDNonSepPS;
|
||||
extern const char *textureRectPS, *dilatePS, *copyPS;
|
||||
|
||||
// Nutt
|
||||
extern const char *depthToInitThicknessPS;
|
||||
extern const char *hfDepthPS, *hfDepthVS, *hfThicknessVS, *hfThicknessPS;
|
||||
extern const char *debugPS, *debugTriVS, *debugTriPS;
|
||||
extern const char *hfThicknessAddPS, *displaySurfaceNutPS, *particleDumbFoamVS, *particleDumbFoamGS, *particleDumbFoamPS, *displaySurfaceNutEscapePS, *displaySurfaceNutEscapeDiffusePS, *particleSprayUseFOMPS, *particleSprayGenFOMPS ;
|
||||
|
||||
extern const char *texture2DPS;
|
||||
|
||||
extern const char *particleSmokeUseFOMPS;
|
||||
|
||||
extern const char *skyboxVS;
|
||||
extern const char *skyboxPS;
|
||||
297
kaplademo/source/demoFramework/Render/glmesh.cpp
Normal file
297
kaplademo/source/demoFramework/Render/glmesh.cpp
Normal file
@ -0,0 +1,297 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#include "glmesh.h"
|
||||
#include <windows.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
GLMesh::GLMesh(GLuint elementTypei) {
|
||||
firstTimeBO = true;
|
||||
vbo = ibo = 0;
|
||||
withTexture = withColor = withNormal = withTangent = false;
|
||||
elementType = elementTypei;
|
||||
}
|
||||
GLMesh::~GLMesh() {
|
||||
firstTimeBO = true;
|
||||
if (vbo) {
|
||||
glDeleteBuffersARB(1, &vbo);
|
||||
}
|
||||
if (ibo) {
|
||||
glDeleteBuffersARB(1, &ibo);
|
||||
}
|
||||
}
|
||||
void GLMesh::reset() {
|
||||
firstTimeBO = true;
|
||||
if (vbo) {
|
||||
glDeleteBuffersARB(1, &vbo);
|
||||
}
|
||||
if (ibo) {
|
||||
glDeleteBuffersARB(1, &ibo);
|
||||
}
|
||||
vbo = ibo = 0;
|
||||
withTexture = withColor = withNormal = withTangent = false;
|
||||
|
||||
indices.clear();
|
||||
vertices.clear();
|
||||
normals.clear();
|
||||
colors.clear();
|
||||
texCoords.clear(); // treats as u v
|
||||
tangents.clear();
|
||||
bitangents.clear();
|
||||
|
||||
// For raw
|
||||
rawVertices.clear();
|
||||
rawNormals.clear();
|
||||
|
||||
}
|
||||
void GLMesh::genVBOIBO() {
|
||||
glGenBuffersARB(1, &vbo);
|
||||
glGenBuffersARB(1, &ibo);
|
||||
}
|
||||
void GLMesh::updateVBOIBO(bool dynamicVB) {
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo);
|
||||
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ibo);
|
||||
int bytesv = 0;
|
||||
if (firstTimeBO) {
|
||||
//if (!((vertices.size() > 0) && (indices.size() > 0) && (normals.size() == 0) && (texCoords.size() > 0) && (colors.size() > 0))) {
|
||||
// // Only support pos, texcoord, color, no normal for now :P
|
||||
// exit(-129);
|
||||
//}
|
||||
bytesv = vertices.size()*sizeof(float)*(3); //position 3, color 3, tex coord 2
|
||||
withColor = (colors.size() != 0);
|
||||
withTexture = (texCoords.size() != 0);
|
||||
withNormal = (normals.size() != 0);
|
||||
withTangent = (tangents.size() != 0) && (bitangents.size() != 0);
|
||||
if (withColor) bytesv += vertices.size()*sizeof(float)*(3);
|
||||
if (withTexture) bytesv += vertices.size()*sizeof(float)*(2);
|
||||
if (withNormal) bytesv += vertices.size()*sizeof(float)*(3);
|
||||
if (withTangent) bytesv += vertices.size()*sizeof(float)*(6);
|
||||
|
||||
vector<char> dummy(bytesv, 0);
|
||||
|
||||
|
||||
if (dynamicVB) {
|
||||
glBufferDataARB(GL_ARRAY_BUFFER_ARB, bytesv, (const void*)&dummy[0], GL_DYNAMIC_DRAW_ARB);
|
||||
} else {
|
||||
//glBufferDataARB(GL_ARRAY_BUFFER_ARB, bytesv, (const void*)&dummy[0], GL_STATIC_DRAW_ARB);
|
||||
}
|
||||
|
||||
int bytesi = indices.size()*sizeof(PxU32);
|
||||
|
||||
dummy.resize(bytesi, 0);
|
||||
glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, bytesi, (const void*)&indices[0], GL_STATIC_DRAW_ARB); // index never change
|
||||
firstTimeBO = 0;
|
||||
|
||||
}
|
||||
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
|
||||
|
||||
|
||||
float* vb = 0;
|
||||
|
||||
if (dynamicVB) vb = (float*)glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); else {
|
||||
vb = new float[bytesv / sizeof(float)];
|
||||
|
||||
}
|
||||
|
||||
|
||||
int numV = vertices.size();
|
||||
int pos = 0;
|
||||
|
||||
|
||||
memcpy(vb, &vertices[0], sizeof(PxVec3)*numV);
|
||||
pos+=3*numV;
|
||||
|
||||
if (withColor) {
|
||||
memcpy(&vb[pos], &colors[0], sizeof(PxVec3)*numV);
|
||||
pos+=3*numV;
|
||||
}
|
||||
|
||||
if (withTexture) {
|
||||
memcpy(&vb[pos], &texCoords[0], sizeof(float)*numV*2);
|
||||
pos+=2*numV;
|
||||
}
|
||||
|
||||
if (withNormal) {
|
||||
memcpy(&vb[pos], &normals[0], sizeof(float)*numV*3);
|
||||
pos+=3*numV;
|
||||
}
|
||||
|
||||
|
||||
if (withTangent) {
|
||||
|
||||
memcpy(&vb[pos], &tangents[0], sizeof(float)*numV*3);
|
||||
pos+=3*numV;
|
||||
memcpy(&vb[pos], &bitangents[0], sizeof(float)*numV*3);
|
||||
pos+=3*numV;
|
||||
}
|
||||
if (dynamicVB) {
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER_ARB);
|
||||
} else {
|
||||
glBufferDataARB(GL_ARRAY_BUFFER_ARB, bytesv, (const void*)vb, GL_STATIC_DRAW_ARB);
|
||||
delete vb;
|
||||
|
||||
}
|
||||
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
|
||||
|
||||
}
|
||||
void GLMesh::drawVBOIBO(bool enable, bool draw, bool disable, bool drawpoints) {
|
||||
|
||||
if ((vbo == 0) || (ibo == 0)) return;
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo);
|
||||
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ibo);
|
||||
|
||||
|
||||
// Only support pos, texcoord, color, no normal for now :P
|
||||
int numV = vertices.size();
|
||||
if(enable) glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glVertexPointer(3, GL_FLOAT, sizeof(PxVec3), 0);
|
||||
GLuint pos = 3*sizeof(float)*numV;
|
||||
if (withColor) {
|
||||
if(enable) glEnableClientState(GL_COLOR_ARRAY);
|
||||
glColorPointer(3, GL_FLOAT, 0, (const GLvoid*) (pos));
|
||||
pos+=3*sizeof(float)*numV;
|
||||
}
|
||||
if (withTexture) {
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
if(enable) glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, (const GLvoid*) (pos));
|
||||
pos+=2*sizeof(float)*numV;
|
||||
}
|
||||
if (withNormal) {
|
||||
if(enable) glEnableClientState(GL_NORMAL_ARRAY);
|
||||
glNormalPointer(GL_FLOAT, sizeof(PxVec3), (const GLvoid*) (pos));
|
||||
pos+=3*sizeof(float)*numV;
|
||||
}
|
||||
|
||||
if (withTangent) {
|
||||
|
||||
|
||||
glClientActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
if(enable) {
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
glTexCoordPointer(3, GL_FLOAT, 0, (const GLvoid*) (pos));
|
||||
pos+=3*sizeof(float)*numV;
|
||||
glClientActiveTextureARB(GL_TEXTURE2_ARB);
|
||||
if(enable) {
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
glTexCoordPointer(3, GL_FLOAT, 0, (const GLvoid*) (pos));
|
||||
pos+=3*sizeof(float)*numV;
|
||||
}
|
||||
|
||||
if (draw) {
|
||||
if (!drawpoints) {
|
||||
glDrawElements(elementType, indices.size(), GL_UNSIGNED_INT, 0);
|
||||
} else {
|
||||
glDrawArrays(GL_POINTS, 0, numV);
|
||||
}
|
||||
}
|
||||
|
||||
if (disable) {
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
glClientActiveTextureARB(GL_TEXTURE2_ARB);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glClientActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
|
||||
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void GLMesh::draw() {
|
||||
if ((vertices.size() > 0) && (indices.size() > 0)) {
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glVertexPointer(3, GL_FLOAT, sizeof(PxVec3), &vertices[0]);
|
||||
|
||||
if (normals.size() > 0) {
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
glNormalPointer(GL_FLOAT, sizeof(PxVec3), &normals[0]);
|
||||
}
|
||||
|
||||
if (texCoords.size() > 0) {
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, &texCoords[0]);
|
||||
}
|
||||
|
||||
if (colors.size() > 0) {
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
glColorPointer(3, GL_FLOAT, 0, &colors[0]);
|
||||
}
|
||||
|
||||
//if (mTexId > 0) {
|
||||
// glColor3f(1.0f, 1.0f, 1.0f);
|
||||
// glEnable(GL_TEXTURE_2D);
|
||||
// glBindTexture(GL_TEXTURE_2D, mTexId);
|
||||
//}
|
||||
//else {
|
||||
// glColor3f(0.5f, 0.5f, 0.5f);
|
||||
// glDisable(GL_TEXTURE_2D);
|
||||
//}
|
||||
|
||||
glDrawElements(elementType, indices.size(), GL_UNSIGNED_INT, &indices[0]);
|
||||
}
|
||||
if (texCoords.size() > 0) {
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
if (colors.size() > 0) {
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
}
|
||||
if (rawVertices.size() > 0) {
|
||||
// Also draw raw buffer
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glVertexPointer(3, GL_FLOAT, sizeof(PxVec3), &rawVertices[0]);
|
||||
if (rawNormals.size() > 0) {
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
glNormalPointer(GL_FLOAT, sizeof(PxVec3), &rawNormals[0]);
|
||||
}
|
||||
glDrawArrays(elementType, 0, rawVertices.size());
|
||||
|
||||
|
||||
}
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
|
||||
|
||||
//glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
//glDisable(GL_TEXTURE_2D);
|
||||
|
||||
|
||||
}
|
||||
|
||||
68
kaplademo/source/demoFramework/Render/glmesh.h
Normal file
68
kaplademo/source/demoFramework/Render/glmesh.h
Normal file
@ -0,0 +1,68 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#ifndef __GLMESH_H__
|
||||
#define __GLMESH_H__
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include "PxPhysics.h"
|
||||
#include <vector>
|
||||
using namespace physx;
|
||||
class GLMesh{
|
||||
public:
|
||||
GLMesh(GLuint elementTypei = GL_TRIANGLES);
|
||||
~GLMesh();
|
||||
void draw();
|
||||
|
||||
// For indices
|
||||
std::vector<PxU32> indices;
|
||||
std::vector<PxVec3> vertices;
|
||||
std::vector<PxVec3> normals;
|
||||
std::vector<PxVec3> colors;
|
||||
std::vector<float> texCoords; // treats as u v
|
||||
std::vector<PxVec3> tangents;
|
||||
std::vector<PxVec3> bitangents;
|
||||
|
||||
// For raw
|
||||
std::vector<PxVec3> rawVertices;
|
||||
std::vector<PxVec3> rawNormals;
|
||||
|
||||
void reset();
|
||||
void genVBOIBO();
|
||||
void updateVBOIBO(bool dynamicVB = true);
|
||||
void drawVBOIBO(bool enable = true, bool draw = true, bool disable = true, bool drawpoints = false);
|
||||
|
||||
// For vertex buffer
|
||||
GLuint vbo;
|
||||
GLuint ibo;
|
||||
bool firstTimeBO;
|
||||
bool withTexture, withColor, withNormal, withTangent;
|
||||
GLuint elementType;
|
||||
|
||||
|
||||
};
|
||||
#endif
|
||||
73
kaplademo/source/demoFramework/Render/newParameters.cpp
Normal file
73
kaplademo/source/demoFramework/Render/newParameters.cpp
Normal file
@ -0,0 +1,73 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
float seedDustRadius = 0.02f;
|
||||
//float seedDustNumPerSite = 15;
|
||||
//float seedDustNumPerSiteCollisionEvent = 3;
|
||||
float seedDustNumPerSite = 20;
|
||||
float seedDustNumPerSiteCollisionEvent = 4.5f;
|
||||
|
||||
float applyForcePointAreaPerSample = 0.005f;
|
||||
float applyForceFromPointsDrag = 0.1f;
|
||||
//float noise3DScale = 1.5f;
|
||||
//float noise2DScale = 0.5f;
|
||||
float noiseKIsoDecay = 0.99f;
|
||||
float noiseKAniDecay = 0.99f;
|
||||
float noise3DScale = 0.75f*0.5f;
|
||||
float noise2DScale = 0.32f*0.5f;
|
||||
float dustMaxLife = 5.0f;
|
||||
float dustMinLife = 1.0f;
|
||||
float dustParticleOpacity = 0.1f;
|
||||
float dustParticleRenderRadius = 0.1f;
|
||||
float particleStartFade = 5.0f;
|
||||
float octaveScaling = 7.0f;
|
||||
float divStrength = 5.0f;
|
||||
float curDivStrength = 0.0f;
|
||||
float divStrengthReductionRate = 8.0f/30;
|
||||
|
||||
bool doGaussianBlur = false;
|
||||
float blurVelSigmaFDX = 1.0f;
|
||||
float blurVelCenterFactor = 30.0f;
|
||||
float curlScale = 10.0f;
|
||||
|
||||
float areaPerDustSample = 0.005f;
|
||||
float areaPerDebris = 0.02f;
|
||||
|
||||
float minSizeDecayRate = 1.0f;
|
||||
float explodeVel = 3.0f;
|
||||
float numParPerMeteor = 3;
|
||||
|
||||
float minMeteorDustLife = 2.0f;
|
||||
float maxMeteorDustLife = 2.3f;
|
||||
float minMeteorDustSize = 0.5f;
|
||||
float maxMeteorDustSize = 1.5f;
|
||||
float minMeteorSizeDecayRate = 1.0f;
|
||||
|
||||
int maxNumDebrisPerType = 500; // Maximum number of debris per each type of debris
|
||||
float sleepingThresholdRB = 0.1f;
|
||||
float sleepingThresholdParticles = 0.1f;
|
||||
int maxNumDebrisToAdd = 100;
|
||||
69
kaplademo/source/demoFramework/Render/newParameters.h
Normal file
69
kaplademo/source/demoFramework/Render/newParameters.h
Normal file
@ -0,0 +1,69 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
extern float seedDustRadius;
|
||||
extern float seedDustNumPerSite;
|
||||
extern float seedDustNumPerSiteCollisionEvent;
|
||||
extern float applyForcePointAreaPerSample;
|
||||
extern float applyForceFromPointsDrag;
|
||||
extern float noiseKIsoDecay;
|
||||
extern float noiseKAniDecay;
|
||||
extern float noise3DScale;
|
||||
extern float noise2DScale;
|
||||
extern float dustMaxLife;
|
||||
extern float dustMinLife;
|
||||
extern float dustParticleOpacity;
|
||||
extern float dustParticleRenderRadius;
|
||||
extern float particleStartFade;
|
||||
extern float octaveScaling;
|
||||
extern float divStrength;
|
||||
extern float curDivStrength;
|
||||
extern float divStrengthReductionRate;
|
||||
|
||||
|
||||
extern bool doGaussianBlur;
|
||||
extern float blurVelSigmaFDX;
|
||||
extern float blurVelCenterFactor;
|
||||
extern float curlScale;
|
||||
extern float areaPerDustSample;
|
||||
extern float areaPerDebris;
|
||||
extern float minSizeDecayRate;
|
||||
|
||||
extern float explodeVel; // Velocity of debris
|
||||
extern float numParPerMeteor;
|
||||
|
||||
extern float minMeteorDustLife;
|
||||
extern float maxMeteorDustLife;
|
||||
extern float minMeteorDustSize;
|
||||
extern float maxMeteorDustSize;
|
||||
|
||||
extern int maxNumDebrisPerType;
|
||||
extern float sleepingThresholdRB;
|
||||
extern float sleepingThresholdParticles;
|
||||
extern int maxNumDebrisToAdd;
|
||||
extern float minMeteorSizeDecayRate;
|
||||
107
kaplademo/source/demoFramework/RenderTarget.cpp
Normal file
107
kaplademo/source/demoFramework/RenderTarget.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#include "RenderTarget.h"
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------------------
|
||||
RenderTarget::RenderTarget(int width, int height)
|
||||
{
|
||||
mColorTexId = 0;
|
||||
mDepthTexId = 0;
|
||||
mFBO = NULL;
|
||||
|
||||
resize(width, height);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------
|
||||
void RenderTarget::clear()
|
||||
{
|
||||
if (mColorTexId > 0) {
|
||||
glDeleteTextures(1, &mColorTexId);
|
||||
mColorTexId = 0;
|
||||
}
|
||||
if (mDepthTexId > 0) {
|
||||
glDeleteTextures(1, &mDepthTexId);
|
||||
mDepthTexId = 0;
|
||||
}
|
||||
if (mFBO)
|
||||
delete mFBO;
|
||||
|
||||
mFBO = NULL;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------
|
||||
RenderTarget::~RenderTarget()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------
|
||||
GLuint RenderTarget::createTexture(GLenum target, int width, int height, GLint internalFormat, GLenum format)
|
||||
{
|
||||
GLuint texid;
|
||||
glGenTextures(1, &texid);
|
||||
glBindTexture(target, texid);
|
||||
|
||||
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
glTexImage2D(target, 0, internalFormat, width, height, 0, format, GL_FLOAT, 0);
|
||||
return texid;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------
|
||||
void RenderTarget::resize(int width, int height)
|
||||
{
|
||||
clear();
|
||||
mFBO = new FrameBufferObject();
|
||||
mColorTexId = createTexture(GL_TEXTURE_RECTANGLE_ARB, width, height, GL_RGBA8, GL_RGBA);
|
||||
mDepthTexId = createTexture(GL_TEXTURE_RECTANGLE_ARB, width, height, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------
|
||||
void RenderTarget::beginCapture()
|
||||
{
|
||||
mFBO->Bind();
|
||||
mFBO->AttachTexture(GL_TEXTURE_RECTANGLE_ARB, mColorTexId, GL_COLOR_ATTACHMENT0_EXT);
|
||||
mFBO->AttachTexture(GL_TEXTURE_RECTANGLE_ARB, mDepthTexId, GL_DEPTH_ATTACHMENT_EXT);
|
||||
mFBO->IsValid();
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------
|
||||
void RenderTarget::endCapture()
|
||||
{
|
||||
mFBO->AttachTexture(GL_TEXTURE_RECTANGLE_ARB, 0, GL_COLOR_ATTACHMENT0_EXT);
|
||||
mFBO->AttachTexture(GL_TEXTURE_RECTANGLE_ARB, 0, GL_DEPTH_ATTACHMENT_EXT);
|
||||
mFBO->Disable();
|
||||
}
|
||||
|
||||
|
||||
|
||||
58
kaplademo/source/demoFramework/RenderTarget.h
Normal file
58
kaplademo/source/demoFramework/RenderTarget.h
Normal file
@ -0,0 +1,58 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#ifndef RENDER_TARGET
|
||||
#define RENDER_TARGET
|
||||
|
||||
#include "FrameBufferObject.h"
|
||||
|
||||
// -------------------------------------------------------------------------------------------
|
||||
class RenderTarget
|
||||
{
|
||||
public:
|
||||
RenderTarget(int width, int height);
|
||||
~RenderTarget();
|
||||
|
||||
void resize(int width, int height);
|
||||
|
||||
void beginCapture();
|
||||
void endCapture();
|
||||
|
||||
GLuint getColorTexId() { return mColorTexId; }
|
||||
GLuint getDepthTexId() { return mDepthTexId; }
|
||||
|
||||
private:
|
||||
void clear();
|
||||
GLuint createTexture(GLenum target, int width, int height, GLint internalFormat, GLenum format);
|
||||
|
||||
GLuint mColorTexId;
|
||||
GLuint mDepthTexId;
|
||||
|
||||
FrameBufferObject *mFBO;
|
||||
};
|
||||
|
||||
#endif
|
||||
426
kaplademo/source/demoFramework/SSAOHelper.cpp
Normal file
426
kaplademo/source/demoFramework/SSAOHelper.cpp
Normal file
@ -0,0 +1,426 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#include "SSAOHelper.h"
|
||||
#include "foundation/PxMat44.h"
|
||||
const char *ssaoFilterVS = STRINGIFY(
|
||||
void main(void)
|
||||
{
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
gl_Position = gl_Vertex * 2.0 - 1.0;
|
||||
}
|
||||
);
|
||||
|
||||
const char *ssaoFilterHFS = STRINGIFY(
|
||||
uniform sampler2D ssaoTex;
|
||||
uniform float sx;
|
||||
|
||||
void main (void)
|
||||
{
|
||||
float SSAO = 0.0;
|
||||
|
||||
for(int x = -2; x <= 2; x++)
|
||||
{
|
||||
SSAO += texture2D(ssaoTex,vec2(x * sx + gl_TexCoord[0].s,gl_TexCoord[0].t)).r * (3.0 - abs(float(x)));
|
||||
}
|
||||
|
||||
gl_FragColor = vec4(vec3(SSAO / 9.0),1.0);
|
||||
gl_FragColor.w = gl_FragColor.x;
|
||||
}
|
||||
);
|
||||
|
||||
const char *ssaoFilterVFS = STRINGIFY(
|
||||
uniform sampler2D ssaoTex;
|
||||
uniform float sy;
|
||||
|
||||
void main (void)
|
||||
{
|
||||
|
||||
float SSAO = 0.0;
|
||||
|
||||
for(int y = -2; y <= 2; y++)
|
||||
{
|
||||
SSAO += texture2D(ssaoTex,vec2(gl_TexCoord[0].s,y * sy + gl_TexCoord[0].t)).r * (3.0 - abs(float(y)));
|
||||
}
|
||||
|
||||
gl_FragColor = vec4(vec3(pow((SSAO / 9.0),1.5)),1.0);
|
||||
gl_FragColor.w = gl_FragColor.x;
|
||||
//gl_FragColor = vec4(1,1,1,1);
|
||||
}
|
||||
);
|
||||
SSAOHelper::SSAOHelper(float fov,float padding,float zNear,float zFar, const char* resourcePath, float scale) : fov(fov),padding(padding),zNear(zNear),zFar(zFar), scale(scale) {
|
||||
|
||||
char ssaoVSF[5000];
|
||||
char ssaoFSF[5000];
|
||||
sprintf(ssaoVSF, "%s\\ssao.vs", resourcePath);
|
||||
sprintf(ssaoFSF, "%s\\ssao.fs", resourcePath);
|
||||
SSAOFilterH.loadShaderCode(ssaoFilterVS,ssaoFilterHFS);
|
||||
SSAOFilterV.loadShaderCode(ssaoFilterVS,ssaoFilterVFS);
|
||||
SSAO.loadShaders(ssaoVSF,ssaoFSF);
|
||||
|
||||
glUseProgram(SSAO);
|
||||
glUniform1i(glGetUniformLocation(SSAO,"depthTex"),0);
|
||||
glUniform1i(glGetUniformLocation(SSAO,"normalTex"),1);
|
||||
glUniform1i(glGetUniformLocation(SSAO,"unitVecTex"),2);
|
||||
glUseProgram(0);
|
||||
// srand(GetTickCount());
|
||||
|
||||
glGenTextures(1,&unitVecTex);
|
||||
|
||||
PxVec3 *RandomUnitVectorsTextureData = new PxVec3[64 * 64];
|
||||
|
||||
for(int i = 0; i < 64 * 64; i++)
|
||||
{
|
||||
RandomUnitVectorsTextureData[i].x = (float)rand() / (float)RAND_MAX * 2.0f - 1.0f;
|
||||
RandomUnitVectorsTextureData[i].y = (float)rand() / (float)RAND_MAX * 2.0f - 1.0f;
|
||||
RandomUnitVectorsTextureData[i].z = (float)rand() / (float)RAND_MAX * 2.0f - 1.0f;
|
||||
|
||||
|
||||
RandomUnitVectorsTextureData[i].normalize();
|
||||
|
||||
RandomUnitVectorsTextureData[i] = RandomUnitVectorsTextureData[i] * 0.5f + PxVec3(0.5f,0.5f,0.5f);
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D,unitVecTex);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
|
||||
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA8,64,64,0,GL_RGB,GL_FLOAT,RandomUnitVectorsTextureData);
|
||||
|
||||
delete [] RandomUnitVectorsTextureData;
|
||||
|
||||
|
||||
PxVec3 *samples = new PxVec3[NUMSAMPLES];
|
||||
|
||||
float alfa = physx::PxPi / SAMPLEDIV,beta = physx::PxPiDivTwo / (SAMPLEDIV * 2.0f),radius = 0.5f;
|
||||
|
||||
for(int i = 0; i < NUMSAMPLES; i++)
|
||||
{
|
||||
samples[i] = PxVec3(cos(alfa),sin(alfa),sin(beta));
|
||||
samples[i].normalize();
|
||||
samples[i] *= ((float)NUMSAMPLES - i) / ((float)NUMSAMPLES);
|
||||
samples[i] *= radius;
|
||||
|
||||
alfa += physx::PxPi / (SAMPLEDIV / 2);
|
||||
|
||||
if(((i + 1) % SAMPLEDIV) == 0)
|
||||
{
|
||||
alfa += physx::PxPi / SAMPLEDIV;
|
||||
beta += physx::PxPiDivTwo / SAMPLEDIV;
|
||||
}
|
||||
}
|
||||
|
||||
glUseProgram(SSAO);
|
||||
glUniform3fv(glGetUniformLocation(SSAO,"samples"),NUMSAMPLES,(GLfloat*)samples);
|
||||
glUseProgram(0);
|
||||
|
||||
delete [] samples;
|
||||
|
||||
glGenTextures(1,&normalTex);
|
||||
glGenTextures(1,&depthTex);
|
||||
glGenTextures(1,&ssaoTex);
|
||||
glGenTextures(1,&blurTex);
|
||||
|
||||
glGenFramebuffers(1,&FBO);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
PxMat44 PerspectiveProjectionMatrixInverse(PxMat44 &PPM)
|
||||
{
|
||||
float PPMI[16];
|
||||
|
||||
PPMI[0] = 1.0f / PPM.column0.x;
|
||||
PPMI[1] = 0.0f;
|
||||
PPMI[2] = 0.0f;
|
||||
PPMI[3] = 0.0f;
|
||||
|
||||
PPMI[4] = 0.0f;
|
||||
PPMI[5] = 1.0f / PPM.column1.y;
|
||||
PPMI[6] = 0.0f;
|
||||
PPMI[7] = 0.0f;
|
||||
|
||||
PPMI[8] = 0.0f;
|
||||
PPMI[9] = 0.0f;
|
||||
PPMI[10] = 0.0f;
|
||||
PPMI[11] = 1.0f / PPM.column3.z;
|
||||
|
||||
PPMI[12] = 0.0f;
|
||||
PPMI[13] = 0.0f;
|
||||
PPMI[14] = 1.0f / PPM.column2.w;
|
||||
PPMI[15] = - PPM.column2.z / (PPM.column2.w * PPM.column3.z);
|
||||
|
||||
return PxMat44(PPMI);
|
||||
}
|
||||
PxMat44 BiasMatrix()
|
||||
{
|
||||
float BM[16];
|
||||
|
||||
BM[0] = 0.5f; BM[4] = 0.0f; BM[8] = 0.0f; BM[12] = 0.5f;
|
||||
BM[1] = 0.0f; BM[5] = 0.5f; BM[9] = 0.0f; BM[13] = 0.5f;
|
||||
BM[2] = 0.0f; BM[6] = 0.0f; BM[10] = 0.5f; BM[14] = 0.5f;
|
||||
BM[3] = 0.0f; BM[7] = 0.0f; BM[11] = 0.0f; BM[15] = 1.0f;
|
||||
|
||||
return PxMat44(BM);
|
||||
}
|
||||
|
||||
PxMat44 BiasMatrixInverse()
|
||||
{
|
||||
float BMI[16];
|
||||
|
||||
BMI[0] = 2.0f; BMI[4] = 0.0f; BMI[8] = 0.0f; BMI[12] = -1.0f;
|
||||
BMI[1] = 0.0f; BMI[5] = 2.0f; BMI[9] = 0.0f; BMI[13] = -1.0f;
|
||||
BMI[2] = 0.0f; BMI[6] = 0.0f; BMI[10] = 2.0f; BMI[14] = -1.0f;
|
||||
BMI[3] = 0.0f; BMI[7] = 0.0f; BMI[11] = 0.0f; BMI[15] = 1.0f;
|
||||
|
||||
return PxMat44(BMI);
|
||||
}
|
||||
void SSAOHelper::Resize(int w,int h) {
|
||||
realWidth = w;
|
||||
realHeight = h;
|
||||
Width = w*scale;
|
||||
Height = h*scale;
|
||||
|
||||
fovPad = 2.0f*atan(tan(fov*0.5f*physx::PxPi/180.0f)*(1.0f+padding))*180.0f/physx::PxPi;
|
||||
|
||||
SWidth = Width*(1.0f+padding);
|
||||
SHeight = Height*(1.0f+padding);
|
||||
|
||||
glViewport(0,0,SWidth,SHeight);
|
||||
|
||||
PxMat44 mat();
|
||||
PxMat44 Projection = PerspectiveProjectionMatrix(fovPad,SWidth,SHeight,zNear,zFar);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadMatrixf(&Projection.column0.x);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D,normalTex);
|
||||
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,SWidth,SHeight,0,GL_RGBA,GL_UNSIGNED_BYTE,NULL);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D,depthTex);
|
||||
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_COMPONENT32,SWidth,SHeight,0,GL_DEPTH_COMPONENT,GL_FLOAT,NULL);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D,ssaoTex);
|
||||
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,SWidth,SHeight,0,GL_RGBA,GL_UNSIGNED_BYTE,NULL);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D,blurTex);
|
||||
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,SWidth,SHeight,0,GL_RGBA,GL_UNSIGNED_BYTE,NULL);
|
||||
|
||||
PxMat44 biasProjMat = BiasMatrix() * Projection;
|
||||
PxMat44 biasProjMatInv = PerspectiveProjectionMatrixInverse(Projection) * BiasMatrixInverse();
|
||||
|
||||
glUseProgram(SSAO);
|
||||
glUniformMatrix4fv(glGetUniformLocation(SSAO,"biasProjMat"),1,GL_FALSE,&biasProjMat.column0.x);
|
||||
glUniformMatrix4fv(glGetUniformLocation(SSAO,"biasProjMatInv"),1,GL_FALSE,&biasProjMatInv.column0.x);
|
||||
glUniform2f(glGetUniformLocation(SSAO,"scaleXY"),(float)SWidth / 64.0f,(float)SHeight / 64.0f);
|
||||
|
||||
glUseProgram(SSAOFilterH);
|
||||
glUniform1f(glGetUniformLocation(SSAOFilterH,"sx"),1.0f / (float)SWidth);
|
||||
|
||||
glUseProgram(SSAOFilterV);
|
||||
glUniform1f(glGetUniformLocation(SSAOFilterV,"sy"),1.0f / (float)SHeight);
|
||||
|
||||
glUseProgram(0);
|
||||
|
||||
}
|
||||
void SSAOHelper::Destroy() {
|
||||
|
||||
SSAO.deleteShaders();
|
||||
SSAOFilterH.deleteShaders();
|
||||
SSAOFilterV.deleteShaders();
|
||||
|
||||
glDeleteTextures(1,&unitVecTex);
|
||||
glDeleteTextures(1,&normalTex);
|
||||
glDeleteTextures(1,&depthTex);
|
||||
glDeleteTextures(1,&ssaoTex);
|
||||
glDeleteTextures(1,&blurTex);
|
||||
glDeleteFramebuffers(1,&FBO);
|
||||
}
|
||||
|
||||
void SSAOHelper::DoSSAO(void (*renderScene)(), GLuint oldFBO) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER,FBO);
|
||||
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D,normalTex,0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,GL_TEXTURE_2D,depthTex,0);
|
||||
|
||||
glViewport(0,0,SWidth,SHeight);
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
|
||||
PxMat44 Projection = PerspectiveProjectionMatrix(fovPad,SWidth,SHeight,zNear,zFar);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadMatrixf(&Projection.column0.x);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_CULL_FACE);
|
||||
renderScene();
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
// if(Blur)
|
||||
// {
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D,ssaoTex,0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,GL_TEXTURE_2D,0,0);
|
||||
|
||||
glClearColor(0.0f,0.0f,0.0f,1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// glBindFramebuffer(GL_FRAMEBUFFER,0);
|
||||
// }
|
||||
|
||||
glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D,depthTex);
|
||||
glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D,normalTex);
|
||||
glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D,unitVecTex);
|
||||
|
||||
glUseProgram(SSAO);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2f(0.0f,0.0f);
|
||||
glVertex2f(1.0f,0.0f);
|
||||
glVertex2f(1.0f,1.0f);
|
||||
glVertex2f(0.0f,1.0f);
|
||||
glEnd();
|
||||
|
||||
glUseProgram(0);
|
||||
|
||||
glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D,0);
|
||||
glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D,0);
|
||||
glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D,0);
|
||||
|
||||
// if(Blur)
|
||||
{
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D,blurTex,0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,GL_TEXTURE_2D,0,0);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D,ssaoTex);
|
||||
|
||||
glUseProgram(SSAOFilterH);
|
||||
glUniform1f(glGetUniformLocation(SSAOFilterH, "sx"), 1.0f / (float)SWidth);
|
||||
|
||||
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
/*
|
||||
glTexCoord2f(0.0f+fx,0.0f+fy); glVertex2f(0.0f,0.0f);
|
||||
glTexCoord2f(1.0f-fx,0.0f+fy); glVertex2f(1.0f,0.0f);
|
||||
glTexCoord2f(1.0f-fx,1.0f-fy); glVertex2f(1.0f,1.0f);
|
||||
glTexCoord2f(0.0f+fx,1.0f-fy); glVertex2f(0.0f,1.0f);
|
||||
*/
|
||||
glTexCoord2f(0.0f,0.0f); glVertex2f(0.0f,0.0f);
|
||||
glTexCoord2f(1.0f,0.0f); glVertex2f(1.0f,0.0f);
|
||||
glTexCoord2f(1.0f,1.0f); glVertex2f(1.0f,1.0f);
|
||||
glTexCoord2f(0.0f,1.0f); glVertex2f(0.0f,1.0f);
|
||||
glEnd();
|
||||
|
||||
glUseProgram(0);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER,oldFBO);
|
||||
//glClearColor(0.0f,0.0f,0.0f,1.0f);
|
||||
//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_FALSE);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_ZERO, GL_SRC_ALPHA);
|
||||
|
||||
glViewport(0,0,realWidth,realHeight);
|
||||
|
||||
Projection = PerspectiveProjectionMatrix(fov,Width,Height,zNear,zFar);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadMatrixf(&Projection.column0.x);
|
||||
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D,blurTex);
|
||||
|
||||
glUseProgram(SSAOFilterV);
|
||||
glUniform1f(glGetUniformLocation(SSAOFilterV, "sy"), 1.0f / (float)SHeight);
|
||||
|
||||
//float fx = 0.5f*(1.0f-(((float)(SWidth-Width))/((float)Width)));
|
||||
//float fy = 0.5f*(1.0f-(((float)(SHeight-Height))/((float)Height)));
|
||||
float fx = 0.5f*((float)(SWidth-Width)) / ((float)SWidth);
|
||||
float fy = 0.5f*((float)(SHeight-Height)) / ((float)SHeight);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(0.0f+fx,0.0f+fy); glVertex2f(0.0f,0.0f);
|
||||
glTexCoord2f(1.0f-fx,0.0f+fy); glVertex2f(1.0f,0.0f);
|
||||
glTexCoord2f(1.0f-fx,1.0f-fy); glVertex2f(1.0f,1.0f);
|
||||
glTexCoord2f(0.0f+fx,1.0f-fy); glVertex2f(0.0f,1.0f);
|
||||
glEnd();
|
||||
|
||||
glUseProgram(0);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D,0);
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_TRUE);
|
||||
}
|
||||
}
|
||||
52
kaplademo/source/demoFramework/SSAOHelper.h
Normal file
52
kaplademo/source/demoFramework/SSAOHelper.h
Normal file
@ -0,0 +1,52 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
#include <GL/glew.h>
|
||||
#include "Shader.h"
|
||||
#define SAMPLEDIV 4
|
||||
#define NUMSAMPLES SAMPLEDIV*SAMPLEDIV
|
||||
|
||||
class SSAOHelper{
|
||||
public:
|
||||
int Width, Height;
|
||||
float padding;
|
||||
int SWidth, SHeight;
|
||||
float fov;
|
||||
float fovPad;
|
||||
float zNear, zFar;
|
||||
float scale;
|
||||
int realWidth, realHeight;
|
||||
|
||||
Shader SSAO, SSAOFilterH, SSAOFilterV;
|
||||
SSAOHelper(float fov, float padding, float zNear, float zFar, const char* resourcePath, float scale);
|
||||
void Resize(int w, int h);
|
||||
|
||||
void DoSSAO(void (*renderScene)(), GLuint oldFBO = 0);
|
||||
void Destroy();
|
||||
GLuint FBO, unitVecTex, normalTex, depthTex, ssaoTex, blurTex;
|
||||
};
|
||||
777
kaplademo/source/demoFramework/Shader.cpp
Normal file
777
kaplademo/source/demoFramework/Shader.cpp
Normal file
@ -0,0 +1,777 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#include "Shader.h"
|
||||
#include <assert.h>
|
||||
//#define NOMINMAX
|
||||
#include <windows.h>
|
||||
|
||||
#include "foundation/PxMat44.h"
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
Shader::Shader()
|
||||
{
|
||||
mVertexShaderSource = NULL;
|
||||
mVertexShaderSourceLength = 0;
|
||||
|
||||
mGeometryShaderSource = NULL;
|
||||
mGeometryShaderSourceLength = 0;
|
||||
|
||||
mFragmentShaderSource = NULL;
|
||||
mFragmentShaderSourceLength = 0;
|
||||
|
||||
mShaderProgram = 0;
|
||||
mVertexShader = 0;
|
||||
mGeometryShader = 0;
|
||||
mFragmentShader = 0;
|
||||
|
||||
mErrorMessage = "";
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
bool Shader::loadShaders(const char* vertexShaderFile, const char* fragmentShaderFile)
|
||||
{
|
||||
mErrorMessage = "";
|
||||
|
||||
if (vertexShaderFile == NULL || fragmentShaderFile == NULL)
|
||||
return false;
|
||||
|
||||
if (!GLEW_VERSION_2_0)
|
||||
return false;
|
||||
|
||||
if (!loadFile(vertexShaderFile, mVertexShaderSource, mVertexShaderSourceLength)) {
|
||||
printf("Can't load vertex shader\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mGeometryShaderSource) {
|
||||
free(mGeometryShaderSource);
|
||||
mGeometryShaderSource = NULL;
|
||||
mGeometryShaderSourceLength = 0;
|
||||
}
|
||||
|
||||
if (!loadFile(fragmentShaderFile, mFragmentShaderSource, mFragmentShaderSourceLength)) {
|
||||
printf("Can't load fragment shader\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!compileShaders()) {
|
||||
printf("Can't compile shaders\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
findVariables();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
bool Shader::loadShaders(const char* vertexShaderFile, const char* geometryShaderFile, const char* fragmentShaderFile)
|
||||
{
|
||||
mErrorMessage = "";
|
||||
|
||||
if (vertexShaderFile == NULL || geometryShaderFile == NULL || fragmentShaderFile == NULL)
|
||||
return false;
|
||||
|
||||
if (!GLEW_VERSION_2_0)
|
||||
return false;
|
||||
|
||||
if (!loadFile(vertexShaderFile, mVertexShaderSource, mVertexShaderSourceLength))
|
||||
return false;
|
||||
|
||||
if (!loadFile(geometryShaderFile, mGeometryShaderSource, mGeometryShaderSourceLength))
|
||||
return false;
|
||||
|
||||
if (!loadFile(fragmentShaderFile, mFragmentShaderSource, mFragmentShaderSourceLength))
|
||||
return false;
|
||||
|
||||
if (!compileShaders())
|
||||
return false;
|
||||
|
||||
findVariables();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
bool Shader::loadShaderCode(const char* vertexShaderCode, const char* fragmentShaderCode)
|
||||
{
|
||||
/*
|
||||
mErrorMessage = "";
|
||||
|
||||
if (!GLEW_VERSION_2_0)
|
||||
return false;
|
||||
|
||||
size_t size;
|
||||
|
||||
if (mVertexShaderSource != NULL)
|
||||
free(mVertexShaderSource);
|
||||
|
||||
size = strlen(vertexShaderCode)+1;
|
||||
mVertexShaderSourceLength = size-1;
|
||||
mVertexShaderSource = (char*)malloc(size * sizeof(char));
|
||||
strcpy_s(mVertexShaderSource, size, vertexShaderCode);
|
||||
|
||||
if (mFragmentShaderSource != NULL)
|
||||
free(mFragmentShaderSource);
|
||||
|
||||
size = strlen(fragmentShaderCode)+1;
|
||||
mFragmentShaderSourceLength = size-1;
|
||||
mFragmentShaderSource = (char*)malloc(size * sizeof(char));
|
||||
strcpy_s(mFragmentShaderSource, size, fragmentShaderCode);
|
||||
|
||||
if (!compileShaders())
|
||||
return false;
|
||||
|
||||
findVariables();
|
||||
|
||||
return true;
|
||||
*/
|
||||
return loadShaderCode(vertexShaderCode, NULL, fragmentShaderCode);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
bool Shader::loadShaderCode(const char* vertexShaderCode, const char* geometryShaderCode, const char* fragmentShaderCode)
|
||||
{
|
||||
mErrorMessage = "";
|
||||
|
||||
if (!GLEW_VERSION_2_0)
|
||||
return false;
|
||||
|
||||
size_t size;
|
||||
|
||||
if (mVertexShaderSource != NULL)
|
||||
free(mVertexShaderSource);
|
||||
|
||||
size = strlen(vertexShaderCode)+1;
|
||||
mVertexShaderSourceLength = size-1;
|
||||
mVertexShaderSource = (char*)malloc(size * sizeof(char));
|
||||
strcpy_s(mVertexShaderSource, size, vertexShaderCode);
|
||||
|
||||
if (mFragmentShaderSource != NULL)
|
||||
free(mFragmentShaderSource);
|
||||
|
||||
if (mGeometryShaderSource != NULL) {
|
||||
free(mGeometryShaderSource);
|
||||
mGeometryShaderSource = NULL;
|
||||
}
|
||||
|
||||
if (geometryShaderCode) {
|
||||
size = strlen(geometryShaderCode)+1;
|
||||
mGeometryShaderSourceLength = size-1;
|
||||
mGeometryShaderSource = (char*)malloc(size * sizeof(char));
|
||||
strcpy_s(mGeometryShaderSource, size, geometryShaderCode);
|
||||
|
||||
}
|
||||
|
||||
if (mFragmentShaderSource != NULL)
|
||||
free(mFragmentShaderSource);
|
||||
|
||||
size = strlen(fragmentShaderCode)+1;
|
||||
mFragmentShaderSourceLength = size-1;
|
||||
mFragmentShaderSource = (char*)malloc(size * sizeof(char));
|
||||
strcpy_s(mFragmentShaderSource, size, fragmentShaderCode);
|
||||
|
||||
if (!compileShaders())
|
||||
return false;
|
||||
|
||||
findVariables();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
Shader::~Shader()
|
||||
{
|
||||
deleteShaders();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void Shader::deleteShaders()
|
||||
{
|
||||
glDetachShader(mShaderProgram, mVertexShader);
|
||||
glDeleteShader(mVertexShader);
|
||||
|
||||
glDetachShader(mShaderProgram, mFragmentShader);
|
||||
glDeleteShader(mFragmentShader);
|
||||
|
||||
|
||||
glDeleteProgram(mShaderProgram);
|
||||
|
||||
mVertexShader = 0;
|
||||
mFragmentShader = 0;
|
||||
mShaderProgram = 0;
|
||||
|
||||
free(mVertexShaderSource);
|
||||
free(mFragmentShaderSource);
|
||||
|
||||
mVertexShaderSource = NULL;
|
||||
mFragmentShaderSource = NULL;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
bool Shader::compileShaders()
|
||||
{
|
||||
if (mShaderProgram != 0) {
|
||||
glDetachShader(mShaderProgram, mVertexShader);
|
||||
glDeleteShader(mVertexShader);
|
||||
|
||||
|
||||
glDetachShader(mShaderProgram, mGeometryShader);
|
||||
glDeleteShader(mGeometryShader);
|
||||
|
||||
glDetachShader(mShaderProgram, mFragmentShader);
|
||||
glDeleteShader(mFragmentShader);
|
||||
|
||||
glDeleteProgram(mShaderProgram);
|
||||
|
||||
mVertexShader = 0;
|
||||
mGeometryShader = 0;
|
||||
mFragmentShader = 0;
|
||||
mShaderProgram = 0;
|
||||
}
|
||||
|
||||
bool ok = true;
|
||||
|
||||
mShaderProgram = glCreateProgram();
|
||||
mVertexShader = glCreateShader(GL_VERTEX_SHADER);
|
||||
if (mGeometryShaderSource) {
|
||||
mGeometryShader = glCreateShader(GL_GEOMETRY_SHADER_ARB);
|
||||
}
|
||||
mFragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
mGlShaderAttributes = 0;
|
||||
|
||||
const GLchar* sources[3];
|
||||
GLint lengths[3];
|
||||
|
||||
char header[128];
|
||||
sprintf_s(header, 128, "\n");
|
||||
sources[0] = header;
|
||||
lengths[0] = strlen(header);
|
||||
|
||||
char footer[2] = "\n";
|
||||
sources[2] = footer;
|
||||
lengths[2] = strlen(footer);
|
||||
|
||||
sources[1] = mVertexShaderSource;
|
||||
lengths[1] = mVertexShaderSourceLength;
|
||||
|
||||
glShaderSource(mVertexShader, 3, sources, lengths);
|
||||
glCompileShader(mVertexShader);
|
||||
|
||||
sources[1] = mFragmentShaderSource;
|
||||
lengths[1] = mFragmentShaderSourceLength;
|
||||
|
||||
glShaderSource(mFragmentShader, 3, sources, lengths);
|
||||
glCompileShader(mFragmentShader);
|
||||
|
||||
|
||||
if (mGeometryShaderSource) {
|
||||
sources[1] = mGeometryShaderSource;
|
||||
lengths[1] = mGeometryShaderSourceLength;
|
||||
|
||||
glShaderSource(mGeometryShader, 3, sources, lengths);
|
||||
glCompileShader(mGeometryShader);
|
||||
|
||||
}
|
||||
|
||||
// error checking
|
||||
int param;
|
||||
|
||||
glGetShaderiv(mVertexShader, GL_COMPILE_STATUS, ¶m);
|
||||
if (param != GL_TRUE) {
|
||||
getCompileError(mVertexShader);
|
||||
deleteShaders();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mGeometryShader) {
|
||||
glGetShaderiv(mGeometryShader, GL_COMPILE_STATUS, ¶m);
|
||||
if (param != GL_TRUE) {
|
||||
getCompileError(mGeometryShader);
|
||||
deleteShaders();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
glGetShaderiv(mFragmentShader, GL_COMPILE_STATUS, ¶m);
|
||||
if (param != GL_TRUE) {
|
||||
getCompileError(mFragmentShader);
|
||||
deleteShaders();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// link
|
||||
glAttachShader(mShaderProgram, mVertexShader);
|
||||
if (mGeometryShader) {
|
||||
GLenum gsInput = GL_POINTS;
|
||||
GLenum gsOutput = GL_TRIANGLE_STRIP;
|
||||
GLuint maxGSVOut = 4;
|
||||
glAttachShader(mShaderProgram, mGeometryShader);
|
||||
|
||||
glProgramParameteriEXT(mShaderProgram, GL_GEOMETRY_INPUT_TYPE_EXT, gsInput);
|
||||
glProgramParameteriEXT(mShaderProgram, GL_GEOMETRY_OUTPUT_TYPE_EXT, gsOutput);
|
||||
glProgramParameteriEXT(mShaderProgram, GL_GEOMETRY_VERTICES_OUT_EXT, maxGSVOut);
|
||||
}
|
||||
glAttachShader(mShaderProgram, mFragmentShader);
|
||||
|
||||
|
||||
glLinkProgram(mShaderProgram);
|
||||
glGetProgramiv(mShaderProgram, GL_LINK_STATUS, ¶m);
|
||||
|
||||
// check if program linked
|
||||
|
||||
if (!param) {
|
||||
char temp[4096];
|
||||
glGetProgramInfoLog(mShaderProgram, 4096, 0, temp);
|
||||
fprintf(stderr, "Failed to link program:\n%s\n", temp);
|
||||
//printf("..\n");
|
||||
getLinkError(mShaderProgram);
|
||||
printf(mErrorMessage.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void Shader::findVariables()
|
||||
{
|
||||
// Find uniforms
|
||||
GLint numUniforms, maxLength;
|
||||
mUniforms.clear();
|
||||
mAttributes.clear();
|
||||
glGetProgramiv(mShaderProgram, GL_ACTIVE_UNIFORMS, &numUniforms);
|
||||
glGetProgramiv(mShaderProgram, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLength);
|
||||
assert(maxLength < 256);
|
||||
char buf[256];
|
||||
|
||||
for (GLint i = 0; i < numUniforms; i++)
|
||||
{
|
||||
GLint length;
|
||||
UniformVariable u;
|
||||
glGetActiveUniform(mShaderProgram, i, 256, &length, &u.size, &u.type, buf);
|
||||
assert(length < 256);
|
||||
if (strncmp("gl_", buf, 3) != 0)
|
||||
{
|
||||
u.index = glGetUniformLocation(mShaderProgram, buf);
|
||||
mUniforms[buf] = u;
|
||||
}
|
||||
}
|
||||
|
||||
// Find attribs
|
||||
GLint numAttribs;
|
||||
glGetProgramiv(mShaderProgram, GL_ACTIVE_ATTRIBUTES, &numAttribs);
|
||||
glGetProgramiv(mShaderProgram, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxLength);
|
||||
assert(maxLength < 256);
|
||||
|
||||
for (GLint i = 0; i < numAttribs; i++)
|
||||
{
|
||||
GLint length;
|
||||
AttributeVariable a;
|
||||
glGetActiveAttrib(mShaderProgram, i, 256, &length, &a.size, &a.type, buf);
|
||||
if (strncmp("gl_", buf, 3) != 0)
|
||||
{
|
||||
a.index = glGetAttribLocation(mShaderProgram, buf);
|
||||
mAttributes[buf] = a;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strncmp("gl_Vertex", buf, 9) == 0)
|
||||
mGlShaderAttributes |= gl_VERTEX;
|
||||
else if (strncmp("gl_Normal", buf, 9) == 0)
|
||||
mGlShaderAttributes |= gl_NORMAL;
|
||||
else if (strncmp("gl_Color", buf, 8) == 0)
|
||||
mGlShaderAttributes |= gl_COLOR;
|
||||
else if (strncmp("gl_MultiTexCoord0", buf, 17) == 0)
|
||||
mGlShaderAttributes |= gl_TEXTURE;
|
||||
else if (strncmp("gl_MultiTexCoord1", buf, 17) == 0)
|
||||
mGlShaderAttributes |= gl_TEXTURE;
|
||||
else if (strncmp("gl_MultiTexCoord2", buf, 17) == 0)
|
||||
mGlShaderAttributes |= gl_TEXTURE;
|
||||
else if (strncmp("gl_MultiTexCoord3", buf, 17) == 0)
|
||||
mGlShaderAttributes |= gl_TEXTURE;
|
||||
else if (strncmp("gl_MultiTexCoord4", buf, 17) == 0)
|
||||
mGlShaderAttributes |= gl_TEXTURE;
|
||||
else if (strncmp("gl_MultiTexCoord5", buf, 17) == 0)
|
||||
mGlShaderAttributes |= gl_TEXTURE;
|
||||
else
|
||||
printf("Unknown gl attribute: %s\n", buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void Shader::getCompileError(GLuint shader)
|
||||
{
|
||||
int infoLogLength;
|
||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
|
||||
|
||||
if (infoLogLength > 1)
|
||||
{
|
||||
char* log = (char*)malloc(sizeof(char) * infoLogLength);
|
||||
int slen;
|
||||
glGetShaderInfoLog(shader, infoLogLength, &slen, log);
|
||||
|
||||
const GLubyte* vendor = glGetString(GL_VENDOR);
|
||||
const GLubyte* renderer = glGetString(GL_RENDERER);
|
||||
const GLubyte* version = glGetString(GL_VERSION);
|
||||
|
||||
printf("Compiler error\nVendor: %s\nRenderer: %s\nVersion: %s\nError: %s\n",
|
||||
vendor, renderer, version, log);
|
||||
|
||||
mErrorMessage = "compile error: ";
|
||||
mErrorMessage += std::string(log);
|
||||
free(log);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void Shader::getLinkError(GLuint shader)
|
||||
{
|
||||
int infoLogLength;
|
||||
glGetProgramiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
|
||||
|
||||
if (infoLogLength > 1)
|
||||
{
|
||||
char* log = (char*)malloc(sizeof(char) * infoLogLength);
|
||||
int slen;
|
||||
glGetProgramInfoLog(shader, infoLogLength, &slen, log);
|
||||
|
||||
//const GLubyte* vendor = glGetString(GL_VENDOR);
|
||||
//const GLubyte* renderer = glGetString(GL_RENDERER);
|
||||
//const GLubyte* version = glGetString(GL_VERSION);
|
||||
|
||||
//printf("Link Error:\nVendor: %s\nRenderer: %s\nVersion: %s\nError:\n%s\n",
|
||||
// vendor, renderer, version, log);
|
||||
|
||||
mErrorMessage = "link error: ";
|
||||
mErrorMessage += std::string(log);
|
||||
|
||||
free(log);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void Shader::activate(const ShaderMaterial &mat)
|
||||
{
|
||||
if (mShaderProgram == 0)
|
||||
return;
|
||||
|
||||
glUseProgram(mShaderProgram);
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void Shader::activate()
|
||||
{
|
||||
if (mShaderProgram == 0)
|
||||
return;
|
||||
|
||||
glUseProgram(mShaderProgram);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void Shader::deactivate()
|
||||
{
|
||||
if (mShaderProgram == 0)
|
||||
return;
|
||||
|
||||
GLint curProg;
|
||||
glGetIntegerv(GL_CURRENT_PROGRAM, &curProg);
|
||||
assert(curProg == mShaderProgram);
|
||||
|
||||
//for (tAttributes::iterator it = mAttributes.begin(); it != mAttributes.end(); ++it)
|
||||
//{
|
||||
// glDisableVertexAttribArray(it->second.index);
|
||||
//}
|
||||
//if (mGlShaderAttributes & gl_VERTEX)
|
||||
// glDisableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
//if (mGlShaderAttributes & gl_NORMAL)
|
||||
// glDisableClientState(GL_NORMAL_ARRAY);
|
||||
|
||||
//if (mGlShaderAttributes & gl_COLOR)
|
||||
// glDisableClientState(GL_COLOR_ARRAY);
|
||||
|
||||
//if (mGlShaderAttributes & gl_TEXTURE)
|
||||
// glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
bool Shader::isValid()
|
||||
{
|
||||
return mShaderProgram != 0;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
bool Shader::setUniform(const char *name, const PxMat33& value)
|
||||
{
|
||||
GLint uniform = getUniformCommon(name);
|
||||
if (uniform != -1)
|
||||
{
|
||||
float v[9];
|
||||
v[0] = value.column0.x; v[3] = value.column0.y; v[6] = value.column0.z;
|
||||
v[1] = value.column1.x; v[4] = value.column1.y; v[7] = value.column1.z;
|
||||
v[2] = value.column2.x; v[5] = value.column2.y; v[8] = value.column2.z;
|
||||
glUniformMatrix3fv(uniform, 1, false, v);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
bool Shader::setUniform(const char *name, const PxTransform& value)
|
||||
{
|
||||
GLint uniform = getUniformCommon(name);
|
||||
if (uniform != -1)
|
||||
{
|
||||
float v[16];
|
||||
PxMat44 v44 = value;
|
||||
v[0] = v44.column0.x; v[4] = v44.column0.y; v[8] = v44.column0.z; v[12] = v44.column0.w;
|
||||
v[1] = v44.column1.x; v[5] = v44.column1.y; v[9] = v44.column1.z; v[13] = v44.column1.w;
|
||||
v[2] = v44.column2.x; v[6] = v44.column2.y; v[10] = v44.column2.z; v[14] = v44.column2.w;
|
||||
v[3] = v44.column3.x; v[7] = v44.column3.y; v[11] = v44.column3.z; v[15] = v44.column3.w;
|
||||
glUniformMatrix4fv(uniform, 1, false, v);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
bool Shader::setUniform(const char *name, PxU32 size, const PxVec3* value)
|
||||
{
|
||||
GLint uniform = getUniformCommon(name);
|
||||
if (uniform != -1)
|
||||
{
|
||||
glUniform3fv(uniform, size, (const GLfloat*)value);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
bool Shader::setUniform1(const char* name, const float value)
|
||||
{
|
||||
GLint loc = glGetUniformLocation(mShaderProgram, name);
|
||||
if (loc >= 0) {
|
||||
glUniform1f(loc, value);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
bool Shader::setUniform2(const char* name, float val0, float val1)
|
||||
{
|
||||
GLint loc = glGetUniformLocation(mShaderProgram, name);
|
||||
if (loc >= 0) {
|
||||
glUniform2f(loc, val0, val1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
bool Shader::setUniform3(const char* name, float val0, float val1, float val2)
|
||||
{
|
||||
GLint loc = glGetUniformLocation(mShaderProgram, name);
|
||||
if (loc >= 0) {
|
||||
glUniform3f(loc, val0, val1, val2);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
bool Shader::setUniform4(const char* name, float val0, float val1, float val2, float val3)
|
||||
{
|
||||
GLint loc = glGetUniformLocation(mShaderProgram, name);
|
||||
if (loc >= 0) {
|
||||
glUniform4f(loc, val0, val1, val2, val3);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
bool Shader::setUniform(const char* name, float value)
|
||||
{
|
||||
GLint uniform = getUniformCommon(name);
|
||||
if (uniform != -1)
|
||||
{
|
||||
glUniform1f(uniform, value);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
bool Shader::setUniform(const char* name, int value)
|
||||
{
|
||||
GLint uniform = getUniformCommon(name);
|
||||
if (uniform != -1)
|
||||
{
|
||||
glUniform1i(uniform, value);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Shader::setUniformfv(const GLchar *name, GLfloat *v, int elementSize, int count)
|
||||
{
|
||||
GLint loc = glGetUniformLocation(mShaderProgram, name);//getUniformCommon( name);
|
||||
if (loc == -1) {
|
||||
return false;
|
||||
}
|
||||
switch (elementSize) {
|
||||
case 1:
|
||||
glUniform1fv(loc, count, v);
|
||||
break;
|
||||
case 2:
|
||||
glUniform2fv(loc, count, v);
|
||||
break;
|
||||
case 3:
|
||||
glUniform3fv(loc, count, v);
|
||||
break;
|
||||
case 4:
|
||||
glUniform4fv(loc, count, v);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
bool Shader::setAttribute(const char* name, PxU32 size, PxU32 stride, GLenum type, void* data)
|
||||
{
|
||||
GLint activeProgram;
|
||||
glGetIntegerv(GL_CURRENT_PROGRAM, &activeProgram);
|
||||
tAttributes::iterator it = mAttributes.find(name);
|
||||
if (it != mAttributes.end())
|
||||
{
|
||||
PxI32 index = it->second.index;
|
||||
glEnableVertexAttribArray(index);
|
||||
glVertexAttribPointer(index, size, type, GL_FALSE, stride, data);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
GLint Shader::getUniformCommon(const char* name)
|
||||
{
|
||||
GLint activeProgram;
|
||||
glGetIntegerv(GL_CURRENT_PROGRAM, &activeProgram);
|
||||
if (activeProgram == 0) return -1;
|
||||
tUniforms::iterator it = mUniforms.find(name);
|
||||
if (it != mUniforms.end())
|
||||
{
|
||||
assert(it->second.index != -1);
|
||||
return it->second.index;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
bool Shader::loadFile(const char* filename, char*& destination, int& destinationLength)
|
||||
{
|
||||
if (destination != NULL)
|
||||
{
|
||||
assert(destinationLength != 0);
|
||||
free(destination);
|
||||
destination = NULL;
|
||||
destinationLength = 0;
|
||||
}
|
||||
assert(destinationLength == 0);
|
||||
|
||||
FILE* file = NULL;
|
||||
file = fopen(filename, "rb");
|
||||
if (file == NULL)
|
||||
{
|
||||
mErrorMessage = "Shader file " + std::string(filename) + "not found\n";
|
||||
return false;
|
||||
}
|
||||
// find length
|
||||
fseek(file, 0, SEEK_END);
|
||||
destinationLength = ftell(file);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
|
||||
if (destinationLength > 0)
|
||||
{
|
||||
destination = (char*)malloc(destinationLength * sizeof(char) + 1);
|
||||
|
||||
fread(destination, 1, destinationLength, file);
|
||||
destination[destinationLength] = 0;
|
||||
}
|
||||
fclose(file);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
Shader::bindTexture(const char *name, GLuint tex, GLenum target, GLint unit)
|
||||
{
|
||||
GLint loc = getUniformCommon(name);
|
||||
if (loc >= 0) {
|
||||
glActiveTexture(GL_TEXTURE0 + unit);
|
||||
glBindTexture(target, tex);
|
||||
glUseProgram(mShaderProgram);
|
||||
glUniform1i(loc, unit);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
} else {
|
||||
#if _DEBUG
|
||||
fprintf(stderr, "Error binding texture '%s'\n", name);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Shader::setUniformMatrix4fv(const GLchar *name, const GLfloat *m, bool transpose)
|
||||
{
|
||||
GLint loc = getUniformCommon(name);
|
||||
if (loc >= 0) {
|
||||
glUniformMatrix4fv(loc, 1, transpose, m);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
173
kaplademo/source/demoFramework/Shader.h
Normal file
173
kaplademo/source/demoFramework/Shader.h
Normal file
@ -0,0 +1,173 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#ifndef SHADER_H
|
||||
#define SHADER_H
|
||||
|
||||
#include "foundation/PxVec3.h"
|
||||
#include "foundation/PxMat33.h"
|
||||
#include "foundation/PxTransform.h"
|
||||
|
||||
#include <GL/glew.h>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
using namespace physx;
|
||||
|
||||
#define STRINGIFY(A) #A
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
struct ShaderMaterial
|
||||
{
|
||||
void init(unsigned int texId = 0) {
|
||||
this->texId = texId;
|
||||
ambientCoeff = 0.0f;
|
||||
diffuseCoeff = 1.0f;
|
||||
specularCoeff = 0.0f;
|
||||
reflectionCoeff = 0.0f;
|
||||
refractionCoeff = 0.0f;
|
||||
shadowCoeff = 0.0f;
|
||||
color[0] = 1.0f; color[1] = 1.0f; color[2] = 1.0f; color[3] = 1.0f;
|
||||
}
|
||||
void setColor(float r, float g, float b, float a = 1.0f) {
|
||||
color[0] = r; color[1] = g; color[2] = b; color[3] = a;
|
||||
}
|
||||
bool operator == (const ShaderMaterial &m) const {
|
||||
if (texId != m.texId) return false;
|
||||
if (color[0] != m.color[0] || color[1] != m.color[1] || color[2] != m.color[2] || color[3] != m.color[3]) return false;
|
||||
return true;
|
||||
}
|
||||
unsigned int texId;
|
||||
float color[4];
|
||||
float ambientCoeff;
|
||||
float diffuseCoeff;
|
||||
float specularCoeff;
|
||||
float reflectionCoeff;
|
||||
float refractionCoeff;
|
||||
float shadowCoeff;
|
||||
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
class Shader
|
||||
{
|
||||
public:
|
||||
Shader();
|
||||
virtual ~Shader();
|
||||
|
||||
bool isValid();
|
||||
virtual void activate();
|
||||
virtual void activate(const ShaderMaterial &mat);
|
||||
virtual void deactivate();
|
||||
operator GLuint ()
|
||||
{
|
||||
return mShaderProgram;
|
||||
}
|
||||
|
||||
const std::string &getErrorMessage() { return mErrorMessage; }
|
||||
GLuint getShaderProgram() {return mShaderProgram;}
|
||||
|
||||
//protected:
|
||||
bool loadShaders(const char* vertexShaderFile, const char* fragmentShaderFile);
|
||||
bool loadShaders(const char* vertexShaderFile, const char* geometryShaderFile, const char* fragmentShaderFile);
|
||||
bool loadShaderCode(const char* vertexShaderCode, const char* fragmentShaderCode);
|
||||
bool loadShaderCode(const char* vertexShaderCode, const char* geometryShaderCode, const char* fragmentShaderCode);
|
||||
void deleteShaders();
|
||||
|
||||
bool compileShaders();
|
||||
void getCompileError(GLuint shader);
|
||||
void getLinkError(GLuint shader);
|
||||
void findVariables();
|
||||
void bindTexture(const char *name, GLuint tex, GLenum target, GLint unit);
|
||||
|
||||
GLuint mShaderProgram;
|
||||
GLuint mVertexShader;
|
||||
GLuint mGeometryShader;
|
||||
GLuint mFragmentShader;
|
||||
GLuint mGlShaderAttributes;
|
||||
|
||||
char* mVertexShaderSource;
|
||||
int mVertexShaderSourceLength;
|
||||
|
||||
char* mGeometryShaderSource;
|
||||
int mGeometryShaderSourceLength;
|
||||
|
||||
char* mFragmentShaderSource;
|
||||
int mFragmentShaderSourceLength;
|
||||
|
||||
struct UniformVariable
|
||||
{
|
||||
GLint size;
|
||||
GLenum type;
|
||||
GLint index;
|
||||
};
|
||||
|
||||
struct AttributeVariable
|
||||
{
|
||||
GLint size;
|
||||
GLenum type;
|
||||
GLint index;
|
||||
};
|
||||
|
||||
enum glShaderAttribute
|
||||
{
|
||||
gl_VERTEX = (1 << 0),
|
||||
gl_NORMAL = (1 << 1),
|
||||
gl_COLOR = (1 << 2),
|
||||
gl_TEXTURE = (1 << 3),
|
||||
};
|
||||
|
||||
typedef std::map<std::string, UniformVariable> tUniforms;
|
||||
tUniforms mUniforms;
|
||||
typedef std::map<std::string, AttributeVariable> tAttributes;
|
||||
tAttributes mAttributes;
|
||||
|
||||
std::string mErrorMessage;
|
||||
|
||||
public:
|
||||
virtual bool setUniform(const char* name, const PxMat33& value);
|
||||
virtual bool setUniform(const char* name, const PxTransform& value);
|
||||
virtual bool setUniform(const char *name, PxU32 size, const PxVec3* value);
|
||||
|
||||
virtual bool setUniform1(const char* name, float val);
|
||||
virtual bool setUniform2(const char* name, float val0, float val1);
|
||||
virtual bool setUniform3(const char* name, float val0, float val1, float val2);
|
||||
virtual bool setUniform4(const char* name, float val0, float val1, float val2, float val3);
|
||||
virtual bool setUniformfv(const GLchar *name, GLfloat *v, int elementSize, int count=1);
|
||||
|
||||
virtual bool setUniform(const char* name, float value);
|
||||
virtual bool setUniform(const char* name, int value);
|
||||
virtual bool setUniformMatrix4fv(const GLchar *name, const GLfloat *m, bool transpose);
|
||||
|
||||
virtual GLint getUniformCommon(const char* name);
|
||||
|
||||
virtual bool setAttribute(const char* name, PxU32 size, PxU32 stride, GLenum type, void* data);
|
||||
bool loadFile(const char* filename, char*& destination, int& destinationLength);
|
||||
};
|
||||
|
||||
#endif
|
||||
2910
kaplademo/source/demoFramework/ShaderShadow.cpp
Normal file
2910
kaplademo/source/demoFramework/ShaderShadow.cpp
Normal file
File diff suppressed because it is too large
Load Diff
132
kaplademo/source/demoFramework/ShaderShadow.h
Normal file
132
kaplademo/source/demoFramework/ShaderShadow.h
Normal file
@ -0,0 +1,132 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#ifndef SHADER_SHADOW_DIFFUSE_H
|
||||
#define SHADER_SHADOW_DIFFUSE_H
|
||||
|
||||
//#define USE_OPTIX 1
|
||||
#include "Shader.h"
|
||||
#include <string>
|
||||
class ShadowMap;
|
||||
|
||||
class ShaderShadow;
|
||||
class ShaderShadow : public Shader
|
||||
{
|
||||
public:
|
||||
// RENDER_DEPTH is for shadow map computation
|
||||
// RENDER_COLOR is for the usual rendering
|
||||
// RENDER_DEPTH_NORMAL is for SSAO
|
||||
enum RenderMode{RENDER_DEPTH, RENDER_COLOR, RENDER_DEPTH_NORMAL};
|
||||
static RenderMode renderMode;
|
||||
static float hdrScale;
|
||||
static GLuint skyBoxTex;
|
||||
|
||||
enum VS_MODE{VS_DEFAULT, VS_4BONES, VS_8BONES, VS_INSTANCE, VS_TEXINSTANCE, VS_DEFAULT_FOR_3D_TEX, VS_FILE,VS_CROSSHAIR};
|
||||
enum PS_MODE{PS_WHITE, PS_SHADE, PS_SHADE3D, PS_FILE, PS_NORMAL, PS_CROSSHAIR};
|
||||
enum SHADER3D_CHOICES{SAND_STONE, WHITE_MARBLE, GRAYVEIN_MARBLE, BLUEVEIN_MARBLE, GREEN_MARBLE, GRAY_MARBLE, RED_GRANITE, YELLOW_GRANITE, WOOD, COMBINE};
|
||||
|
||||
ShaderShadow(VS_MODE vsMode = VS_DEFAULT, PS_MODE psMode = PS_SHADE, SHADER3D_CHOICES shade3D = GRAY_MARBLE);
|
||||
~ShaderShadow() {};
|
||||
|
||||
bool init();
|
||||
|
||||
void setSpotLight(int nr, const PxVec3 &pos, PxVec3 &dir, float decayBegin = 0.98f, float decayEnd = 0.997f);
|
||||
void setBackLightDir(const PxVec3 &dir) { mBackLightDir = dir; }
|
||||
|
||||
void updateCamera(float* modelView, float* proj);
|
||||
|
||||
void setShadowMap(int nr, ShadowMap *shadowMap) { mShadowMaps[nr] = shadowMap; }
|
||||
void setNumShadows(int num) { mNumShadows = num; }
|
||||
void setShowReflection(bool show) { mShowReflection = show; }
|
||||
bool getShowReflection() const {return mShowReflection;}
|
||||
|
||||
void setReflectionTexId(unsigned int texId) { mReflectionTexId = texId; }
|
||||
|
||||
virtual void activate(const ShaderMaterial &mat);
|
||||
virtual void deactivate();
|
||||
|
||||
void setShadowAmbient(float sa);
|
||||
|
||||
// For fast shader debugging
|
||||
bool forceLoadShaderFromFile(VS_MODE vsm, PS_MODE psm, const char* vsName = NULL, const char* psName = NULL);
|
||||
|
||||
SHADER3D_CHOICES getMyShade3DChoice() {return myShade3DChoice;}
|
||||
|
||||
PxVec3 getDustColor() { return dustColor; }
|
||||
|
||||
virtual bool setUniform(const char* name, const PxMat33& value);
|
||||
virtual bool setUniform(const char* name, const PxTransform& value);
|
||||
virtual bool setUniform(const char *name, PxU32 size, const PxVec3* value);
|
||||
|
||||
virtual bool setUniform1(const char* name, float val);
|
||||
virtual bool setUniform2(const char* name, float val0, float val1);
|
||||
virtual bool setUniform3(const char* name, float val0, float val1, float val2);
|
||||
virtual bool setUniform4(const char* name, float val0, float val1, float val2, float val3);
|
||||
virtual bool setUniformfv(const GLchar *name, GLfloat *v, int elementSize, int count=1);
|
||||
|
||||
virtual bool setUniform(const char* name, float value);
|
||||
virtual bool setUniform(const char* name, int value);
|
||||
virtual bool setUniformMatrix4fv(const GLchar *name, const GLfloat *m, bool transpose);
|
||||
|
||||
virtual GLint getUniformCommon(const char* name);
|
||||
|
||||
virtual bool setAttribute(const char* name, PxU32 size, PxU32 stride, GLenum type, void* data);
|
||||
|
||||
private:
|
||||
static const int mNumLights = 1;
|
||||
|
||||
ShadowMap *mShadowMaps[mNumLights];
|
||||
|
||||
PxVec3 mSpotLightPos[mNumLights];
|
||||
PxVec3 mSpotLightDir[mNumLights];
|
||||
|
||||
float mSpotLightCosineDecayBegin[mNumLights];
|
||||
float mSpotLightCosineDecayEnd[mNumLights];
|
||||
|
||||
GLuint mReflectionTexId;
|
||||
|
||||
PxVec3 mBackLightDir;
|
||||
int mNumShadows;
|
||||
bool mShowReflection;
|
||||
|
||||
float mCamModelView[16];
|
||||
float mCamProj[16];
|
||||
float shadowAmbient;
|
||||
PxVec3 ambientColor;
|
||||
VS_MODE vsMode;
|
||||
PS_MODE psMode;
|
||||
|
||||
std::string fragmentShader3DComposite;
|
||||
SHADER3D_CHOICES myShade3DChoice;
|
||||
PxVec3 dustColor;
|
||||
|
||||
// For shadow map and SSAO
|
||||
ShaderShadow* whiteShader;
|
||||
ShaderShadow* normalShader;
|
||||
};
|
||||
|
||||
#endif
|
||||
395
kaplademo/source/demoFramework/ShadowMap.cpp
Normal file
395
kaplademo/source/demoFramework/ShadowMap.cpp
Normal file
@ -0,0 +1,395 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2007-2018 NVIDIA Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------------------------
|
||||
// File: ShadowMapping.cpp
|
||||
// Original Author: Rouslan Dimitrov
|
||||
// Modified by: Nuttapong Chentanez and Matthias Mueller-Fischer
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
#include "ShadowMap.h"
|
||||
#include <GL/glew.h>
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
struct ShadowMap::Vec4 {
|
||||
Vec4() {}
|
||||
Vec4(const PxVec3 &v, float vw = 1.0f) { x = v.x; y = v.y; z = v.z; w = vw; }
|
||||
float x,y,z,w;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
struct ShadowMap::Matrix44 {
|
||||
Vec4 operator*(const Vec4& v) const {
|
||||
Vec4 res;
|
||||
res.x = elems[0] * v.x + elems[4] * v.y + elems[8] * v.z + elems[12] * v.w;
|
||||
res.y = elems[1] * v.x + elems[5] * v.y + elems[9] * v.z + elems[13] * v.w;
|
||||
res.z = elems[2] * v.x + elems[6] * v.y + elems[10] * v.z + elems[14] * v.w;
|
||||
res.w = elems[3] * v.x + elems[7] * v.y + elems[11] * v.z + elems[15] * v.w;
|
||||
return res;
|
||||
}
|
||||
float &element(int i, int j) { return elems[i + 4*j]; }
|
||||
void zero() { for (int i = 0; i < 16; i++) elems[i] = 0.0f; }
|
||||
void id() { zero(); elems[0] = 1.0f; elems[5] = 1.0f; elems[10] = 1.0f; elems[15] = 1.0f; }
|
||||
|
||||
float elems[16];
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
ShadowMap::ShadowMap( int w, int h, float fovi, int matOffseti, int resolution)
|
||||
{
|
||||
shadowOff = 1.0f;
|
||||
shadowOff2 = 2048.0f;
|
||||
fov = fovi;
|
||||
cur_num_splits = 1;
|
||||
//cur_num_splits = 3;
|
||||
|
||||
width = w;
|
||||
height = h;
|
||||
depth_size = resolution;
|
||||
split_weight = 0.75;
|
||||
matOffset = matOffseti;
|
||||
|
||||
minZAdd = 0;
|
||||
maxZAdd = 30.0f;
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
void ShadowMap::updateFrustumPoints(Frustum &f, const PxVec3 ¢er, const PxVec3 &view_dir)
|
||||
{
|
||||
PxVec3 up(0.0, 1.0, 0.0);
|
||||
PxVec3 right = view_dir.cross(up);
|
||||
|
||||
PxVec3 fc = center + view_dir*f.fard;
|
||||
PxVec3 nc = center + view_dir*f.neard;
|
||||
|
||||
right.normalize();
|
||||
up = right.cross(view_dir);
|
||||
up.normalize();
|
||||
|
||||
// these heights and widths are half the heights and widths of
|
||||
// the near and far plane rectangles
|
||||
float near_height = tanf(f.fov/2.0f) * f.neard;
|
||||
float near_width = near_height * f.ratio;
|
||||
float far_height = tanf(f.fov/2.0f) * f.fard;
|
||||
float far_width = far_height * f.ratio;
|
||||
|
||||
f.point[0] = nc - up*near_height - right*near_width;
|
||||
f.point[1] = nc + up*near_height - right*near_width;
|
||||
f.point[2] = nc + up*near_height + right*near_width;
|
||||
f.point[3] = nc - up*near_height + right*near_width;
|
||||
|
||||
f.point[4] = fc - up*far_height - right*far_width;
|
||||
f.point[5] = fc + up*far_height - right*far_width;
|
||||
f.point[6] = fc + up*far_height + right*far_width;
|
||||
f.point[7] = fc - up*far_height + right*far_width;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// updateSplitDist computes the near and far distances for every frustum slice
|
||||
// in camera eye space - that is, at what distance does a slice start and end
|
||||
void ShadowMap::updateSplitDist(Frustum f[MAX_SPLITS], float nd, float fd)
|
||||
{
|
||||
float lambda = split_weight;
|
||||
float ratio = fd/nd;
|
||||
f[0].neard = nd;
|
||||
|
||||
for(int i=1; i<cur_num_splits; i++)
|
||||
{
|
||||
float si = i / (float)cur_num_splits;
|
||||
|
||||
f[i].neard = lambda*(nd*powf(ratio, si)) + (1-lambda)*(nd + (fd - nd)*si);
|
||||
f[i-1].fard = f[i].neard * 1.005f;
|
||||
}
|
||||
f[cur_num_splits-1].fard = fd;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// this function builds a projection matrix for rendering from the shadow's POV.
|
||||
// First, it computes the appropriate z-range and sets an orthogonal projection.
|
||||
// Then, it translates and scales it, so that it exactly captures the bounding box
|
||||
// of the current frustum slice
|
||||
float ShadowMap::applyCropMatrix(Frustum &f)
|
||||
{
|
||||
float shad_proj[16];
|
||||
float maxX = -1000.0;
|
||||
float maxY = -1000.0;
|
||||
float maxZ;
|
||||
float minX = 1000.0;
|
||||
float minY = 1000.0;
|
||||
float minZ;
|
||||
|
||||
Matrix44 nv_mvp;
|
||||
Vec4 transf;
|
||||
|
||||
// find the z-range of the current frustum as seen from the light
|
||||
// in order to increase precision
|
||||
glGetFloatv(GL_MODELVIEW_MATRIX, nv_mvp.elems);
|
||||
|
||||
// note that only the z-component is need and thus
|
||||
// the multiplication can be simplified
|
||||
// transf.z = shad_modelview[2] * f.point[0].x + shad_modelview[6] * f.point[0].y + shad_modelview[10] * f.point[0].z + shad_modelview[14];
|
||||
transf = nv_mvp * Vec4(f.point[0]);
|
||||
minZ = transf.z;
|
||||
maxZ = transf.z;
|
||||
for(int i=1; i<8; i++)
|
||||
{
|
||||
transf = nv_mvp * Vec4(f.point[i]);
|
||||
if(transf.z > maxZ) maxZ = transf.z;
|
||||
if(transf.z < minZ) minZ = transf.z;
|
||||
}
|
||||
|
||||
minZ += minZAdd;
|
||||
maxZ += maxZAdd;
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
// set the projection matrix with the new z-bounds
|
||||
// note the inversion because the light looks at the neg. z axis
|
||||
// gluPerspective(LIGHT_FOV, 1.0, maxZ, minZ); // for point lights
|
||||
glOrtho(-1.0, 1.0, -1.0, 1.0, -maxZ, -minZ);
|
||||
glGetFloatv(GL_PROJECTION_MATRIX, shad_proj);
|
||||
glPushMatrix();
|
||||
glMultMatrixf(nv_mvp.elems);
|
||||
glGetFloatv(GL_PROJECTION_MATRIX, nv_mvp.elems);
|
||||
glPopMatrix();
|
||||
|
||||
// find the extends of the frustum slice as projected in light's homogeneous coordinates
|
||||
for(int i=0; i<8; i++)
|
||||
{
|
||||
transf = nv_mvp * Vec4(f.point[i]);
|
||||
|
||||
transf.x /= transf.w;
|
||||
transf.y /= transf.w;
|
||||
|
||||
if(transf.x > maxX) maxX = transf.x;
|
||||
if(transf.x < minX) minX = transf.x;
|
||||
if(transf.y > maxY) maxY = transf.y;
|
||||
if(transf.y < minY) minY = transf.y;
|
||||
}
|
||||
|
||||
float scaleX = 2.0f/(maxX - minX);
|
||||
float scaleY = 2.0f/(maxY - minY);
|
||||
float offsetX = -0.5f*(maxX + minX)*scaleX;
|
||||
float offsetY = -0.5f*(maxY + minY)*scaleY;
|
||||
|
||||
// apply a crop matrix to modify the projection matrix we got from glOrtho.
|
||||
nv_mvp.id();
|
||||
nv_mvp.element(0,0) = scaleX;
|
||||
nv_mvp.element(1,1) = scaleY;
|
||||
nv_mvp.element(0,3) = offsetX;
|
||||
nv_mvp.element(1,3) = offsetY;
|
||||
glLoadMatrixf(nv_mvp.elems);
|
||||
glMultMatrixf(shad_proj);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
return minZ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// here all shadow map textures and their corresponding matrices are created
|
||||
void ShadowMap::makeShadowMap(const PxVec3 &cameraPos, const PxVec3 &cameraDir, const PxVec3 &lightDir, float znear, float zfar,
|
||||
void (*renderShadowCasters)())
|
||||
{
|
||||
float shad_modelview[16];
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
gluLookAt(
|
||||
cameraPos.x, cameraPos.y, cameraPos.z,
|
||||
cameraPos.x-lightDir.x, cameraPos.y-lightDir.y, cameraPos.z-lightDir.z,
|
||||
-1.0, 0.0, 0.0);
|
||||
|
||||
glGetFloatv(GL_MODELVIEW_MATRIX, shad_modelview);
|
||||
|
||||
// redirect rendering to the depth texture
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, depth_fb);
|
||||
// store the screen viewport
|
||||
glPushAttrib(GL_VIEWPORT_BIT);
|
||||
// and render only to the shadowmap
|
||||
glViewport(0, 0, depth_size, depth_size);
|
||||
// offset the geometry slightly to prevent z-fighting
|
||||
// note that this introduces some light-leakage artifacts
|
||||
glPolygonOffset(shadowOff, shadowOff2);
|
||||
// cout<<"shadowOff = "<<shadowOff<<endl;
|
||||
// cout<<"shadowOff2 = "<<shadowOff2<<endl;
|
||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
|
||||
// compute the z-distances for each split as seen in camera space
|
||||
updateSplitDist(f, znear, zfar);
|
||||
|
||||
// for all shadow maps:
|
||||
for(int i=0; i<cur_num_splits; i++)
|
||||
{
|
||||
// compute the camera frustum slice boundary points in world space
|
||||
updateFrustumPoints(f[i], cameraPos, cameraDir);
|
||||
// adjust the view frustum of the light, so that it encloses the camera frustum slice fully.
|
||||
// note that this function sets the projection matrix as it sees best fit
|
||||
// minZ is just for optimization to cull trees that do not affect the shadows
|
||||
float minZ = applyCropMatrix(f[i]);
|
||||
// make the current depth map a rendering target
|
||||
glFramebufferTextureLayerEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, depth_tex_ar, 0, i);
|
||||
|
||||
// clear the depth texture from last time
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// draw the scene
|
||||
(*renderShadowCasters)();
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
// store the product of all shadow matries for later
|
||||
glMultMatrixf(shad_modelview);
|
||||
glGetFloatv(GL_PROJECTION_MATRIX, shad_cpm[i]);
|
||||
}
|
||||
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
glPopAttrib();
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
void ShadowMap::cameraInverse(float dst[16], float src[16])
|
||||
{
|
||||
dst[0] = src[0];
|
||||
dst[1] = src[4];
|
||||
dst[2] = src[8];
|
||||
dst[3] = 0.0;
|
||||
dst[4] = src[1];
|
||||
dst[5] = src[5];
|
||||
dst[6] = src[9];
|
||||
dst[7] = 0.0;
|
||||
dst[8] = src[2];
|
||||
dst[9] = src[6];
|
||||
dst[10] = src[10];
|
||||
dst[11] = 0.0;
|
||||
dst[12] = -(src[12] * src[0]) - (src[13] * src[1]) - (src[14] * src[2]);
|
||||
dst[13] = -(src[12] * src[4]) - (src[13] * src[5]) - (src[14] * src[6]);
|
||||
dst[14] = -(src[12] * src[8]) - (src[13] * src[9]) - (src[14] * src[10]);
|
||||
dst[15] = 1.0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
void ShadowMap::doneRender()
|
||||
{
|
||||
// Unbind texture
|
||||
for (int i = 0; i < 8; i++) {
|
||||
glActiveTexture(GL_TEXTURE0 + i);
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadIdentity();
|
||||
}
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
void ShadowMap::prepareForRender(float* cam_modelview, float* cam_proj)
|
||||
{
|
||||
float cam_inverse_modelview[16];
|
||||
const float bias[16] = { 0.5, 0.0, 0.0, 0.0,
|
||||
0.0, 0.5, 0.0, 0.0,
|
||||
0.0, 0.0, 0.5, 0.0,
|
||||
0.5, 0.5f, 0.5, 1.0 };
|
||||
|
||||
// update the camera, so that the user can have a free look
|
||||
cameraInverse(cam_inverse_modelview, cam_modelview);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
for(int i=cur_num_splits; i<MAX_SPLITS; i++)
|
||||
far_bound[i] = 0;
|
||||
|
||||
// for every active split
|
||||
for(int i=0; i<cur_num_splits; i++)
|
||||
{
|
||||
// f[i].fard is originally in eye space - tell's us how far we can see.
|
||||
// Here we compute it in camera homogeneous coordinates. Basically, we calculate
|
||||
// cam_proj * (0, 0, f[i].fard, 1)^t and then normalize to [0; 1]
|
||||
far_bound[i] = 0.5f*(-f[i].fard*cam_proj[10]+cam_proj[14])/f[i].fard + 0.5f;
|
||||
|
||||
// compute a matrix that transforms from camera eye space to light clip space
|
||||
// and pass it to the shader through the OpenGL texture matrices, since we
|
||||
// don't use them now
|
||||
glActiveTexture(GL_TEXTURE0 + (GLenum)i + matOffset);
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadMatrixf(bias);
|
||||
glMultMatrixf(shad_cpm[i]);
|
||||
// multiply the light's (bias*crop*proj*modelview) by the inverse camera modelview
|
||||
// so that we can transform a pixel as seen from the camera
|
||||
glMultMatrixf(cam_inverse_modelview);
|
||||
}
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
void ShadowMap::init()
|
||||
{
|
||||
//glClearColor(0.8f, 0.8f , 0.9f, 1.0);
|
||||
//glEnable(GL_CULL_FACE);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_LIGHTING);
|
||||
glEnable(GL_LIGHT0);
|
||||
|
||||
|
||||
glGenFramebuffersEXT(1, &depth_fb);
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, depth_fb);
|
||||
glDrawBuffer(GL_NONE);
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
|
||||
glGenTextures(1, &depth_tex_ar);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY_EXT, depth_tex_ar);
|
||||
glTexImage3D(GL_TEXTURE_2D_ARRAY_EXT, 0, GL_DEPTH_COMPONENT32, depth_size, depth_size, MAX_SPLITS, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
|
||||
|
||||
for(int i=0; i<MAX_SPLITS; i++)
|
||||
{
|
||||
// note that fov is in radians here and in OpenGL it is in degrees.
|
||||
// the 0.2f factor is important because we might get artifacts at
|
||||
// the screen borders.
|
||||
f[i].fov = fov/57.2957795f + 0.2f;
|
||||
f[i].ratio = (float)width/(float)height;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
107
kaplademo/source/demoFramework/ShadowMap.h
Normal file
107
kaplademo/source/demoFramework/ShadowMap.h
Normal file
@ -0,0 +1,107 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2007-2018 NVIDIA Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------------------------
|
||||
// File: ShadowMapping.cpp
|
||||
// Original Author: Rouslan Dimitrov
|
||||
// Modified by: Nuttapong Chentanez and Matthias Mueller-Fischer
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef SHADOWMAP_H
|
||||
#define SHADOWMAP_H
|
||||
|
||||
#include "foundation/PxVec3.h"
|
||||
#include <GL/glew.h>
|
||||
|
||||
using namespace physx;
|
||||
|
||||
#define FAR_DIST 200.0
|
||||
#define MAX_SPLITS 1
|
||||
#define LIGHT_FOV 45.0
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
class ShadowMap
|
||||
{
|
||||
public:
|
||||
ShadowMap( int w, int h, float fovi, int matOffseti, int resolution = 4096);
|
||||
|
||||
void makeShadowMap(const PxVec3 &cameraPos, const PxVec3 &cameraDir, const PxVec3 &lightDir, float znear, float zfar,
|
||||
void (*renderShadowCasters)());
|
||||
|
||||
// call before the map is used for rendering
|
||||
void prepareForRender(float* cam_modelview, float* cam_proj);
|
||||
// call when rendering is done
|
||||
void doneRender();
|
||||
|
||||
int getTextureSize() { return depth_size; }
|
||||
GLuint getDepthTexArray() { return depth_tex_ar; }
|
||||
float getFarBound(int i) { return far_bound[i]; }
|
||||
int getNumSplits() { return cur_num_splits; }
|
||||
|
||||
private:
|
||||
struct Frustum {
|
||||
float neard;
|
||||
float fard;
|
||||
float fov;
|
||||
float ratio;
|
||||
PxVec3 point[8];
|
||||
};
|
||||
|
||||
struct Vec4;
|
||||
struct Matrix44;
|
||||
|
||||
void updateFrustumPoints(Frustum &f, const PxVec3 ¢er, const PxVec3 &view_dir);
|
||||
void updateSplitDist(Frustum f[MAX_SPLITS], float nd, float fd);
|
||||
float applyCropMatrix(Frustum &f);
|
||||
|
||||
void cameraInverse(float dst[16], float src[16]);
|
||||
void init();
|
||||
|
||||
float far_bound[MAX_SPLITS];
|
||||
|
||||
float minZAdd;
|
||||
float maxZAdd;
|
||||
|
||||
float shadowOff;
|
||||
float shadowOff2;
|
||||
float fov;
|
||||
|
||||
int cur_num_splits;
|
||||
int width;
|
||||
int height;
|
||||
int depth_size ;
|
||||
|
||||
GLuint depth_fb;
|
||||
GLuint depth_tex_ar;
|
||||
|
||||
Frustum f[MAX_SPLITS];
|
||||
float shad_cpm[MAX_SPLITS][16];
|
||||
|
||||
float split_weight;
|
||||
int matOffset;
|
||||
};
|
||||
#endif
|
||||
264
kaplademo/source/demoFramework/Texture.cpp
Normal file
264
kaplademo/source/demoFramework/Texture.cpp
Normal file
@ -0,0 +1,264 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <GL/glew.h>
|
||||
#include "BmpFile.h"
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
// standard cubemap face names
|
||||
/*
|
||||
const char *faceName[6] = {
|
||||
"negz",
|
||||
"negz",
|
||||
"posy",
|
||||
"negy",
|
||||
"negz",
|
||||
"negz",
|
||||
};
|
||||
*/
|
||||
const char *faceName0[6] = {
|
||||
"posx",
|
||||
"negx",
|
||||
"posy",
|
||||
"negy",
|
||||
"posz",
|
||||
"negz",
|
||||
};
|
||||
const char *faceName1[6] = {
|
||||
"ft",
|
||||
"bk",
|
||||
"up",
|
||||
"dn",
|
||||
"rt",
|
||||
"lf",
|
||||
};
|
||||
|
||||
|
||||
void loadImg(GLenum target, const char *filename, char mode = 0, float sr = 0.0f, float sg = 0.0f, float sb = 0.0f, float startGrad = -1.0f, float endGrad = -1.0f, char dir = 1)
|
||||
{
|
||||
int len = strlen(filename);
|
||||
|
||||
unsigned char* ptr = 0, *ptrBegin;
|
||||
int w, h;
|
||||
|
||||
BmpLoaderBuffer loader;
|
||||
|
||||
if (strcmp(&filename[len-4], ".bmp") == 0)
|
||||
{
|
||||
// bmp
|
||||
if (!loader.loadFile(filename)) {
|
||||
fprintf(stderr, "Error loading bmp '%s'\n");
|
||||
return;
|
||||
}
|
||||
ptrBegin = ptr = loader.mRGB;
|
||||
h = loader.mHeight;
|
||||
w = loader.mWidth;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Error loading '%s' jpg, tga and and other formats not supported\n");
|
||||
return;
|
||||
}
|
||||
/*{GLenum er = glGetError(); if (er != GL_NO_ERROR) { cout<<"Var name: "<<name<<" OGL Error "<<er<<endl; }}*/
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
/*{GLenum er = glGetError(); if (er != GL_NO_ERROR) { cout<<"Var name: "<<name<<" OGL Error "<<er<<endl; }}*/
|
||||
if (mode == 0) {
|
||||
// Nothing
|
||||
}
|
||||
float rf = sr*255.0f;
|
||||
float gf = sg*255.0f;
|
||||
float bf = sb*255.0f;
|
||||
unsigned char r = (unsigned char)(rf+0.5f);
|
||||
unsigned char g = (unsigned char)(gf+0.5f);
|
||||
unsigned char b = (unsigned char)(bf+0.5f);
|
||||
|
||||
|
||||
if (mode == 1) {
|
||||
// Fill all with sky color
|
||||
//printf("Mode is 1\n");
|
||||
|
||||
for (int i = 0; i < h; i++) {
|
||||
for (int j = 0; j < w; j++) {
|
||||
*(ptr++) = r;
|
||||
*(ptr++) = g;
|
||||
*(ptr++) = b;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mode == 2) {
|
||||
// Fill with gradient
|
||||
int sh = startGrad*h + 0.5f;
|
||||
int eh = endGrad*h + 0.5f;
|
||||
if (dir == 1) {
|
||||
for (int i = 0; i < sh; i++) {
|
||||
for (int j = 0; j < w; j++) {
|
||||
*(ptr++) = r;
|
||||
*(ptr++) = g;
|
||||
*(ptr++) = b;
|
||||
}
|
||||
}
|
||||
float grad = 1.0f/(eh - sh);
|
||||
float frac = 0.0f;
|
||||
for (int i = sh; i < eh; i++) {
|
||||
for (int j = 0; j < w; j++) {
|
||||
ptr[0] = (unsigned char)(0.5f + ptr[0]*frac + (1.0f-frac)*rf);
|
||||
ptr[1] = (unsigned char)(0.5f + ptr[1]*frac + (1.0f-frac)*gf);
|
||||
ptr[2] = (unsigned char)(0.5f + ptr[2]*frac + (1.0f-frac)*bf);
|
||||
ptr+=3;
|
||||
}
|
||||
frac+=grad;
|
||||
}
|
||||
} else {
|
||||
ptr+=(w*3*sh);
|
||||
float grad = 1.0f/(eh - sh);
|
||||
float frac = 1.0f;
|
||||
for (int i = sh; i < eh; i++) {
|
||||
for (int j = 0; j < w; j++) {
|
||||
ptr[0] = (unsigned char)(0.5f + ptr[0]*frac + (1.0f-frac)*rf);
|
||||
ptr[1] = (unsigned char)(0.5f + ptr[1]*frac + (1.0f-frac)*gf);
|
||||
ptr[2] = (unsigned char)(0.5f + ptr[2]*frac + (1.0f-frac)*bf);
|
||||
ptr+=3;
|
||||
}
|
||||
frac-=grad;
|
||||
}
|
||||
for (int i = eh; i < h; i++) {
|
||||
for (int j = 0; j < w; j++) {
|
||||
*(ptr++) = r;
|
||||
*(ptr++) = g;
|
||||
*(ptr++) = b;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*{GLenum er = glGetError(); if (er != GL_NO_ERROR) { cout<<"Var name: "<<name<<" OGL Error "<<er<<endl; }}*/
|
||||
glTexImage2D(target, 0, GL_RGBA8, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, ptrBegin);
|
||||
|
||||
/*{GLenum er = glGetError(); if (er != GL_NO_ERROR) { cout<<"Var name: "<<name<<" OGL Error "<<er<<endl; }}*/
|
||||
//glGenerateMipmapEXT(target);
|
||||
/*{GLenum er = glGetError(); if (er != GL_NO_ERROR) { cout<<"Var name: "<<name<<" OGL Error "<<er<<endl; }}*/
|
||||
|
||||
}
|
||||
|
||||
GLuint loadImgTexture(const char *filename)
|
||||
{
|
||||
GLuint texID;
|
||||
glGenTextures(1, &texID);
|
||||
glBindTexture(GL_TEXTURE_2D, texID);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
|
||||
loadImg(GL_TEXTURE_2D, filename);
|
||||
|
||||
return texID;
|
||||
}
|
||||
|
||||
|
||||
// specify filename in printf format, e.g. "cubemap_%s.png"
|
||||
GLuint loadCubeMap(const char *string, char mode, char nameset, float sr, float sg, float sb, float startGrad, float endGrad, char dir)
|
||||
{
|
||||
GLuint texID;
|
||||
glGenTextures(1, &texID);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, texID);
|
||||
/*{GLenum er = glGetError(); if (er != GL_NO_ERROR) { cout<<"Var name: "<<name<<" OGL Error "<<er<<endl; }}*/
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||
/*{GLenum er = glGetError(); if (er != GL_NO_ERROR) { cout<<"Var name: "<<name<<" OGL Error "<<er<<endl; }}*/
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
/*{GLenum er = glGetError(); if (er != GL_NO_ERROR) { cout<<"Var name: "<<name<<" OGL Error "<<er<<endl; }}*/
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
|
||||
/*{GLenum er = glGetError(); if (er != GL_NO_ERROR) { cout<<"Var name: "<<name<<" OGL Error "<<er<<endl; }}*/
|
||||
// load faces
|
||||
if (mode <= 1) {
|
||||
for(int i=0; i<6; i++) {
|
||||
char buff[1024];
|
||||
if (nameset == 0) {
|
||||
sprintf(buff, string, faceName0[i]);
|
||||
} else {
|
||||
sprintf(buff, string, faceName1[i]);
|
||||
}
|
||||
loadImg(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + i, buff, mode, sr, sg, sb, startGrad, endGrad, dir);
|
||||
|
||||
|
||||
}
|
||||
} /*{GLenum er = glGetError(); if (er != GL_NO_ERROR) { cout<<"Var name: "<<name<<" OGL Error "<<er<<endl; }}*/
|
||||
if (mode == 2) {
|
||||
for(int i=0; i<6; i++) {
|
||||
char buff[1024];
|
||||
if (nameset == 0) {
|
||||
sprintf(buff, string, faceName0[i]);
|
||||
} else {
|
||||
sprintf(buff, string, faceName1[i]);
|
||||
}
|
||||
if (i == 2) {
|
||||
if (dir == -1) {
|
||||
loadImg(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + i, buff, 0);
|
||||
} else {
|
||||
loadImg(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + i, buff, 1, sr, sg, sb);
|
||||
}
|
||||
} else
|
||||
if (i == 3) {
|
||||
if (dir == -1) {
|
||||
loadImg(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + i, buff, 1, sr, sg, sb);
|
||||
} else {
|
||||
loadImg(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + i, buff, 0);
|
||||
}
|
||||
} else {
|
||||
loadImg(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + i, buff, mode, sr, sg, sb, startGrad, endGrad, dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*{GLenum er = glGetError(); if (er != GL_NO_ERROR) { cout<<"Var name: "<<name<<" OGL Error "<<er<<endl; }}*/
|
||||
glGenerateMipmapEXT(GL_TEXTURE_CUBE_MAP);
|
||||
/*{GLenum er = glGetError(); if (er != GL_NO_ERROR) { cout<<"Var name: "<<name<<" OGL Error "<<er<<endl; }}*/
|
||||
return texID;
|
||||
}
|
||||
|
||||
|
||||
GLuint createTexture(GLenum target, GLint internalformat, int w, int h, GLenum type, GLenum format, void *data)
|
||||
{
|
||||
GLuint texid;
|
||||
glGenTextures(1, &texid);
|
||||
glBindTexture(target, texid);
|
||||
|
||||
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
glTexImage2D(target, 0, internalformat, w, h, 0, format, type, data);
|
||||
|
||||
return texid;
|
||||
}
|
||||
40
kaplademo/source/demoFramework/Texture.h
Normal file
40
kaplademo/source/demoFramework/Texture.h
Normal file
@ -0,0 +1,40 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#ifndef TEXTURE_H
|
||||
#define TEXTURE_H
|
||||
|
||||
GLuint loadImgTexture(const char *filename);
|
||||
GLuint loadCubeMap(const char *string, char mode = 0, char nameset = 0, float sr = 0.0f, float sg = 0.0f, float sb = 0.0f, float startGrad = -1.0f, float endGrad = -1.0f, char dir = 1);
|
||||
GLuint createTexture(GLenum target, GLint internalformat, int w, int h, GLenum type, GLenum format, void *data);
|
||||
|
||||
#endif // !TEXTURE_H
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user