Simple game engine with complete export to scripting language
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

420 lines
12 KiB

  1. #include "MeshManager.h"
  2. #include "Utilities/format.h"
  3. #include "Utilities/Log.h"
  4. #include "physfs.h"
  5. #include "trimeshloader.h"
  6. #include <iostream>
  7. #include <vector>
  8. using namespace std;
  9. namespace BlueCore
  10. {
  11. //------------------------------------------------------------------------------
  12. Mesh::Mesh(RenderDevice* device) :
  13. _Device(device)
  14. {
  15. }
  16. //------------------------------------------------------------------------------
  17. Mesh::~Mesh()
  18. {
  19. clog << ">>> Mesh destructed ..."<< endline;
  20. }
  21. //------------------------------------------------------------------------------
  22. void Mesh::render()
  23. {
  24. glEnableClientState(GL_VERTEX_ARRAY);
  25. glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  26. glEnableClientState(GL_NORMAL_ARRAY);
  27. glVertexPointer( 3, GL_FLOAT, sizeof(Vertex), &VertexBuffer[0].point.x);
  28. glTexCoordPointer( 2, GL_FLOAT, sizeof(Vertex), &VertexBuffer[0].u);
  29. glNormalPointer(GL_FLOAT, sizeof(Vertex), &VertexBuffer[0].normal.x);
  30. glDrawElements(GL_TRIANGLES, IndexBuffer.count() * 3, GL_UNSIGNED_SHORT,
  31. IndexBuffer.data() );
  32. glDisableClientState(GL_VERTEX_ARRAY);
  33. glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  34. glDisableClientState(GL_NORMAL_ARRAY);
  35. }
  36. #if 0
  37. //--------------------------------------------------------------------------
  38. void Mesh::createVBO()
  39. {
  40. if ( GLEW_ARB_vertex_buffer_object && !vbo )
  41. {
  42. glGenBuffersARB ( 1, &vbo );
  43. glBindBufferARB ( GL_ARRAY_BUFFER_ARB, vbo );
  44. glBufferDataARB (
  45. GL_ARRAY_BUFFER_ARB,
  46. size(),
  47. data(),
  48. GL_STATIC_DRAW_ARB );
  49. }
  50. }
  51. //--------------------------------------------------------------------------
  52. void Mesh::releaseVBO()
  53. {
  54. if ( GLEW_ARB_vertex_buffer_object && vbo )
  55. {
  56. glDeleteBuffersARB ( 1, &vbo );
  57. vbo = 0;
  58. }
  59. }
  60. //--------------------------------------------------------------------------
  61. void Mesh::bind()
  62. {
  63. if ( GLEW_ARB_vertex_buffer_object && vbo )
  64. {
  65. glBindBufferARB ( GL_ARRAY_BUFFER_ARB, vbo );
  66. // hardcoded offset and stride
  67. glVertexPointer ( 3, GL_FLOAT, sizeof ( Vertex ), 0 );
  68. glTexCoordPointer ( 2, GL_FLOAT, sizeof ( Vertex ), ( const GLvoid* ) ( sizeof ( float ) * 3 ) );
  69. glNormalPointer ( GL_FLOAT, sizeof ( Vertex ), ( const GLvoid* ) ( sizeof ( float ) * 5 ) );
  70. }
  71. else
  72. {
  73. // hardcoded offset and stride
  74. glVertexPointer ( 3, GL_FLOAT, sizeof ( Vertex ), data() );
  75. glTexCoordPointer ( 2, GL_FLOAT, sizeof ( Vertex ), data() + sizeof ( float ) * 3 );
  76. glNormalPointer ( GL_FLOAT, sizeof ( Vertex ), data() + sizeof ( float ) * 5 );
  77. }
  78. }
  79. #endif
  80. //------------------------------------------------------------------------------
  81. MeshManager::MeshManager(RenderDevice* device) :
  82. _Device(device)
  83. {
  84. BlueCore::clog << ">>> MeshManager constructed..." << endlog;
  85. }
  86. //------------------------------------------------------------------------------
  87. MeshManager::~MeshManager()
  88. {
  89. clog << ">>> MeshManager destructed ..." << endlog;
  90. }
  91. //------------------------------------------------------------------------------
  92. bool loadTrimesh(const char* filename, Mesh *mesh)
  93. {
  94. PHYSFS_file* file = PHYSFS_openRead(filename);
  95. if (file != 0)
  96. {
  97. char buffer[1024];
  98. unsigned int size = 0;
  99. if (tlObjCheckFileExtension(filename) == 0)
  100. {
  101. tlObjState *state = tlObjCreateState();
  102. while (PHYSFS_eof(file) == 0)
  103. {
  104. size = (unsigned int) PHYSFS_read(file, buffer, 1,
  105. sizeof(buffer));
  106. tlObjParse(state, buffer, size, size < sizeof(buffer) ? 1 : 0);
  107. }
  108. mesh->VertexBuffer.create(tlObjVertexCount(state));
  109. for (unsigned int i = 0; i < mesh->VertexBuffer.count(); i++)
  110. tlObjGetVertex(state, i, &mesh->VertexBuffer[i].point.x,
  111. &mesh->VertexBuffer[i].point.y,
  112. &mesh->VertexBuffer[i].point.z,
  113. &mesh->VertexBuffer[i].u, &mesh->VertexBuffer[i].v,
  114. &mesh->VertexBuffer[i].normal.x,
  115. &mesh->VertexBuffer[i].normal.y,
  116. &mesh->VertexBuffer[i].normal.z);
  117. mesh->IndexBuffer.create(tlObjFaceCount(state));
  118. for (unsigned int i = 0; i < mesh->IndexBuffer.count(); i++)
  119. tlObjGetFace(state, i, &mesh->IndexBuffer[i].a,
  120. &mesh->IndexBuffer[i].b, &mesh->IndexBuffer[i].c);
  121. mesh->SubsetBuffer.create(tlObjObjectCount(state));
  122. for (unsigned int i = 0; i < mesh->SubsetBuffer.count(); i++)
  123. {
  124. mesh->SubsetBuffer[i].first = tlObjObjectFaceIndex(state, i);
  125. mesh->SubsetBuffer[i].count = tlObjObjectFaceCount(state, i);
  126. }
  127. tlObjDestroyState(state);
  128. }
  129. else if (tl3dsCheckFileExtension(filename) == 0)
  130. {
  131. tl3dsState *state = tl3dsCreateState();
  132. while (PHYSFS_eof(file) == 0)
  133. {
  134. size = (unsigned int) PHYSFS_read(file, buffer, 1,
  135. sizeof(buffer));
  136. tl3dsParse(state, buffer, size, size < sizeof(buffer) ? 1 : 0);
  137. }
  138. mesh->VertexBuffer.create(tl3dsVertexCount(state));
  139. for (unsigned int i = 0; i < mesh->VertexBuffer.count(); i++)
  140. tl3dsGetVertex(state, i, &mesh->VertexBuffer[i].point.x,
  141. &mesh->VertexBuffer[i].point.y,
  142. &mesh->VertexBuffer[i].point.z,
  143. &mesh->VertexBuffer[i].u, &mesh->VertexBuffer[i].v,
  144. &mesh->VertexBuffer[i].normal.x,
  145. &mesh->VertexBuffer[i].normal.y,
  146. &mesh->VertexBuffer[i].normal.z);
  147. mesh->IndexBuffer.create(tl3dsFaceCount(state));
  148. for (unsigned int i = 0; i < mesh->IndexBuffer.count(); i++)
  149. tl3dsGetFace(state, i, &mesh->IndexBuffer[i].a,
  150. &mesh->IndexBuffer[i].b, &mesh->IndexBuffer[i].c);
  151. mesh->SubsetBuffer.create(tl3dsObjectCount(state));
  152. for (unsigned int i = 0; i < mesh->SubsetBuffer.count(); i++)
  153. {
  154. mesh->SubsetBuffer[i].first = tl3dsObjectFaceIndex(state, i);
  155. mesh->SubsetBuffer[i].count = tl3dsObjectFaceCount(state, i);
  156. }
  157. tl3dsDestroyState(state);
  158. }
  159. PHYSFS_close(file);
  160. return 0;
  161. }
  162. return 1;
  163. }
  164. //------------------------------------------------------------------------------
  165. Mesh *MeshManager::loadMesh(const string &filename)
  166. {
  167. // check if this mesh is already loaded
  168. std::map<std::string, weak_ptr<Mesh> >::const_iterator result;
  169. result = _Meshes.find(filename);
  170. if (result != _Meshes.end() && result->second.valid())
  171. {
  172. return result->second.pointer();
  173. }
  174. Mesh *mesh = new Mesh (_Device);
  175. // check cache
  176. PHYSFS_sint64 mod_file = PHYSFS_getLastModTime(filename.c_str());
  177. std::string cachename = filename + ".msc";
  178. PHYSFS_sint64 mod_cache = PHYSFS_getLastModTime(cachename.c_str());
  179. if ( (mod_cache > mod_file) && loadFromCache(mesh, filename) )
  180. {
  181. clog << ">>> Mesh '" << filename << "' loaded from cache." << endline;
  182. _Meshes[filename] = mesh;
  183. return mesh;
  184. }
  185. clog << ">>> Mesh '" << filename << "': loading from file..." << endlog;
  186. if (loadTrimesh(filename.c_str(), mesh) != 0)
  187. {
  188. mesh->removeReference();
  189. clog << "!!! Mesh not found!" << endline;
  190. return 0;
  191. }
  192. #if 0
  193. mesh->buildShadowFaceBuffer();
  194. mesh->buildTangentBuffer();
  195. unsigned int counter;
  196. // calculate bounding sphere
  197. clog << " calculate bounding sphere";
  198. mesh->bounding_sphere.center().zero();
  199. for ( counter = 0; counter < mesh->vertex_buffer.count(); counter++ )
  200. {
  201. mesh->bounding_sphere.center() += mesh->vertex_buffer[counter].point;
  202. }
  203. mesh->bounding_sphere.center() /= mesh->vertex_buffer.size();
  204. mesh->bounding_sphere.radius() = 0.;
  205. for ( counter = 0; counter < mesh->vertex_buffer.count(); counter++ )
  206. {
  207. Scalar distance = ( mesh->vertex_buffer[counter].point - mesh->bounding_sphere.center() ).length();
  208. if ( distance > mesh->bounding_sphere.radius() )
  209. mesh->bounding_sphere.radius() = distance;
  210. }
  211. clog << ": " << mesh->bounding_sphere.radius() << endline;
  212. // create normlas, tangents, and binomials
  213. clog << " create normlas, tangents, and binomials" << endline;
  214. for ( counter = 0; counter < mesh->vertex_buffer.count(); counter += 1 )
  215. {
  216. mesh->vertex_buffer[counter].normal.zero();
  217. }
  218. for ( counter = 0; counter < mesh->index_buffer.count(); counter += 3 )
  219. {
  220. Index a = mesh->index_buffer[counter];
  221. Index b = mesh->index_buffer[counter+1];
  222. Index c = mesh->index_buffer[counter+2];
  223. Vector3Template<float> ab = mesh->vertex_buffer[ a ].point - mesh->vertex_buffer[ b ].point;
  224. Vector3Template<float> ac = mesh->vertex_buffer[ a ].point - mesh->vertex_buffer[ c ].point;
  225. Vector3Template<float> n = ab.cross ( ac );
  226. mesh->vertex_buffer[ a ].normal += n;
  227. mesh->vertex_buffer[ b ].normal += n;
  228. mesh->vertex_buffer[ c ].normal += n;
  229. }
  230. for ( counter = 0; counter < mesh->vertex_buffer.count(); counter += 1 )
  231. {
  232. mesh->vertex_buffer[counter].normal.normalize();
  233. }
  234. clog << " create vbos" << endline;
  235. mesh->vertex_buffer.createVBO();
  236. mesh->index_buffer.createVBO();
  237. mesh->tangent_buffer.createVBO();
  238. mesh->bitangent_buffer.createVBO();
  239. #endif
  240. _Meshes[filename] = mesh;
  241. saveToCache(mesh, filename);
  242. return mesh;
  243. }
  244. //------------------------------------------------------------------------------
  245. bool MeshManager::loadFromCache(Mesh *mesh, const std::string &name)
  246. {
  247. std::string filename = name + ".msc";
  248. PHYSFS_file *file = PHYSFS_openRead(filename.c_str());
  249. if (file == 0)
  250. return false;
  251. unsigned int size;
  252. // read vertex_buffer
  253. PHYSFS_read(file, &size, sizeof (size ), 1);
  254. mesh->VertexBuffer.create(size);
  255. PHYSFS_read(file, mesh->VertexBuffer.data(), mesh->VertexBuffer.size(), 1);
  256. // read index buffer
  257. PHYSFS_read(file, &size, sizeof (size ), 1);
  258. mesh->IndexBuffer.create(size);
  259. PHYSFS_read(file, mesh->IndexBuffer.data(), mesh->IndexBuffer.size(), 1);
  260. #if 0
  261. // read tangent buffer
  262. PHYSFS_read ( file, &size, sizeof ( size ), 1 );
  263. mesh->tangent_buffer.create ( size );
  264. PHYSFS_read ( file, mesh->tangent_buffer.data(), mesh->tangent_buffer.size(), 1 );
  265. // read bitangent buffer
  266. PHYSFS_read ( file, &size, sizeof ( size ), 1 );
  267. mesh->bitangent_buffer.create ( size );
  268. PHYSFS_read ( file, mesh->bitangent_buffer.data(), mesh->bitangent_buffer.size(), 1 );
  269. // read bounding sphere
  270. PHYSFS_read ( file, &mesh->bounding_sphere, sizeof ( mesh->bounding_sphere ), 1 );
  271. #endif
  272. // read subsets
  273. PHYSFS_read(file, &size, sizeof (size ), 1);
  274. mesh->SubsetBuffer.create(size);
  275. PHYSFS_read(file, mesh->SubsetBuffer.data(), mesh->SubsetBuffer.size(), 1);
  276. #if 0
  277. // read bitangent buffer
  278. PHYSFS_read ( file, &size, sizeof ( size ), 1 );
  279. mesh->shadowface_buffer.create ( size );
  280. PHYSFS_read ( file, mesh->shadowface_buffer.data(), mesh->shadowface_buffer.size(), 1 );
  281. #endif
  282. PHYSFS_close(file);
  283. return true;
  284. }
  285. //------------------------------------------------------------------------------
  286. bool MeshManager::saveToCache(Mesh *mesh, const std::string &name)
  287. {
  288. std::string filename = name + ".msc";
  289. PHYSFS_file *file = PHYSFS_openWrite(filename.c_str() );
  290. if (file == 0)
  291. {
  292. clog << ">>> cannot open cache file for mesh: " << name << endline;
  293. return false;
  294. }
  295. // write vertex_buffer
  296. unsigned int size = mesh->VertexBuffer.count();
  297. PHYSFS_write(file, &size, sizeof (size ), 1);
  298. PHYSFS_write(file, mesh->VertexBuffer.data(), mesh->VertexBuffer.size(), 1);
  299. // write index_buffer
  300. size = mesh->IndexBuffer.count();
  301. PHYSFS_write(file, &size, sizeof (size ), 1);
  302. PHYSFS_write(file, mesh->IndexBuffer.data(), mesh->IndexBuffer.size(), 1);
  303. // write subsets
  304. size = mesh->SubsetBuffer.count();
  305. PHYSFS_write(file, &size, sizeof (size ), 1);
  306. PHYSFS_write(file, mesh->SubsetBuffer.data(), mesh->SubsetBuffer.size(), 1);
  307. #if 0
  308. // write tangent_buffer
  309. size = mesh->tangent_buffer.count();
  310. PHYSFS_write ( file, &size, sizeof ( size ), 1 );
  311. PHYSFS_write ( file, mesh->tangent_buffer.data(), mesh->tangent_buffer.size(), 1 );
  312. // write bitangent_buffer
  313. size = mesh->bitangent_buffer.count();
  314. PHYSFS_write ( file, &size, sizeof ( size ), 1 );
  315. PHYSFS_write ( file, mesh->bitangent_buffer.data(), mesh->bitangent_buffer.size(), 1 );
  316. // write bounding sphere
  317. PHYSFS_write ( file, &mesh->bounding_sphere, sizeof ( mesh->bounding_sphere ), 1 );
  318. // write shadowfaces
  319. size = mesh->shadowface_buffer.count();
  320. PHYSFS_write ( file, &size, sizeof ( size ), 1 );
  321. PHYSFS_write ( file, mesh->shadowface_buffer.data(), mesh->shadowface_buffer.size(), 1 );
  322. #endif
  323. PHYSFS_close(file);
  324. return true;
  325. }
  326. } // namespace BlueCore