src/texture.c

changeset 89
e1f682a8a145
parent 88
6234b7ea48f3
--- a/src/texture.c	Sun Apr 20 15:41:16 2025 +0200
+++ b/src/texture.c	Mon Apr 21 17:27:33 2025 +0200
@@ -31,6 +31,7 @@
 #include "ascension/filesystem.h"
 
 #include <assert.h>
+#include <cx/utils.h>
 #include <GL/glew.h>
 #include <SDL2/SDL_image.h>
 
@@ -46,7 +47,7 @@
 }
 
 void asc_texture_from_surface(AscTexture *tex, SDL_Surface const *surface) {
-    if (asc_texture_uninitialized(tex)) {
+    if (tex->tex_id == 0) {
         asc_error("Tried to use uninitialized texture.");
         asc_dprintf("Texture address: %"PRIxPTR, (uintptr_t) tex);
         return;
@@ -109,6 +110,7 @@
 
 void asc_texture_init(
         AscTexture *tex,
+        unsigned count,
         enum asc_texture_target target,
         enum asc_texture_min_filter min_filter,
         enum asc_texture_mag_filter mag_filter
@@ -128,18 +130,37 @@
     assert(target < sizeof(texture_targets) / sizeof(GLenum));
     assert(min_filter < sizeof(texture_filters) / sizeof(GLint));
     assert(mag_filter < 2); // mag filter only supports nearest/linear
-    tex->target = texture_targets[target];
-    glGenTextures(1, &tex->tex_id);
-    glBindTexture(tex->target, tex->tex_id);
-    glTexParameteri(tex->target, GL_TEXTURE_MIN_FILTER,
-                    texture_filters[min_filter]);
-    glTexParameteri(tex->target, GL_TEXTURE_MAG_FILTER,
-                    texture_filters[mag_filter]);
-    asc_dprintf("Initialized texture: %u", tex->tex_id);
+
+    GLuint textures[count];
+    glGenTextures(count, textures);
+
+    for (unsigned i = 0; i < count; ++i) {
+        memset(&tex[i], 0, sizeof(AscTexture));
+        tex[i].tex_id = textures[i];
+        tex[i].target = texture_targets[target];
+        glBindTexture(tex[i].target, tex[i].tex_id);
+        glTexParameteri(tex[i].target, GL_TEXTURE_MIN_FILTER,
+                        texture_filters[min_filter]);
+        glTexParameteri(tex[i].target, GL_TEXTURE_MAG_FILTER,
+                        texture_filters[mag_filter]);
+        asc_dprintf("Initialized texture: %u", tex[i].tex_id);
+    }
+
+    // TODO: proper error handling for each gl call
     asc_error_catch_all_gl();
 }
 
-void asc_texture_destroy(AscTexture *tex) {
-    asc_dprintf("Destroy texture: %u", tex->tex_id);
-    glDeleteTextures(1, &tex->tex_id);
+void asc_texture_destroy(AscTexture *tex, unsigned count) {
+    GLuint textures[count];
+    for (unsigned i = 0; i < count; ++i) {
+        if (tex[i].refcount > 0) {
+            // TODO: asc_wprintf() for warnings
+            asc_dprintf("Texture %u still in use by %u objects.",
+                tex[i].tex_id, tex[i].refcount);
+        }
+        asc_dprintf("Destroy texture: %u", tex[i].tex_id);
+        textures[i] = tex[i].tex_id;
+        memset(&tex[i], 0, sizeof(AscTexture));
+    }
+    glDeleteTextures(count, textures);
 }

mercurial