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 } |