Clone of mesa.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

texcmp.c 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. /*
  2. * Compressed texture demo. Written by Daniel Borca.
  3. * This program is in the public domain.
  4. */
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <math.h>
  8. #include <string.h>
  9. #define GL_GLEXT_PROTOTYPES 1
  10. #include <GL/glut.h>
  11. #include "readtex.c" /* I know, this is a hack. */
  12. #define TEXTURE_FILE "../images/tree2.rgba"
  13. static float Rot = 0.0;
  14. static GLboolean Anim = 1;
  15. typedef struct {
  16. GLubyte *data;
  17. GLuint size;
  18. GLenum format;
  19. GLuint w, h;
  20. GLenum TC;
  21. GLubyte *cData;
  22. GLuint cSize;
  23. GLenum cFormat;
  24. } TEXTURE;
  25. static TEXTURE *Tx, t1, t2, t3;
  26. static GLboolean fxt1, dxtc, s3tc;
  27. static const char *TextureName (GLenum TC)
  28. {
  29. switch (TC) {
  30. case GL_RGB:
  31. return "RGB";
  32. case GL_RGBA:
  33. return "RGBA";
  34. case GL_COMPRESSED_RGB:
  35. return "COMPRESSED_RGB";
  36. case GL_COMPRESSED_RGBA:
  37. return "COMPRESSED_RGBA";
  38. case GL_COMPRESSED_RGB_FXT1_3DFX:
  39. return "GL_COMPRESSED_RGB_FXT1_3DFX";
  40. case GL_COMPRESSED_RGBA_FXT1_3DFX:
  41. return "GL_COMPRESSED_RGBA_FXT1_3DFX";
  42. case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
  43. return "GL_COMPRESSED_RGB_S3TC_DXT1_EXT";
  44. case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
  45. return "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT";
  46. case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
  47. return "GL_COMPRESSED_RGBA_S3TC_DXT3_EXT";
  48. case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
  49. return "GL_COMPRESSED_RGBA_S3TC_DXT5_EXT";
  50. case GL_RGB_S3TC:
  51. return "GL_RGB_S3TC";
  52. case GL_RGB4_S3TC:
  53. return "GL_RGB4_S3TC";
  54. case GL_RGBA_S3TC:
  55. return "GL_RGBA_S3TC";
  56. case GL_RGBA4_S3TC:
  57. return "GL_RGBA4_S3TC";
  58. case 0:
  59. return "Invalid format";
  60. default:
  61. return "Unknown format";
  62. }
  63. }
  64. static void
  65. PrintString(const char *s)
  66. {
  67. while (*s) {
  68. glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
  69. s++;
  70. }
  71. }
  72. static void Idle( void )
  73. {
  74. float t = glutGet(GLUT_ELAPSED_TIME) * 0.001; /* in seconds */
  75. Rot = t * 360 / 4; /* 1 rotation per 4 seconds */
  76. glutPostRedisplay();
  77. }
  78. static void Display( void )
  79. {
  80. /* draw background gradient */
  81. glDisable(GL_TEXTURE_2D);
  82. glBegin(GL_POLYGON);
  83. glColor3f(1.0, 0.0, 0.2); glVertex2f(-1.5, -1.0);
  84. glColor3f(1.0, 0.0, 0.2); glVertex2f( 1.5, -1.0);
  85. glColor3f(0.0, 0.0, 1.0); glVertex2f( 1.5, 1.0);
  86. glColor3f(0.0, 0.0, 1.0); glVertex2f(-1.5, 1.0);
  87. glEnd();
  88. glPushMatrix();
  89. glRotatef(Rot, 0, 0, 1);
  90. glEnable(GL_TEXTURE_2D);
  91. glBegin(GL_POLYGON);
  92. glTexCoord2f(0, 1); glVertex2f(-1, -0.5);
  93. glTexCoord2f(1, 1); glVertex2f( 1, -0.5);
  94. glTexCoord2f(1, 0); glVertex2f( 1, 0.5);
  95. glTexCoord2f(0, 0); glVertex2f(-1, 0.5);
  96. glEnd();
  97. glPopMatrix();
  98. /* info */
  99. glColor4f(1, 1, 1, 1);
  100. glRasterPos3f(-1.2, -0.7, 0);
  101. PrintString("Selected: ");
  102. PrintString(TextureName(Tx->TC));
  103. if (Tx->cData) {
  104. char tmp[64];
  105. glRasterPos3f(-1.2, -0.8, 0);
  106. PrintString("Internal: ");
  107. PrintString(TextureName(Tx->cFormat));
  108. glRasterPos3f(-1.2, -0.9, 0);
  109. PrintString("Size : ");
  110. sprintf(tmp, "%d (%d%% of %d)", Tx->cSize, Tx->cSize * 100 / Tx->size, Tx->size);
  111. PrintString(tmp);
  112. }
  113. glutSwapBuffers();
  114. }
  115. static void Reshape( int width, int height )
  116. {
  117. glViewport( 0, 0, width, height );
  118. glMatrixMode( GL_PROJECTION );
  119. glLoadIdentity();
  120. glOrtho( -1.5, 1.5, -1.0, 1.0, -1.0, 1.0 );
  121. glMatrixMode( GL_MODELVIEW );
  122. glLoadIdentity();
  123. }
  124. static void ReInit( GLenum TC, TEXTURE *Tx )
  125. {
  126. GLint rv;
  127. if ((Tx->TC == TC) && (Tx->cData != NULL)) {
  128. glCompressedTexImage2DARB(GL_TEXTURE_2D, /* target */
  129. 0, /* level */
  130. Tx->cFormat, /* real format */
  131. Tx->w, /* original width */
  132. Tx->h, /* original height */
  133. 0, /* border */
  134. Tx->cSize, /* compressed size*/
  135. Tx->cData); /* compressed data*/
  136. } else {
  137. glTexImage2D(GL_TEXTURE_2D, /* target */
  138. 0, /* level */
  139. TC, /* internal format */
  140. Tx->w, Tx->h, /* width, height */
  141. 0, /* border */
  142. Tx->format, /* texture format */
  143. GL_UNSIGNED_BYTE, /* texture type */
  144. Tx->data); /* the texture */
  145. /* okay, now cache the compressed texture */
  146. Tx->TC = TC;
  147. if (Tx->cData != NULL) {
  148. free(Tx->cData);
  149. Tx->cData = NULL;
  150. }
  151. glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_ARB, &rv);
  152. if (rv) {
  153. glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, (GLint *)&Tx->cFormat);
  154. glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB, (GLint *)&Tx->cSize);
  155. if ((Tx->cData = malloc(Tx->cSize)) != NULL) {
  156. glGetCompressedTexImageARB(GL_TEXTURE_2D, 0, Tx->cData);
  157. }
  158. }
  159. }
  160. }
  161. static void Init( void )
  162. {
  163. /* HEIGHT * WIDTH + 1 (for trailing '\0') */
  164. static char pattern[8 * 32 + 1] = {"\
  165. \
  166. MMM EEEE SSS AAA \
  167. M M M E S S A A \
  168. M M M EEEE SS A A \
  169. M M M E SS AAAAA \
  170. M M E S S A A \
  171. M M EEEE SSS A A \
  172. "
  173. };
  174. GLuint i, j;
  175. GLubyte (*texture1)[8 * 32][4];
  176. GLubyte (*texture2)[256][256][4];
  177. t1.w = 32;
  178. t1.h = 8;
  179. t1.size = t1.w * t1.h * 4;
  180. t1.data = malloc(t1.size);
  181. t1.format = GL_RGBA;
  182. t1.TC = GL_RGBA;
  183. texture1 = (GLubyte (*)[8 * 32][4])t1.data;
  184. for (i = 0; i < sizeof(pattern) - 1; i++) {
  185. switch (pattern[i]) {
  186. default:
  187. case ' ':
  188. (*texture1)[i][0] = 255;
  189. (*texture1)[i][1] = 255;
  190. (*texture1)[i][2] = 255;
  191. (*texture1)[i][3] = 64;
  192. break;
  193. case 'M':
  194. (*texture1)[i][0] = 255;
  195. (*texture1)[i][1] = 0;
  196. (*texture1)[i][2] = 0;
  197. (*texture1)[i][3] = 255;
  198. break;
  199. case 'E':
  200. (*texture1)[i][0] = 0;
  201. (*texture1)[i][1] = 255;
  202. (*texture1)[i][2] = 0;
  203. (*texture1)[i][3] = 255;
  204. break;
  205. case 'S':
  206. (*texture1)[i][0] = 0;
  207. (*texture1)[i][1] = 0;
  208. (*texture1)[i][2] = 255;
  209. (*texture1)[i][3] = 255;
  210. break;
  211. case 'A':
  212. (*texture1)[i][0] = 255;
  213. (*texture1)[i][1] = 255;
  214. (*texture1)[i][2] = 0;
  215. (*texture1)[i][3] = 255;
  216. break;
  217. }
  218. }
  219. t2.w = 256;
  220. t2.h = 256;
  221. t2.size = t2.w * t2.h * 4;
  222. t2.data = malloc(t2.size);
  223. t2.format = GL_RGBA;
  224. t2.TC = GL_RGBA;
  225. texture2 = (GLubyte (*)[256][256][4])t2.data;
  226. for (j = 0; j < t2.h; j++) {
  227. for (i = 0; i < t2.w; i++) {
  228. (*texture2)[j][i][0] = sqrt(i * j * 255 * 255 / (t2.w * t2.h));
  229. (*texture2)[j][i][1] = 0;
  230. (*texture2)[j][i][2] = 0;
  231. (*texture2)[j][i][3] = 255;
  232. }
  233. }
  234. t3.data = LoadRGBImage(TEXTURE_FILE, (GLint *)&t3.w, (GLint *)&t3.h, &t3.format);
  235. t3.size = t3.w * t3.h * ((t3.format == GL_RGB) ? 3 : 4);
  236. t3.TC = GL_RGBA;
  237. ReInit(GL_RGBA, Tx = &t1);
  238. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  239. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  240. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  241. glEnable(GL_TEXTURE_2D);
  242. glEnable(GL_BLEND);
  243. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  244. }
  245. static void Key( unsigned char key, int x, int y )
  246. {
  247. (void) x;
  248. (void) y;
  249. switch (key) {
  250. case 27:
  251. exit(0);
  252. break;
  253. case ' ':
  254. Anim = !Anim;
  255. if (Anim)
  256. glutIdleFunc( Idle );
  257. else
  258. glutIdleFunc( NULL );
  259. break;
  260. case 't':
  261. if (Tx == &t1) {
  262. Tx = &t2;
  263. } else if (Tx == &t2) {
  264. Tx = &t3;
  265. } else {
  266. Tx = &t1;
  267. }
  268. ReInit(Tx->TC, Tx);
  269. break;
  270. case '9':
  271. ReInit(GL_RGB, Tx);
  272. break;
  273. case '0':
  274. ReInit(GL_RGBA, Tx);
  275. break;
  276. case '1':
  277. ReInit(GL_COMPRESSED_RGB, Tx);
  278. break;
  279. case '2':
  280. ReInit(GL_COMPRESSED_RGBA, Tx);
  281. break;
  282. case '3':
  283. if (fxt1) ReInit(GL_COMPRESSED_RGB_FXT1_3DFX, Tx);
  284. break;
  285. case '4':
  286. if (fxt1) ReInit(GL_COMPRESSED_RGBA_FXT1_3DFX, Tx);
  287. break;
  288. case '5':
  289. if (dxtc) ReInit(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, Tx);
  290. break;
  291. case '6':
  292. if (dxtc) ReInit(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, Tx);
  293. break;
  294. case '7':
  295. if (dxtc) ReInit(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, Tx);
  296. break;
  297. case '8':
  298. if (dxtc) ReInit(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, Tx);
  299. break;
  300. case 'a':
  301. if (s3tc) ReInit(GL_RGB_S3TC, Tx);
  302. break;
  303. case 's':
  304. if (s3tc) ReInit(GL_RGB4_S3TC, Tx);
  305. break;
  306. case 'd':
  307. if (s3tc) ReInit(GL_RGBA_S3TC, Tx);
  308. break;
  309. case 'f':
  310. if (s3tc) ReInit(GL_RGBA4_S3TC, Tx);
  311. break;
  312. }
  313. glutPostRedisplay();
  314. }
  315. int main( int argc, char *argv[] )
  316. {
  317. float gl_version;
  318. GLint num_formats;
  319. GLint i;
  320. GLint formats[64];
  321. glutInit( &argc, argv );
  322. glutInitWindowPosition( 0, 0 );
  323. glutInitWindowSize( 400, 300 );
  324. glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
  325. if (glutCreateWindow(argv[0]) <= 0) {
  326. printf("Couldn't create window\n");
  327. exit(0);
  328. }
  329. gl_version = atof( (const char *) glGetString( GL_VERSION ) );
  330. if ( (gl_version < 1.3)
  331. && !glutExtensionSupported("GL_ARB_texture_compression") ) {
  332. printf("Sorry, GL_ARB_texture_compression not supported\n");
  333. exit(0);
  334. }
  335. if (glutExtensionSupported("GL_3DFX_texture_compression_FXT1")) {
  336. fxt1 = GL_TRUE;
  337. }
  338. if (glutExtensionSupported("GL_EXT_texture_compression_s3tc")) {
  339. dxtc = GL_TRUE;
  340. }
  341. if (glutExtensionSupported("GL_S3_s3tc")) {
  342. s3tc = GL_TRUE;
  343. }
  344. glGetIntegerv( GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB, & num_formats );
  345. (void) memset( formats, 0, sizeof( formats ) );
  346. glGetIntegerv( GL_COMPRESSED_TEXTURE_FORMATS_ARB, formats );
  347. printf( "The following texture formats are supported:\n" );
  348. for ( i = 0 ; i < num_formats ; i++ ) {
  349. printf( "\t%s\n", TextureName( formats[i] ) );
  350. }
  351. Init();
  352. glutReshapeFunc( Reshape );
  353. glutKeyboardFunc( Key );
  354. glutDisplayFunc( Display );
  355. if (Anim)
  356. glutIdleFunc( Idle );
  357. glutMainLoop();
  358. return 0;
  359. }