TinyRenderer.cpp 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. #include "TinyRenderer.h"
  2. #include <vector>
  3. #include <limits>
  4. #include <iostream>
  5. #include "tgaimage.h"
  6. #include "model.h"
  7. #include "geometry.h"
  8. #include "our_gl.h"
  9. #include "../Utils/b3ResourcePath.h"
  10. #include "Bullet3Common/b3MinMax.h"
  11. #include "../OpenGLWindow/ShapeData.h"
  12. #include "LinearMath/btAlignedObjectArray.h"
  13. #include "LinearMath/btVector3.h"
  14. struct Shader : public IShader {
  15. Model* m_model;
  16. Vec3f m_light_dir_local;
  17. Matrix& m_modelMat;
  18. Matrix m_invModelMat;
  19. Matrix& m_modelView1;
  20. Matrix& m_projectionMatrix;
  21. Vec3f m_localScaling;
  22. Vec4f m_colorRGBA;
  23. mat<2,3,float> varying_uv; // triangle uv coordinates, written by the vertex shader, read by the fragment shader
  24. mat<4,3,float> varying_tri; // triangle coordinates (clip coordinates), written by VS, read by FS
  25. mat<3,3,float> varying_nrm; // normal per vertex to be interpolated by FS
  26. //mat<3,3,float> ndc_tri; // triangle in normalized device coordinates
  27. Shader(Model* model, Vec3f light_dir_local, Matrix& modelView, Matrix& projectionMatrix, Matrix& modelMat, Vec3f localScaling, const Vec4f& colorRGBA)
  28. :m_model(model),
  29. m_light_dir_local(light_dir_local),
  30. m_modelView1(modelView),
  31. m_projectionMatrix(projectionMatrix),
  32. m_modelMat(modelMat),
  33. m_localScaling(localScaling),
  34. m_colorRGBA(colorRGBA)
  35. {
  36. m_invModelMat = m_modelMat.invert_transpose();
  37. }
  38. virtual Vec4f vertex(int iface, int nthvert) {
  39. Vec2f uv = m_model->uv(iface, nthvert);
  40. varying_uv.set_col(nthvert, uv);
  41. //varying_nrm.set_col(nthvert, proj<3>((m_projectionMatrix*m_modelView).invert_transpose()*embed<4>(m_model->normal(iface, nthvert), 0.f)));
  42. varying_nrm.set_col(nthvert, proj<3>(m_invModelMat*embed<4>(m_model->normal(iface, nthvert), 0.f)));
  43. //m_localNormal = m_model->normal(iface, nthvert);
  44. //varying_nrm.set_col(nthvert, m_model->normal(iface, nthvert));
  45. Vec3f unScaledVert = m_model->vert(iface, nthvert);
  46. Vec3f scaledVert=Vec3f(unScaledVert[0]*m_localScaling[0],
  47. unScaledVert[1]*m_localScaling[1],
  48. unScaledVert[2]*m_localScaling[2]);
  49. Vec4f gl_Vertex = m_projectionMatrix*m_modelView1*embed<4>(scaledVert);
  50. varying_tri.set_col(nthvert, gl_Vertex);
  51. return gl_Vertex;
  52. }
  53. virtual bool fragment(Vec3f bar, TGAColor &color) {
  54. Vec3f bn = (varying_nrm*bar).normalize();
  55. Vec2f uv = varying_uv*bar;
  56. Vec3f reflection_direction = (bn * (bn * m_light_dir_local * 2.f) - m_light_dir_local).normalize();
  57. float specular = pow(b3Max(reflection_direction.z, 0.f), m_model->specular(uv));
  58. float diffuse = b3Max(0.f, bn * m_light_dir_local);
  59. float ambient_coefficient = 0.6;
  60. float diffuse_coefficient = 0.35;
  61. float specular_coefficient = 0.05;
  62. float intensity = ambient_coefficient + b3Min(diffuse * diffuse_coefficient + specular * specular_coefficient, 1.0f - ambient_coefficient);
  63. color = m_model->diffuse(uv) * intensity;
  64. //warning: bgra color is swapped to rgba to upload texture
  65. color.bgra[0] *= m_colorRGBA[0];
  66. color.bgra[1] *= m_colorRGBA[1];
  67. color.bgra[2] *= m_colorRGBA[2];
  68. color.bgra[3] *= m_colorRGBA[3];
  69. return false;
  70. }
  71. };
  72. TinyRenderObjectData::TinyRenderObjectData(TGAImage& rgbColorBuffer,b3AlignedObjectArray<float>&depthBuffer)
  73. :m_rgbColorBuffer(rgbColorBuffer),
  74. m_depthBuffer(depthBuffer),
  75. m_segmentationMaskBufferPtr(0),
  76. m_model(0),
  77. m_userData(0),
  78. m_userIndex(-1),
  79. m_objectIndex(-1)
  80. {
  81. Vec3f eye(1,1,3);
  82. Vec3f center(0,0,0);
  83. Vec3f up(0,0,1);
  84. m_lightDirWorld.setValue(0,0,0);
  85. m_localScaling.setValue(1,1,1);
  86. m_modelMatrix = Matrix::identity();
  87. }
  88. TinyRenderObjectData::TinyRenderObjectData(TGAImage& rgbColorBuffer,b3AlignedObjectArray<float>&depthBuffer, b3AlignedObjectArray<int>* segmentationMaskBuffer, int objectIndex)
  89. :m_rgbColorBuffer(rgbColorBuffer),
  90. m_depthBuffer(depthBuffer),
  91. m_segmentationMaskBufferPtr(segmentationMaskBuffer),
  92. m_model(0),
  93. m_userData(0),
  94. m_userIndex(-1),
  95. m_objectIndex(objectIndex)
  96. {
  97. Vec3f eye(1,1,3);
  98. Vec3f center(0,0,0);
  99. Vec3f up(0,0,1);
  100. m_lightDirWorld.setValue(0,0,0);
  101. m_localScaling.setValue(1,1,1);
  102. m_modelMatrix = Matrix::identity();
  103. }
  104. void TinyRenderObjectData::loadModel(const char* fileName)
  105. {
  106. //todo(erwincoumans) move the file loading out of here
  107. char relativeFileName[1024];
  108. if (!b3ResourcePath::findResourcePath(fileName, relativeFileName, 1024))
  109. {
  110. printf("Cannot find file %s\n", fileName);
  111. } else
  112. {
  113. m_model = new Model(relativeFileName);
  114. }
  115. }
  116. void TinyRenderObjectData::registerMeshShape(const float* vertices, int numVertices,const int* indices, int numIndices, const float rgbaColor[4],
  117. unsigned char* textureImage, int textureWidth, int textureHeight)
  118. {
  119. if (0==m_model)
  120. {
  121. m_model = new Model();
  122. m_model->setColorRGBA(rgbaColor);
  123. if (textureImage)
  124. {
  125. m_model->setDiffuseTextureFromData(textureImage,textureWidth,textureHeight);
  126. } else
  127. {
  128. /*char relativeFileName[1024];
  129. if (b3ResourcePath::findResourcePath("floor_diffuse.tga", relativeFileName, 1024))
  130. {
  131. m_model->loadDiffuseTexture(relativeFileName);
  132. }
  133. */
  134. }
  135. m_model->reserveMemory(numVertices,numIndices);
  136. for (int i=0;i<numVertices;i++)
  137. {
  138. m_model->addVertex(vertices[i*9],
  139. vertices[i*9+1],
  140. vertices[i*9+2],
  141. vertices[i*9+4],
  142. vertices[i*9+5],
  143. vertices[i*9+6],
  144. vertices[i*9+7],
  145. vertices[i*9+8]);
  146. }
  147. for (int i=0;i<numIndices;i+=3)
  148. {
  149. m_model->addTriangle(indices[i],indices[i],indices[i],
  150. indices[i+1],indices[i+1],indices[i+1],
  151. indices[i+2],indices[i+2],indices[i+2]);
  152. }
  153. }
  154. }
  155. void TinyRenderObjectData::registerMesh2(btAlignedObjectArray<btVector3>& vertices, btAlignedObjectArray<btVector3>& normals,btAlignedObjectArray<int>& indices)
  156. {
  157. if (0==m_model)
  158. {
  159. int numVertices = vertices.size();
  160. int numIndices = indices.size();
  161. m_model = new Model();
  162. char relativeFileName[1024];
  163. if (b3ResourcePath::findResourcePath("floor_diffuse.tga", relativeFileName, 1024))
  164. {
  165. m_model->loadDiffuseTexture(relativeFileName);
  166. }
  167. for (int i=0;i<numVertices;i++)
  168. {
  169. m_model->addVertex(vertices[i].x(),
  170. vertices[i].y(),
  171. vertices[i].z(),
  172. normals[i].x(),
  173. normals[i].y(),
  174. normals[i].z(),
  175. 0.5,0.5);
  176. }
  177. for (int i=0;i<numIndices;i+=3)
  178. {
  179. m_model->addTriangle(indices[i],indices[i],indices[i],
  180. indices[i+1],indices[i+1],indices[i+1],
  181. indices[i+2],indices[i+2],indices[i+2]);
  182. }
  183. }
  184. }
  185. void TinyRenderObjectData::createCube(float halfExtentsX,float halfExtentsY,float halfExtentsZ)
  186. {
  187. m_model = new Model();
  188. char relativeFileName[1024];
  189. if (b3ResourcePath::findResourcePath("floor_diffuse.tga", relativeFileName, 1024))
  190. {
  191. m_model->loadDiffuseTexture(relativeFileName);
  192. }
  193. int strideInBytes = 9*sizeof(float);
  194. int numVertices = sizeof(cube_vertices_textured)/strideInBytes;
  195. int numIndices = sizeof(cube_indices)/sizeof(int);
  196. for (int i=0;i<numVertices;i++)
  197. {
  198. m_model->addVertex(halfExtentsX*cube_vertices_textured[i*9],
  199. halfExtentsY*cube_vertices_textured[i*9+1],
  200. halfExtentsY*cube_vertices_textured[i*9+2],
  201. cube_vertices_textured[i*9+4],
  202. cube_vertices_textured[i*9+5],
  203. cube_vertices_textured[i*9+6],
  204. cube_vertices_textured[i*9+7],
  205. cube_vertices_textured[i*9+8]);
  206. }
  207. for (int i=0;i<numIndices;i+=3)
  208. {
  209. m_model->addTriangle(cube_indices[i],cube_indices[i],cube_indices[i],
  210. cube_indices[i+1],cube_indices[i+1],cube_indices[i+1],
  211. cube_indices[i+2],cube_indices[i+2],cube_indices[i+2]);
  212. }
  213. }
  214. TinyRenderObjectData::~TinyRenderObjectData()
  215. {
  216. delete m_model;
  217. }
  218. void TinyRenderer::renderObject(TinyRenderObjectData& renderData)
  219. {
  220. int width = renderData.m_rgbColorBuffer.get_width();
  221. int height = renderData.m_rgbColorBuffer.get_height();
  222. Vec3f light_dir_local = Vec3f(renderData.m_lightDirWorld[0],renderData.m_lightDirWorld[1],renderData.m_lightDirWorld[2]);
  223. Model* model = renderData.m_model;
  224. if (0==model)
  225. return;
  226. renderData.m_viewportMatrix = viewport(0,0,width, height);
  227. b3AlignedObjectArray<float>& zbuffer = renderData.m_depthBuffer;
  228. int* segmentationMaskBufferPtr = (renderData.m_segmentationMaskBufferPtr && renderData.m_segmentationMaskBufferPtr->size())?&renderData.m_segmentationMaskBufferPtr->at(0):0;
  229. TGAImage& frame = renderData.m_rgbColorBuffer;
  230. {
  231. Matrix modelViewMatrix = renderData.m_viewMatrix*renderData.m_modelMatrix;
  232. Vec3f localScaling(renderData.m_localScaling[0],renderData.m_localScaling[1],renderData.m_localScaling[2]);
  233. Shader shader(model, light_dir_local, modelViewMatrix, renderData.m_projectionMatrix,renderData.m_modelMatrix, localScaling, model->getColorRGBA());
  234. //printf("Render %d triangles.\n",model->nfaces());
  235. for (int i=0; i<model->nfaces(); i++)
  236. {
  237. for (int j=0; j<3; j++) {
  238. shader.vertex(i, j);
  239. }
  240. triangle(shader.varying_tri, shader, frame, &zbuffer[0], segmentationMaskBufferPtr, renderData.m_viewportMatrix, renderData.m_objectIndex);
  241. }
  242. }
  243. }