diff --git a/examples/BasicDemo/BasicExample.cpp b/examples/BasicDemo/BasicExample.cpp index d501b5109..775f6fbb6 100644 --- a/examples/BasicDemo/BasicExample.cpp +++ b/examples/BasicDemo/BasicExample.cpp @@ -52,7 +52,7 @@ void BasicExample::initPhysics() m_guiHelper->setUpAxis(1); createEmptyDynamicsWorld(); - + //m_dynamicsWorld->setGravity(btVector3(0,0,0)); m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); if (m_dynamicsWorld->getDebugDrawer()) @@ -63,7 +63,7 @@ void BasicExample::initPhysics() //groundShape->initializePolyhedralFeatures(); -// btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50); + //btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50); m_collisionShapes.push_back(groundShape); diff --git a/examples/BasicDemo/main.cpp b/examples/BasicDemo/main.cpp index fa576f451..eb5e6c958 100644 --- a/examples/BasicDemo/main.cpp +++ b/examples/BasicDemo/main.cpp @@ -18,38 +18,252 @@ subject to the following restrictions: #include "../CommonInterfaces/CommonExampleInterface.h" #include "../CommonInterfaces/CommonGUIHelperInterface.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" +#include "BulletCollision/CollisionShapes/btCollisionShape.h" +#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h" +#include "LinearMath/btTransform.h" +#include "LinearMath/btHashMap.h" + #ifdef USE_GUI +#include "../TinyRenderer/TinyRenderer.h" #include "../OpenGLWindow/SimpleOpenGL3App.h" #include #include "../ExampleBrowser/OpenGLGuiHelper.h" +class SW_And_OpenGLGuiHelper : public OpenGLGuiHelper +{ + + btHashMap m_swRenderObjects; + btHashMap m_swInstances; + + + int m_swWidth; + int m_swHeight; + TGAImage m_rgbColorBuffer; + + b3AlignedObjectArray m_depthBuffer; + int m_textureHandle; + unsigned char* m_image; + GLPrimitiveRenderer* m_primRenderer; + +public: + SW_And_OpenGLGuiHelper (CommonGraphicsApp* glApp, bool useOpenGL2, int swWidth, int swHeight, GLPrimitiveRenderer* primRenderer) + :OpenGLGuiHelper(glApp,useOpenGL2), + m_swWidth(swWidth), + m_swHeight(swHeight), + m_rgbColorBuffer(swWidth,swHeight,TGAImage::RGB), + m_primRenderer(primRenderer) + { + + m_depthBuffer.resize(swWidth*swHeight); + CommonRenderInterface* render = getRenderInterface(); + m_image=new unsigned char[m_swWidth*m_swHeight*4]; + + m_textureHandle = render->registerTexture(m_image,m_swWidth,m_swHeight); + } + + void clearBuffers(TGAColor& clearColor) + { + for(int y=0;ygetUserIndex(); + int shapeIndex = obj->getCollisionShape()->getUserIndex(); + + if (colIndex>=0 && shapeIndex>=0) + { + m_swInstances.insert(colIndex,shapeIndex); + } + + } + + virtual int registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices) + { + int shapeIndex = OpenGLGuiHelper::registerGraphicsShape(vertices,numvertices,indices,numIndices); + if (shapeIndex>=0) + { + TinyRenderObjectData* swObj = new TinyRenderObjectData(m_swWidth,m_swHeight,m_rgbColorBuffer,m_depthBuffer); + //swObj->registerMeshShape(vertices,numvertices,indices,numIndices); + swObj->createCube(1,1,1);//MeshShape(vertices,numvertices,indices,numIndices); + + m_swRenderObjects.insert(shapeIndex,swObj); + } + return shapeIndex; + } + + virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling) + { + int instanceId = OpenGLGuiHelper::registerGraphicsInstance(shapeIndex,position,quaternion,color,scaling); + return instanceId ; + } + + virtual void createCollisionShapeGraphicsObject(btCollisionShape* collisionShape) + { + OpenGLGuiHelper::createCollisionShapeGraphicsObject(collisionShape); + } + + virtual void syncPhysicsToGraphics(const btDiscreteDynamicsWorld* rbWorld) + { + OpenGLGuiHelper::syncPhysicsToGraphics(rbWorld); + } + + virtual void render(const btDiscreteDynamicsWorld* rbWorld) + { + OpenGLGuiHelper::render(rbWorld); + + //clear the color buffer + TGAColor clearColor; + clearColor.bgra[0] = 255; + clearColor.bgra[1] = 255; + clearColor.bgra[2] = 255; + clearColor.bgra[3] = 255; + + clearBuffers(clearColor); + + + ATTRIBUTE_ALIGNED16(float modelMat[16]); + ATTRIBUTE_ALIGNED16(float viewMat[16]); + CommonRenderInterface* render = getRenderInterface(); + + render->getActiveCamera()->getCameraViewMatrix(viewMat); + + + for (int i=0;igetNumCollisionObjects();i++) + { + btCollisionObject* colObj = rbWorld->getCollisionObjectArray()[i]; + int colObjIndex = colObj->getUserIndex(); + int shapeIndex = colObj->getCollisionShape()->getUserIndex(); + if (colObjIndex>=0 && shapeIndex>=0) + { + + TinyRenderObjectData* renderObj = 0; + + int* cptr = m_swInstances[colObjIndex]; + if (cptr) + { + int c = *cptr; + TinyRenderObjectData** sptr = m_swRenderObjects[c]; + if (sptr) + { + renderObj = *sptr; + } + } + //sync the object transform + const btTransform& tr = colObj->getWorldTransform(); + tr.getOpenGLMatrix(modelMat); + + for (int i=0;i<4;i++) + { + for (int j=0;j<4;j++) + { + renderObj->m_modelMatrix[i][j] = modelMat[i+4*j]; + renderObj->m_viewMatrix[i][j] = viewMat[i+4*j]; + } + } + TinyRenderer::renderObject(*renderObj); + } + } + + for(int y=0;yactivateTexture(m_textureHandle); + render->updateTexture(m_textureHandle,m_image); + + static int counter=0; + counter++; + if (counter>10) + { + counter=0; + getFrameBuffer().write_tga_file("/Users/erwincoumans/develop/bullet3/framebuf.tga",true); + } + float color[4] = {1,1,1,1}; + m_primRenderer->drawTexturedRect(0,0,m_swWidth, m_swHeight,color,0,0,1,1,true); + + + } + + virtual void autogenerateGraphicsObjects(btDiscreteDynamicsWorld* rbWorld) + { + OpenGLGuiHelper::autogenerateGraphicsObjects(rbWorld); + } + +}; + int main(int argc, char* argv[]) { SimpleOpenGL3App* app = new SimpleOpenGL3App("BasicDemoGui",1024,768,true); - OpenGLGuiHelper gui(app,false); - CommonExampleOptions options(&gui); - CommonExampleInterface* example = BasicExampleCreateFunc(options); + int textureWidth = 640; + int textureHeight = 480; + + + SW_And_OpenGLGuiHelper gui(app,false,textureWidth,textureHeight,app->m_primRenderer); + + CommonExampleOptions options(&gui); + CommonExampleInterface* example = BasicExampleCreateFunc(options); example->initPhysics(); - int frameCount = 0; do { app->m_instancingRenderer->init(); - app->m_instancingRenderer->updateCamera(); - example->stepSimulation(1./60.); - example->renderScene(); - app->drawGrid(); - app->swapBuffer(); - } while (!app->m_window->requestedExit()); + app->m_instancingRenderer->updateCamera(); - example->exitPhysics(); - delete example; + example->stepSimulation(1./60.); + + + example->renderScene(); + + app->drawGrid(); + app->swapBuffer(); + } while (!app->m_window->requestedExit()); + + example->exitPhysics(); + delete example; delete app; - return 0; + return 0; } diff --git a/examples/BasicDemo/premake4.lua b/examples/BasicDemo/premake4.lua index c55bc2525..8e9625e55 100644 --- a/examples/BasicDemo/premake4.lua +++ b/examples/BasicDemo/premake4.lua @@ -46,7 +46,13 @@ files { "**.cpp", "**.h", "../ExampleBrowser/OpenGLGuiHelper.cpp", - "../ExampleBrowser/GL_ShapeDrawer.cpp" + "../ExampleBrowser/GL_ShapeDrawer.cpp", + "../TinyRenderer/geometry.cpp", + "../TinyRenderer/model.cpp", + "../TinyRenderer/tgaimage.cpp", + "../TinyRenderer/our_gl.cpp", + "../TinyRenderer/TinyRenderer.cpp", + "../Utils/b3ResourcePath.cpp" } if os.is("Linux") then initX11() end diff --git a/examples/ExampleBrowser/OpenGLGuiHelper.cpp b/examples/ExampleBrowser/OpenGLGuiHelper.cpp index 19d392758..ec88c0c78 100644 --- a/examples/ExampleBrowser/OpenGLGuiHelper.cpp +++ b/examples/ExampleBrowser/OpenGLGuiHelper.cpp @@ -437,7 +437,7 @@ void OpenGLGuiHelper::createCollisionShapeGraphicsObject(btCollisionShape* colli if (vertices.size() && indices.size()) { - int shapeId = m_data->m_glApp->m_renderer->registerShape(&vertices[0].xyzw[0],vertices.size(),&indices[0],indices.size()); + int shapeId = registerGraphicsShape(&vertices[0].xyzw[0],vertices.size(),&indices[0],indices.size()); collisionShape->setUserIndex(shapeId); } diff --git a/examples/ExampleBrowser/premake4.lua b/examples/ExampleBrowser/premake4.lua index 9239b5924..f671d5a0d 100644 --- a/examples/ExampleBrowser/premake4.lua +++ b/examples/ExampleBrowser/premake4.lua @@ -46,6 +46,8 @@ project "App_BulletExampleBrowser" files {"../LuaDemo/LuaPhysicsSetup.cpp"} end + defines {"INCLUDE_CLOTH_DEMOS"} + files { "main.cpp", "ExampleEntries.cpp", diff --git a/examples/OpenGLWindow/GLInstancingRenderer.cpp b/examples/OpenGLWindow/GLInstancingRenderer.cpp index 2bd7c92ad..e6304ad70 100644 --- a/examples/OpenGLWindow/GLInstancingRenderer.cpp +++ b/examples/OpenGLWindow/GLInstancingRenderer.cpp @@ -561,9 +561,9 @@ void GLInstancingRenderer::updateTexture(int textureIndex, const unsigned cha { for (int j = 0; j < h.m_height; j++) { - flippedTexels[(i + j*h.m_width) * 3] = texels[(i + (h.m_height-1-j)*h.m_width) * 3]; - flippedTexels[(i + j*h.m_width) * 3+1] = texels[(i + (h.m_height - 1 - j)*h.m_width) * 3+1]; - flippedTexels[(i + j*h.m_width) * 3+2] = texels[(i + (h.m_height - 1 - j)*h.m_width) * 3+1]; + flippedTexels[(i + j*h.m_width) * 3] = texels[(i + (h.m_height - 1 -j )*h.m_width) * 3]; + flippedTexels[(i + j*h.m_width) * 3+1] = texels[(i + (h.m_height - 1 - j)*h.m_width) * 3+1]; + flippedTexels[(i + j*h.m_width) * 3+2] = texels[(i + (h.m_height - 1 - j)*h.m_width) * 3+2]; } } diff --git a/examples/TinyRenderer/TinyRenderer.cpp b/examples/TinyRenderer/TinyRenderer.cpp index bbc9bbf16..a78e9d6ac 100644 --- a/examples/TinyRenderer/TinyRenderer.cpp +++ b/examples/TinyRenderer/TinyRenderer.cpp @@ -3,12 +3,13 @@ #include #include #include -#include "TinyRenderer/tgaimage.h" -#include "TinyRenderer/model.h" -#include "TinyRenderer/geometry.h" -#include "TinyRenderer/our_gl.h" +#include "tgaimage.h" +#include "model.h" +#include "geometry.h" +#include "our_gl.h" #include "../Utils/b3ResourcePath.h" #include "Bullet3Common/b3MinMax.h" +#include "../OpenGLWindow/ShapeData.h" Vec3f light_dir_world(1,1,1); @@ -35,7 +36,11 @@ struct Shader : public IShader { } virtual Vec4f vertex(int iface, int nthvert) { - varying_uv.set_col(nthvert, m_model->uv(iface, nthvert)); + + Vec2f uv = m_model->uv(iface, nthvert); + //printf("uv = %f,%f\n", uv.x,uv.y); + varying_uv.set_col(nthvert, uv); + varying_nrm.set_col(nthvert, proj<3>((m_projectionMatrix*m_modelView).invert_transpose()*embed<4>(m_model->normal(iface, nthvert), 0.f))); Vec4f gl_Vertex = m_projectionMatrix*m_modelView*embed<4>(m_model->vert(iface, nthvert)); varying_tri.set_col(nthvert, gl_Vertex); @@ -64,49 +69,37 @@ struct Shader : public IShader { Vec3f n = (B*m_model->normal(uv)).normalize(); - float diff = b3Min(b3Max(0.f, n*m_light_dir_local+0.6f),1.f); + //float diff = b3Min(b3Max(0.f, n*m_light_dir_local+0.3f),1.f); + float diff = b3Max(0.f, n*m_light_dir_local); color = m_model->diffuse(uv)*diff; return false; } }; -/* -struct TinyRenderObjectData -{ - //Camera - Matrix m_viewMatrix; - Matrix m_projectionMatrix; - Matrix m_viewPortMatrix; - //Model (vertices, indices, textures, shader) - Matrix m_modelMatrix; - class Model* m_model; - class IShader* m_shader; - - - //Output - TGAImage m_rgbColorBuffer; - b3AlignedObjectArray m_depthBuffer; -}; -*/ - -TinyRenderObjectData::TinyRenderObjectData(int width, int height, const char* fileName) +TinyRenderObjectData::TinyRenderObjectData(int width, int height,TGAImage& rgbColorBuffer,b3AlignedObjectArray&depthBuffer) :m_width(width), m_height(height), -m_rgbColorBuffer(width,height,TGAImage::RGB), -m_model(0) +m_rgbColorBuffer(rgbColorBuffer), +m_depthBuffer(depthBuffer), +m_model(0), +m_userData(0), +m_userIndex(-1) { Vec3f eye(1,1,3); Vec3f center(0,0,0); Vec3f up(0,1,0); + m_modelMatrix = Matrix::identity(); m_viewMatrix = lookat(eye, center, up); m_viewportMatrix = viewport(width/8, height/8, width*3/4, height*3/4); m_projectionMatrix = projection(-1.f/(eye-center).norm()); + +} - - m_depthBuffer.resize(width*height); +void TinyRenderObjectData::loadModel(const char* fileName) +{ //todo(erwincoumans) move the file loading out of here char relativeFileName[1024]; if (!b3ResourcePath::findResourcePath(fileName, relativeFileName, 1024)) @@ -115,9 +108,73 @@ m_model(0) } else { m_model = new Model(relativeFileName); + } +} + + +void TinyRenderObjectData::registerMeshShape(const float* vertices, int numVertices,const int* indices, int numIndices) +{ + if (0==m_model) + { + m_model = new Model(); + char relativeFileName[1024]; + if (b3ResourcePath::findResourcePath("floor_diffuse.tga", relativeFileName, 1024)) + { + m_model->loadDiffuseTexture(relativeFileName); + } + + for (int i=0;iaddVertex(vertices[i*9], + vertices[i*9+1], + vertices[i*9+2], + vertices[i*9+4], + vertices[i*9+5], + vertices[i*9+6], + vertices[i*9+7], + vertices[i*9+8]); + } + for (int i=0;iaddTriangle(indices[i],indices[i],indices[i], + indices[i+1],indices[i+1],indices[i+1], + indices[i+2],indices[i+2],indices[i+2]); + } + } +} +void TinyRenderObjectData::createCube(float halfExtentsX,float halfExtentsY,float halfExtentsZ) +{ + m_model = new Model(); + + char relativeFileName[1024]; + if (b3ResourcePath::findResourcePath("floor_diffuse.tga", relativeFileName, 1024)) + { + m_model->loadDiffuseTexture(relativeFileName); } - + + int strideInBytes = 9*sizeof(float); + int numVertices = sizeof(cube_vertices_textured)/strideInBytes; + int numIndices = sizeof(cube_indices)/sizeof(int); + + for (int i=0;iaddVertex(halfExtentsX*cube_vertices_textured[i*9], + halfExtentsY*cube_vertices_textured[i*9+1], + halfExtentsY*cube_vertices_textured[i*9+2], + cube_vertices_textured[i*9+4], + cube_vertices_textured[i*9+5], + cube_vertices_textured[i*9+6], + cube_vertices_textured[i*9+7], + cube_vertices_textured[i*9+8]); + } + for (int i=0;iaddTriangle(cube_indices[i],cube_indices[i],cube_indices[i], + cube_indices[i+1],cube_indices[i+1],cube_indices[i+1], + cube_indices[i+2],cube_indices[i+2],cube_indices[i+2]); + } + } TinyRenderObjectData::~TinyRenderObjectData() @@ -127,34 +184,20 @@ TinyRenderObjectData::~TinyRenderObjectData() void TinyRenderer::renderObject(TinyRenderObjectData& renderData) { - const char* fileName = "obj/floor.obj"; - - - -//new Model(relativeFileName);//argv[m]); Model* model = renderData.m_model; if (0==model) return; - const int width = renderData.m_width; - const int height = renderData.m_height; b3AlignedObjectArray& zbuffer = renderData.m_depthBuffer; - //todo(erwincoumans) make this a separate call - for (int i=width*height; i--; zbuffer[i] = -std::numeric_limits::max()); - TGAImage& frame = renderData.m_rgbColorBuffer; - - //lookat(eye, center, up); - //viewport(width/8, height/8, width*3/4, height*3/4); - //projection(-1.f/(eye-center).norm()); - - Vec3f light_dir_local = proj<3>((renderData.m_projectionMatrix*renderData.m_viewMatrix*embed<4>(light_dir_world, 0.f))).normalize(); + + Vec3f light_dir_local = proj<3>((renderData.m_projectionMatrix*renderData.m_viewMatrix*renderData.m_modelMatrix*embed<4>(light_dir_world, 0.f))).normalize(); { - //for (int m=1; mnfaces(); i++) { for (int j=0; j<3; j++) { shader.vertex(i, j); @@ -163,9 +206,6 @@ void TinyRenderer::renderObject(TinyRenderObjectData& renderData) } } - //frame.flip_vertically(); // to place the origin in the bottom left corner of the image - //frame.write_tga_file("framebuffer.tga"); - } diff --git a/examples/TinyRenderer/TinyRenderer.h b/examples/TinyRenderer/TinyRenderer.h index 1bcd49b95..86514b545 100644 --- a/examples/TinyRenderer/TinyRenderer.h +++ b/examples/TinyRenderer/TinyRenderer.h @@ -1,10 +1,9 @@ #ifndef TINY_RENDERER_H #define TINY_RENDERER_H -//#include "TinyRenderer/our_gl.h" -#include "TinyRenderer/geometry.h" +#include "geometry.h" #include "Bullet3Common/b3AlignedObjectArray.h" -#include "TinyRenderer/tgaimage.h" +#include "tgaimage.h" struct TinyRenderObjectData { @@ -14,19 +13,25 @@ struct TinyRenderObjectData Matrix m_viewportMatrix; //Model (vertices, indices, textures, shader) - Matrix m_modelMatrix; + Matrix m_modelMatrix; class Model* m_model; //class IShader* m_shader; todo(erwincoumans) expose the shader, for now we use a default shader //Output int m_width; int m_height; - TGAImage m_rgbColorBuffer; - b3AlignedObjectArray m_depthBuffer; + TGAImage& m_rgbColorBuffer; + b3AlignedObjectArray& m_depthBuffer; - TinyRenderObjectData(int width, int height, const char* objFileName); + TinyRenderObjectData(int width, int height,TGAImage& rgbColorBuffer,b3AlignedObjectArray& depthBuffer); virtual ~TinyRenderObjectData(); + void loadModel(const char* fileName); + void createCube(float HalfExtentsX,float HalfExtentsY,float HalfExtentsZ); + void registerMeshShape(const float* vertices, int numVertices,const int* indices, int numIndices); + + void* m_userData; + int m_userIndex; }; diff --git a/examples/TinyRenderer/main.cpp b/examples/TinyRenderer/main.cpp index 65a3352f6..b6ca73126 100644 --- a/examples/TinyRenderer/main.cpp +++ b/examples/TinyRenderer/main.cpp @@ -1,6 +1,8 @@ #include "OpenGLWindow/SimpleOpenGL3App.h" #include "Bullet3Common/b3Quaternion.h" #include "Bullet3Common/b3CommandLineArgs.h" +#include "Bullet3Common/b3Transform.h" + #include "assert.h" #include @@ -81,8 +83,16 @@ int main(int argc, char* argv[]) int textureWidth = gWidth; int textureHeight = gHeight; - TinyRenderObjectData renderData(textureWidth, textureHeight, "floor.obj"); - + TGAImage rgbColorBuffer(textureWidth,textureHeight,TGAImage::RGB); + b3AlignedObjectArray depthBuffer; + depthBuffer.resize(textureWidth*textureHeight); + + TinyRenderObjectData renderData(textureWidth, textureHeight,rgbColorBuffer,depthBuffer);//, "african_head/african_head.obj");//floor.obj"); + + //renderData.loadModel("african_head/african_head.obj"); + renderData.loadModel("floor.obj"); + + //renderData.createCube(1,1,1); myArgs.GetCmdLineArgument("mp4_file",gVideoFileName); @@ -123,19 +133,7 @@ int main(int argc, char* argv[]) app->m_instancingRenderer->init(); app->m_instancingRenderer->updateCamera(); - float projMat[16]; - app->m_instancingRenderer->getActiveCamera()->getCameraProjectionMatrix(projMat); - float viewMat[16]; - app->m_instancingRenderer->getActiveCamera()->getCameraViewMatrix(viewMat); - for (int i=0;i<4;i++) - { - for (int j=0;j<4;j++) - { - renderData.m_viewMatrix[i][j] = viewMat[i+4*j]; - //renderData.m_projectionMatrix[i][j] = projMat[i+4*j]; - } - } - + ///clear the color and z (depth) buffer for(int y=0;ym_instancingRenderer->getActiveCamera()->getCameraProjectionMatrix(projMat); + float viewMat[16]; + app->m_instancingRenderer->getActiveCamera()->getCameraViewMatrix(viewMat); + B3_ATTRIBUTE_ALIGNED16(float modelMat[16]); + + //sync the object transform + b3Transform tr; + tr.setIdentity(); + static float posUp = 0.f; + // posUp += 0.001; + b3Vector3 org = b3MakeVector3(0,posUp,0); + tr.setOrigin(org); + tr.getOpenGLMatrix(modelMat); + + for (int i=0;i<4;i++) + { + for (int j=0;j<4;j++) + { + renderData.m_viewMatrix[i][j] = viewMat[i+4*j]; + renderData.m_modelMatrix[i][j] = modelMat[i+4*j]; + } + } + + //render the object TinyRenderer::renderObject(renderData); #if 1 @@ -162,9 +187,10 @@ int main(int argc, char* argv[]) { TGAColor color = renderData.m_rgbColorBuffer.get(x,y); - pi[0] = color.bgra[2]; - pi[1] = color.bgra[1]; - pi[2] = color.bgra[0]; + pi[0] = color.bgra[2]; + pi[1] = color.bgra[1]; + pi[2] = color.bgra[0]; + pi[3] = 255; pi+=3; } } @@ -177,10 +203,13 @@ int main(int argc, char* argv[]) unsigned char* pi=image+y*textureWidth*3; for(int x=0;x>4; const unsigned char b=180; unsigned char c=b+((s+(t&1))&1)*(255-b); - pi[0]=pi[1]=pi[2]=pi[3]=c;pi+=3; + pi[0]=pi[1]=pi[2]=pi[3]=c; + pi+=3; } } #endif diff --git a/examples/TinyRenderer/model.cpp b/examples/TinyRenderer/model.cpp index bc7983dd5..f52b01126 100644 --- a/examples/TinyRenderer/model.cpp +++ b/examples/TinyRenderer/model.cpp @@ -44,6 +44,34 @@ Model::Model(const char *filename) : verts_(), faces_(), norms_(), uv_(), diffus load_texture(filename, "_spec.tga", specularmap_); } +Model::Model():verts_(), faces_(), norms_(), uv_(), diffusemap_(), normalmap_(), specularmap_() +{ +} + +void Model::loadDiffuseTexture(const char* relativeFileName) +{ + diffusemap_.read_tga_file(relativeFileName); +} + +void Model::addVertex(float x,float y,float z, float normalX, float normalY, float normalZ, float u, float v) +{ + verts_.push_back(Vec3f(x,y,z)); + norms_.push_back(Vec3f(normalX,normalY,normalZ)); + uv_.push_back(Vec2f(u,v)); + +} +void Model::addTriangle(int vertexposIndex0, int normalIndex0, int uvIndex0, + int vertexposIndex1, int normalIndex1, int uvIndex1, + int vertexposIndex2, int normalIndex2, int uvIndex2) +{ + std::vector f; + f.push_back(Vec3i(vertexposIndex0, normalIndex0, uvIndex0)); + f.push_back(Vec3i(vertexposIndex1, normalIndex1, uvIndex1)); + f.push_back(Vec3i(vertexposIndex2, normalIndex2, uvIndex2)); + faces_.push_back(f); +} + + Model::~Model() {} int Model::nverts() { diff --git a/examples/TinyRenderer/model.h b/examples/TinyRenderer/model.h index 035cc119a..72f505f9a 100644 --- a/examples/TinyRenderer/model.h +++ b/examples/TinyRenderer/model.h @@ -17,6 +17,13 @@ private: void load_texture(std::string filename, const char *suffix, TGAImage &img); public: Model(const char *filename); + Model(); + void loadDiffuseTexture(const char* relativeFileName); + void addVertex(float x,float y,float z, float normalX, float normalY, float normalZ, float u, float v); + void addTriangle(int vertexposIndex0, int normalIndex0, int uvIndex0, + int vertexposIndex1, int normalIndex1, int uvIndex1, + int vertexposIndex2, int normalIndex2, int uvIndex2); + ~Model(); int nverts(); int nfaces(); diff --git a/examples/TinyRenderer/our_gl.cpp b/examples/TinyRenderer/our_gl.cpp index 4c99c0685..867c2cdd3 100644 --- a/examples/TinyRenderer/our_gl.cpp +++ b/examples/TinyRenderer/our_gl.cpp @@ -61,23 +61,36 @@ Vec3f barycentric(Vec2f A, Vec2f B, Vec2f C, Vec2f P) { void triangle(mat<4,3,float> &clipc, IShader &shader, TGAImage &image, float *zbuffer, const Matrix& viewPortMatrix) { mat<3,4,float> pts = (viewPortMatrix*clipc).transpose(); // transposed to ease access to each of the points - mat<3,2,float> pts2; + + + //we don't clip triangles that cross the near plane, just discard them instead of showing artifacts + if (pts[0][3]<0 || pts[1][3] <0 || pts[2][3] <0) + return; + + + mat<3,2,float> pts2; for (int i=0; i<3; i++) pts2[i] = proj<2>(pts[i]/pts[i][3]); Vec2f bboxmin( std::numeric_limits::max(), std::numeric_limits::max()); Vec2f bboxmax(-std::numeric_limits::max(), -std::numeric_limits::max()); Vec2f clamp(image.get_width()-1, image.get_height()-1); + for (int i=0; i<3; i++) { for (int j=0; j<2; j++) { bboxmin[j] = b3Max(0.f, b3Min(bboxmin[j], pts2[i][j])); bboxmax[j] = b3Min(clamp[j], b3Max(bboxmax[j], pts2[i][j])); } } - Vec2i P; + + + + Vec2i P; TGAColor color; for (P.x=bboxmin.x; P.x<=bboxmax.x; P.x++) { for (P.y=bboxmin.y; P.y<=bboxmax.y; P.y++) { Vec3f bc_screen = barycentric(pts2[0], pts2[1], pts2[2], P); + + Vec3f bc_clip = Vec3f(bc_screen.x/pts[0][3], bc_screen.y/pts[1][3], bc_screen.z/pts[2][3]); bc_clip = bc_clip/(bc_clip.x+bc_clip.y+bc_clip.z); float frag_depth = clipc[2]*bc_clip; diff --git a/examples/TinyRenderer/tgaimage.cpp b/examples/TinyRenderer/tgaimage.cpp index 47e6ff833..b68fb32fc 100644 --- a/examples/TinyRenderer/tgaimage.cpp +++ b/examples/TinyRenderer/tgaimage.cpp @@ -141,7 +141,7 @@ bool TGAImage::load_rle_data(std::ifstream &in) { return true; } -bool TGAImage::write_tga_file(const char *filename, bool rle) { +bool TGAImage::write_tga_file(const char *filename, bool rle) const { unsigned char developer_area_ref[4] = {0, 0, 0, 0}; unsigned char extension_area_ref[4] = {0, 0, 0, 0}; unsigned char footer[18] = {'T','R','U','E','V','I','S','I','O','N','-','X','F','I','L','E','.','\0'}; @@ -202,7 +202,7 @@ bool TGAImage::write_tga_file(const char *filename, bool rle) { } // TODO: it is not necessary to break a raw chunk for two equal pixels (for the matter of the resulting size) -bool TGAImage::unload_rle_data(std::ofstream &out) { +bool TGAImage::unload_rle_data(std::ofstream &out) const { const unsigned char max_chunk_length = 128; unsigned long npixels = width*height; unsigned long curpix = 0; @@ -244,9 +244,9 @@ bool TGAImage::unload_rle_data(std::ofstream &out) { return true; } -TGAColor TGAImage::get(int x, int y) { +TGAColor TGAImage::get(int x, int y) const { if (!data || x<0 || y<0 || x>=width || y>=height) { - return TGAColor(); + return TGAColor(128.f,128.f,128.f,255.f); } return TGAColor(data+(x+y*width)*bytespp, bytespp); } diff --git a/examples/TinyRenderer/tgaimage.h b/examples/TinyRenderer/tgaimage.h index 63a944bca..7a4dbfae9 100644 --- a/examples/TinyRenderer/tgaimage.h +++ b/examples/TinyRenderer/tgaimage.h @@ -68,7 +68,7 @@ protected: int bytespp; bool load_rle_data(std::ifstream &in); - bool unload_rle_data(std::ofstream &out); + bool unload_rle_data(std::ofstream &out) const; public: enum Format { GRAYSCALE=1, RGB=3, RGBA=4 @@ -78,11 +78,12 @@ public: TGAImage(int w, int h, int bpp); TGAImage(const TGAImage &img); bool read_tga_file(const char *filename); - bool write_tga_file(const char *filename, bool rle=true); + bool write_tga_file(const char *filename, bool rle=true) const; bool flip_horizontally(); bool flip_vertically(); bool scale(int w, int h); - TGAColor get(int x, int y); + TGAColor get(int x, int y) const; + bool set(int x, int y, TGAColor &c); bool set(int x, int y, const TGAColor &c); ~TGAImage();