blocks.c (2529B)
1 #include "minecraft.h" 2 #include "stb_image.h" 3 4 Block_t blocks[] = { 5 { BLOCK_GRASS, { 6 "assets/grass_side.png", /* back */ 7 "assets/grass_side.png", /* front */ 8 "assets/grass_side.png", /* left */ 9 "assets/grass_side.png", /* right */ 10 "assets/dirt.png", /* bottom */ 11 "assets/grass_top.png", /* top */ 12 }}, 13 { BLOCK_STONE, { 14 "assets/stone.png", "assets/stone.png", 15 "assets/stone.png", "assets/stone.png", 16 "assets/stone.png", "assets/stone.png", 17 }}, 18 { BLOCK_DIRT, { 19 "assets/dirt.png", "assets/dirt.png", 20 "assets/dirt.png", "assets/dirt.png", 21 "assets/dirt.png", "assets/dirt.png", 22 }}, 23 }; 24 int block_count = sizeof(blocks) / sizeof(blocks[0]); 25 26 static unsigned int *block_textures = NULL; 27 28 static unsigned int load_texture(const char *path) { 29 unsigned int tex; 30 glGenTextures(1, &tex); 31 glBindTexture(GL_TEXTURE_2D, tex); 32 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 33 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 34 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 35 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 36 int w, h, nrChannels; 37 stbi_set_flip_vertically_on_load(true); 38 unsigned char *data = stbi_load(path, &w, &h, &nrChannels, 0); 39 if (!data) { 40 printf("err: failed to load texture %s\n", path); 41 return 0; 42 } 43 GLenum fmt = (nrChannels == 4) ? GL_RGBA 44 : (nrChannels == 3) ? GL_RGB 45 : GL_RED; 46 glTexImage2D(GL_TEXTURE_2D, 0, fmt, w, h, 0, fmt, 47 GL_UNSIGNED_BYTE, data); 48 glGenerateMipmap(GL_TEXTURE_2D); 49 stbi_image_free(data); 50 return tex; 51 } 52 53 void blocks_init(void) { 54 block_textures = malloc(sizeof(unsigned int) * block_count * FACE_COUNT); 55 for (int i = 0; i < block_count; i++) 56 for (int f = 0; f < FACE_COUNT; f++) 57 block_textures[i * FACE_COUNT + f] = 58 load_texture(blocks[i].texture_paths[f]); 59 } 60 61 void blocks_end(void) { 62 if (block_textures) { 63 glDeleteTextures(block_count * FACE_COUNT, block_textures); 64 free(block_textures); 65 block_textures = NULL; 66 } 67 } 68 69 unsigned int block_texture(unsigned int id, int face) { 70 if (face < 0 || face >= FACE_COUNT) return 0; 71 for (int i = 0; i < block_count; i++) 72 if (blocks[i].id == id) 73 return block_textures[i * FACE_COUNT + face]; 74 return 0; 75 }