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