add texture.h

Tue, 09 Apr 2024 21:18:52 +0200

author
Mike Becker <universe@uap-core.de>
date
Tue, 09 Apr 2024 21:18:52 +0200
changeset 50
d8d2e4817db1
parent 49
77493525eac2
child 51
a656496594f9

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  

mercurial