summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author3gg <3gg@shellblade.net>2023-06-21 08:57:30 -0700
committer3gg <3gg@shellblade.net>2023-06-21 08:57:30 -0700
commit97ffb9cd1b9bdf8f7691c1ed9751bf2b93a3d966 (patch)
tree94310c906387095bfc911f392a053aa72bdbb0d2
parenta6767082a78e8b090fcce8c386fcbd359da8ecee (diff)
Add ability to update texture contents.
-rw-r--r--gfx/include/gfx/render_backend.h35
-rw-r--r--gfx/src/render/texture.c69
-rw-r--r--gfx/src/render/texture.h4
-rw-r--r--gfx/src/util/texture.c4
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.
216typedef enum { Texture2D, TextureCubeMap } TextureDimension; 217typedef enum { Texture2D, TextureCubeMap } TextureDimension;
217 218
219/// Texture data format.
218typedef enum { 220typedef 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.
229typedef enum { NearestFiltering, LinearFiltering } TextureFiltering; 232typedef enum { NearestFiltering, LinearFiltering } TextureFiltering;
230 233
234/// Texture wrap mode.
231typedef enum { Repeat, ClampToEdge } TextureWrapping; 235typedef enum { Repeat, ClampToEdge } TextureWrapping;
232 236
237/// Cubemap faces.
233typedef enum { 238typedef 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.
243typedef struct TextureDesc { 248typedef 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.
263typedef 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*);
339void gfx_destroy_buffer(RenderBackend*, Buffer**); 349void gfx_destroy_buffer(RenderBackend*, Buffer**);
340 350
341/// Update the buffer's data. 351/// Update the buffer's data.
342void gfx_update_buffer(RenderBackend*, Buffer*, const BufferDataDesc*); 352void 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.
386void gfx_destroy_texture(RenderBackend*, Texture**); 396void gfx_destroy_texture(RenderBackend*, Texture**);
387 397
398/// Update the texture.
399void 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
88void 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
106GLenum to_GL_dimension(TextureDimension dim) { 123GLenum 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 @@
7typedef struct Texture { 7typedef 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 }