Chunk.java 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. package me.hammerle.snuviengine.api;
  2. import java.io.IOException;
  3. import java.nio.FloatBuffer;
  4. import me.hammerle.snuviengine.util.WrappedInputStream;
  5. import me.hammerle.snuviengine.util.WrappedOutputStream;
  6. import org.lwjgl.BufferUtils;
  7. import static org.lwjgl.opengl.GL11.*;
  8. import static org.lwjgl.opengl.GL15.*;
  9. import static org.lwjgl.opengl.GL20.*;
  10. import static org.lwjgl.opengl.GL30.*;
  11. public class Chunk
  12. {
  13. public final static int CHUNK_SIZE = 8;
  14. public final static int TILE_SIZE = 16;
  15. public final static int LAYERS = 4;
  16. public final static int LAST_BACK_LAYER = 1;
  17. private final short[][][] data = new short[LAYERS][CHUNK_SIZE][CHUNK_SIZE];
  18. private final int chunkX;
  19. private final int chunkY;
  20. private int vao;
  21. private int vbo;
  22. private final FloatBuffer buffer = BufferUtils.createFloatBuffer(CHUNK_SIZE * CHUNK_SIZE * 24);
  23. private boolean[] dirty = new boolean[LAYERS];
  24. public Chunk(int x, int y)
  25. {
  26. this.chunkX = x;
  27. this.chunkY = y;
  28. for(int i = 0; i < LAYERS; i++)
  29. {
  30. dirty[i] = true;
  31. }
  32. Shader.addTask(() ->
  33. {
  34. vao = glGenVertexArrays();
  35. vbo = glGenBuffers();
  36. GLHelper.glBindVertexArray(vao);
  37. GLHelper.glBindBuffer(vbo);
  38. glEnableVertexAttribArray(0);
  39. glVertexAttribPointer(0, 2, GL_FLOAT, false, 16, 0);
  40. glEnableVertexAttribArray(1);
  41. glVertexAttribPointer(1, 2, GL_FLOAT, false, 16, 8);
  42. glBufferData(GL_ARRAY_BUFFER, CHUNK_SIZE * CHUNK_SIZE * 96 * LAYERS, GL_STATIC_DRAW);
  43. });
  44. }
  45. public void read(WrappedInputStream in) throws IOException
  46. {
  47. for(int l = 0; l < LAYERS; l++)
  48. {
  49. for(int x = 0; x < CHUNK_SIZE; x++)
  50. {
  51. for(int y = 0; y < CHUNK_SIZE; y++)
  52. {
  53. data[l][x][y] = in.readShort();
  54. }
  55. }
  56. }
  57. }
  58. public void write(WrappedOutputStream out) throws IOException
  59. {
  60. for(int l = 0; l < LAYERS; l++)
  61. {
  62. for(int x = 0; x < CHUNK_SIZE; x++)
  63. {
  64. for(int y = 0; y < CHUNK_SIZE; y++)
  65. {
  66. out.writeShort(data[l][x][y]);
  67. }
  68. }
  69. }
  70. }
  71. private void rebuild(int layer)
  72. {
  73. for(int x = 0; x < CHUNK_SIZE; x++)
  74. {
  75. for(int y = 0; y < CHUNK_SIZE; y++)
  76. {
  77. short tile = data[layer][x][y];
  78. float minX = x * TILE_SIZE;
  79. float minY = y * TILE_SIZE;
  80. float maxX = minX + TILE_SIZE;
  81. float maxY = minY + TILE_SIZE;
  82. float tMinX = (tile % 8) * 0.125f;
  83. float tMinY = (tile / 8) * 0.0108695652f;
  84. float tMaxX = tMinX + 0.125f;
  85. float tMaxY = tMinY + 0.0108695652f;
  86. buffer.put(minX);
  87. buffer.put(maxY);
  88. buffer.put(tMinX);
  89. buffer.put(tMaxY);
  90. buffer.put(minX);
  91. buffer.put(minY);
  92. buffer.put(tMinX);
  93. buffer.put(tMinY);
  94. buffer.put(maxX);
  95. buffer.put(maxY);
  96. buffer.put(tMaxX);
  97. buffer.put(tMaxY);
  98. buffer.put(maxX);
  99. buffer.put(maxY);
  100. buffer.put(tMaxX);
  101. buffer.put(tMaxY);
  102. buffer.put(minX);
  103. buffer.put(minY);
  104. buffer.put(tMinX);
  105. buffer.put(tMinY);
  106. buffer.put(maxX);
  107. buffer.put(minY);
  108. buffer.put(tMaxX);
  109. buffer.put(tMinY);
  110. }
  111. }
  112. buffer.flip();
  113. GLHelper.glBindVertexArray(vao);
  114. GLHelper.glBindBuffer(vbo);
  115. glBufferSubData(GL_ARRAY_BUFFER, CHUNK_SIZE * CHUNK_SIZE * 96 * layer, buffer);
  116. }
  117. public void drawBackground()
  118. {
  119. for(int i = 0; i <= LAST_BACK_LAYER; i++)
  120. {
  121. if(dirty[i])
  122. {
  123. rebuild(i);
  124. dirty[i] = false;
  125. }
  126. }
  127. GLHelper.glBindVertexArray(vao);
  128. GLHelper.glBindBuffer(vbo);
  129. Shader.pushMatrix();
  130. Shader.translate(chunkX * CHUNK_SIZE * TILE_SIZE, chunkY * CHUNK_SIZE * TILE_SIZE);
  131. Shader.updateMatrix();
  132. Shader.popMatrix();
  133. glDrawArrays(GL_TRIANGLES, 0, CHUNK_SIZE * CHUNK_SIZE * 6 * (LAST_BACK_LAYER + 1));
  134. }
  135. public void drawForeground()
  136. {
  137. for(int i = LAST_BACK_LAYER + 1; i < LAYERS; i++)
  138. {
  139. if(dirty[i])
  140. {
  141. rebuild(i);
  142. dirty[i] = false;
  143. }
  144. }
  145. GLHelper.glBindVertexArray(vao);
  146. GLHelper.glBindBuffer(vbo);
  147. Shader.pushMatrix();
  148. Shader.translate(chunkX * CHUNK_SIZE * TILE_SIZE, chunkY * CHUNK_SIZE * TILE_SIZE);
  149. Shader.updateMatrix();
  150. Shader.popMatrix();
  151. glDrawArrays(GL_TRIANGLES, CHUNK_SIZE * CHUNK_SIZE * 6 * (LAST_BACK_LAYER + 1), CHUNK_SIZE * CHUNK_SIZE * 6 * (LAYERS - LAST_BACK_LAYER - 1));
  152. }
  153. }