103 lines
2.3 KiB
C
103 lines
2.3 KiB
C
/**
|
|
* 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;
|
|
} |