ChunkRenderer.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #include "ChunkRenderer.h"
  2. #include "../../engine/Wrapper.h"
  3. #include "block/BlockRenderers.h"
  4. #include "block/BlockRenderer.h"
  5. ChunkRenderer::ChunkRenderer() : blockTexture("resources/textures.png")
  6. {
  7. mesh = new ChunkMesh[chunkX * chunkZ * Chunk::HEIGHT_PARTIONS];
  8. }
  9. ChunkRenderer::~ChunkRenderer()
  10. {
  11. delete[] mesh;
  12. }
  13. void ChunkRenderer::renderTick(Shader& shader, Camera3D camera, DirectRenderer& dr, float lag)
  14. {
  15. blockTexture.bind();
  16. //int frustumCull1 = 0;
  17. //int frustumCull2 = 0;
  18. for(int x = 0; x < chunkX; x++)
  19. {
  20. for(int z = 0; z < chunkZ; z++)
  21. {
  22. int sx = x * Chunk::WIDTH;
  23. int sz = z * Chunk::DEPTH;
  24. int ex = sx + Chunk::WIDTH;
  25. int ez = sz + Chunk::DEPTH;
  26. if(camera.isInFrustum(sx, 0, sz, ex, Chunk::HEIGHT, ez))
  27. {
  28. shader.translateTo(x * Chunk::WIDTH, 0, z * Chunk::DEPTH);
  29. Engine::setWorldModelMatrix(shader.getModelMatrix());
  30. for(int l = 0; l < Chunk::HEIGHT_PARTIONS; l++)
  31. {
  32. if(camera.isInFrustum(sx, l * Chunk::PARTION_HEIGHT, sz, ex, (l + 1) * Chunk::PARTION_HEIGHT, ez))
  33. {
  34. mesh[l + z * Chunk::HEIGHT_PARTIONS + x * chunkZ * Chunk::HEIGHT_PARTIONS].draw();
  35. }
  36. //else
  37. //{
  38. // frustumCull2++;
  39. //}
  40. }
  41. }
  42. //else
  43. //{
  44. // frustumCull1 += 16;
  45. //}
  46. }
  47. }
  48. //cout << "CULL :" << frustumCull1 << " " << frustumCull2 << endl;
  49. }
  50. void ChunkRenderer::updateChunk(Chunk& c, Chunk* north, Chunk* east, Chunk* south, Chunk* west)
  51. {
  52. int x = c.getChunkX();
  53. int z = c.getChunkZ();
  54. if(x < 0 || x >= chunkX || z < 0 || z >= chunkZ)
  55. {
  56. return;
  57. }
  58. cout << "UPDATE: " << x << " " << z << endl;
  59. for(int l = 0; l < Chunk::HEIGHT_PARTIONS; l++)
  60. {
  61. if(c.isDirty(l))
  62. {
  63. buildChunk(l, c, north, east, south, west);
  64. }
  65. }
  66. }
  67. void ChunkRenderer::buildChunk(int partionY, Chunk& c, Chunk* north, Chunk* east, Chunk* south, Chunk* west)
  68. {
  69. Mesh& m = mesh[partionY + c.getChunkZ() * Chunk::HEIGHT_PARTIONS + c.getChunkX() * chunkZ * Chunk::HEIGHT_PARTIONS];
  70. int max = (partionY + 1) * Chunk::PARTION_HEIGHT;
  71. for(int y = partionY * Chunk::PARTION_HEIGHT; y < max; y++)
  72. {
  73. for(int x = 0; x < Chunk::WIDTH; x++)
  74. {
  75. for(int z = 0; z < Chunk::DEPTH; z++)
  76. {
  77. const Block& block = c.getBlock(x, y, z);
  78. if(!block.isEmpty())
  79. {
  80. BlockRenderers::getBlockRenderer(block.getId()).addToMesh(m, x, y, z,
  81. Face::getCullData(
  82. // top
  83. y + 1 < Chunk::HEIGHT && c.getBlock(x, y + 1, z).isBlockingFace(Face::DOWN),
  84. // bottom
  85. y > 0 && c.getBlock(x, y - 1, z).isBlockingFace(Face::UP),
  86. // north
  87. (x + 1 >= Chunk::WIDTH || c.getBlock(x + 1, y, z).isBlockingFace(Face::SOUTH)) &&
  88. (x + 1 < Chunk::WIDTH || (north != nullptr && north->getBlock(x + 1 - Chunk::WIDTH, y, z).isBlockingFace(Face::SOUTH))),
  89. // south
  90. (x - 1 < 0 || c.getBlock(x - 1, y, z).isBlockingFace(Face::NORTH)) &&
  91. (x - 1 >= 0 || (south != nullptr && south->getBlock(x - 1 + Chunk::WIDTH, y, z).isBlockingFace(Face::NORTH))),
  92. // east
  93. (z + 1 >= Chunk::DEPTH || c.getBlock(x, y, z + 1).isBlockingFace(Face::WEST)) &&
  94. (z + 1 < Chunk::DEPTH || (east != nullptr && east->getBlock(x, y, z + 1 - Chunk::DEPTH).isBlockingFace(Face::WEST))),
  95. // west
  96. (z - 1 < 0 || c.getBlock(x, y, z - 1).isBlockingFace(Face::EAST)) &&
  97. (z - 1 >= 0 || (west != nullptr && west->getBlock(x, y, z - 1 + Chunk::DEPTH).isBlockingFace(Face::EAST)))));
  98. }
  99. }
  100. }
  101. }
  102. m.build();
  103. }