diff options
author | 3gg <3gg@shellblade.net> | 2023-06-21 08:57:30 -0700 |
---|---|---|
committer | 3gg <3gg@shellblade.net> | 2023-06-21 08:57:30 -0700 |
commit | 97ffb9cd1b9bdf8f7691c1ed9751bf2b93a3d966 (patch) | |
tree | 94310c906387095bfc911f392a053aa72bdbb0d2 | |
parent | a6767082a78e8b090fcce8c386fcbd359da8ecee (diff) |
Add ability to update texture contents.
-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 | } |