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;
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_ */
--- /dev/null
+#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;
+}