Files
PhysX4.1/kaplademo/source/kaplaDemo/Fracture/SimScene.cpp
2025-11-28 23:13:44 +05:30

737 lines
24 KiB
C++

//
// 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 "SimScene.h"
#include <foundation/PxMat44.h>
#include "PxRigidBodyExt.h"
#include "Actor.h"
#include "Compound.h"
#include "Convex.h"
#include "CompoundCreator.h"
#include "PolygonTriangulator.h"
#include "SampleViewerScene.h"
#include <windows.h>
#include <iostream>
using namespace std;
#include <vector>
#include "TerrainMesh.h"
#define USE_CONVEX_RENDERER 1
#define NUM_NO_SOUND_FRAMES 1
//#define REL_VEL_FRACTURE_THRESHOLD 5.0f
#define REL_VEL_FRACTURE_THRESHOLD 0.1f
//extern std::vector<Compound*> delCompoundList;
SimScene* SimScene::createSimScene(PxPhysics *pxPhysics, PxCooking *pxCooking, bool isGrbScene, float minConvexSize, PxMaterial* defaultMat, const char *resourcePath)
{
SimScene* s = PX_NEW(SimScene)(pxPhysics,pxCooking,isGrbScene,minConvexSize,defaultMat,resourcePath);
s->createSingletons();
return s;
}
void SimScene::createSingletons()
{
mCompoundCreator = PX_NEW(CompoundCreator)(this);
mPolygonTriangulator = PX_NEW(PolygonTriangulator)(this);
addActor(createActor());
}
base::Actor* SimScene::createActor()
{
return (base::Actor*)PX_NEW(Actor)(this);
}
base::Convex* SimScene::createConvex()
{
return (base::Convex*)PX_NEW(Convex)(this);
}
base::Compound* SimScene::createCompound(PxReal contactOffset, PxReal restOffset)
{
return (base::Compound*)PX_NEW(Compound)(this, contactOffset, restOffset);
}
SimScene::SimScene(PxPhysics *pxPhysics, PxCooking *pxCooking, bool isGrbScene, float minConvexSize, PxMaterial* defaultMat, const char *resourcePath):
base::SimScene(pxPhysics,pxCooking,isGrbScene,minConvexSize,defaultMat,resourcePath)
{
//mParticles = NULL;
diffuseTexArray = 0;
bumpTexArray = 0;
specularTexArray = 0;
emissiveReflectSpecPowerTexArray = 0;
create3dTexture();
}
// --------------------------------------------------------------------------------------------
SimScene::~SimScene()
{
mShader = NULL;
mShaderMat.init();
if (mRenderBuffers.volTex) glDeleteTextures(1, &mRenderBuffers.volTex);
if (mRenderBuffers.VBO) glDeleteBuffersARB(1, &mRenderBuffers.VBO);
if (mRenderBuffers.IBO) glDeleteBuffersARB(1, &mRenderBuffers.IBO);
if (mRenderBuffers.matTex) glDeleteTextures(1, &mRenderBuffers.matTex);
}
// --------------------------------------------------------------------------------------------
void SimScene::clear()
{
base::SimScene::clear();
}
// --------------------------------------------------------------------------------------------
void SimScene::postSim(float dt, RegularCell3D* fluidSim)
{
for (int i = 0; i < mActors.size(); i++)
{
mActors[i]->postSim(dt);
}
mFrameNr++;
mNoFractureFrames--;
mNoSoundFrames--;
}
void SimScene::profileBegin(const char* name)
{
}
void SimScene::profileEnd(const char* name)
{
}
// ------------------------- Renderering --------------------------------
GLuint SimScene::loadTextureArray(std::vector<std::string>& names) {
GLuint texid;
glGenTextures(1, &texid);
glBindTexture( GL_TEXTURE_2D_ARRAY_EXT, texid);
glTexParameteri( GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri( GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri( GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri( GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri( GL_TEXTURE_2D_ARRAY_EXT, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
class BmpLoaderBuffer : public ::BmpLoaderBuffer, public ::physx::shdfnd::UserAllocated {};
BmpLoaderBuffer *bmps;
bmps = PX_NEW(BmpLoaderBuffer)[names.size()];
char path[512];
int w = 0, h = 0, d = 0;
for (int i = 0; i < (int)names.size(); i++) {
if (names[i].size() > 0) {
sprintf_s(path, 512, "%s", names[i].c_str());
int len = strlen(path);
int mw = 0, mh = 0;
if (strcmp(&path[len-4], ".jpg") == 0) {
printf("Can't load %s, jpg no longer supported\n", path);
} else {
bmps[i].loadFile(path);
mw = bmps[i].mWidth;
mh = bmps[i].mHeight;
}
if ((mw != 0) && (mh != 0)) {
if ( ((w != 0) && (w != mw)) ||
((h != 0) && (h != mh)) ) {
printf("Textures in array need to be same size!\n");
}
w = mw;
h = mh;
}
}
}
d = names.size();
if (w == 0) {
w=h=128;
}
unsigned char* tmpBlack = (unsigned char*)PX_ALLOC(sizeof(unsigned char)*w*h*3,PX_DEBUG_EXP("RT_FRACTURE"));
memset(tmpBlack, 0, w*h*3);
glTexImage3D(GL_TEXTURE_2D_ARRAY_EXT, 0, GL_RGB8, w, h, d, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
for (int i = 0; i < (int)names.size(); i++) {
glTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 0, 0, 0, i, w, h, 1, GL_RGB, GL_UNSIGNED_BYTE, (bmps[i].mRGB) ? bmps[i].mRGB :tmpBlack
);
}
glGenerateMipmapEXT(GL_TEXTURE_2D_ARRAY_EXT);
PX_FREE(tmpBlack);
PX_DELETE_ARRAY(bmps);
/* names
// 2D Texture arrays a loaded just like 3D textures
glTexImage3D(GL_TEXTURE_2D_ARRAY_EXT, 0, GL_RGBA8, images[0].getWidth(), images[0].getHeight(), NIMAGES, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
for (int i = 0; i < NIMAGES; i++) {
glTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 0, 0, 0, i, images[i].getWidth(), images[i].getHeight(), 1, images[i].getFormat(), images[i].getType(), images[i].getLevel(0));
}
*/
return texid;
}
void SimScene::loadAndCreateTextureArrays() {
diffuseTexArray = loadTextureArray(diffuseTexNames);
bumpTexArray = loadTextureArray(bumpTexNames);
specularTexArray = loadTextureArray(specularTexNames);
emissiveReflectSpecPowerTexArray = loadTextureArray(emissiveReflectSpecPowerTexNames);
}
// --------------------------------------------------------------------------------------------
#define WIDTH 128
#define HEIGHT 128
#define DEPTH 128
#define BYTES_PER_TEXEL 3
#define LAYER(r) (WIDTH * HEIGHT * r * BYTES_PER_TEXEL)
// 2->1 dimension mapping function
#define TEXEL2(s, t) (BYTES_PER_TEXEL * (s * WIDTH + t))
// 3->1 dimension mapping function
#define TEXEL3(s, t, r) (TEXEL2(s, t) + LAYER(r))
// --------------------------------------------------------------------------------------------
void SimScene::create3dTexture()
{
unsigned char *texels = (unsigned char *)malloc(WIDTH * HEIGHT * DEPTH * BYTES_PER_TEXEL);
memset(texels, 0, WIDTH*HEIGHT*DEPTH);
// each of the following loops defines one layer of our 3d texture, there are 3 unsigned bytes (red, green, blue) for each texel so each iteration sets 3 bytes
// the memory pointed to by texels is technically a single dimension (C++ won't allow more than one dimension to be of variable length), the
// work around is to use a mapping function like the one above that maps the 3 coordinates onto one dimension
// layer 0 occupies the first (width * height * bytes per texel) bytes, followed by layer 1, etc...
// define layer 0 as red
// Perlin perlin(8,4,1,91114);
unsigned char* tt = texels;
float idx = 1.0f / DEPTH;
for (int i = 0; i < DEPTH; i++) {
for (int j = 0; j < HEIGHT; j++) {
for (int k = 0; k < WIDTH; k++) {
//float v[3] = {i*idx, j*idx, k*idx};
//float val = (perlin.noise3(v)*0.5f + 0.5f)*255.0f;//cos( (perlin.Noise3(i*0.01f,j*0.01f,k*0.01f)*255000 + i*0.)*5.0f)*0.5f+0.5f;//perlin.Noise3(k,j,i)*255.0f;
//(cos(perlin.Noise3(k,j,i) + j*0.01f) + 1.0f)*0.5f*255;
unsigned char val = rand() % 255;
tt[0] = val;
tt[1] = val;
tt[2] = val;
tt+=3;
}
}
}
// request 1 texture name from OpenGL
glGenTextures(1, &mRenderBuffers.volTex);
// tell OpenGL we're going to be setting up the texture name it gave us
glBindTexture(GL_TEXTURE_3D, mRenderBuffers.volTex);
// when this texture needs to be shrunk to fit on small polygons, use linear interpolation of the texels to determine the color
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// when this texture needs to be magnified to fit on a big polygon, use linear interpolation of the texels to determine the color
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// we want the texture to repeat over the S axis, so if we specify coordinates out of range we still get textured.
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT);
// same as above for T axis
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// same as above for R axis
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT);
// this is a 3d texture, level 0 (max detail), GL should store it in RGB8 format, its WIDTHxHEIGHTxDEPTH in size,
// it doesnt have a border, we're giving it to GL in RGB format as a series of unsigned bytes, and texels is where the texel data is.
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB8, WIDTH, HEIGHT, DEPTH, 0, GL_RGB, GL_UNSIGNED_BYTE, texels);
glBindTexture(GL_TEXTURE_3D, 0);
}
// --------------------------------------------------------------------------------------------
void SimScene::createRenderBuffers()
{
if (!mRenderBuffers.VBO) {
glGenBuffersARB(1, &mRenderBuffers.VBO);
}
if (!mRenderBuffers.IBO) {
glGenBuffersARB(1, &mRenderBuffers.IBO);
}
if (!mRenderBuffers.matTex) {
glGenTextures(1, &mRenderBuffers.matTex);
glBindTexture(GL_TEXTURE_2D, mRenderBuffers.matTex);
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);
glBindTexture(GL_TEXTURE_2D, 0);
}
// Count number of vertices and indices in convexes
// Count number of indices in convexes
mRenderBuffers.numConvexes = 0;
mRenderBuffers.numVertices = 0;
mRenderBuffers.numIndices = 0;
for (int k = 0; k < (int)mActors.size(); k++)
{
const shdfnd::Array<base::Compound*>& mCompounds = mActors[k]->getCompounds();
for (int i = 0; i < (int)mCompounds.size(); i++) {
if (((Compound*)mCompounds[i])->getShader() != mShader)
continue;
const shdfnd::Array<base::Convex*> &convexes = mCompounds[i]->getConvexes();
mRenderBuffers.numConvexes += convexes.size();
for (int j = 0; j < (int)convexes.size(); j++) {
mRenderBuffers.numVertices += convexes[j]->getVisVertices().size();
mRenderBuffers.numIndices += convexes[j]->getVisTriIndices().size();
}
}
}
if (mRenderBuffers.numVertices == 0 || mRenderBuffers.numIndices == 0)
return;
mRenderBuffers.tmpVertices.resize(mRenderBuffers.numVertices*12);
mRenderBuffers.tmpIndices.resize(mRenderBuffers.numIndices);
float* vp = &mRenderBuffers.tmpVertices[0];
unsigned int* ip = &mRenderBuffers.tmpIndices[0];
int sumV = 0;
// Make cpu copy of VBO and IBO
int convexNr = 0;
for (int k = 0; k < (int)mActors.size(); k++)
{
const shdfnd::Array<base::Compound*>& mCompounds = mActors[k]->getCompounds();
for (int i = 0; i < (int)mCompounds.size(); i++) {
if (((Compound*)mCompounds[i])->getShader() != mShader)
continue;
const shdfnd::Array<base::Convex*> &convexes = mCompounds[i]->getConvexes();
for (int j = 0; j < (int)convexes.size(); j++, convexNr++) {
Convex* c = (Convex*)convexes[j];
// PxVec3 matOff = c->getMaterialOffset();
int nv = c->getVisVertices().size();
int ni = c->getVisTriIndices().size();
if (nv > 0) {
float* cvp = (float*)&c->getVisVertices()[0]; // float3
float* cnp = (float*)&c->getVisNormals()[0]; // float3
// float* c3dtp = (float*)&c->getVisVertices()[0]; // float3
float* c2dtp = (float*)&c->getVisTexCoords()[0]; // float2
float* ctanp = (float*)&c->getVisTangents()[0]; // float3
int* cip = (int*)&c->getVisTriIndices()[0];
for (int k = 0; k < nv; k++) {
*(vp++) = *(cvp++);
*(vp++) = *(cvp++);
*(vp++) = *(cvp++);
*(vp++) = *(cnp++);
*(vp++) = *(cnp++);
*(vp++) = *(cnp++);
*(vp++) = *(ctanp++);
*(vp++) = *(ctanp++);
*(vp++) = *(ctanp++);
*(vp++) = (float)convexNr;
*(vp++) = *(c2dtp++);
*(vp++) = *(c2dtp++);
}
for (int k = 0; k < ni; k++) {
*(ip++) = *(cip++) + sumV;
}
}
//memcpy(ip, cip, sizeof(int)*ni);
//ip += 3*ni;
//std::vector<PxVec3> mTriVertices;
//std::vector<PxVec3> mTriNormals;
//std::vector<int> mTriIndices;
//std::vector<float> mTriTexCoords; // 3d + obj nr
sumV += nv;
}
}
}
glBindBufferARB(GL_ARRAY_BUFFER_ARB, mRenderBuffers.VBO);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, mRenderBuffers.tmpVertices.size()*sizeof(float), &mRenderBuffers.tmpVertices[0], GL_STATIC_DRAW);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mRenderBuffers.IBO);
glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mRenderBuffers.tmpIndices.size()*sizeof(unsigned int), &mRenderBuffers.tmpIndices[0], GL_STATIC_DRAW);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
int oldTexSize = mRenderBuffers.texSize;
if (mRenderBuffers.texSize == 0) {
// First time
oldTexSize = 1;
mRenderBuffers.texSize = 32;
}
while (1) {
int convexesPerRow = mRenderBuffers.texSize / 4;
if (convexesPerRow * mRenderBuffers.texSize >= mRenderBuffers.numConvexes) {
break;
} else {
mRenderBuffers.texSize *= 2;
}
}
if (mRenderBuffers.texSize != oldTexSize) {
mRenderBuffers.tmpTexCoords.resize(mRenderBuffers.texSize*mRenderBuffers.texSize*4);
// Let's allocate texture
glBindTexture(GL_TEXTURE_2D, mRenderBuffers.matTex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, mRenderBuffers.texSize, mRenderBuffers.texSize, 0, GL_RGBA, GL_FLOAT, 0);
glBindTexture(GL_TEXTURE_2D, 0);
}
mRenderBufferVersion = mSceneVersion;
//instanceVBOCPU.resize( newSize * 16);
}
// --------------------------------------------------------------------------------------------
void SimScene::updateConvexesTex()
{
float* tt = &mRenderBuffers.tmpTexCoords[0];
for (int k = 0; k < (int)mActors.size(); k++)
{
const shdfnd::Array<base::Compound*>& mCompounds = mActors[k]->getCompounds();
for (int i = 0; i < (int)mCompounds.size(); i++) {
if ( ((Compound*)mCompounds[i])->getShader() != mShader)
continue;
const shdfnd::Array<base::Convex*> &convexes = mCompounds[i]->getConvexes();
for (int j = 0; j < (int)convexes.size(); j++) {
Convex* c = (Convex*)convexes[j];
PxMat44 pose(convexes[j]->getGlobalPose());
float* mp = (float*)pose.front();
float* ta = tt;
for (int k = 0; k < 16; k++) {
*(tt++) = *(mp++);
}
PxVec3 matOff = c->getMaterialOffset();
ta[3] = matOff.x;
ta[7] = matOff.y;
ta[11] = matOff.z;
int idFor2DTex = c->getSurfaceMaterialId();
int idFor3DTex = 0;
const int MAX_3D_TEX = 8;
ta[15] = (float)(idFor2DTex*MAX_3D_TEX + idFor3DTex);
}
}
}
glBindTexture(GL_TEXTURE_2D, mRenderBuffers.matTex);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, mRenderBuffers.texSize, mRenderBuffers.texSize,
GL_RGBA, GL_FLOAT, &mRenderBuffers.tmpTexCoords[0]);
glBindTexture(GL_TEXTURE_2D, 0);
}
// --------------------------------------------------------------------------------------------
#ifdef USE_OPTIX
// Updater class for Optix renderer.
class FractureModelUpdate : public optix_demo::IModelUpdate
{
public:
FractureModelUpdate( shdfnd::Array< Compound* > const& compounds, bool complete_update )
: m_compounds(compounds), m_is_complete_update( complete_update )
{}
bool isCompleteUpdate() const {return m_is_complete_update;}
void to_first();
void to_next();
bool at_end() const;
size_t num_vertices() const {return (*m_iconvex)->getVisVertices().size();}
size_t num_indices() const {return (*m_iconvex)->getVisTriIndices().size();}
float const* vertices() const {return &(*m_iconvex)->getVisVertices()[0].x;}
float const* normals() const {return &(*m_iconvex)->getVisNormals()[0].x;}
int const* indices() const {return &(*m_iconvex)->getVisTriIndices()[0];}
void global_transform( float* rmat3x3, float* translation );
private:
void advance();
bool is_valid_convex( Convex const* c ) const
{
return !c->getVisVertices().empty();
}
shdfnd::Array< Compound* > const& m_compounds;
bool m_is_complete_update;
shdfnd::Array< Compound* >::ConstIterator m_icompound;
shdfnd::Array< Convex* >::ConstIterator m_iconvex;
};
void FractureModelUpdate::to_first()
{
m_icompound = m_compounds.begin();
if (m_icompound == m_compounds.end()) return;
while ((*m_icompound)->getConvexes().empty()) {
++m_icompound;
if (m_icompound == m_compounds.end()) return;
}
m_iconvex = (*m_icompound)->getConvexes().begin();
while (!is_valid_convex(*m_iconvex)) {
advance();
if (m_icompound == m_compounds.end()) return;
}
}
void FractureModelUpdate::to_next()
{
if (m_icompound != m_compounds.end()) {
do {
advance();
} while (m_icompound != m_compounds.end() && !is_valid_convex(*m_iconvex));
}
}
void FractureModelUpdate::advance()
{
if (m_iconvex != (*m_icompound)->getConvexes().end()) {
++m_iconvex;
}
if (m_iconvex == (*m_icompound)->getConvexes().end()) {
// End of convexes of this compound.
do {
++m_icompound;
if (m_icompound == m_compounds.end()) return;
} while ((*m_icompound)->getConvexes().empty());
m_iconvex = (*m_icompound)->getConvexes().begin();
}
}
bool FractureModelUpdate::at_end() const
{
return m_icompound == m_compounds.end();
}
void FractureModelUpdate::global_transform( float* rmat3x3, float* translation )
{
PxTransform pose = (*m_iconvex)->getGlobalPose();
PxMat33 rot(pose.q);
rmat3x3[0] = rot.column0.x; rmat3x3[1] = rot.column1.x; rmat3x3[2] = rot.column2.x;
rmat3x3[3] = rot.column0.y; rmat3x3[4] = rot.column1.y; rmat3x3[5] = rot.column2.y;
rmat3x3[6] = rot.column0.z; rmat3x3[7] = rot.column1.z; rmat3x3[8] = rot.column2.z;
translation[0] = pose.p.x;
translation[1] = pose.p.y;
translation[2] = pose.p.z;
}
#endif //USE_OPTIX
extern bool gConvexTexOutdate;
// --------------------------------------------------------------------------------------------
void SimScene::draw(bool useShader)
{
if (mDebugDraw) {
for (int k = 0; k < (int)mActors.size(); k++)
{
const shdfnd::Array<base::Compound*>& mCompounds = mActors[k]->getCompounds();
for (int i = 0; i < (int)mCompounds.size(); i++)
mCompounds[i]->draw(false, true);
}
return;
}
int numCompounds = 0;
for (int k = 0; k < (int)mActors.size(); k++)
{
const shdfnd::Array<base::Compound*>& mCompounds = mActors[k]->getCompounds();
numCompounds += mCompounds.size();
}
if (numCompounds == 0) return;
if (SampleViewerScene::getRenderType() == SampleViewerScene::rtOPENGL) {
#if USE_CONVEX_RENDERER
mConvexRenderer.setShaderMaterial(mShader, mShaderMat);
mConvexRenderer.setTexArrays(diffuseTexArray, bumpTexArray,
specularTexArray, emissiveReflectSpecPowerTexArray);
mConvexRenderer.setVolTex(mRenderBuffers.volTex);
mConvexRenderer.render();
#else
mConvexRenderer.setActive(false);
if (mRenderBufferVersion != mSceneVersion)
createRenderBuffers();
if (mRenderBuffers.numIndices > 0) {
if (gConvexTexOutdate) {
updateConvexesTex();
gConvexTexOutdate = false;
}
mShader->activate(mShaderMat);
// Assume convex all use the same shader
glActiveTexture(GL_TEXTURE7);
glBindTexture(GL_TEXTURE_3D, mRenderBuffers.volTex);
glActiveTexture(GL_TEXTURE8);
glBindTexture(GL_TEXTURE_2D, mRenderBuffers.matTex);
glActiveTexture(GL_TEXTURE10);
glBindTexture(GL_TEXTURE_2D_ARRAY_EXT, diffuseTexArray);
glActiveTexture(GL_TEXTURE11);
glBindTexture(GL_TEXTURE_2D_ARRAY_EXT, bumpTexArray);
glActiveTexture(GL_TEXTURE12);
glBindTexture(GL_TEXTURE_2D_ARRAY_EXT, specularTexArray);
glActiveTexture(GL_TEXTURE13);
glBindTexture(GL_TEXTURE_2D_ARRAY_EXT, emissiveReflectSpecPowerTexArray);
glActiveTexture(GL_TEXTURE0);
float itt = 1.0f/mRenderBuffers.texSize;
mShader->setUniform("diffuseTexArray", 10);
mShader->setUniform("bumpTexArray", 11);
mShader->setUniform("specularTexArray", 12);
mShader->setUniform("emissiveReflectSpecPowerTexArray", 13);
mShader->setUniform("ttt3D", 7);
mShader->setUniform("transTex", 8);
mShader->setUniform("transTexSize", mRenderBuffers.texSize);
mShader->setUniform("iTransTexSize", itt);
mShader->setUniform("bumpTextureUVScale", bumpTextureUVScale);
mShader->setUniform("extraNoiseScale",extraNoiseScale);
mShader->setUniform("roughnessScale", roughnessScale);
if (mShaderMat.color[3] < 1.0f) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_DEPTH_TEST);
glColor4f(mShaderMat.color[0], mShaderMat.color[1], mShaderMat.color[2], mShaderMat.color[3]);
}
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glClientActiveTexture(GL_TEXTURE0);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, mRenderBuffers.VBO);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mRenderBuffers.IBO);
int stride = 12*sizeof(float);
glVertexPointer(3, GL_FLOAT, stride, 0);
glNormalPointer(GL_FLOAT, stride, (void*)(3*sizeof(float)));
glTexCoordPointer(4, GL_FLOAT, stride, (void*)(6*sizeof(float)));
glClientActiveTexture(GL_TEXTURE1);
glTexCoordPointer(2, GL_FLOAT, stride, (void*)(10*sizeof(float)));
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glDrawElements(GL_TRIANGLES, mRenderBuffers.numIndices, GL_UNSIGNED_INT, 0);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTexture(GL_TEXTURE0);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
if (mShaderMat.color[3] < 1.0f) {
glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
}
mShader->deactivate();
}
#endif
}
#ifdef USE_OPTIX
else if (SampleViewerScene::getRenderType() == SampleViewerScene::rtOPTIX) {
FractureModelUpdate update( mCompounds, mOptixBufferVersion != mSceneVersion );
if (mOptixBufferVersion != mSceneVersion) {
// Complete buffer update.
mOptixBufferVersion = mSceneVersion;
}
Profiler::getInstance()->begin("Optix data update");
SampleViewerScene::getOptixRenderer()->update( update );
OptixRenderer::Camera cam;
const size_t size_of_float3 = sizeof(float) * 3;
PxVec3 lookat = mCameraPos + mCameraDir;
memcpy( cam.eye, &mCameraPos.x, size_of_float3);
memcpy( cam.lookat, &lookat.x, size_of_float3);
memcpy( cam.up, &mCameraUp.x, size_of_float3);
cam.fov = mCameraFov;
Profiler::getInstance()->end("Optix data update");
Profiler::getInstance()->begin("Optix render");
SampleViewerScene::getOptixRenderer()->render( cam );
Profiler::getInstance()->end("Optix render");
}
#endif // USE_OPTIX
}
// --------------------------------------------------------------------------------------------
void SimScene::dumpSceneGeometry()
{
#ifdef USE_OPTIX
if( SampleViewerScene::getRenderType() == SampleViewerScene::rtOPTIX && SampleViewerScene::getOptixRenderer()) {
SampleViewerScene::getOptixRenderer()->dump_geometry();
}
#endif
}