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.

chunkmesh.cpp 3.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. #include "graphics/chunkmesh.h"
  2. #include "world.h"
  3. #include "chunk.h"
  4. #include <vector>
  5. #include <GL/glew.h>
  6. #include <GL/gl.h>
  7. #include <iostream>
  8. namespace vtk {
  9. ChunkMesh::ChunkMesh(World& world, glm::ivec3 chunkPos) :
  10. mLinkedWorld(world),
  11. mLinkedChunkPos(chunkPos),
  12. mLocked(false)
  13. {
  14. glGenBuffers(1, &mGeometryTexVBO);
  15. glGenBuffers(1, &mLightVBO);
  16. glGenBuffers(1, &mFaceAttribsVBO);
  17. glGenVertexArrays(1, &mVAO);
  18. glBindVertexArray(mVAO);
  19. glBindBuffer(GL_ARRAY_BUFFER, mGeometryTexVBO);
  20. //vertices
  21. glVertexAttribIPointer(0, 1, GL_UNSIGNED_INT, GL_FALSE, 0);
  22. glEnableVertexAttribArray(0);
  23. //face attribs
  24. glBindBuffer(GL_ARRAY_BUFFER, mFaceAttribsVBO);
  25. glVertexAttribIPointer(1, 1, GL_UNSIGNED_INT, GL_FALSE, 0);
  26. glEnableVertexAttribArray(1);
  27. }
  28. bool ChunkMesh::rebuildChunkGeometry() {
  29. // check if it's currently rebuilding
  30. if (mLocked) return true;
  31. mLocked = true;
  32. //get the chunk from position
  33. auto chunk = mLinkedWorld.getChunk(mLinkedChunkPos);
  34. if (!chunk->isLoaded()) {
  35. mLocked = false; //unlock the builder before returning
  36. return false;
  37. }
  38. // geometry format: x,y,z,u,v,i
  39. mGeometry.clear();
  40. mFaceAttribs.clear();
  41. mFaceCount = 0;
  42. int chunkSize = 16;
  43. for (int i = 0; i < chunkSize; ++i) {
  44. for (int j = 0; j < chunkSize; ++j) {
  45. for (int k = 0; k < chunkSize; ++k) {
  46. if (chunk->isVoxelSolid(i,j,k)) {
  47. //build face attrib
  48. // 0b00000000000000000xxxxxyyyyyzzzzz
  49. unsigned faceAttrib = 0;
  50. faceAttrib = (faceAttrib << 5) | i;
  51. faceAttrib = (faceAttrib << 5) | j;
  52. faceAttrib = (faceAttrib << 5) | k;
  53. //lambda expression for adding vertices
  54. auto addFaceModel = [&](int faceIndex) {
  55. auto mesh = mVoxelModel.getFaceMesh(faceIndex);
  56. unsigned texIndex = mLinkedWorld.voxelInfo.getTextureIndex(chunk->getVoxelType(i,j,k),
  57. static_cast<FaceDirection>(faceIndex));
  58. unsigned faceAttribT = faceAttrib | (texIndex << 15); // pack texture index into faceAttrib
  59. ++mFaceCount;
  60. for (int l = 0; l < 6; ++l) {
  61. mGeometry.push_back(mesh[l]);
  62. mFaceAttribs.push_back(faceAttribT);
  63. }
  64. };
  65. if (!chunk->isVoxelSolid(i,j+1,k)) addFaceModel(0); // T
  66. if (!chunk->isVoxelSolid(i,j-1,k)) addFaceModel(1); // B
  67. if (!chunk->isVoxelSolid(i,j,k+1)) addFaceModel(2); // N
  68. if (!chunk->isVoxelSolid(i,j,k-1)) addFaceModel(3); // S
  69. if (!chunk->isVoxelSolid(i+1,j,k)) addFaceModel(4); // E
  70. if (!chunk->isVoxelSolid(i-1,j,k)) addFaceModel(5); // W
  71. }
  72. }
  73. }
  74. }
  75. mUpdated = true;
  76. mLocked = false;
  77. return true;
  78. }
  79. void ChunkMesh::rebuildChunkLighting() {
  80. //this doesn't do anything yet
  81. }
  82. void ChunkMesh::draw() {
  83. if (mFaceCount > 0) {
  84. updateGeometry();
  85. glBindVertexArray(mVAO);
  86. glDrawArrays(GL_TRIANGLES, 0, mGeometryFaceCount * 6);
  87. }
  88. }
  89. bool ChunkMesh::updateGeometry() {
  90. if (mUpdated) {
  91. mUpdated = false;
  92. glBindBuffer(GL_ARRAY_BUFFER, mGeometryTexVBO);
  93. glBufferData(GL_ARRAY_BUFFER,
  94. sizeof(unsigned) * mGeometry.size(),
  95. mGeometry.data(),
  96. GL_STATIC_DRAW);
  97. glBindBuffer(GL_ARRAY_BUFFER, mFaceAttribsVBO);
  98. glBufferData(GL_ARRAY_BUFFER,
  99. sizeof(unsigned) * mFaceAttribs.size(),
  100. mFaceAttribs.data(),
  101. GL_STATIC_DRAW);
  102. mGeometryFaceCount = mFaceCount;
  103. return true;
  104. }
  105. return false;
  106. }
  107. } //namespace vtk