astc.h (4166B)
1 #pragma once 2 3 #define GL_GLEXT_PROTOTYPES 1 4 #include <GL/gl.h> 5 #include <GL/glx.h> 6 #include <GL/glu.h> 7 #include <inttypes.h> 8 9 #define GL_CHECK(x) \ 10 x; \ 11 { \ 12 GLenum glError = glGetError(); \ 13 if (glError!=GL_NO_ERROR) { \ 14 printf("glGetError() = %i (%#.8x) at %s:%i\n", glError, glError, __FILE__, __LINE__); \ 15 exit(EXIT_FAILURE); \ 16 } \ 17 } 18 19 #define CHECK_ASTC_FORMAT(bx, by) if (x==bx&&y==by) return GL_COMPRESSED_RGBA_ASTC_##bx##x##by##_KHR; 20 #define ASTC_EXT ".astc" 21 #define ASTC_LEN 5 22 23 /* ASTC header declaration. */ 24 typedef struct 25 { 26 uint8_t magic[4]; 27 uint8_t blockdim_x; 28 uint8_t blockdim_y; 29 uint8_t blockdim_z; 30 uint8_t xsize[3]; 31 uint8_t ysize[3]; 32 uint8_t zsize[3]; 33 } astc_header; 34 35 static GLenum get_astc_format(uint8_t x, uint8_t y) { 36 CHECK_ASTC_FORMAT(4,4) 37 CHECK_ASTC_FORMAT(5,4) 38 CHECK_ASTC_FORMAT(5,5) 39 CHECK_ASTC_FORMAT(6,5) 40 CHECK_ASTC_FORMAT(6,6) 41 CHECK_ASTC_FORMAT(8,5) 42 CHECK_ASTC_FORMAT(8,6) 43 CHECK_ASTC_FORMAT(8,8) 44 CHECK_ASTC_FORMAT(10,5) 45 CHECK_ASTC_FORMAT(10,6) 46 CHECK_ASTC_FORMAT(10,8) 47 CHECK_ASTC_FORMAT(10,10) 48 CHECK_ASTC_FORMAT(12,10) 49 CHECK_ASTC_FORMAT(12,12) 50 printf("invalid ASTC block size\n"); 51 exit(-1); 52 } 53 54 static GLuint mkTextureAstc(const char *filename) { 55 FILE *f = fopen(filename, "rb"); 56 if (f==NULL) { 57 printf("error loading file %s\n", filename); 58 exit(EXIT_FAILURE); 59 } 60 61 fseek(f, 0, SEEK_END); 62 int64_t fsize = ftell(f); 63 rewind(f); 64 65 printf("astc file size: %"PRIi64" bytes\n", fsize); 66 67 uint8_t *data = malloc(fsize); 68 if (fread(data, 1, fsize, f) != fsize) { 69 printf("error reading file %s\n", filename); 70 exit(EXIT_FAILURE); 71 } 72 73 const astc_header *astc_data = (astc_header *)data; 74 printf("astc block: %dx%d\n", astc_data->blockdim_x, astc_data->blockdim_y); 75 GLenum astc_format = get_astc_format(astc_data->blockdim_x, astc_data->blockdim_y); 76 /* Merge x,y,z-sizes from 3 chars into one integer value. */ 77 GLsizei xsize = astc_data->xsize[0] + (astc_data->xsize[1] << 8) + (astc_data->xsize[2] << 16); 78 GLsizei ysize = astc_data->ysize[0] + (astc_data->ysize[1] << 8) + (astc_data->ysize[2] << 16); 79 GLsizei zsize = astc_data->zsize[0] + (astc_data->zsize[1] << 8) + (astc_data->zsize[2] << 16); 80 81 printf("astc dimensions: %dx%d\n", xsize, ysize); 82 83 /* Compute number of blocks in each direction. */ 84 GLsizei xblocks = (xsize + astc_data->blockdim_x - 1) / astc_data->blockdim_x; 85 GLsizei yblocks = (ysize + astc_data->blockdim_y - 1) / astc_data->blockdim_y; 86 GLsizei zblocks = (zsize + astc_data->blockdim_z - 1) / astc_data->blockdim_z; 87 88 // maybe we can do just fsize-16 here 89 GLsizei astc_size = xblocks * yblocks * zblocks << 4; 90 91 printf("astc data size: %lld bytes\n", astc_size); 92 93 GLuint tex; 94 GL_CHECK(glGenTextures(1, &tex)); 95 GL_CHECK(glBindTexture(GL_TEXTURE_2D, tex)); 96 GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)); // GL_REPEAT 97 GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)); // GL_CLAMP_TO_EDGE 98 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); 99 GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); 100 GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); 101 GL_CHECK(glCompressedTexImage2D(GL_TEXTURE_2D, 0, astc_format, xsize, ysize, 0, astc_size, (const GLvoid *)astc_data)); 102 //GL_CHECK(glGenerateMipmap(GL_TEXTURE_2D)); 103 GL_CHECK(glEnable(GL_TEXTURE_2D)); 104 105 fclose(f); 106 free(data); 107 return tex; 108 }