diff options
Diffstat (limited to 'KaplaDemo/samples/sampleViewer3/Fracture/ConvexRenderer.cpp')
| -rw-r--r-- | KaplaDemo/samples/sampleViewer3/Fracture/ConvexRenderer.cpp | 376 |
1 files changed, 376 insertions, 0 deletions
diff --git a/KaplaDemo/samples/sampleViewer3/Fracture/ConvexRenderer.cpp b/KaplaDemo/samples/sampleViewer3/Fracture/ConvexRenderer.cpp new file mode 100644 index 00000000..4c438127 --- /dev/null +++ b/KaplaDemo/samples/sampleViewer3/Fracture/ConvexRenderer.cpp @@ -0,0 +1,376 @@ +#include "Shader.h" +#include "ConvexRenderer.h" +#include "Compound.h" +#include <foundation/PxMat44.h> + +//-------------------------------------------------------- +ConvexRenderer::ConvexRenderer() +{ + init(); +} + +//-------------------------------------------------------- +ConvexRenderer::~ConvexRenderer() +{ +} + +//-------------------------------------------------------- +void ConvexRenderer::init() +{ + mShader = NULL; + mShaderMat.init(); + + mBumpTextureUVScale = 0.1f; + mExtraNoiseScale = 2.0f; + mRoughnessScale = 0.2f; + + mDiffuseTexArray = 0; + mBumpTexArray = 0; + mSpecularTexArray = 0; + mEmissiveReflectSpecPowerTexArray = 0; + + mActive = true; +} + +//-------------------------------------------------------- +void ConvexRenderer::add(const base::Convex* convex, Shader* shader) +{ + if (!mActive) + return; + + ConvexGroup *g; + + // int gnr = 0; // to search all groups + int gnr = 0;// !mGroups.empty() ? mGroups.size() - 1 : 0; // to search only last + int numNewVerts = convex->getVisVertices().size(); + + while (gnr < (int)mGroups.size() && (mGroups[gnr]->numVertices + numNewVerts >= maxVertsPerGroup || mGroups[gnr]->mShader != shader)) + gnr++; + + if (gnr == (int)mGroups.size()) { // create new group + g = new ConvexGroup(); + g->init(); + g->mShader = shader; + gnr = mGroups.size(); + mGroups.push_back(g); + } + g = mGroups[gnr]; + convex->setConvexRendererInfo(gnr, g->convexes.size()); + g->convexes.push_back((Convex*)convex); + g->numIndices += convex->getVisTriIndices().size(); + g->numVertices += convex->getVisVertices().size(); + g->dirty = true; + +} + +//-------------------------------------------------------- +void ConvexRenderer::remove(const base::Convex* convex) +{ + if (!mActive) + return; + + int gnr = convex->getConvexRendererGroupNr(); + int pos = convex->getConvexRendererGroupPos(); + if (gnr < 0 || gnr >= (int)mGroups.size()) + return; + + ConvexGroup *g = mGroups[gnr]; + if (pos < 0 || pos > (int)g->convexes.size()) + return; + + if (g->convexes[pos] != convex) + return; + + g->numIndices -= convex->getVisTriIndices().size(); + g->numVertices -= convex->getVisVertices().size(); + + g->convexes[pos] = g->convexes[g->convexes.size()-1]; + g->convexes[pos]->setConvexRendererInfo(gnr, pos); + g->convexes.pop_back(); + g->dirty = true; +} + +//-------------------------------------------------------- +void ConvexRenderer::updateRenderBuffers() +{ + /* + static int maxNumV = 0; + static int maxNumI = 0; + static int maxNumC = 0; + static int maxNumG = 0; + if (mGroups.size() > maxNumG) maxNumG = mGroups.size(); + */ + + for (int i = 0; i < (int)mGroups.size(); i++) { + + + ConvexGroup *g = mGroups[i]; + if (!g->dirty) + continue; + + if (g->numIndices == 0 || g->numVertices == 0) + continue; + + if (!g->VBO) { + glGenBuffersARB(1, &g->VBO); + } + if (!g->IBO) { + glGenBuffersARB(1, &g->IBO); + } + if (!g->matTex) { + glGenTextures(1, &g->matTex); + glBindTexture(GL_TEXTURE_2D, g->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); + + } + if (g->numVertices == 0 || g->numIndices == 0) + return; + + // recalculate in case they have changed + g->numVertices = 0; + g->numIndices = 0; + for (int i = 0; i < (int)g->convexes.size(); i++) { + g->numVertices += g->convexes[i]->getVisVertices().size(); + g->numIndices += g->convexes[i]->getVisTriIndices().size(); + } + + g->vertices.resize(g->numVertices*12); + g->indices.resize(g->numIndices); + float* vp = &g->vertices[0]; + unsigned int* ip = &g->indices[0]; + + int sumV = 0; + // Make cpu copy of VBO and IBO + + int convexNr = 0; + for (int j = 0; j < (int)g->convexes.size(); j++, convexNr++) { + const Convex* c = g->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; + } +/* + if (g->vertices.size() > maxNumV) maxNumV = g->vertices.size(); + if (g->indices.size() > maxNumI) maxNumI = g->indices.size(); + if (g->convexes.size() > maxNumC) maxNumC = g->convexes.size(); +*/ + glBindBufferARB(GL_ARRAY_BUFFER_ARB, g->VBO); + glBufferDataARB(GL_ARRAY_BUFFER_ARB, g->vertices.size()*sizeof(float), &g->vertices[0], GL_DYNAMIC_DRAW); + + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, g->IBO); + glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, g->indices.size()*sizeof(unsigned int), &g->indices[0], GL_DYNAMIC_DRAW); + + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); + glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + + int oldTexSize = g->texSize; + if (g->texSize == 0) { + // First time + oldTexSize = 1; + g->texSize = 32; + } + + while (1) { + int convexesPerRow = g->texSize / 4; + if (convexesPerRow * g->texSize >= (int)g->convexes.size()) { + break; + } else { + g->texSize *= 2; + } + } + if (g->texSize != oldTexSize) { + g->texCoords.resize(g->texSize*g->texSize*4); + // Let's allocate texture + glBindTexture(GL_TEXTURE_2D, g->matTex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, g->texSize, g->texSize, 0, GL_RGBA, GL_FLOAT, 0); + glBindTexture(GL_TEXTURE_2D, 0); + } + + g->dirty = false; + } + +// printf("maxV = %d, maxI = %d, maxC = %d, maxG = %d\n", maxNumV, maxNumI, maxNumC, maxNumG); + +} + +//-------------------------------------------------------- +void ConvexRenderer::updateTransformations() +{ + for (int i = 0; i < (int)mGroups.size(); i++) { + ConvexGroup *g = mGroups[i]; + if (g->texCoords.empty()) + continue; + + float* tt = &g->texCoords[0]; + + for (int j = 0; j < (int)g->convexes.size(); j++) { + const Convex* c = g->convexes[j]; + + PxMat44 pose(c->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 = c->getMaterialId(); + const int MAX_3D_TEX = 8; + ta[15] = (float)(idFor2DTex*MAX_3D_TEX + idFor3DTex); + + + } + + glBindTexture(GL_TEXTURE_2D, g->matTex); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, g->texSize, g->texSize, + GL_RGBA, GL_FLOAT, &g->texCoords[0]); + glBindTexture(GL_TEXTURE_2D, 0); + } +} + +//-------------------------------------------------------- +void ConvexRenderer::render() +{ + if (!mActive) + return; + + updateRenderBuffers(); + + updateTransformations(); + + for (int i = 0; i < (int)mGroups.size(); i++) { + + ConvexGroup *g = mGroups[i]; + + Shader* shader = mShader; + if (g->mShader != NULL) + shader = g->mShader; + + shader->activate(mShaderMat); + // Assume convex all use the same shader + + glActiveTexture(GL_TEXTURE7); + glBindTexture(GL_TEXTURE_3D, volTex); + + glActiveTexture(GL_TEXTURE8); + glBindTexture(GL_TEXTURE_2D, g->matTex); + + glActiveTexture(GL_TEXTURE10); + glBindTexture(GL_TEXTURE_2D_ARRAY_EXT, mDiffuseTexArray); + glActiveTexture(GL_TEXTURE11); + glBindTexture(GL_TEXTURE_2D_ARRAY_EXT, mBumpTexArray); + glActiveTexture(GL_TEXTURE12); + glBindTexture(GL_TEXTURE_2D_ARRAY_EXT, mSpecularTexArray); + glActiveTexture(GL_TEXTURE13); + glBindTexture(GL_TEXTURE_2D_ARRAY_EXT, mEmissiveReflectSpecPowerTexArray); + + glActiveTexture(GL_TEXTURE0); + + float itt = 1.0f/g->texSize; + + shader->setUniform("diffuseTexArray", 10); + shader->setUniform("bumpTexArray", 11); + shader->setUniform("specularTexArray", 12); + shader->setUniform("emissiveReflectSpecPowerTexArray", 13); + + shader->setUniform("ttt3D", 7); + shader->setUniform("transTex", 8); + shader->setUniform("transTexSize", g->texSize); + shader->setUniform("iTransTexSize", itt); + shader->setUniform("bumpTextureUVScale", mBumpTextureUVScale); + shader->setUniform("extraNoiseScale", mExtraNoiseScale); + shader->setUniform("roughnessScale", mRoughnessScale); + + 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, g->VBO); + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, g->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, g->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); + } + + shader->deactivate(); + } +}
\ No newline at end of file |