textures master
authorJohn Tsiombikas <nuclear@member.fsf.org>
Sat, 6 Apr 2024 17:15:16 +0000 (20:15 +0300)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Sat, 6 Apr 2024 17:15:16 +0000 (20:15 +0300)
src/gfx.h
src/gl/gfx_gl.h
src/gl/tex_gl.c [new file with mode: 0644]
src/nexus3d.c
src/nexus3d.h

index fc9816a..cf3887c 100644 (file)
--- a/src/gfx.h
+++ b/src/gfx.h
@@ -43,6 +43,17 @@ enum nex_cube_face {
        NEX_CUBE_PZ, NEX_CUBE_NZ
 };
 
+enum nex_pixfmt {
+       NEX_GREY8,
+       NEX_RGB24,
+       NEX_RGBA32,
+       NEX_SRGB,
+       NEX_SRGBA,
+       NEX_GREYF,
+       NEX_RGBF,
+       NEX_RGBAF
+};
+
 typedef struct nex_buffer nex_buffer;
 typedef struct nex_geometry nex_geometry;
 typedef struct nex_shader nex_shader;
@@ -104,4 +115,21 @@ nex_sdrprog *nex_load_sdrprog(const char *vpath, const char *ppath);
 nex_texture *nex_alloc_texture(enum nex_tex_type type);
 void nex_free_texture(nex_texture *tex);
 
+void nex_tex_storage1d(nex_texture *tex, int sz, enum nex_pixfmt fmt);
+void nex_tex_storage2d(nex_texture *tex, int xsz, int ysz, enum nex_pixfmt fmt);
+void nex_tex_storage3d(nex_texture *tex, int xsz, int ysz, int zsz, enum nex_pixfmt fmt);
+void nex_tex_storagecube(nex_texture *tex, int xsz, int ysz, enum nex_pixfmt fmt);
+
+void nex_tex_update1d(nex_texture *tex, int lvl, int x, int width,
+               enum nex_pixfmt pixfmt, void *data, long pitch);
+void nex_tex_update2d(nex_texture *tex, int lvl, int x, int y, int width, int height,
+               enum nex_pixfmt pixfmt, void *data, long pitch);
+void nex_tex_update3d(nex_texture *tex, int lvl, int x, int y, int z, int width,
+               int height, int depth, enum nex_pixfmt pixfmt, void *data, long pitch);
+void nex_tex_updatecube(nex_texture *tex, int lvl, enum nex_cube_face face,
+               int x, int y, int width, int height, enum nex_pixfmt pixfmt, void *data,
+               long pitch);
+
+void bind_texture(int tunit, nex_texture *tex);
+
 #endif /* NEXUS3D_GFX_H_ */
index 01fa5c8..2ed2e77 100644 (file)
@@ -47,4 +47,12 @@ struct nex_sdrprog {
        int num_sdr;
 };
 
+
+struct nex_texture {
+       unsigned int tex;
+       int xsz, ysz, zsz;
+       enum nex_tex_type type;
+       enum nex_pixfmt pixfmt;
+};
+
 #endif /* NEXUS3D_GFX_GL_H_ */
