--- a/src/texture.c Sat Apr 19 19:30:46 2025 +0200 +++ b/src/texture.c Sun Apr 20 15:41:16 2025 +0200 @@ -25,11 +25,14 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include "ascension/context.h" #include "ascension/texture.h" #include "ascension/error.h" +#include "ascension/filesystem.h" #include <assert.h> #include <GL/glew.h> +#include <SDL2/SDL_image.h> void asc_texture_bind(AscTexture const *tex, int uniform_location, int unit) { glActiveTexture(GL_TEXTURE0 + unit); @@ -48,16 +51,62 @@ asc_dprintf("Texture address: %"PRIxPTR, (uintptr_t) tex); return; } + tex->width = surface->w; + tex->height = surface->h; glBindTexture(tex->target,tex->tex_id); glPixelStorei(GL_UNPACK_ROW_LENGTH, surface->pitch / surface->format->BytesPerPixel); - glTexImage2D(tex->target, 0, GL_RGBA, + + // Determine the format and internal format based on the SDL surface format + GLint internal_format; + GLenum format; + switch (surface->format->format) { + case SDL_PIXELFORMAT_RGB24: + internal_format = GL_RGB8; + format = GL_RGB; + break; + case SDL_PIXELFORMAT_BGR24: + internal_format = GL_RGB8; + format = GL_BGR; + break; + case SDL_PIXELFORMAT_RGBA32: + case SDL_PIXELFORMAT_ABGR32: + internal_format = GL_RGBA8; + format = GL_RGBA; + break; + case SDL_PIXELFORMAT_ARGB32: + case SDL_PIXELFORMAT_BGRA32: + internal_format = GL_RGBA8; + format = GL_BGRA; + break; + default: + // TODO: add more output once asc_error allows format strings + asc_error("Unsupported pixel format."); + return; + } + glTexImage2D(tex->target, 0, internal_format, surface->w, surface->h, - 0, GL_BGRA, + 0, format, GL_UNSIGNED_BYTE, surface->pixels); + // TODO: replace catch all with proper error handling for this single call asc_error_catch_all_gl(); } +void asc_texture_from_file(AscTexture *tex, const char *name) { + cxmutstr filepath = asc_filesystem_combine_paths(cx_strcast(asc_context.texture_path), cx_str(name)); + asc_dprintf("Load texture from %" CX_PRIstr, CX_SFMT(filepath)); + SDL_Surface *image = IMG_Load(filepath.ptr); + cx_strfree(&filepath); + if (image == NULL) { + asc_error("Failed to load texture."); + asc_error(IMG_GetError()); + return; + } + asc_texture_from_surface(tex, image); + asc_dprintf("Free temporary surface %"PRIxPTR, (uintptr_t) image); + SDL_FreeSurface(image); +} + void asc_texture_init( AscTexture *tex, enum asc_texture_target target, @@ -65,7 +114,8 @@ enum asc_texture_mag_filter mag_filter ) { static const GLenum texture_targets[] = { - GL_TEXTURE_RECTANGLE + GL_TEXTURE_RECTANGLE, + GL_TEXTURE_2D, }; static const GLint texture_filters[] = { GL_NEAREST,