From d186320f3052778eaee654b9de093a40630283e0 Mon Sep 17 00:00:00 2001 From: Erwin Coumans Date: Fri, 13 May 2016 18:45:56 -0700 Subject: [PATCH] fixes in rendering --- .../Collision/CollisionTutorialBullet2.cpp | 2 +- .../CommonGraphicsAppInterface.h | 1 + examples/ExampleBrowser/CMakeLists.txt | 3 +- .../ImportMeshUtility/b3ImportMeshUtility.cpp | 97 +++++++++++++++++++ .../ImportMeshUtility/b3ImportMeshUtility.h | 15 +++ .../ImportObjDemo/ImportObjExample.cpp | 91 +++-------------- .../Wavefront2GLInstanceGraphicsShape.cpp | 62 +++++++++--- .../Wavefront2GLInstanceGraphicsShape.h | 2 +- .../OpenCL/rigidbody/GpuRigidBodyDemo.cpp | 2 +- .../RenderingExamples/TinyRendererSetup.cpp | 5 +- .../Wavefront/tiny_obj_loader.cpp | 44 ++++++++- examples/Tutorial/Tutorial.cpp | 2 +- 12 files changed, 223 insertions(+), 103 deletions(-) create mode 100644 examples/Importers/ImportMeshUtility/b3ImportMeshUtility.cpp create mode 100644 examples/Importers/ImportMeshUtility/b3ImportMeshUtility.h diff --git a/examples/Collision/CollisionTutorialBullet2.cpp b/examples/Collision/CollisionTutorialBullet2.cpp index 9473c83f2..1198f9e5d 100644 --- a/examples/Collision/CollisionTutorialBullet2.cpp +++ b/examples/Collision/CollisionTutorialBullet2.cpp @@ -226,7 +226,7 @@ public: { char relativeFileName[1024]; sprintf(relativeFileName,"%s%s",prefix[i],filename); - image = stbi_load(relativeFileName, &width, &height, &n, 0); + image = stbi_load(relativeFileName, &width, &height, &n, 3); } b3Assert(image); diff --git a/examples/CommonInterfaces/CommonGraphicsAppInterface.h b/examples/CommonInterfaces/CommonGraphicsAppInterface.h index 302148ab1..999a1762c 100644 --- a/examples/CommonInterfaces/CommonGraphicsAppInterface.h +++ b/examples/CommonInterfaces/CommonGraphicsAppInterface.h @@ -121,6 +121,7 @@ struct CommonGraphicsApp virtual void drawText3D( const char* txt, float posX, float posZY, float posZ, float size)=0; virtual int registerCubeShape(float halfExtentsX,float halfExtentsY, float halfExtentsZ, int textureIndex = -1, float textureScaling = 1)=0; virtual int registerGraphicsUnitSphereShape(EnumSphereLevelOfDetail lod, int textureId=-1) = 0; + virtual void registerGrid(int xres, int yres, float color0[4], float color1[4])=0; diff --git a/examples/ExampleBrowser/CMakeLists.txt b/examples/ExampleBrowser/CMakeLists.txt index 91536b947..735915f7e 100644 --- a/examples/ExampleBrowser/CMakeLists.txt +++ b/examples/ExampleBrowser/CMakeLists.txt @@ -205,7 +205,8 @@ SET(BulletExampleBrowser_SRCS ../Importers/ImportBsp/BspConverter.h ../Importers/ImportBullet/SerializeSetup.cpp ../Importers/ImportBullet/SerializeSetup.h - + ../Importers/ImportMeshUtility/b3ImportMeshUtility.cpp +../Importers/ImportMeshUtility/b3ImportMeshUtility.h ../../Extras/Serialize/BulletWorldImporter/btWorldImporter.cpp ../../Extras/Serialize/BulletWorldImporter/btBulletWorldImporter.cpp ../../Extras/Serialize/BulletFileLoader/bChunk.cpp diff --git a/examples/Importers/ImportMeshUtility/b3ImportMeshUtility.cpp b/examples/Importers/ImportMeshUtility/b3ImportMeshUtility.cpp new file mode 100644 index 000000000..e97f81018 --- /dev/null +++ b/examples/Importers/ImportMeshUtility/b3ImportMeshUtility.cpp @@ -0,0 +1,97 @@ +#include "b3ImportMeshUtility.h" + +#include +#include "../../OpenGLWindow/GLInstancingRenderer.h" +#include"Wavefront/tiny_obj_loader.h" +#include "../../OpenGLWindow/GLInstanceGraphicsShape.h" +#include "btBulletDynamicsCommon.h" +#include "../../OpenGLWindow/SimpleOpenGL3App.h" +#include "../ImportObjDemo/Wavefront2GLInstanceGraphicsShape.h" +#include "../../Utils/b3ResourcePath.h" +#include "Bullet3Common/b3FileUtils.h" +#include "stb_image/stb_image.h" + + +int b3ImportMeshUtility::loadAndRegisterMeshFromFile(const std::string& fileName, CommonRenderInterface* renderer) +{ + int shapeId = -1; + + char relativeFileName[1024]; + if (b3ResourcePath::findResourcePath(fileName.c_str(), relativeFileName, 1024)) + { + char pathPrefix[1024]; + + b3FileUtils::extractPath(relativeFileName, pathPrefix, 1024); + + + + btVector3 shift(0,0,0); + + // int index=10; + + { + + std::vector shapes; + std::string err = tinyobj::LoadObj(shapes, relativeFileName, pathPrefix); + + GLInstanceGraphicsShape* gfxShape = btgCreateGraphicsShapeFromWavefrontObj(shapes); + + + + int textureIndex = -1; + //try to load some texture + for (int i=0;i0) + { + + int width,height,n; + const char* filename = shape.material.diffuse_texname.c_str(); + const unsigned char* image=0; + + const char* prefix[]={ pathPrefix,"./","./data/","../data/","../../data/","../../../data/","../../../../data/"}; + int numprefix = sizeof(prefix)/sizeof(const char*); + + for (int i=0;!image && iregisterTexture(image,width,height); + if (textureIndex>=0) + { + break; + } + } + + } + + } + + shapeId = renderer->registerShape(&gfxShape->m_vertices->at(0).xyzw[0], gfxShape->m_numvertices, &gfxShape->m_indices->at(0), gfxShape->m_numIndices,B3_GL_TRIANGLES,textureIndex); + + + + + + } + } + else + { + b3Warning("Cannot find %s\n", fileName.c_str()); + } + return shapeId; +} + diff --git a/examples/Importers/ImportMeshUtility/b3ImportMeshUtility.h b/examples/Importers/ImportMeshUtility/b3ImportMeshUtility.h new file mode 100644 index 000000000..a2de5e1b6 --- /dev/null +++ b/examples/Importers/ImportMeshUtility/b3ImportMeshUtility.h @@ -0,0 +1,15 @@ +#ifndef B3_IMPORT_MESH_UTILITY_H +#define B3_IMPORT_MESH_UTILIY_H + +#include + +class b3ImportMeshUtility +{ +public: +static int loadAndRegisterMeshFromFile(const std::string& fileName, class CommonRenderInterface* renderer); + +}; + + +#endif //B3_IMPORT_MESH_UTILITY_H + diff --git a/examples/Importers/ImportObjDemo/ImportObjExample.cpp b/examples/Importers/ImportObjDemo/ImportObjExample.cpp index f4a8956b3..a8995c148 100644 --- a/examples/Importers/ImportObjDemo/ImportObjExample.cpp +++ b/examples/Importers/ImportObjDemo/ImportObjExample.cpp @@ -12,7 +12,7 @@ #include "stb_image/stb_image.h" #include "../CommonInterfaces/CommonRigidBodyBase.h" - +#include "../ImportMeshUtility/b3ImportMeshUtility.h" class ImportObjSetup : public CommonRigidBodyBase { @@ -45,7 +45,7 @@ ImportObjSetup::ImportObjSetup(struct GUIHelperInterface* helper, const char* fi m_fileName = fileName; } else { - m_fileName = "cube.obj";//sphere8.obj";//sponza_closed.obj";//sphere8.obj"; + m_fileName = "cube.obj";//"sponza_closed.obj";//sphere8.obj"; } } @@ -68,82 +68,21 @@ void ImportObjSetup::initPhysics() m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe); - - char relativeFileName[1024]; - if (b3ResourcePath::findResourcePath(m_fileName.c_str(), relativeFileName, 1024)) - { - char pathPrefix[1024]; - - b3FileUtils::extractPath(relativeFileName, pathPrefix, 1024); - - - - btVector3 shift(0,0,0); - btVector3 scaling(1,1,1); -// int index=10; - - { + btTransform trans; + trans.setIdentity(); + trans.setRotation(btQuaternion(btVector3(1,0,0),SIMD_HALF_PI)); + btVector3 position = trans.getOrigin(); + btQuaternion orn = trans.getRotation(); - std::vector shapes; - std::string err = tinyobj::LoadObj(shapes, relativeFileName, pathPrefix); + btVector3 scaling(1,1,1); + btVector3 color(1,1,1); - GLInstanceGraphicsShape* gfxShape = btgCreateGraphicsShapeFromWavefrontObj(shapes); - - btTransform trans; - trans.setIdentity(); - trans.setRotation(btQuaternion(btVector3(1,0,0),SIMD_HALF_PI)); - - btVector3 position = trans.getOrigin(); - btQuaternion orn = trans.getRotation(); - - btVector3 color(1,1,1); - - int textureIndex = -1; - //try to load some texture - for (int i=0;i0) - { - - int width,height,n; - const char* filename = shape.material.diffuse_texname.c_str(); - const unsigned char* image=0; - - const char* prefix[]={ pathPrefix,"./","./data/","../data/","../../data/","../../../data/","../../../../data/"}; - int numprefix = sizeof(prefix)/sizeof(const char*); - - for (int i=0;!image && igetRenderInterface()->registerTexture(image,width,height); - if (textureIndex>=0) - { - break; - } - } - - } - - } - - int shapeId = m_guiHelper->getRenderInterface()->registerShape(&gfxShape->m_vertices->at(0).xyzw[0], gfxShape->m_numvertices, &gfxShape->m_indices->at(0), gfxShape->m_numIndices,B3_GL_TRIANGLES,textureIndex); - - //int id = - m_guiHelper->getRenderInterface()->registerGraphicsInstance(shapeId,position,orn,color,scaling); - - - }} - else - { - b3Warning("Cannot find %s\n", m_fileName.c_str()); - } + int shapeId = b3ImportMeshUtility::loadAndRegisterMeshFromFile(m_fileName, m_guiHelper->getRenderInterface()); + if (shapeId>=0) + { + //int id = + m_guiHelper->getRenderInterface()->registerGraphicsInstance(shapeId,position,orn,color,scaling); + } } diff --git a/examples/Importers/ImportObjDemo/Wavefront2GLInstanceGraphicsShape.cpp b/examples/Importers/ImportObjDemo/Wavefront2GLInstanceGraphicsShape.cpp index c57dabf8b..a83ac9c31 100644 --- a/examples/Importers/ImportObjDemo/Wavefront2GLInstanceGraphicsShape.cpp +++ b/examples/Importers/ImportObjDemo/Wavefront2GLInstanceGraphicsShape.cpp @@ -8,7 +8,7 @@ #include "../../OpenGLWindow/GLInstancingRenderer.h" #include "../../OpenGLWindow/GLInstanceGraphicsShape.h" -GLInstanceGraphicsShape* btgCreateGraphicsShapeFromWavefrontObj(std::vector& shapes) +GLInstanceGraphicsShape* btgCreateGraphicsShapeFromWavefrontObj(std::vector& shapes, bool flatShading) { b3AlignedObjectArray* vertices = new b3AlignedObjectArray; @@ -82,29 +82,59 @@ GLInstanceGraphicsShape* btgCreateGraphicsShapeFromWavefrontObj(std::vector SIMD_EPSILON) + unsigned int maxIndex = 0; + maxIndex = b3Max(maxIndex,shape.mesh.indices[f]*3+0); + maxIndex = b3Max(maxIndex,shape.mesh.indices[f]*3+1); + maxIndex = b3Max(maxIndex,shape.mesh.indices[f]*3+2); + maxIndex = b3Max(maxIndex,shape.mesh.indices[f+1]*3+0); + maxIndex = b3Max(maxIndex,shape.mesh.indices[f+1]*3+1); + maxIndex = b3Max(maxIndex,shape.mesh.indices[f+1]*3+2); + maxIndex = b3Max(maxIndex,shape.mesh.indices[f+2]*3+0); + maxIndex = b3Max(maxIndex,shape.mesh.indices[f+2]*3+1); + maxIndex = b3Max(maxIndex,shape.mesh.indices[f+2]*3+2); + bool hasNormals = (shape.mesh.normals.size() && maxIndex SIMD_EPSILON) + { + normal.normalize(); + } else + { + normal.setValue(0,0,0); + } + vtx0.normal[0] = normal[0]; + vtx0.normal[1] = normal[1]; + vtx0.normal[2] = normal[2]; + vtx1.normal[0] = normal[0]; + vtx1.normal[1] = normal[1]; + vtx1.normal[2] = normal[2]; + vtx2.normal[0] = normal[0]; + vtx2.normal[1] = normal[1]; + vtx2.normal[2] = normal[2]; } else { - normal.setValue(0,0,0); + + vtx0.normal[0] = shape.mesh.normals[shape.mesh.indices[f]*3+0]; + vtx0.normal[1] = shape.mesh.normals[shape.mesh.indices[f]*3+1]; + vtx0.normal[2] = shape.mesh.normals[shape.mesh.indices[f]*3+2]; //shape.mesh.indices[f+1]*3+0 + vtx1.normal[0] = shape.mesh.normals[shape.mesh.indices[f+1]*3+0]; + vtx1.normal[1] = shape.mesh.normals[shape.mesh.indices[f+1]*3+1]; + vtx1.normal[2] = shape.mesh.normals[shape.mesh.indices[f+1]*3+2]; + vtx2.normal[0] = shape.mesh.normals[shape.mesh.indices[f+2]*3+0]; + vtx2.normal[1] = shape.mesh.normals[shape.mesh.indices[f+2]*3+1]; + vtx2.normal[2] = shape.mesh.normals[shape.mesh.indices[f+2]*3+2]; + + } - vtx0.normal[0] = normal[0]; - vtx0.normal[1] = normal[1]; - vtx0.normal[2] = normal[2]; - vtx1.normal[0] = normal[0]; - vtx1.normal[1] = normal[1]; - vtx1.normal[2] = normal[2]; - vtx2.normal[0] = normal[0]; - vtx2.normal[1] = normal[1]; - vtx2.normal[2] = normal[2]; vertices->push_back(vtx0); vertices->push_back(vtx1); vertices->push_back(vtx2); diff --git a/examples/Importers/ImportObjDemo/Wavefront2GLInstanceGraphicsShape.h b/examples/Importers/ImportObjDemo/Wavefront2GLInstanceGraphicsShape.h index a2b129bea..3df100a6c 100644 --- a/examples/Importers/ImportObjDemo/Wavefront2GLInstanceGraphicsShape.h +++ b/examples/Importers/ImportObjDemo/Wavefront2GLInstanceGraphicsShape.h @@ -4,6 +4,6 @@ #include"../../ThirdPartyLibs/Wavefront/tiny_obj_loader.h" #include -struct GLInstanceGraphicsShape* btgCreateGraphicsShapeFromWavefrontObj(std::vector& shapes); +struct GLInstanceGraphicsShape* btgCreateGraphicsShapeFromWavefrontObj(std::vector& shapes, bool flatShading=false); #endif //WAVEFRONT2GRAPHICS_H diff --git a/examples/OpenCL/rigidbody/GpuRigidBodyDemo.cpp b/examples/OpenCL/rigidbody/GpuRigidBodyDemo.cpp index 80e4e8e82..d2ee9794a 100644 --- a/examples/OpenCL/rigidbody/GpuRigidBodyDemo.cpp +++ b/examples/OpenCL/rigidbody/GpuRigidBodyDemo.cpp @@ -356,7 +356,7 @@ b3Vector3 GpuRigidBodyDemo::getRayTo(int x,int y) unsigned char* GpuRigidBodyDemo::loadImage(const char* fileName, int& width, int& height, int& n) { - unsigned char *data = stbi_load(fileName, &width, &height, &n, 0); + unsigned char *data = stbi_load(fileName, &width, &height, &n, 3); return data; } diff --git a/examples/RenderingExamples/TinyRendererSetup.cpp b/examples/RenderingExamples/TinyRendererSetup.cpp index d10f6f0de..33cc9e723 100644 --- a/examples/RenderingExamples/TinyRendererSetup.cpp +++ b/examples/RenderingExamples/TinyRendererSetup.cpp @@ -114,7 +114,7 @@ struct TinyRendererSetupInternalData for (int i=0;isetUpAxis(2); + m_internalData->m_canvas = m_app->m_2dCanvasInterface; diff --git a/examples/ThirdPartyLibs/Wavefront/tiny_obj_loader.cpp b/examples/ThirdPartyLibs/Wavefront/tiny_obj_loader.cpp index 5271384a2..8479992d5 100644 --- a/examples/ThirdPartyLibs/Wavefront/tiny_obj_loader.cpp +++ b/examples/ThirdPartyLibs/Wavefront/tiny_obj_loader.cpp @@ -30,6 +30,40 @@ namespace tinyobj { +//See http://stackoverflow.com/questions/6089231/getting-std-ifstream-to-handle-lf-cr-and-crlf +std::istream& safeGetline(std::istream& is, std::string& t) +{ + t.clear(); + + // The characters in the stream are read one-by-one using a std::streambuf. + // That is faster than reading them one-by-one using the std::istream. + // Code that uses streambuf this way must be guarded by a sentry object. + // The sentry object performs various tasks, + // such as thread synchronization and updating the stream state. + + std::istream::sentry se(is, true); + std::streambuf* sb = is.rdbuf(); + + for(;;) { + int c = sb->sbumpc(); + switch (c) { + case '\n': + return is; + case '\r': + if(sb->sgetc() == '\n') + sb->sbumpc(); + return is; + case EOF: + // Also handle the case when the last line has no line ending + if(t.empty()) + is.setstate(std::ios::eofbit); + return is; + default: + t += (char)c; + } + } +} + struct vertex_index { int v_idx, vt_idx, vn_idx, dummy; }; @@ -313,9 +347,11 @@ std::string LoadMtl ( int maxchars = 8192; // Alloc enough size. std::vector buf(maxchars); // Alloc enough size. while (ifs.peek() != -1) { - ifs.getline(&buf[0], maxchars); - std::string linebuf(&buf[0]); + std::string linebuf; + safeGetline(ifs,linebuf); + + // Trim newline '\r\n' or '\r' if (linebuf.size() > 0) { @@ -502,9 +538,9 @@ LoadObj( int maxchars = 8192; // Alloc enough size. std::vector buf(maxchars); // Alloc enough size. while (ifs.peek() != -1) { - ifs.getline(&buf[0], maxchars); - std::string linebuf(&buf[0]); + std::string linebuf; + safeGetline(ifs,linebuf); // Trim newline '\r\n' or '\r' if (linebuf.size() > 0) { diff --git a/examples/Tutorial/Tutorial.cpp b/examples/Tutorial/Tutorial.cpp index 8a2e0ca81..19bb62ce3 100644 --- a/examples/Tutorial/Tutorial.cpp +++ b/examples/Tutorial/Tutorial.cpp @@ -415,7 +415,7 @@ public: { char relativeFileName[1024]; sprintf(relativeFileName,"%s%s",prefix[i],filename); - image = stbi_load(relativeFileName, &width, &height, &n, 0); + image = stbi_load(relativeFileName, &width, &height, &n, 3); } b3Assert(image);