Sun, 20 Apr 2025 15:41:16 +0200
add support for 2d textures in sprite shader - fixes #386
50 | 1 | /* |
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. | |
3 | * Copyright 2024 Mike Becker. All rights reserved. | |
4 | * | |
5 | * Redistribution and use in source and binary forms, with or without | |
6 | * modification, are permitted provided that the following conditions are met: | |
7 | * | |
8 | * 1. Redistributions of source code must retain the above copyright | |
9 | * notice, this list of conditions and the following disclaimer. | |
10 | * | |
11 | * 2. Redistributions in binary form must reproduce the above copyright | |
12 | * notice, this list of conditions and the following disclaimer in the | |
13 | * documentation and/or other materials provided with the distribution. | |
14 | * | |
15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
16 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
17 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
18 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE | |
19 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
20 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
21 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
22 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
23 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
24 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
25 | * POSSIBILITY OF SUCH DAMAGE. | |
26 | */ | |
27 | ||
88
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
28 | #include "ascension/context.h" |
50 | 29 | #include "ascension/texture.h" |
30 | #include "ascension/error.h" | |
88
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
31 | #include "ascension/filesystem.h" |
50 | 32 | |
33 | #include <assert.h> | |
34 | #include <GL/glew.h> | |
88
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
35 | #include <SDL2/SDL_image.h> |
50 | 36 | |
37 | void asc_texture_bind(AscTexture const *tex, int uniform_location, int unit) { | |
38 | glActiveTexture(GL_TEXTURE0 + unit); | |
39 | GLenum error = glGetError(); | |
40 | if (error == GL_INVALID_ENUM) { | |
41 | asc_error("Tried to use more texture units than available."); | |
42 | } | |
43 | glBindTexture(tex->target, tex->tex_id); | |
44 | glUniform1i(uniform_location, unit); | |
86
943bf9d7c6d6
make asset paths configurable
Mike Becker <universe@uap-core.de>
parents:
85
diff
changeset
|
45 | asc_error_catch_all_gl(); |
50 | 46 | } |
47 | ||
48 | void asc_texture_from_surface(AscTexture *tex, SDL_Surface const *surface) { | |
86
943bf9d7c6d6
make asset paths configurable
Mike Becker <universe@uap-core.de>
parents:
85
diff
changeset
|
49 | if (asc_texture_uninitialized(tex)) { |
943bf9d7c6d6
make asset paths configurable
Mike Becker <universe@uap-core.de>
parents:
85
diff
changeset
|
50 | asc_error("Tried to use uninitialized texture."); |
943bf9d7c6d6
make asset paths configurable
Mike Becker <universe@uap-core.de>
parents:
85
diff
changeset
|
51 | asc_dprintf("Texture address: %"PRIxPTR, (uintptr_t) tex); |
943bf9d7c6d6
make asset paths configurable
Mike Becker <universe@uap-core.de>
parents:
85
diff
changeset
|
52 | return; |
943bf9d7c6d6
make asset paths configurable
Mike Becker <universe@uap-core.de>
parents:
85
diff
changeset
|
53 | } |
88
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
54 | tex->width = surface->w; |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
55 | tex->height = surface->h; |
50 | 56 | glBindTexture(tex->target,tex->tex_id); |
57 | glPixelStorei(GL_UNPACK_ROW_LENGTH, | |
58 | surface->pitch / surface->format->BytesPerPixel); | |
88
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
59 | |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
60 | // Determine the format and internal format based on the SDL surface format |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
61 | GLint internal_format; |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
62 | GLenum format; |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
63 | switch (surface->format->format) { |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
64 | case SDL_PIXELFORMAT_RGB24: |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
65 | internal_format = GL_RGB8; |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
66 | format = GL_RGB; |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
67 | break; |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
68 | case SDL_PIXELFORMAT_BGR24: |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
69 | internal_format = GL_RGB8; |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
70 | format = GL_BGR; |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
71 | break; |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
72 | case SDL_PIXELFORMAT_RGBA32: |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
73 | case SDL_PIXELFORMAT_ABGR32: |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
74 | internal_format = GL_RGBA8; |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
75 | format = GL_RGBA; |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
76 | break; |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
77 | case SDL_PIXELFORMAT_ARGB32: |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
78 | case SDL_PIXELFORMAT_BGRA32: |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
79 | internal_format = GL_RGBA8; |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
80 | format = GL_BGRA; |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
81 | break; |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
82 | default: |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
83 | // TODO: add more output once asc_error allows format strings |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
84 | asc_error("Unsupported pixel format."); |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
85 | return; |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
86 | } |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
87 | glTexImage2D(tex->target, 0, internal_format, |
50 | 88 | surface->w, surface->h, |
88
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
89 | 0, format, |
50 | 90 | GL_UNSIGNED_BYTE, surface->pixels); |
88
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
91 | // TODO: replace catch all with proper error handling for this single call |
86
943bf9d7c6d6
make asset paths configurable
Mike Becker <universe@uap-core.de>
parents:
85
diff
changeset
|
92 | asc_error_catch_all_gl(); |
50 | 93 | } |
94 | ||
88
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
95 | void asc_texture_from_file(AscTexture *tex, const char *name) { |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
96 | cxmutstr filepath = asc_filesystem_combine_paths(cx_strcast(asc_context.texture_path), cx_str(name)); |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
97 | asc_dprintf("Load texture from %" CX_PRIstr, CX_SFMT(filepath)); |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
98 | SDL_Surface *image = IMG_Load(filepath.ptr); |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
99 | cx_strfree(&filepath); |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
100 | if (image == NULL) { |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
101 | asc_error("Failed to load texture."); |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
102 | asc_error(IMG_GetError()); |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
103 | return; |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
104 | } |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
105 | asc_texture_from_surface(tex, image); |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
106 | asc_dprintf("Free temporary surface %"PRIxPTR, (uintptr_t) image); |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
107 | SDL_FreeSurface(image); |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
108 | } |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
109 | |
50 | 110 | void asc_texture_init( |
111 | AscTexture *tex, | |
112 | enum asc_texture_target target, | |
113 | enum asc_texture_min_filter min_filter, | |
114 | enum asc_texture_mag_filter mag_filter | |
115 | ) { | |
116 | static const GLenum texture_targets[] = { | |
88
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
117 | GL_TEXTURE_RECTANGLE, |
6234b7ea48f3
add support for 2d textures in sprite shader - fixes #386
Mike Becker <universe@uap-core.de>
parents:
86
diff
changeset
|
118 | GL_TEXTURE_2D, |
50 | 119 | }; |
120 | static const GLint texture_filters[] = { | |
121 | GL_NEAREST, | |
122 | GL_LINEAR, | |
123 | GL_NEAREST_MIPMAP_NEAREST, | |
124 | GL_LINEAR_MIPMAP_NEAREST, | |
125 | GL_NEAREST_MIPMAP_LINEAR, | |
126 | GL_LINEAR_MIPMAP_LINEAR | |
127 | }; | |
128 | assert(target < sizeof(texture_targets) / sizeof(GLenum)); | |
129 | assert(min_filter < sizeof(texture_filters) / sizeof(GLint)); | |
130 | assert(mag_filter < 2); // mag filter only supports nearest/linear | |
131 | tex->target = texture_targets[target]; | |
132 | glGenTextures(1, &tex->tex_id); | |
133 | glBindTexture(tex->target, tex->tex_id); | |
134 | glTexParameteri(tex->target, GL_TEXTURE_MIN_FILTER, | |
135 | texture_filters[min_filter]); | |
136 | glTexParameteri(tex->target, GL_TEXTURE_MAG_FILTER, | |
137 | texture_filters[mag_filter]); | |
85 | 138 | asc_dprintf("Initialized texture: %u", tex->tex_id); |
86
943bf9d7c6d6
make asset paths configurable
Mike Becker <universe@uap-core.de>
parents:
85
diff
changeset
|
139 | asc_error_catch_all_gl(); |
50 | 140 | } |
141 | ||
142 | void asc_texture_destroy(AscTexture *tex) { | |
85 | 143 | asc_dprintf("Destroy texture: %u", tex->tex_id); |
50 | 144 | glDeleteTextures(1, &tex->tex_id); |
145 | } |