diff options
| -rw-r--r-- | gfx/include/gfx/render_backend.h | 35 | ||||
| -rw-r--r-- | gfx/src/render/texture.c | 69 | ||||
| -rw-r--r-- | gfx/src/render/texture.h | 4 | ||||
| -rw-r--r-- | gfx/src/util/texture.c | 4 |
4 files changed, 73 insertions, 39 deletions
diff --git a/gfx/include/gfx/render_backend.h b/gfx/include/gfx/render_backend.h index b07cf16..722ea5e 100644 --- a/gfx/include/gfx/render_backend.h +++ b/gfx/include/gfx/render_backend.h | |||
| @@ -213,8 +213,10 @@ typedef struct ShaderUniform { | |||
| 213 | } value; | 213 | } value; |
| 214 | } ShaderUniform; | 214 | } ShaderUniform; |
| 215 | 215 | ||
| 216 | /// Texture dimension. | ||
| 216 | typedef enum { Texture2D, TextureCubeMap } TextureDimension; | 217 | typedef enum { Texture2D, TextureCubeMap } TextureDimension; |
| 217 | 218 | ||
| 219 | /// Texture data format. | ||
| 218 | typedef enum { | 220 | typedef enum { |
| 219 | TextureDepth, | 221 | TextureDepth, |
| 220 | TextureRG16, | 222 | TextureRG16, |
| @@ -226,10 +228,13 @@ typedef enum { | |||
| 226 | TextureSRGBA8 | 228 | TextureSRGBA8 |
| 227 | } TextureFormat; | 229 | } TextureFormat; |
| 228 | 230 | ||
| 231 | /// Texture filtering. | ||
| 229 | typedef enum { NearestFiltering, LinearFiltering } TextureFiltering; | 232 | typedef enum { NearestFiltering, LinearFiltering } TextureFiltering; |
| 230 | 233 | ||
| 234 | /// Texture wrap mode. | ||
| 231 | typedef enum { Repeat, ClampToEdge } TextureWrapping; | 235 | typedef enum { Repeat, ClampToEdge } TextureWrapping; |
| 232 | 236 | ||
| 237 | /// Cubemap faces. | ||
| 233 | typedef enum { | 238 | typedef enum { |
| 234 | CubemapFacePosX, | 239 | CubemapFacePosX, |
| 235 | CubemapFaceNegX, | 240 | CubemapFaceNegX, |
| @@ -239,16 +244,8 @@ typedef enum { | |||
| 239 | CubemapFaceNegZ | 244 | CubemapFaceNegZ |
| 240 | } CubemapFace; | 245 | } CubemapFace; |
| 241 | 246 | ||
| 242 | /// Describes a texture. | 247 | /// Texture data descriptor. |
| 243 | typedef struct TextureDesc { | 248 | typedef struct TextureDataDesc { |
| 244 | int width; | ||
| 245 | int height; | ||
| 246 | int depth; // Not used until 3D textures are exposed. | ||
| 247 | TextureDimension dimension; | ||
| 248 | TextureFormat format; | ||
| 249 | TextureFiltering filtering; | ||
| 250 | TextureWrapping wrap; | ||
| 251 | bool mipmaps; | ||
| 252 | union { | 249 | union { |
| 253 | const void* pixels; | 250 | const void* pixels; |
| 254 | struct { | 251 | struct { |
| @@ -260,6 +257,19 @@ typedef struct TextureDesc { | |||
| 260 | const void* pixels_neg_z; | 257 | const void* pixels_neg_z; |
| 261 | } cubemap; | 258 | } cubemap; |
| 262 | }; | 259 | }; |
| 260 | } TextureDataDesc; | ||
| 261 | |||
| 262 | /// Describes a texture. | ||
| 263 | typedef struct TextureDesc { | ||
| 264 | int width; | ||
| 265 | int height; | ||
| 266 | int depth; // Not used until 3D textures are exposed. | ||
| 267 | TextureDimension dimension; | ||
| 268 | TextureFormat format; | ||
| 269 | TextureFiltering filtering; | ||
| 270 | TextureWrapping wrap; | ||
| 271 | bool mipmaps; | ||
| 272 | TextureDataDesc data; | ||
| 263 | } TextureDesc; | 273 | } TextureDesc; |
| 264 | 274 | ||
| 265 | /// Describes a renderbuffer. | 275 | /// Describes a renderbuffer. |
| @@ -339,7 +349,7 @@ Buffer* gfx_make_buffer(RenderBackend*, const BufferDesc*); | |||
| 339 | void gfx_destroy_buffer(RenderBackend*, Buffer**); | 349 | void gfx_destroy_buffer(RenderBackend*, Buffer**); |
| 340 | 350 | ||
| 341 | /// Update the buffer's data. | 351 | /// Update the buffer's data. |
| 342 | void gfx_update_buffer(RenderBackend*, Buffer*, const BufferDataDesc*); | 352 | void gfx_update_buffer(Buffer*, const BufferDataDesc*); |
| 343 | 353 | ||
| 344 | // ----------------------------------------------------------------------------- | 354 | // ----------------------------------------------------------------------------- |
| 345 | // Geometry. | 355 | // Geometry. |
| @@ -385,6 +395,9 @@ Texture* gfx_make_texture(RenderBackend*, const TextureDesc*); | |||
| 385 | /// Destroy the texture. | 395 | /// Destroy the texture. |
| 386 | void gfx_destroy_texture(RenderBackend*, Texture**); | 396 | void gfx_destroy_texture(RenderBackend*, Texture**); |
| 387 | 397 | ||
| 398 | /// Update the texture. | ||
| 399 | void gfx_update_texture(Texture*, const TextureDataDesc*); | ||
| 400 | |||
| 388 | // ----------------------------------------------------------------------------- | 401 | // ----------------------------------------------------------------------------- |
| 389 | // Renderbuffers. | 402 | // Renderbuffers. |
| 390 | // ----------------------------------------------------------------------------- | 403 | // ----------------------------------------------------------------------------- |
diff --git a/gfx/src/render/texture.c b/gfx/src/render/texture.c index 312aecc..489f7a2 100644 --- a/gfx/src/render/texture.c +++ b/gfx/src/render/texture.c | |||
| @@ -37,32 +37,14 @@ bool gfx_init_texture(Texture* texture, const TextureDesc* desc) { | |||
| 37 | return false; | 37 | return false; |
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | // glTexSubImageXD | 40 | texture->format = to_GL_format(desc->format); |
| 41 | const GLenum format = to_GL_format(desc->format); | 41 | texture->type = to_GL_type(desc->format); |
| 42 | const GLenum type = to_GL_type(desc->format); | 42 | texture->width = desc->width; |
| 43 | switch (texture->target) { | 43 | texture->height = desc->height; |
| 44 | case GL_TEXTURE_2D: | 44 | gfx_update_texture(texture, &desc->data); |
| 45 | if (desc->pixels) { | 45 | |
| 46 | glTexSubImage2D( | 46 | // gfx_update_texture() unbinds the texture at the end, so re-bind it here. |
| 47 | GL_TEXTURE_2D, /*level=*/0, /*xoffset=*/0, | 47 | glBindTexture(texture->target, texture->id); |
| 48 | /*yoffset=*/0, desc->width, desc->height, format, type, desc->pixels); | ||
| 49 | } | ||
| 50 | break; | ||
| 51 | case GL_TEXTURE_CUBE_MAP: | ||
| 52 | for (int i = 0; i < 6; ++i) { | ||
| 53 | const void* pixels = *(&desc->cubemap.pixels_pos_x + i); | ||
| 54 | if (pixels) { | ||
| 55 | glTexSubImage2D( | ||
| 56 | GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, /*level=*/0, /*xoffset=*/0, | ||
| 57 | /*yoffset=*/0, desc->width, desc->height, format, type, pixels); | ||
| 58 | } | ||
| 59 | } | ||
| 60 | break; | ||
| 61 | default: | ||
| 62 | assert(false && "Unhandled texture dimension"); | ||
| 63 | gfx_del_texture(texture); | ||
| 64 | return false; | ||
| 65 | } | ||
| 66 | 48 | ||
| 67 | // Mipmaps. | 49 | // Mipmaps. |
| 68 | if (desc->mipmaps) { | 50 | if (desc->mipmaps) { |
| @@ -103,6 +85,41 @@ void gfx_del_texture(Texture* texture) { | |||
| 103 | } | 85 | } |
| 104 | } | 86 | } |
| 105 | 87 | ||
| 88 | void gfx_update_texture(Texture* texture, const TextureDataDesc* desc) { | ||
| 89 | assert(texture); | ||
| 90 | assert(desc); | ||
| 91 | |||
| 92 | glBindTexture(texture->target, texture->id); | ||
| 93 | |||
| 94 | // glTexSubImageXD | ||
| 95 | switch (texture->target) { | ||
| 96 | case GL_TEXTURE_2D: | ||
| 97 | if (desc->pixels) { | ||
| 98 | glTexSubImage2D( | ||
| 99 | GL_TEXTURE_2D, /*level=*/0, /*xoffset=*/0, | ||
| 100 | /*yoffset=*/0, texture->width, texture->height, texture->format, | ||
| 101 | texture->type, desc->pixels); | ||
| 102 | } | ||
| 103 | break; | ||
| 104 | case GL_TEXTURE_CUBE_MAP: | ||
| 105 | for (int i = 0; i < 6; ++i) { | ||
| 106 | const void* pixels = *(&desc->cubemap.pixels_pos_x + i); | ||
| 107 | if (pixels) { | ||
| 108 | glTexSubImage2D( | ||
| 109 | GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, /*level=*/0, /*xoffset=*/0, | ||
| 110 | /*yoffset=*/0, texture->width, texture->height, texture->format, | ||
| 111 | texture->type, pixels); | ||
| 112 | } | ||
| 113 | } | ||
| 114 | break; | ||
| 115 | default: | ||
| 116 | assert(false && "Unhandled texture dimension"); | ||
| 117 | break; | ||
| 118 | } | ||
| 119 | |||
| 120 | glBindTexture(texture->target, 0); | ||
| 121 | } | ||
| 122 | |||
| 106 | GLenum to_GL_dimension(TextureDimension dim) { | 123 | GLenum to_GL_dimension(TextureDimension dim) { |
| 107 | switch (dim) { | 124 | switch (dim) { |
| 108 | case Texture2D: | 125 | case Texture2D: |
diff --git a/gfx/src/render/texture.h b/gfx/src/render/texture.h index b4e4bed..f667752 100644 --- a/gfx/src/render/texture.h +++ b/gfx/src/render/texture.h | |||
| @@ -7,6 +7,10 @@ | |||
| 7 | typedef struct Texture { | 7 | typedef struct Texture { |
| 8 | GLuint id; | 8 | GLuint id; |
| 9 | GLenum target; | 9 | GLenum target; |
| 10 | GLenum format; | ||
| 11 | GLenum type; | ||
| 12 | int width; | ||
| 13 | int height; | ||
| 10 | } Texture; | 14 | } Texture; |
| 11 | 15 | ||
| 12 | /// Create a new texture. | 16 | /// Create a new texture. |
diff --git a/gfx/src/util/texture.c b/gfx/src/util/texture.c index 7ec0e40..23f15f0 100644 --- a/gfx/src/util/texture.c +++ b/gfx/src/util/texture.c | |||
| @@ -159,11 +159,11 @@ Texture* gfx_load_texture( | |||
| 159 | 159 | ||
| 160 | switch (cmd->type) { | 160 | switch (cmd->type) { |
| 161 | case LoadTexture: | 161 | case LoadTexture: |
| 162 | desc.pixels = pixels[0]; | 162 | desc.data.pixels = pixels[0]; |
| 163 | break; | 163 | break; |
| 164 | case LoadCubemap: | 164 | case LoadCubemap: |
| 165 | for (int i = 0; i < 6; ++i) { | 165 | for (int i = 0; i < 6; ++i) { |
| 166 | *(&desc.cubemap.pixels_pos_x + i) = pixels[i]; | 166 | *(&desc.data.cubemap.pixels_pos_x + i) = pixels[i]; |
| 167 | } | 167 | } |
| 168 | break; | 168 | break; |
| 169 | } | 169 | } |
