This commit is contained in:
2025-11-28 23:13:44 +05:30
commit a3a8e79709
7360 changed files with 1156074 additions and 0 deletions

View 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;
}

View 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

View 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);
}

View 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;
};

View 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;
}

View 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

File diff suppressed because it is too large Load Diff

View 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

View 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__

View 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;
}

View 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;
};

View 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);
}

View 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;
};

View 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;
}

View 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

File diff suppressed because it is too large Load Diff

View 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;

View 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);
}

View 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

View 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;

View 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;

View 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();
}

View 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

View 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);
}
}

View 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;
};

View 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, &param);
if (param != GL_TRUE) {
getCompileError(mVertexShader);
deleteShaders();
return false;
}
if (mGeometryShader) {
glGetShaderiv(mGeometryShader, GL_COMPILE_STATUS, &param);
if (param != GL_TRUE) {
getCompileError(mGeometryShader);
deleteShaders();
return false;
}
}
glGetShaderiv(mFragmentShader, GL_COMPILE_STATUS, &param);
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, &param);
// 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;
}

View 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

File diff suppressed because it is too large Load Diff

View 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

View 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 &center, 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;
}
}

View 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 &center, 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

View 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;
}

View 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