src/texture.c

changeset 89
e1f682a8a145
parent 88
6234b7ea48f3
equal deleted inserted replaced
88:6234b7ea48f3 89:e1f682a8a145
29 #include "ascension/texture.h" 29 #include "ascension/texture.h"
30 #include "ascension/error.h" 30 #include "ascension/error.h"
31 #include "ascension/filesystem.h" 31 #include "ascension/filesystem.h"
32 32
33 #include <assert.h> 33 #include <assert.h>
34 #include <cx/utils.h>
34 #include <GL/glew.h> 35 #include <GL/glew.h>
35 #include <SDL2/SDL_image.h> 36 #include <SDL2/SDL_image.h>
36 37
37 void asc_texture_bind(AscTexture const *tex, int uniform_location, int unit) { 38 void asc_texture_bind(AscTexture const *tex, int uniform_location, int unit) {
38 glActiveTexture(GL_TEXTURE0 + unit); 39 glActiveTexture(GL_TEXTURE0 + unit);
44 glUniform1i(uniform_location, unit); 45 glUniform1i(uniform_location, unit);
45 asc_error_catch_all_gl(); 46 asc_error_catch_all_gl();
46 } 47 }
47 48
48 void asc_texture_from_surface(AscTexture *tex, SDL_Surface const *surface) { 49 void asc_texture_from_surface(AscTexture *tex, SDL_Surface const *surface) {
49 if (asc_texture_uninitialized(tex)) { 50 if (tex->tex_id == 0) {
50 asc_error("Tried to use uninitialized texture."); 51 asc_error("Tried to use uninitialized texture.");
51 asc_dprintf("Texture address: %"PRIxPTR, (uintptr_t) tex); 52 asc_dprintf("Texture address: %"PRIxPTR, (uintptr_t) tex);
52 return; 53 return;
53 } 54 }
54 tex->width = surface->w; 55 tex->width = surface->w;
107 SDL_FreeSurface(image); 108 SDL_FreeSurface(image);
108 } 109 }
109 110
110 void asc_texture_init( 111 void asc_texture_init(
111 AscTexture *tex, 112 AscTexture *tex,
113 unsigned count,
112 enum asc_texture_target target, 114 enum asc_texture_target target,
113 enum asc_texture_min_filter min_filter, 115 enum asc_texture_min_filter min_filter,
114 enum asc_texture_mag_filter mag_filter 116 enum asc_texture_mag_filter mag_filter
115 ) { 117 ) {
116 static const GLenum texture_targets[] = { 118 static const GLenum texture_targets[] = {
126 GL_LINEAR_MIPMAP_LINEAR 128 GL_LINEAR_MIPMAP_LINEAR
127 }; 129 };
128 assert(target < sizeof(texture_targets) / sizeof(GLenum)); 130 assert(target < sizeof(texture_targets) / sizeof(GLenum));
129 assert(min_filter < sizeof(texture_filters) / sizeof(GLint)); 131 assert(min_filter < sizeof(texture_filters) / sizeof(GLint));
130 assert(mag_filter < 2); // mag filter only supports nearest/linear 132 assert(mag_filter < 2); // mag filter only supports nearest/linear
131 tex->target = texture_targets[target]; 133
132 glGenTextures(1, &tex->tex_id); 134 GLuint textures[count];
133 glBindTexture(tex->target, tex->tex_id); 135 glGenTextures(count, textures);
134 glTexParameteri(tex->target, GL_TEXTURE_MIN_FILTER, 136
135 texture_filters[min_filter]); 137 for (unsigned i = 0; i < count; ++i) {
136 glTexParameteri(tex->target, GL_TEXTURE_MAG_FILTER, 138 memset(&tex[i], 0, sizeof(AscTexture));
137 texture_filters[mag_filter]); 139 tex[i].tex_id = textures[i];
138 asc_dprintf("Initialized texture: %u", tex->tex_id); 140 tex[i].target = texture_targets[target];
141 glBindTexture(tex[i].target, tex[i].tex_id);
142 glTexParameteri(tex[i].target, GL_TEXTURE_MIN_FILTER,
143 texture_filters[min_filter]);
144 glTexParameteri(tex[i].target, GL_TEXTURE_MAG_FILTER,
145 texture_filters[mag_filter]);
146 asc_dprintf("Initialized texture: %u", tex[i].tex_id);
147 }
148
149 // TODO: proper error handling for each gl call
139 asc_error_catch_all_gl(); 150 asc_error_catch_all_gl();
140 } 151 }
141 152
142 void asc_texture_destroy(AscTexture *tex) { 153 void asc_texture_destroy(AscTexture *tex, unsigned count) {
143 asc_dprintf("Destroy texture: %u", tex->tex_id); 154 GLuint textures[count];
144 glDeleteTextures(1, &tex->tex_id); 155 for (unsigned i = 0; i < count; ++i) {
156 if (tex[i].refcount > 0) {
157 // TODO: asc_wprintf() for warnings
158 asc_dprintf("Texture %u still in use by %u objects.",
159 tex[i].tex_id, tex[i].refcount);
160 }
161 asc_dprintf("Destroy texture: %u", tex[i].tex_id);
162 textures[i] = tex[i].tex_id;
163 memset(&tex[i], 0, sizeof(AscTexture));
164 }
165 glDeleteTextures(count, textures);
145 } 166 }

mercurial