minecraft

minecraft
git clone git://git.evenfri.pw/minecraft.git
Log | Files | Refs | README

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 }