opengl_x11

Playing with OpenGL
git clone git://bsandro.tech/opengl_x11
Log | Files | Refs | README | LICENSE

commit f4c87b5a1ae882272b28946a3b3723d90ef7cb94
parent d9f9e2744eea45ae8c876faf0055bf3c673ec7f9
Author: bsandro <email@bsandro.tech>
Date:   Thu, 20 Nov 2025 21:44:14 +0200

moved astc stuff to separate file

Diffstat:
Aastc.h | 107+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acube.c | 291++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtexture.c | 94+------------------------------------------------------------------------------
Mtrans.c | 94+------------------------------------------------------------------------------
4 files changed, 400 insertions(+), 186 deletions(-)

diff --git a/astc.h b/astc.h @@ -0,0 +1,107 @@ +#pragma once + +#define GL_GLEXT_PROTOTYPES 1 +#include <GL/gl.h> +#include <GL/glx.h> +#include <GL/glu.h> + +#define GL_CHECK(x) \ +x; \ +{ \ + GLenum glError = glGetError(); \ + if (glError!=GL_NO_ERROR) { \ + printf("glGetError() = %i (%#.8x) at %s:%i\n", glError, glError, __FILE__, __LINE__); \ + exit(EXIT_FAILURE); \ + } \ +} + +#define CHECK_ASTC_FORMAT(bx, by) if (x==bx&&y==by) return GL_COMPRESSED_RGBA_ASTC_##bx##x##by##_KHR; +#define ASTC_EXT ".astc" +#define ASTC_LEN 5 + +/* ASTC header declaration. */ +typedef struct +{ + uint8_t magic[4]; + uint8_t blockdim_x; + uint8_t blockdim_y; + uint8_t blockdim_z; + uint8_t xsize[3]; + uint8_t ysize[3]; + uint8_t zsize[3]; +} astc_header; + +static GLenum get_astc_format(uint8_t x, uint8_t y) { + CHECK_ASTC_FORMAT(4,4) + CHECK_ASTC_FORMAT(5,4) + CHECK_ASTC_FORMAT(5,5) + CHECK_ASTC_FORMAT(6,5) + CHECK_ASTC_FORMAT(6,6) + CHECK_ASTC_FORMAT(8,5) + CHECK_ASTC_FORMAT(8,6) + CHECK_ASTC_FORMAT(8,8) + CHECK_ASTC_FORMAT(10,5) + CHECK_ASTC_FORMAT(10,6) + CHECK_ASTC_FORMAT(10,8) + CHECK_ASTC_FORMAT(10,10) + CHECK_ASTC_FORMAT(12,10) + CHECK_ASTC_FORMAT(12,12) + printf("invalid ASTC block size\n"); + exit(-1); +} + +static GLuint mkTextureAstc(const char *filename) { + FILE *f = fopen(filename, "rb"); + if (f==NULL) { + printf("error loading file %s\n", filename); + exit(EXIT_FAILURE); + } + + fseek(f, 0, SEEK_END); + int64_t fsize = ftell(f); + rewind(f); + + printf("astc file size: %lld bytes\n", fsize); + + uint8_t *data = malloc(fsize); + if (fread(data, 1, fsize, f) != fsize) { + printf("error reading file %s\n", filename); + exit(EXIT_FAILURE); + } + + const astc_header *astc_data = (astc_header *)data; + printf("astc block: %dx%d\n", astc_data->blockdim_x, astc_data->blockdim_y); + GLenum astc_format = get_astc_format(astc_data->blockdim_x, astc_data->blockdim_y); + /* Merge x,y,z-sizes from 3 chars into one integer value. */ + GLsizei xsize = astc_data->xsize[0] + (astc_data->xsize[1] << 8) + (astc_data->xsize[2] << 16); + GLsizei ysize = astc_data->ysize[0] + (astc_data->ysize[1] << 8) + (astc_data->ysize[2] << 16); + GLsizei zsize = astc_data->zsize[0] + (astc_data->zsize[1] << 8) + (astc_data->zsize[2] << 16); + + printf("astc dimensions: %dx%d\n", xsize, ysize); + + /* Compute number of blocks in each direction. */ + GLsizei xblocks = (xsize + astc_data->blockdim_x - 1) / astc_data->blockdim_x; + GLsizei yblocks = (ysize + astc_data->blockdim_y - 1) / astc_data->blockdim_y; + GLsizei zblocks = (zsize + astc_data->blockdim_z - 1) / astc_data->blockdim_z; + + // maybe we can do just fsize-16 here + GLsizei astc_size = xblocks * yblocks * zblocks << 4; + + printf("astc data size: %lld bytes\n", astc_size); + + GLuint tex; + GL_CHECK(glGenTextures(1, &tex)); + GL_CHECK(glBindTexture(GL_TEXTURE_2D, tex)); + GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)); // GL_REPEAT + GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)); // GL_CLAMP_TO_EDGE + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); + GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); + GL_CHECK(glCompressedTexImage2D(GL_TEXTURE_2D, 0, astc_format, xsize, ysize, 0, astc_size, (const GLvoid *)astc_data)); + //GL_CHECK(glGenerateMipmap(GL_TEXTURE_2D)); + GL_CHECK(glEnable(GL_TEXTURE_2D)); + + fclose(f); + free(data); + return tex; +} diff --git a/cube.c b/cube.c @@ -0,0 +1,291 @@ +/* 3D cube */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <unistd.h> +#include <math.h> +#include <X11/X.h> +#include <X11/Xlib.h> +#define GL_GLEXT_PROTOTYPES 1 +#include <GL/gl.h> +#include <GL/glx.h> +#include <GL/glu.h> +#include "../cglm/include/cglm/cglm.h" +#include "astc.h" +#define STB_IMAGE_IMPLEMENTATION +#include "stb_image.h" + +#define GL_CHECK(x) \ +x; \ +{ \ + GLenum glError = glGetError(); \ + if (glError!=GL_NO_ERROR) { \ + printf("glGetError() = %i (%#.8x) at %s:%i\n", glError, glError, __FILE__, __LINE__); \ + exit(EXIT_FAILURE); \ + } \ +} + +static const double current_ts() { + struct timespec ts; + timespec_get(&ts, TIME_UTC); + return (double)ts.tv_sec + (double)ts.tv_nsec/1e9; +} + +static double t_started; + +//@todo move shaders to separate files +static const GLchar *vertexSrc = R"( +#version 420 +layout(location=0) in vec2 position; +layout(location=1) in vec2 aTexCoord; +out vec2 texCoord; +uniform mat4 trans; +void main() { + gl_Position = trans * vec4(position, 0.0, 1.0); + texCoord = aTexCoord; +} +)"; + +static const GLchar *fragmentSrc = R"( +#version 420 +uniform double iTime; +uniform sampler2D ourTex; +uniform mat4 trans; +out vec4 outColor; +in vec2 texCoord; +void main() { + vec3 color; + color.r = 0.2; + color.g = 0.6; + color.b = 0.1; + float c1 = abs(sin(float(iTime))); + float c2 = abs(cos(float(iTime))); + vec4 modColor = vec4(color+c1-c2, 1.0); + outColor = texture(ourTex, texCoord) + modColor; +} +)"; + +static GLuint mkShader(GLenum type, const GLchar *src) { + GLuint shader = glCreateShader(type); + glShaderSource(shader, 1, &src, NULL); + glCompileShader(shader); + GLint ok = 0; + glGetShaderiv(shader, GL_COMPILE_STATUS, &ok); + if (!ok) { + static char buf[512] = {0}; + glGetShaderInfoLog(shader, sizeof(buf)-1, NULL, buf); + fprintf(stderr, "Shader %d compile error: %s\n", (int)type, buf); + } + return shader; +} + +static GLuint linkProgram(GLuint vertex, GLuint fragment) { + GLuint shaderProgram = glCreateProgram(); + glAttachShader(shaderProgram, vertex); + glAttachShader(shaderProgram, fragment); + glBindAttribLocation(shaderProgram, 0, "position"); + glBindAttribLocation(shaderProgram, 1, "aTexCoord"); + glLinkProgram(shaderProgram); + return shaderProgram; +} + +static GLuint mkTexture(const char *filename) { + GLuint tex; + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_2D, tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + int w, h, numchan; + //stbi_set_flip_vertically_on_load(1); + uint8_t *data = stbi_load(filename, &w, &h, &numchan, 3); + if (data) { + printf("texture %dx%d %dbpp\n", w, h, numchan*8); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, data); + glGenerateMipmap(GL_TEXTURE_2D); + glEnable(GL_TEXTURE_2D); + stbi_image_free(data); + } else { + printf("Failed to load texture %s: %s\n", filename, stbi_failure_reason()); + } + return tex; +} + +void __attribute__((constructor)) start() { + printf("start()\n"); + + // just a playground + vec4 vector = {1.0f, 0.0f, 0.0f, 1.0f}; + mat4 trans; + glm_mat4_identity(trans); + vec3 t = {1.0f, 1.0f, 0.0f}; + glm_translate(trans, t); + vec4 out; + glm_mat4_mulv(trans, vector, out); + glm_vec4_print(out, stdout); + + mat4 trans1; + glm_mat4_identity(trans1); + glm_rotate(trans1, glm_rad(90.0f), (vec3){0.0, 0.0, 1.0}); + glm_scale(trans1, (vec3){0.5, 0.5, 0.5}); + glm_mat4_print(trans1, stdout); + + t_started = current_ts(); +} + +void __attribute((destructor)) end() { + printf("end()\n"); +} + +int main(int argc, char *argv[]) { + const char *tex_fname; + bool is_astc = false; + if (argc>1) { + tex_fname = argv[1]; + int len = strlen(tex_fname); + // ".astc" extension = 5 bytes + is_astc = (len>ASTC_LEN&&strncmp(tex_fname+len-ASTC_LEN, ASTC_EXT, ASTC_LEN)==0); + } else { + tex_fname = "hina.astc"; + is_astc = true; + } + printf("texture file: %s (%s)\n", tex_fname, is_astc ? "astc" : "plain"); + + Display *dpy = XOpenDisplay(NULL); + XSetWindowAttributes swa; + Window win; + XWindowAttributes gwa; + GLint attr[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None }; + + if (dpy == NULL) { + printf("\n\tcannot connect to X server\n\n"); + exit(0); + } + + Window root = DefaultRootWindow(dpy); + XVisualInfo *vi = glXChooseVisual(dpy, 0, attr); + + if (vi == NULL) { + printf("\n\tno appropriate visual found\n\n"); + exit(0); + } else { + printf("\n\tvisual %p selected\n", (void *)vi->visualid); /* %p creates hexadecimal output like in glxinfo */ + } + + Colormap cmap = XCreateColormap(dpy, root, vi->visual, AllocNone); + swa.colormap = cmap; + swa.event_mask = ExposureMask | KeyPressMask; + win = XCreateWindow(dpy, root, 0, 0, 500, 500, 0, vi->depth, InputOutput, vi->visual, CWColormap | CWEventMask, &swa); + XMapWindow(dpy, win); + XStoreName(dpy, win, "OPENGL"); + GLXContext ctx = glXCreateContext(dpy, vi, NULL, GL_TRUE); + glXMakeCurrent(dpy, win, ctx); + + // USEFUL DEBUG INFO + //@todo validate ASTC support + /*GLint extn; + GL_CHECK(glGetIntegerv(GL_NUM_EXTENSIONS, &extn)); + printf("%d GL Extensions:\n", extn); + for (GLint i=0; i<extn; ++i) { + printf("\t%s\n", glGetStringi(GL_EXTENSIONS, i)); + }*/ + + GLuint vao; + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + + // @todo geh + const GLfloat c = 0; //0.099f; + + // x,y,tx,ty + static const GLfloat vertices[] = { + -0.5, -0.5, 0+c, 1-c, + 0.5, -0.5, 1-c, 1-c, + 0.5, 0.5, 1-c, 0+c, + -0.5, 0.5, 0+c, 0+c + }; + static const GLuint elements[] = { + 0, 1, 2, + 2, 3, 0 + }; + + GLuint vbo; + glGenBuffers(1, &vbo); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + + GLuint ebo; + glGenBuffers(1, &ebo); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW); + + GLuint vertex = mkShader(GL_VERTEX_SHADER, vertexSrc); + GLuint fragment = mkShader(GL_FRAGMENT_SHADER, fragmentSrc); + GLuint shaderPrg = linkProgram(vertex, fragment); + + GLint prgStatus; + glGetProgramiv(shaderPrg, GL_LINK_STATUS, &prgStatus); + printf("shader link status: %s\n", prgStatus == GL_TRUE ? "ok" : "error"); + + // texture + GLuint tex = is_astc ? mkTextureAstc(tex_fname) : mkTexture(tex_fname); + GLint position = glGetAttribLocation(shaderPrg, "position"); + glVertexAttribPointer(position, 2, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), (void *)0); + glEnableVertexAttribArray(position); + GLint aTexCoord = glGetAttribLocation(shaderPrg, "aTexCoord"); + glVertexAttribPointer(aTexCoord, 2, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), (void *)(2*sizeof(GLfloat))); + glEnableVertexAttribArray(aTexCoord); + + mat4 trans; + glm_mat4_identity(trans); + //glm_rotate(trans, glm_rad(90.0f), (vec3){0.0, 0.0, 1.0}); + glm_scale(trans, (vec3){1.2, 1.2, 1.2}); + glm_mat4_print(trans, stdout); + + float rotation = 1.f; + + while (1) { + while (XPending(dpy)) { + XEvent xev; + XNextEvent(dpy, &xev); + if (xev.type == Expose) { + XGetWindowAttributes(dpy, win, &gwa); + glViewport(0, 0, gwa.width, gwa.height); + } else if (xev.type == KeyPress) { + printf("btn:%3d\n", xev.xbutton.button); + if (xev.xbutton.button==24||xev.xbutton.button==9) { + glXMakeCurrent(dpy, None, NULL); + glXDestroyContext(dpy, ctx); + XDestroyWindow(dpy, win); + XCloseDisplay(dpy); + exit(0); + } + } else if (xev.type == ConfigureNotify) { + XConfigureEvent *ce = (XConfigureEvent *)&xev; + glViewport(0, 0, ce->width, ce->height); + } + } + + glClearColor(0.1f, 0.1f, 0.15f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + + GLfloat iTime = glGetUniformLocation(shaderPrg, "iTime"); + glUniform1d(iTime, current_ts()-t_started); + //printf("%f\n", fabsf(sinf(current_ts()-t_started))); + + glm_rotate(trans, glm_rad(rotation), (vec3){0.0, 0.0, 1.0}); + GLuint transform = glGetUniformLocation(shaderPrg, "trans"); + glUniformMatrix4fv(transform, 1, GL_FALSE, trans[0]); + + glUseProgram(shaderPrg); + glUniform1i(tex, 0); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, tex); + glDrawElements(GL_TRIANGLES, sizeof(elements)/sizeof(elements[0]), GL_UNSIGNED_INT, 0); + + glXSwapBuffers(dpy, win); + usleep(1000*7); // 144hz + } +} diff --git a/texture.c b/texture.c @@ -13,6 +13,7 @@ #include <GL/glu.h> #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" +#include "astc.h" #define GL_CHECK(x) \ x; \ @@ -24,21 +25,6 @@ x; } \ } -#define ASTC_EXT ".astc" -#define ASTC_LEN 5 - -/* ASTC header declaration. */ -typedef struct -{ - uint8_t magic[4]; - uint8_t blockdim_x; - uint8_t blockdim_y; - uint8_t blockdim_z; - uint8_t xsize[3]; - uint8_t ysize[3]; - uint8_t zsize[3]; -} astc_header; - static const double current_ts() { struct timespec ts; timespec_get(&ts, TIME_UTC); @@ -124,84 +110,6 @@ static GLuint mkTexture(const char *filename) { return tex; } -#define CHECK_ASTC_FORMAT(bx, by) if (x==bx&&y==by) return GL_COMPRESSED_RGBA_ASTC_##bx##x##by##_KHR; - -GLenum get_astc_format(uint8_t x, uint8_t y) { - CHECK_ASTC_FORMAT(4,4) - CHECK_ASTC_FORMAT(5,4) - CHECK_ASTC_FORMAT(5,5) - CHECK_ASTC_FORMAT(6,5) - CHECK_ASTC_FORMAT(6,6) - CHECK_ASTC_FORMAT(8,5) - CHECK_ASTC_FORMAT(8,6) - CHECK_ASTC_FORMAT(8,8) - CHECK_ASTC_FORMAT(10,5) - CHECK_ASTC_FORMAT(10,6) - CHECK_ASTC_FORMAT(10,8) - CHECK_ASTC_FORMAT(10,10) - CHECK_ASTC_FORMAT(12,10) - CHECK_ASTC_FORMAT(12,12) - - printf("invalid ASTC block size\n"); - exit(-1); -} - -static GLuint mkTextureAstc(const char *filename) { - FILE *f = fopen(filename, "rb"); - if (f==NULL) { - printf("error loading file %s\n", filename); - exit(EXIT_FAILURE); - } - - fseek(f, 0, SEEK_END); - int64_t fsize = ftell(f); - rewind(f); - - printf("astc file size: %lld bytes\n", fsize); - - uint8_t *data = malloc(fsize); - if (fread(data, 1, fsize, f) != fsize) { - printf("error reading file %s\n", filename); - exit(EXIT_FAILURE); - } - - const astc_header *astc_data = (astc_header *)data; - printf("astc block: %dx%d\n", astc_data->blockdim_x, astc_data->blockdim_y); - GLenum astc_format = get_astc_format(astc_data->blockdim_x, astc_data->blockdim_y); - /* Merge x,y,z-sizes from 3 chars into one integer value. */ - GLsizei xsize = astc_data->xsize[0] + (astc_data->xsize[1] << 8) + (astc_data->xsize[2] << 16); - GLsizei ysize = astc_data->ysize[0] + (astc_data->ysize[1] << 8) + (astc_data->ysize[2] << 16); - GLsizei zsize = astc_data->zsize[0] + (astc_data->zsize[1] << 8) + (astc_data->zsize[2] << 16); - - printf("astc dimensions: %dx%d\n", xsize, ysize); - - /* Compute number of blocks in each direction. */ - GLsizei xblocks = (xsize + astc_data->blockdim_x - 1) / astc_data->blockdim_x; - GLsizei yblocks = (ysize + astc_data->blockdim_y - 1) / astc_data->blockdim_y; - GLsizei zblocks = (zsize + astc_data->blockdim_z - 1) / astc_data->blockdim_z; - - // maybe we can do just fsize-16 here - GLsizei astc_size = xblocks * yblocks * zblocks << 4; - - printf("astc data size: %lld bytes\n", astc_size); - - GLuint tex; - GL_CHECK(glGenTextures(1, &tex)); - GL_CHECK(glBindTexture(GL_TEXTURE_2D, tex)); - GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)); // GL_REPEAT - GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)); // GL_CLAMP_TO_EDGE - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); - GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); - GL_CHECK(glCompressedTexImage2D(GL_TEXTURE_2D, 0, astc_format, xsize, ysize, 0, astc_size, (const GLvoid *)astc_data)); - //GL_CHECK(glGenerateMipmap(GL_TEXTURE_2D)); - GL_CHECK(glEnable(GL_TEXTURE_2D)); - - fclose(f); - free(data); - return tex; -} - void __attribute__((constructor)) start() { printf("start()\n"); t_started = current_ts(); diff --git a/trans.c b/trans.c @@ -14,6 +14,7 @@ #include "../cglm/include/cglm/cglm.h" #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" +#include "astc.h" #define GL_CHECK(x) \ x; \ @@ -25,21 +26,6 @@ x; } \ } -#define ASTC_EXT ".astc" -#define ASTC_LEN 5 - -/* ASTC header declaration. */ -typedef struct -{ - uint8_t magic[4]; - uint8_t blockdim_x; - uint8_t blockdim_y; - uint8_t blockdim_z; - uint8_t xsize[3]; - uint8_t ysize[3]; - uint8_t zsize[3]; -} astc_header; - static const double current_ts() { struct timespec ts; timespec_get(&ts, TIME_UTC); @@ -132,84 +118,6 @@ static GLuint mkTexture(const char *filename) { return tex; } -#define CHECK_ASTC_FORMAT(bx, by) if (x==bx&&y==by) return GL_COMPRESSED_RGBA_ASTC_##bx##x##by##_KHR; - -GLenum get_astc_format(uint8_t x, uint8_t y) { - CHECK_ASTC_FORMAT(4,4) - CHECK_ASTC_FORMAT(5,4) - CHECK_ASTC_FORMAT(5,5) - CHECK_ASTC_FORMAT(6,5) - CHECK_ASTC_FORMAT(6,6) - CHECK_ASTC_FORMAT(8,5) - CHECK_ASTC_FORMAT(8,6) - CHECK_ASTC_FORMAT(8,8) - CHECK_ASTC_FORMAT(10,5) - CHECK_ASTC_FORMAT(10,6) - CHECK_ASTC_FORMAT(10,8) - CHECK_ASTC_FORMAT(10,10) - CHECK_ASTC_FORMAT(12,10) - CHECK_ASTC_FORMAT(12,12) - - printf("invalid ASTC block size\n"); - exit(-1); -} - -static GLuint mkTextureAstc(const char *filename) { - FILE *f = fopen(filename, "rb"); - if (f==NULL) { - printf("error loading file %s\n", filename); - exit(EXIT_FAILURE); - } - - fseek(f, 0, SEEK_END); - int64_t fsize = ftell(f); - rewind(f); - - printf("astc file size: %lld bytes\n", fsize); - - uint8_t *data = malloc(fsize); - if (fread(data, 1, fsize, f) != fsize) { - printf("error reading file %s\n", filename); - exit(EXIT_FAILURE); - } - - const astc_header *astc_data = (astc_header *)data; - printf("astc block: %dx%d\n", astc_data->blockdim_x, astc_data->blockdim_y); - GLenum astc_format = get_astc_format(astc_data->blockdim_x, astc_data->blockdim_y); - /* Merge x,y,z-sizes from 3 chars into one integer value. */ - GLsizei xsize = astc_data->xsize[0] + (astc_data->xsize[1] << 8) + (astc_data->xsize[2] << 16); - GLsizei ysize = astc_data->ysize[0] + (astc_data->ysize[1] << 8) + (astc_data->ysize[2] << 16); - GLsizei zsize = astc_data->zsize[0] + (astc_data->zsize[1] << 8) + (astc_data->zsize[2] << 16); - - printf("astc dimensions: %dx%d\n", xsize, ysize); - - /* Compute number of blocks in each direction. */ - GLsizei xblocks = (xsize + astc_data->blockdim_x - 1) / astc_data->blockdim_x; - GLsizei yblocks = (ysize + astc_data->blockdim_y - 1) / astc_data->blockdim_y; - GLsizei zblocks = (zsize + astc_data->blockdim_z - 1) / astc_data->blockdim_z; - - // maybe we can do just fsize-16 here - GLsizei astc_size = xblocks * yblocks * zblocks << 4; - - printf("astc data size: %lld bytes\n", astc_size); - - GLuint tex; - GL_CHECK(glGenTextures(1, &tex)); - GL_CHECK(glBindTexture(GL_TEXTURE_2D, tex)); - GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)); // GL_REPEAT - GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)); // GL_CLAMP_TO_EDGE - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); - GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); - GL_CHECK(glCompressedTexImage2D(GL_TEXTURE_2D, 0, astc_format, xsize, ysize, 0, astc_size, (const GLvoid *)astc_data)); - //GL_CHECK(glGenerateMipmap(GL_TEXTURE_2D)); - GL_CHECK(glEnable(GL_TEXTURE_2D)); - - fclose(f); - free(data); - return tex; -} - void __attribute__((constructor)) start() { printf("start()\n");