/** * Copyright (c) 2023 Dominic Masters * * This software is released under the MIT License. * https://opensource.org/licenses/MIT */ #include "texture.h" #include "assert/assert.h" #include "assert/assertgl.h" #include "asset.h" #include "util/math.h" #include "util/memory.h" #define TEXTURE_BUFFER_SIZE 32768 int32_t TEXTURE_ACTIVE_COUNT; void textureLoad( texture_t *texture, const char_t *path ) { assertNotNull(texture, "Texture is null."); assertNotNull(path, "Path is null."); // Open asset assetOpen(path); // Setup spng spng_ctx *ctx = spng_ctx_new(0); spng_set_png_stream(ctx, &textureSPNGBuffer, NULL); // Get image info struct spng_ihdr ihdr; spng_get_ihdr(ctx, &ihdr); texture->width = ihdr.width; texture->height = ihdr.height; // Decode the image. I can probably stream this in the future. size_t dataSize = ihdr.width * ihdr.height * 4;// 4 for RGBA uint8_t *data = (uint8_t *)memoryAllocate(dataSize); assertNotNull(data, "Failed to allocate memory for texture data."); spng_decode_image(ctx, data, dataSize, SPNG_FMT_RGBA8, 0); // Finish decoding spng_ctx_free(ctx); assetClose(); // Create texture glGenTextures(1, &texture->id); assertNoGLError(); glBindTexture(GL_TEXTURE_2D, texture->id); assertNoGLError(); // Buffer then cleanup glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, texture->width, texture->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data ); assertNoGLError(); memoryFree(data); // Setup texture parameters glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); assertNoGLError(); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); assertNoGLError(); glBindTexture(GL_TEXTURE_2D, 0); assertNoGLError(); } void textureBind( const texture_t *texture, const GLuint slot ) { assertNotNull(texture, "Texture is null."); glActiveTexture(GL_TEXTURE0 + slot); assertNoGLError(); glBindTexture(GL_TEXTURE_2D, texture->id); assertNoGLError(); } void textureDispose(texture_t *texture) { glDeleteTextures(1, &texture->id); assertNoGLError(); } int32_t textureSPNGBuffer( spng_ctx *ctx, void *user, void *destination, size_t length ) { size_t read = assetRead(destination, length); if(read == 0) return SPNG_IO_EOF; return SPNG_OK; }