diff --git a/src/gl/tex_gl.c b/src/gl/tex_gl.c
new file mode 100644 (file)
index 0000000..6369a5c
--- /dev/null
@@ -0,0 +1,210 @@
+#include "nexus3d_impl.h"
+#include "gfx_gl.h"
+#include "opengl.h"
+
+static unsigned int gltextype(enum nex_tex_type type);
+static unsigned int glpixfmt(enum nex_pixfmt fmt);
+static unsigned int glformat(enum nex_pixfmt fmt);
+static unsigned int gltype(enum nex_pixfmt fmt);
+/*static unsigned int glcubeface(enum nex_cube_face face);*/
+static unsigned int miplevels(int x, int y, int z);
+
+nex_texture *nex_alloc_texture(enum nex_tex_type type)
+{
+       nex_texture *tex;
+
+       if(!(tex = calloc(1, sizeof *tex))) {
+               return 0;
+       }
+       tex->type = type;
+       glCreateTextures(gltextype(type), 1, &tex->tex);
+       return tex;
+}
+
+void nex_free_texture(nex_texture *tex)
+{
+       if(!tex) return;
+
+       glDeleteTextures(1, &tex->tex);
+       free(tex);
+}
+
+
+void nex_tex_storage1d(nex_texture *tex, int sz, enum nex_pixfmt fmt)
+{
+       glTextureStorage1D(tex->tex, miplevels(sz, 0, 0), glpixfmt(fmt), sz);
+}
+
+void nex_tex_storage2d(nex_texture *tex, int xsz, int ysz, enum nex_pixfmt fmt)
+{
+       int levels = miplevels(xsz, ysz, 0);
+       glTextureStorage2D(tex->tex, levels, glpixfmt(fmt), xsz, ysz);
+}
+
+void nex_tex_storage3d(nex_texture *tex, int xsz, int ysz, int zsz, enum nex_pixfmt fmt)
+{
+       int levels = miplevels(xsz, ysz, zsz);
+       glTextureStorage3D(tex->tex, levels, glpixfmt(fmt), xsz, ysz, zsz);
+}
+
+void nex_tex_storagecube(nex_texture *tex, int xsz, int ysz, enum nex_pixfmt fmt)
+{
+       nex_tex_storage2d(tex, xsz, ysz, fmt);
+}
+
+
+void nex_tex_update1d(nex_texture *tex, int lvl, int x, int width,
+               enum nex_pixfmt pixfmt, void *data, long pitch)
+{
+       int fmt = glformat(pixfmt);
+       int type = gltype(pixfmt);
+       glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch);
+       glTextureSubImage1D(tex->tex, lvl, x, width, fmt, type, data);
+       glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+}
+
+void nex_tex_update2d(nex_texture *tex, int lvl, int x, int y, int width, int height,
+               enum nex_pixfmt pixfmt, void *data, long pitch)
+{
+       int fmt = glformat(pixfmt);
+       int type = gltype(pixfmt);
+       glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch);
+       glTextureSubImage2D(tex->tex, lvl, x, y, width, height, fmt, type, data);
+       glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+}
+
+void nex_tex_update3d(nex_texture *tex, int lvl, int x, int y, int z, int width,
+               int height, int depth, enum nex_pixfmt pixfmt, void *data, long pitch)
+{
+       int fmt = glformat(pixfmt);
+       int type = gltype(pixfmt);
+       glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch);
+       glTextureSubImage3D(tex->tex, lvl, x, y, z, width, height, depth, fmt, type,
+                       data);
+       glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+}
+
+
+void nex_tex_updatecube(nex_texture *tex, int lvl, enum nex_cube_face face,
+               int x, int y, int width, int height, enum nex_pixfmt pixfmt, void *data,
+               long pitch)
+{
+       int fmt = glformat(pixfmt);
+       int type = gltype(pixfmt);
+       glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch);
+       glTextureSubImage3D(tex->tex, lvl, x, y, face, width, height, 1, fmt, type,
+                       data);
+       glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+}
+
+void bind_texture(int tunit, nex_texture *tex)
+{
+       glBindTextureUnit(tunit, tex->tex);
+}
+
+
+static unsigned int gltextype(enum nex_tex_type type)
+{
+       switch(type) {
+       case NEX_TEX1D:
+               return GL_TEXTURE_1D;
+       case NEX_TEX2D:
+               return GL_TEXTURE_2D;
+       case NEX_TEX3D:
+               return GL_TEXTURE_3D;
+       case NEX_TEXCUBE:
+               return GL_TEXTURE_CUBE_MAP;
+       default:
+               break;
+       }
+       return 0;
+}
+
+static unsigned int glpixfmt(enum nex_pixfmt fmt)
+{
+       switch(fmt) {
+       case NEX_GREY8:
+               return GL_LUMINANCE;
+       case NEX_RGB24:
+               return GL_RGB;
+       case NEX_RGBA32:
+               return GL_RGBA;
+       case NEX_SRGB:
+               return GL_SRGB;
+       case NEX_SRGBA:
+               return GL_SRGB_ALPHA;
+       case NEX_GREYF:
+               return GL_LUMINANCE16F_ARB;
+       case NEX_RGBF:
+               return GL_RGB16F;
+       case NEX_RGBAF:
+               return GL_RGBA16F;
+       default:
+               break;
+       }
+       return 0;
+}
+
+/*
+static unsigned int glcubeface(enum nex_cube_face face)
+{
+       switch(face) {
+       case NEX_CUBE_PX:
+               return GL_TEXTURE_CUBE_MAP_POSITIVE_X;
+       case NEX_CUBE_NX:
+               return GL_TEXTURE_CUBE_MAP_NEGATIVE_X;
+       case NEX_CUBE_PY:
+               return GL_TEXTURE_CUBE_MAP_POSITIVE_Y;
+       case NEX_CUBE_NY:
+               return GL_TEXTURE_CUBE_MAP_NEGATIVE_Y;
+       case NEX_CUBE_PZ:
+               return GL_TEXTURE_CUBE_MAP_POSITIVE_Z;
+       case NEX_CUBE_NZ:
+               return GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
+       default:
+               break;
+       }
+       return 0;
+}
+*/
+
+static unsigned int glformat(enum nex_pixfmt fmt)
+{
+       switch(fmt) {
+       case NEX_GREY8:
+       case NEX_GREYF:
+               return GL_LUMINANCE;
+       case NEX_RGB24:
+       case NEX_SRGB:
+       case NEX_RGBF:
+               return GL_RGB;
+       case NEX_RGBA32:
+       case NEX_SRGBA:
+       case NEX_RGBAF:
+               return GL_RGBA;
+       default:
+               break;
+       }
+       return 0;
+}
+
+static unsigned int gltype(enum nex_pixfmt fmt)
+{
+       if(fmt == NEX_GREYF || fmt == NEX_RGBF || fmt == NEX_RGBAF) {
+               return GL_FLOAT;
+       }
+       return GL_UNSIGNED_BYTE;
+}
+
+static unsigned int miplevels(int x, int y, int z)
+{
+       int lvl = 0;
+       if(y > x) x = y;
+       if(z > x) x = z;
+
+       while(x > 0) {
+               lvl++;
+               x >>= 1;
+       }
+       return lvl;
+}
index a4e8f1e..340967c 100644 (file)
@@ -11,3 +11,21 @@ void nex_gfxapi_opengl(int vmaj, int vmin, enum nex_apiflags_gl flags)
        nex_apicfg.gl.ver_minor = vmin;
        nex_apicfg.gl.flags = flags;
 }
+
+struct nex_span nex_span(int x, int len)
+{
+       struct nex_span s;
+       s.start = x;
+       s.len = len;
+       return s;
+}
+
+struct nex_rect nex_rect(int x, int y, int w, int h)
+{
+       struct nex_rect r;
+       r.x = x;
+       r.y = y;
+       r.width = w;
+       r.height = h;
+       return r;
+}
index f1ad71b..b2e67f6 100644 (file)
@@ -5,6 +5,14 @@
 #include "wsys/wsys.h"
 #include "cgmath2/cgmath2.h"
 
+struct nex_span {
+       int start, len;
+};
+
+struct nex_rect {
+       int x, y, width, height;
+};
+
 enum nex_apiflags_gl {
        NEX_OPENGL_COMPAT       = 1,
        NEX_OPENGL_DEBUG        = 2
@@ -12,4 +20,7 @@ enum nex_apiflags_gl {
 
 void nex_gfxapi_opengl(int vmaj, int vmin, enum nex_apiflags_gl flags);
 
+struct nex_span nex_span(int x, int len);
+struct nex_rect nex_rect(int x, int y, int w, int h);
+
 #endif /* NEXUS3D_H_ */