1 #define STB_IMAGE_IMPLEMENTATION
2 #include <stb/stb_image.h>
4 #include <dragontype/list.h>
5 #include "client/texture.h"
10 __attribute((constructor(101))) static void textures_init()
12 textures = list_create(&list_compare_string);
15 static void list_delete_texture(unused void *key, void *value, unused void *arg)
17 texture_delete(value);
20 __attribute((destructor)) static void textures_deinit()
22 list_clear_func(&textures, &list_delete_texture, NULL);
25 Texture *texture_create(unsigned char *data, int width, int height, GLenum format, bool mipmap)
27 Texture *texture = malloc(sizeof(Texture));
28 texture->width = width;
29 texture->height = height;
31 glGenTextures(1, &texture->id);
33 glBindTexture(GL_TEXTURE_2D, texture->id);
35 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mipmap ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST);
36 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
37 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
38 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
40 glTexImage2D(GL_TEXTURE_2D, 0, format, texture->width, texture->height, 0, format, GL_UNSIGNED_BYTE, data);
41 glGenerateMipmap(GL_TEXTURE_2D);
43 glBindTexture(GL_TEXTURE_2D, 0);
48 GLuint texture_create_cubemap(char *path)
51 glGenTextures(1, &id);
53 glBindTexture(GL_TEXTURE_CUBE_MAP, id);
55 const char *directions[6] = {
64 for (int i = 0; i < 6; i++) {
65 char filename[strlen(path) + 1 + strlen(directions[i]) + 1 + 3 + 1];
66 sprintf(filename, "%s/%s.png", path, directions[i]);
68 int width, height, channels;
69 unsigned char *data = stbi_load(filename, &width, &height, &channels, 0);
71 fprintf(stderr, "Failed to load texture %s\n", filename);
75 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
76 stbi_image_free(data);
79 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
80 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
81 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
82 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
83 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
88 void texture_delete(Texture *texture)
90 glDeleteTextures(1, &texture->id);
94 Texture *texture_load(char *path, bool mipmap)
96 int width, height, channels;
98 unsigned char *data = stbi_load(path, &width, &height, &channels, 0);
100 fprintf(stderr, "Failed to load texture %s\n", path);
104 Texture *texture = texture_create(data, width, height, GL_RGBA, mipmap);
106 stbi_image_free(data);
108 list_put(&textures, texture, NULL);