/** * Copyright (c) 2021 Dominic Masters * * This software is released under the MIT License. * https://opensource.org/licenses/MIT */ #include "texture.h" // Due to some compiler bullshit, this is here. #ifndef STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION #include #endif void textureInit(texture_t *texture, int32_t width, int32_t height, pixel_t *pixels ) { ASSERT_NOT_NULL(texture); ASSERT_GREATER_THAN(width, 0); ASSERT_GREATER_THAN(height, 0); texture->width = width; texture->height = height; // Generate a texture ID and bind. glGenTextures(1, &texture->id); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture->id); // Setup our preferred texture params glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Start by buffering all transparent black pixels. if(pixels == NULL) { // TODO: I can optimize this, I think the GPU can default this somehow pixels = calloc(width * height, sizeof(pixel_t)); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels ); free(pixels); } else { glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels ); } textureBind(texture, 0x00); } void textureBind(texture_t *texture, textureslot_t slot) { ASSERT_NOT_NULL(texture); ASSERT_GREATER_THAN_EQUAL_TO(slot, 0); ASSERT_LESS_THAN(slot, TEXTURE_SLOTS_MAX); glActiveTexture(GL_TEXTURE0 + slot); glBindTexture(GL_TEXTURE_2D, texture->id); } void textureBufferPixels(texture_t *texture, int32_t x, int32_t y, int32_t width, int32_t height, pixel_t *pixels ) { ASSERT_NOT_NULL(texture); ASSERT_NOT_NULL(pixels); ASSERT_GREATER_THAN_EQUAL_TO(x, 0); ASSERT_GREATER_THAN_EQUAL_TO(y, 0); ASSERT_GREATER_THAN(width, 0); ASSERT_GREATER_THAN(height, 0); ASSERT_LESS_THAN_EQUAL_TO(width, texture->width); ASSERT_LESS_THAN_EQUAL_TO(height, texture->height); glBindTexture(GL_TEXTURE_2D, texture->id); glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels ); } void textureDispose(texture_t *texture) { ASSERT_NOT_NULL(texture); glDeleteTextures(1, &texture->id); }