Tue, 09 Apr 2024 21:18:52 +0200
add texture.h
shader/sprite_frag.glsl | file | annotate | diff | comparison | revisions | |
src/Makefile | file | annotate | diff | comparison | revisions | |
src/ascension/shader.h | file | annotate | diff | comparison | revisions | |
src/ascension/texture.h | file | annotate | diff | comparison | revisions | |
src/ascension/ui/text.h | file | annotate | diff | comparison | revisions | |
src/glcontext.c | file | annotate | diff | comparison | revisions | |
src/shader.c | file | annotate | diff | comparison | revisions | |
src/text.c | file | annotate | diff | comparison | revisions | |
src/texture.c | file | annotate | diff | comparison | revisions | |
test/Makefile | file | annotate | diff | comparison | revisions |
1.1 --- a/shader/sprite_frag.glsl Mon Apr 01 19:44:00 2024 +0200 1.2 +++ b/shader/sprite_frag.glsl Tue Apr 09 21:18:52 2024 +0200 1.3 @@ -3,8 +3,8 @@ 1.4 layout(location = 0) out vec4 diffuse; 1.5 in vec2 texcoord; 1.6 1.7 -uniform sampler2DRect surface; 1.8 +uniform sampler2DRect tex; 1.9 1.10 void main(void) { 1.11 - diffuse = texture(surface, texcoord); 1.12 + diffuse = texture(tex, texcoord); 1.13 }
2.1 --- a/src/Makefile Mon Apr 01 19:44:00 2024 +0200 2.2 +++ b/src/Makefile Tue Apr 09 21:18:52 2024 +0200 2.3 @@ -28,7 +28,7 @@ 2.4 BUILD_DIR=../build/lib 2.5 2.6 SRC = context.c glcontext.c error.c window.c files.c shader.c font.c text.c \ 2.7 - scene.c camera.c primitives.c 2.8 + texture.c scene.c camera.c primitives.c 2.9 2.10 OBJ = $(SRC:%.c=$(BUILD_DIR)/%.o) 2.11 2.12 @@ -102,11 +102,15 @@ 2.13 2.14 $(BUILD_DIR)/text.o: text.c ascension/ui/text.h ascension/ui/font.h \ 2.15 ascension/ui/../scene.h ascension/ui/../datatypes.h \ 2.16 - ascension/ui/../transform.h ascension/ui/../camera.h ascension/context.h \ 2.17 - ascension/datatypes.h ascension/window.h ascension/glcontext.h \ 2.18 - ascension/primitives.h ascension/mesh.h ascension/shader.h \ 2.19 - ascension/scene.h ascension/ui/font.h ascension/error.h \ 2.20 - ascension/shader.h 2.21 + ascension/ui/../transform.h ascension/ui/../camera.h \ 2.22 + ascension/ui/../texture.h ascension/context.h ascension/datatypes.h \ 2.23 + ascension/window.h ascension/glcontext.h ascension/primitives.h \ 2.24 + ascension/mesh.h ascension/shader.h ascension/scene.h \ 2.25 + ascension/ui/font.h ascension/error.h ascension/shader.h 2.26 + @echo "Compiling $<" 2.27 + $(CC) -o $@ $(CFLAGS) -c $< 2.28 + 2.29 +$(BUILD_DIR)/texture.o: texture.c ascension/texture.h ascension/error.h 2.30 @echo "Compiling $<" 2.31 $(CC) -o $@ $(CFLAGS) -c $< 2.32
3.1 --- a/src/ascension/shader.h Mon Apr 01 19:44:00 2024 +0200 3.2 +++ b/src/ascension/shader.h Tue Apr 09 21:18:52 2024 +0200 3.3 @@ -41,8 +41,8 @@ 3.4 3.5 typedef struct AscShaderSprite { 3.6 AscShaderProgram base; 3.7 - int surface; 3.8 int depth; 3.9 + int tex; 3.10 } AscShaderSprite; 3.11 3.12
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/src/ascension/texture.h Tue Apr 09 21:18:52 2024 +0200 4.3 @@ -0,0 +1,81 @@ 4.4 +/* 4.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 4.6 + * Copyright 2024 Mike Becker. All rights reserved. 4.7 + * 4.8 + * Redistribution and use in source and binary forms, with or without 4.9 + * modification, are permitted provided that the following conditions are met: 4.10 + * 4.11 + * 1. Redistributions of source code must retain the above copyright 4.12 + * notice, this list of conditions and the following disclaimer. 4.13 + * 4.14 + * 2. Redistributions in binary form must reproduce the above copyright 4.15 + * notice, this list of conditions and the following disclaimer in the 4.16 + * documentation and/or other materials provided with the distribution. 4.17 + * 4.18 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 4.19 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4.20 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4.21 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 4.22 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 4.23 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 4.24 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 4.25 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 4.26 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 4.27 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 4.28 + * POSSIBILITY OF SUCH DAMAGE. 4.29 + */ 4.30 + 4.31 +#ifndef ASCENSION_TEXTURE_H 4.32 +#define ASCENSION_TEXTURE_H 4.33 + 4.34 +#include <SDL2/SDL_surface.h> 4.35 + 4.36 +typedef struct AscTexture AscTexture; 4.37 + 4.38 +struct AscTexture { 4.39 + unsigned target; 4.40 + unsigned tex_id; 4.41 +}; 4.42 + 4.43 +#define asc_texture_uninitialized(tex) ((tex)->tex_id == 0) 4.44 + 4.45 +enum asc_texture_target { 4.46 + ASC_TEXTURE_RECTANGLE 4.47 +}; 4.48 + 4.49 +enum asc_texture_min_filter { 4.50 + ASC_TEXTURE_MIN_FILTER_NEAREST, 4.51 + ASC_TEXTURE_MIN_FILTER_LINEAR, 4.52 + ASC_TEXTURE_MIN_FILTER_NEAREST_MIPMAP_NEAREST, 4.53 + ASC_TEXTURE_MIN_FILTER_LINEAR_MIPMAP_NEAREST, 4.54 + ASC_TEXTURE_MIN_FILTER_NEAREST_MIPMAP_LINEAR, 4.55 + ASC_TEXTURE_MIN_FILTER_LINEAR_MIPMAP_LINEAR 4.56 +}; 4.57 + 4.58 +enum asc_texture_mag_filter { 4.59 + ASC_TEXTURE_MAG_FILTER_NEAREST, 4.60 + ASC_TEXTURE_MAG_FILTER_LINEAR 4.61 +}; 4.62 + 4.63 +__attribute__((__nonnull__)) 4.64 +void asc_texture_init( 4.65 + AscTexture *tex, 4.66 + enum asc_texture_target target, 4.67 + enum asc_texture_min_filter min_filter, 4.68 + enum asc_texture_mag_filter mag_filter 4.69 +); 4.70 + 4.71 +__attribute__((__nonnull__)) 4.72 +void asc_texture_destroy(AscTexture *tex); 4.73 + 4.74 +#define asc_texture_init_rectangle(tex) \ 4.75 + asc_texture_init(tex, ASC_TEXTURE_RECTANGLE, \ 4.76 + ASC_TEXTURE_MIN_FILTER_LINEAR, ASC_TEXTURE_MAG_FILTER_LINEAR) 4.77 + 4.78 +__attribute__((__nonnull__)) 4.79 +void asc_texture_bind(AscTexture const *tex, int uniform_location, int unit); 4.80 + 4.81 +__attribute__((__nonnull__)) 4.82 +void asc_texture_from_surface(AscTexture *tex, SDL_Surface const *surface); 4.83 + 4.84 +#endif //ASCENSION_TEXTURE_H
5.1 --- a/src/ascension/ui/text.h Mon Apr 01 19:44:00 2024 +0200 5.2 +++ b/src/ascension/ui/text.h Tue Apr 09 21:18:52 2024 +0200 5.3 @@ -30,6 +30,7 @@ 5.4 5.5 #include "font.h" 5.6 #include "../scene.h" 5.7 +#include "../texture.h" 5.8 5.9 typedef struct AscText { 5.10 extend_asc_scene_node; 5.11 @@ -39,7 +40,7 @@ 5.12 unsigned max_width; 5.13 bool hidden; 5.14 bool centered; 5.15 - unsigned tex_id; 5.16 + AscTexture tex; 5.17 } AscText; 5.18 5.19
6.1 --- a/src/glcontext.c Mon Apr 01 19:44:00 2024 +0200 6.2 +++ b/src/glcontext.c Tue Apr 09 21:18:52 2024 +0200 6.3 @@ -51,8 +51,8 @@ 6.4 static void asc_shader_initialize_predefined(AscGLContext *ctx) { 6.5 AscShaderSprite *sprite = &ctx->shader.sprite; 6.6 sprite->base = asc_shader_easy_compile_and_link("shader/sprite_vtx.glsl", "shader/sprite_frag.glsl"); 6.7 - sprite->surface = glGetUniformLocation(sprite->base.id, "surface"); 6.8 sprite->depth = glGetUniformLocation(sprite->base.id, "depth"); 6.9 + sprite->tex = glGetUniformLocation(sprite->base.id, "texture"); 6.10 } 6.11 6.12 static void asc_shader_destroy_predefined(AscGLContext *ctx) {
7.1 --- a/src/shader.c Mon Apr 01 19:44:00 2024 +0200 7.2 +++ b/src/shader.c Tue Apr 09 21:18:52 2024 +0200 7.3 @@ -32,9 +32,6 @@ 7.4 #include <GL/glew.h> 7.5 #include <string.h> 7.6 7.7 -AscShaderSprite ASC_SHADER_SPRITE; 7.8 - 7.9 - 7.10 AscShader asc_shader_compile(unsigned int type, 7.11 char const *code, 7.12 int length) {
8.1 --- a/src/text.c Mon Apr 01 19:44:00 2024 +0200 8.2 +++ b/src/text.c Tue Apr 09 21:18:52 2024 +0200 8.3 @@ -33,7 +33,7 @@ 8.4 #include <GL/glew.h> 8.5 8.6 static void asc_text_draw(AscText const *node) { 8.7 - if (node->color.alpha == 0 || node->hidden || node->tex_id == 0) { 8.8 + if (node->color.alpha == 0 || node->hidden) { 8.9 return; 8.10 } 8.11 8.12 @@ -44,10 +44,8 @@ 8.13 glUniformMatrix4fv(shader->base.model, 1, 8.14 GL_FALSE, node->base.world_transform); 8.15 8.16 - // Upload surface 8.17 - glActiveTexture(GL_TEXTURE0); 8.18 - glBindTexture(GL_TEXTURE_RECTANGLE, node->tex_id); 8.19 - glUniform1i(shader->surface, 0); 8.20 + // Bind texture 8.21 + asc_texture_bind(&node->tex, shader->tex, 0); 8.22 8.23 // Apply depth 8.24 glUniform1f(shader->depth, (float)(node->base.depth)); 8.25 @@ -63,12 +61,8 @@ 8.26 } 8.27 8.28 // Generate new texture, if required 8.29 - if (node->tex_id == 0) { 8.30 - glGenTextures(1, &node->tex_id); 8.31 - glBindTexture(GL_TEXTURE_RECTANGLE, node->tex_id); 8.32 - glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 8.33 - glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 8.34 - asc_dprintf("Generated new texture for text node: %u", node->tex_id); 8.35 + if (asc_texture_uninitialized(&node->tex)) { 8.36 + asc_texture_init_rectangle(&node->tex); 8.37 } 8.38 8.39 // Render text onto a surface 8.40 @@ -87,12 +81,7 @@ 8.41 asc_update_transform((AscSceneNode *) node); 8.42 8.43 // Transfer Image Data 8.44 - // TODO: move the image data transfer to a separate function - we will need it more often 8.45 - glBindTexture(GL_TEXTURE_RECTANGLE, node->tex_id); 8.46 - glPixelStorei(GL_UNPACK_ROW_LENGTH, surface->pitch / surface->format->BytesPerPixel); 8.47 - glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA, 8.48 - surface->w, surface->h, 8.49 - 0, GL_BGRA, GL_UNSIGNED_BYTE, surface->pixels); 8.50 + asc_texture_from_surface(&node->tex, surface); 8.51 8.52 // Free the surface 8.53 SDL_FreeSurface(surface); 8.54 @@ -100,10 +89,6 @@ 8.55 8.56 AscSceneNode *asc_text(int x, int y, char const *text) { 8.57 AscText *node = calloc(1, sizeof(AscText)); 8.58 - if (node == NULL) { 8.59 - asc_error("Out of memory."); 8.60 - return NULL; 8.61 - } 8.62 8.63 node->base.render_group = ASC_RENDER_GROUP_SPRITE_BLEND; 8.64 node->base.free_func = (asc_scene_free_func) asc_text_free; 8.65 @@ -125,8 +110,7 @@ 8.66 } 8.67 8.68 void asc_text_free(AscText *node) { 8.69 - asc_dprintf("Release text node texture: %u", node->tex_id); 8.70 - glDeleteTextures(1, &node->tex_id); 8.71 + asc_texture_destroy(&node->tex); 8.72 free(node->text); 8.73 free(node); 8.74 } 8.75 \ No newline at end of file
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/src/texture.c Tue Apr 09 21:18:52 2024 +0200 9.3 @@ -0,0 +1,87 @@ 9.4 +/* 9.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 9.6 + * Copyright 2024 Mike Becker. All rights reserved. 9.7 + * 9.8 + * Redistribution and use in source and binary forms, with or without 9.9 + * modification, are permitted provided that the following conditions are met: 9.10 + * 9.11 + * 1. Redistributions of source code must retain the above copyright 9.12 + * notice, this list of conditions and the following disclaimer. 9.13 + * 9.14 + * 2. Redistributions in binary form must reproduce the above copyright 9.15 + * notice, this list of conditions and the following disclaimer in the 9.16 + * documentation and/or other materials provided with the distribution. 9.17 + * 9.18 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 9.19 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 9.20 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 9.21 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 9.22 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 9.23 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 9.24 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 9.25 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 9.26 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 9.27 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 9.28 + * POSSIBILITY OF SUCH DAMAGE. 9.29 + */ 9.30 + 9.31 +#include "ascension/texture.h" 9.32 +#include "ascension/error.h" 9.33 + 9.34 +#include <assert.h> 9.35 +#include <GL/glew.h> 9.36 + 9.37 +void asc_texture_bind(AscTexture const *tex, int uniform_location, int unit) { 9.38 + glActiveTexture(GL_TEXTURE0 + unit); 9.39 + GLenum error = glGetError(); 9.40 + if (error == GL_INVALID_ENUM) { 9.41 + asc_error("Tried to use more texture units than available."); 9.42 + } 9.43 + glBindTexture(tex->target, tex->tex_id); 9.44 + glUniform1i(uniform_location, unit); 9.45 +} 9.46 + 9.47 +void asc_texture_from_surface(AscTexture *tex, SDL_Surface const *surface) { 9.48 + glBindTexture(tex->target,tex->tex_id); 9.49 + glPixelStorei(GL_UNPACK_ROW_LENGTH, 9.50 + surface->pitch / surface->format->BytesPerPixel); 9.51 + glTexImage2D(tex->target, 0, GL_RGBA, 9.52 + surface->w, surface->h, 9.53 + 0, GL_BGRA, 9.54 + GL_UNSIGNED_BYTE, surface->pixels); 9.55 +} 9.56 + 9.57 +void asc_texture_init( 9.58 + AscTexture *tex, 9.59 + enum asc_texture_target target, 9.60 + enum asc_texture_min_filter min_filter, 9.61 + enum asc_texture_mag_filter mag_filter 9.62 +) { 9.63 + static const GLenum texture_targets[] = { 9.64 + GL_TEXTURE_RECTANGLE 9.65 + }; 9.66 + static const GLint texture_filters[] = { 9.67 + GL_NEAREST, 9.68 + GL_LINEAR, 9.69 + GL_NEAREST_MIPMAP_NEAREST, 9.70 + GL_LINEAR_MIPMAP_NEAREST, 9.71 + GL_NEAREST_MIPMAP_LINEAR, 9.72 + GL_LINEAR_MIPMAP_LINEAR 9.73 + }; 9.74 + assert(target < sizeof(texture_targets) / sizeof(GLenum)); 9.75 + assert(min_filter < sizeof(texture_filters) / sizeof(GLint)); 9.76 + assert(mag_filter < 2); // mag filter only supports nearest/linear 9.77 + tex->target = texture_targets[target]; 9.78 + glGenTextures(1, &tex->tex_id); 9.79 + glBindTexture(tex->target, tex->tex_id); 9.80 + glTexParameteri(tex->target, GL_TEXTURE_MIN_FILTER, 9.81 + texture_filters[min_filter]); 9.82 + glTexParameteri(tex->target, GL_TEXTURE_MAG_FILTER, 9.83 + texture_filters[mag_filter]); 9.84 + asc_dprintf("Generated new texture for text node: %u", tex->tex_id); 9.85 +} 9.86 + 9.87 +void asc_texture_destroy(AscTexture *tex) { 9.88 + asc_dprintf("Release text node texture: %u", tex->tex_id); 9.89 + glDeleteTextures(1, &tex->tex_id); 9.90 +}
10.1 --- a/test/Makefile Mon Apr 01 19:44:00 2024 +0200 10.2 +++ b/test/Makefile Tue Apr 09 21:18:52 2024 +0200 10.3 @@ -49,7 +49,8 @@ 10.4 ../src/ascension/scene.h ../src/ascension/transform.h \ 10.5 ../src/ascension/camera.h ../src/ascension/ui/font.h \ 10.6 ../src/ascension/ui.h ../src/ascension/ui/text.h \ 10.7 - ../src/ascension/ui/font.h ../src/ascension/ui/../scene.h 10.8 + ../src/ascension/ui/font.h ../src/ascension/ui/../scene.h \ 10.9 + ../src/ascension/ui/../texture.h 10.10 @echo "Compiling $<" 10.11 $(CC) -o $@ $(CFLAGS) -c $< 10.12