render.c (6516B)
1 #include "minecraft.h" 2 #define STB_IMAGE_IMPLEMENTATION 3 #include "stb_image.h" 4 5 unsigned int VBO, VAO, EBO; 6 unsigned int Texture; 7 static int u_model, u_view, u_proj; 8 9 void render_init() { 10 float vertices[] = { 11 /* back */ 12 -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 13 -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 14 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 15 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 16 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 17 -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 18 19 /* front */ 20 -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 21 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 22 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 23 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 24 -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 25 -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 26 27 /* left */ 28 -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 29 -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 30 -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 31 -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 32 -0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 33 -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 34 35 /* right */ 36 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 37 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 38 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 39 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 40 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 41 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 42 43 /* bottom */ 44 -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 45 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 46 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 47 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 48 -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 49 -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 50 51 /* top */ 52 -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 53 -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 54 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 55 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 56 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 57 -0.5f, 0.5f, -0.5f, 0.0f, 1.0f 58 }; 59 60 glGenVertexArrays(1, &VAO); 61 glGenBuffers(1, &VBO); 62 63 glBindVertexArray(VAO); 64 65 glBindBuffer(GL_ARRAY_BUFFER, VBO); 66 glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); 67 68 /* position attribute */ 69 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); 70 /* texture coord attribute */ 71 glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), 72 (void*)(3 * sizeof(float))); 73 74 glEnableVertexAttribArray(0); 75 glEnableVertexAttribArray(1); 76 77 // glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 78 79 glUseProgram(Shader); 80 glUniform1i(glGetUniformLocation(Shader, "texture1"), 0); 81 u_model = glGetUniformLocation(Shader, "model"); 82 u_view = glGetUniformLocation(Shader, "view"); 83 u_proj = glGetUniformLocation(Shader, "projection"); 84 blocks_init(); 85 } 86 87 void render_block(unsigned int block_id, vec3 pos, 88 uint8_t r_back, 89 uint8_t r_front, 90 uint8_t r_left, 91 uint8_t r_right, 92 uint8_t r_bottom, 93 uint8_t r_top) { 94 if (!(r_back || r_front || r_left || r_right || r_bottom || r_top)) return; 95 mat4 model = mat4_translate(pos.x, pos.y, pos.z); 96 glUniformMatrix4fv(u_model, 1, GL_FALSE, model.m); 97 98 for (int face = 0; face < FACE_COUNT; face++) { 99 if (face == FACE_BACK && r_back == 0) continue; 100 if (face == FACE_FRONT && r_front == 0) continue; 101 if (face == FACE_LEFT && r_left == 0) continue; 102 if (face == FACE_RIGHT && r_right == 0) continue; 103 if (face == FACE_BOTTOM && r_bottom == 0) continue; 104 if (face == FACE_TOP && r_top == 0) continue; 105 106 unsigned int tex = block_texture(block_id, face); 107 if (!tex) continue; 108 glActiveTexture(GL_TEXTURE0); 109 glBindTexture(GL_TEXTURE_2D, tex); 110 glDrawArrays(GL_TRIANGLES, face * 6, 6); 111 } 112 } 113 114 void render_chunk(Chunk_t *chunk, 115 Chunk_t *chunk_front, Chunk_t *chunk_back, 116 Chunk_t *chunk_right, Chunk_t *chunk_left) { 117 if (!chunk) return; 118 119 uint8_t back_face_vis = 0; 120 uint8_t front_face_vis = 0; 121 uint8_t left_face_vis = 0; 122 uint8_t right_face_vis = 0; 123 uint8_t bottom_face_vis = 0; 124 uint8_t top_face_vis = 0; 125 126 int base_x = (int)(chunk->position.x * CHUNK_SIZE); 127 int base_z = (int)(chunk->position.z * CHUNK_SIZE); 128 129 for (int x = 0; x < CHUNK_SIZE; x++) { 130 for (int z = 0; z < CHUNK_SIZE; z++) { 131 for (int y = 0; y < CHUNK_HEIGHT; y++) { 132 int block_id = chunk->blocks[x][y][z]; 133 if (block_id == BLOCK_AIR) continue; 134 135 float wx = (float)(base_x + x); 136 float wz = (float)(base_z + z); 137 138 if (z == 0) { 139 back_face_vis = 140 (!chunk_back || chunk_back->blocks[x][y][CHUNK_SIZE - 1] == 0); 141 } else { 142 back_face_vis = (chunk->blocks[x][y][z - 1] == 0); 143 } 144 145 if (z == CHUNK_SIZE - 1) { 146 front_face_vis = (!chunk_front || chunk_front->blocks[x][y][0] == 0); 147 } else { 148 front_face_vis = (chunk->blocks[x][y][z + 1] == 0); 149 } 150 151 if (x == 0) { 152 left_face_vis = 153 (!chunk_left || chunk_left->blocks[CHUNK_SIZE - 1][y][z] == 0); 154 } else { 155 left_face_vis = (chunk->blocks[x - 1][y][z] == 0); 156 } 157 158 if (x == CHUNK_SIZE - 1) { 159 right_face_vis = 160 (!chunk_right || chunk_right->blocks[0][y][z] == 0); 161 } else { 162 right_face_vis = (chunk->blocks[x + 1][y][z] == 0); 163 } 164 165 bottom_face_vis = (y == 0 || chunk->blocks[x][y - 1][z] == 0); 166 top_face_vis = 167 (y == CHUNK_HEIGHT - 1 || chunk->blocks[x][y + 1][z] == 0); 168 169 render_block(block_id, (vec3){ wx, y, wz }, 170 back_face_vis, 171 front_face_vis, 172 left_face_vis, 173 right_face_vis, 174 bottom_face_vis, 175 top_face_vis); 176 } 177 } 178 } 179 } 180 181 void render_world() { 182 for (int x = 0; x < WORLD_SIZE; x++) { 183 for (int z = 0; z < WORLD_SIZE; z++) { 184 Chunk_t *current = World.chunks[x][z]; 185 if (!current) continue; 186 187 Chunk_t *c_left = (x > 0) ? World.chunks[x - 1][z] : NULL; 188 Chunk_t *c_right = (x < WORLD_SIZE - 1) ? World.chunks[x + 1][z] : NULL; 189 Chunk_t *c_back = (z > 0) ? World.chunks[x][z - 1] : NULL; 190 Chunk_t *c_front = (z < WORLD_SIZE - 1) ? World.chunks[x][z + 1] : NULL; 191 192 render_chunk(current, c_front, c_back, c_right, c_left); 193 } 194 } 195 } 196 197 void render_frame() { 198 glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 199 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 200 201 glUseProgram(Shader); 202 203 mat4 view = camera_get_view(); 204 mat4 projection = mat4_perspective(camera.fov, 205 (float)WINDOW_WIDTH / (float)WINDOW_HEIGHT, 206 0.1f, 100.0f); 207 glUniformMatrix4fv(u_view, 1, GL_FALSE, view.m); 208 glUniformMatrix4fv(u_proj, 1, GL_FALSE, projection.m); 209 210 glBindVertexArray(VAO); 211 212 render_world(); 213 214 glfwPollEvents(); 215 glfwSwapBuffers(Window); 216 } 217 218 void render_end() { 219 glDeleteVertexArrays(1, &VAO); 220 glDeleteBuffers(1, &VBO); 221 glDeleteTextures(1, &Texture); 222 }