Clone of mesa.
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

texcmp.c 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  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. #include <GL/glew.h>
  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, v;
  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. v = 0;
  146. glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
  147. GL_TEXTURE_INTERNAL_FORMAT, &v);
  148. printf("Requested internal format = 0x%x, actual = 0x%x\n", TC, v);
  149. /* okay, now cache the compressed texture */
  150. Tx->TC = TC;
  151. if (Tx->cData != NULL) {
  152. free(Tx->cData);
  153. Tx->cData = NULL;
  154. }
  155. glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_ARB, &rv);
  156. if (rv) {
  157. glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, (GLint *)&Tx->cFormat);
  158. glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB, (GLint *)&Tx->cSize);
  159. if ((Tx->cData = malloc(Tx->cSize)) != NULL) {
  160. glGetCompressedTexImageARB(GL_TEXTURE_2D, 0, Tx->cData);
  161. }
  162. }
  163. }
  164. }
  165. static void Init( void )
  166. {
  167. /* HEIGHT * WIDTH + 1 (for trailing '\0') */
  168. static char pattern[8 * 32 + 1] = {"\
  169. \
  170. MMM EEEE SSS AAA \
  171. M M M E S S A A \
  172. M M M EEEE SS A A \
  173. M M M E SS AAAAA \
  174. M M E S S A A \
  175. M M EEEE SSS A A \
  176. "
  177. };
  178. GLuint i, j;
  179. GLubyte (*texture1)[8 * 32][4];
  180. GLubyte (*texture2)[256][256][4];
  181. t1.w = 32;
  182. t1.h = 8;
  183. t1.size = t1.w * t1.h * 4;
  184. t1.data = malloc(t1.size);
  185. t1.format = GL_RGBA;
  186. t1.TC = GL_RGBA;
  187. texture1 = (GLubyte (*)[8 * 32][4])t1.data;
  188. for (i = 0; i < sizeof(pattern) - 1; i++) {
  189. switch (pattern[i]) {
  190. default:
  191. case ' ':
  192. (*texture1)[i][0] = 255;
  193. (*texture1)[i][1] = 255;
  194. (*texture1)[i][2] = 255;
  195. (*texture1)[i][3] = 64;
  196. break;
  197. case 'M':
  198. (*texture1)[i][0] = 255;
  199. (*texture1)[i][1] = 0;
  200. (*texture1)[i][2] = 0;
  201. (*texture1)[i][3] = 255;
  202. break;
  203. case 'E':
  204. (*texture1)[i][0] = 0;
  205. (*texture1)[i][1] = 255;
  206. (*texture1)[i][2] = 0;
  207. (*texture1)[i][3] = 255;
  208. break;
  209. case 'S':
  210. (*texture1)[i][0] = 0;
  211. (*texture1)[i][1] = 0;
  212. (*texture1)[i][2] = 255;
  213. (*texture1)[i][3] = 255;
  214. break;
  215. case 'A':
  216. (*texture1)[i][0] = 255;
  217. (*texture1)[i][1] = 255;
  218. (*texture1)[i][2] = 0;
  219. (*texture1)[i][3] = 255;
  220. break;
  221. }
  222. }
  223. t2.w = 256;
  224. t2.h = 256;
  225. t2.size = t2.w * t2.h * 4;
  226. t2.data = malloc(t2.size);
  227. t2.format = GL_RGBA;
  228. t2.TC = GL_RGBA;
  229. texture2 = (GLubyte (*)[256][256][4])t2.data;
  230. for (j = 0; j < t2.h; j++) {
  231. for (i = 0; i < t2.w; i++) {
  232. (*texture2)[j][i][0] = sqrt(i * j * 255 * 255 / (t2.w * t2.h));
  233. (*texture2)[j][i][1] = 0;
  234. (*texture2)[j][i][2] = 0;
  235. (*texture2)[j][i][3] = 255;
  236. }
  237. }
  238. t3.data = LoadRGBImage(TEXTURE_FILE, (GLint *)&t3.w, (GLint *)&t3.h, &t3.format);
  239. t3.size = t3.w * t3.h * ((t3.format == GL_RGB) ? 3 : 4);
  240. t3.TC = GL_RGBA;
  241. ReInit(GL_RGBA, Tx = &t1);
  242. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  243. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  244. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  245. glEnable(GL_TEXTURE_2D);
  246. glEnable(GL_BLEND);
  247. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  248. }
  249. static void Key( unsigned char key, int x, int y )
  250. {
  251. (void) x;
  252. (void) y;
  253. switch (key) {
  254. case 27:
  255. exit(0);
  256. break;
  257. case ' ':
  258. Anim = !Anim;
  259. if (Anim)
  260. glutIdleFunc( Idle );
  261. else
  262. glutIdleFunc( NULL );
  263. break;
  264. case 't':
  265. if (Tx == &t1) {
  266. Tx = &t2;
  267. } else if (Tx == &t2) {
  268. Tx = &t3;
  269. } else {
  270. Tx = &t1;
  271. }
  272. ReInit(Tx->TC, Tx);
  273. break;
  274. case '9':
  275. ReInit(GL_RGB, Tx);
  276. break;
  277. case '0':
  278. ReInit(GL_RGBA, Tx);
  279. break;
  280. case '1':
  281. ReInit(GL_COMPRESSED_RGB, Tx);
  282. break;
  283. case '2':
  284. ReInit(GL_COMPRESSED_RGBA, Tx);
  285. break;
  286. case '3':
  287. if (fxt1) ReInit(GL_COMPRESSED_RGB_FXT1_3DFX, Tx);
  288. break;
  289. case '4':
  290. if (fxt1) ReInit(GL_COMPRESSED_RGBA_FXT1_3DFX, Tx);
  291. break;
  292. case '5':
  293. if (dxtc) ReInit(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, Tx);
  294. break;
  295. case '6':
  296. if (dxtc) ReInit(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, Tx);
  297. break;
  298. case '7':
  299. if (dxtc) ReInit(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, Tx);
  300. break;
  301. case '8':
  302. if (dxtc) ReInit(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, Tx);
  303. break;
  304. case 'a':
  305. if (s3tc) ReInit(GL_RGB_S3TC, Tx);
  306. break;
  307. case 's':
  308. if (s3tc) ReInit(GL_RGB4_S3TC, Tx);
  309. break;
  310. case 'd':
  311. if (s3tc) ReInit(GL_RGBA_S3TC, Tx);
  312. break;
  313. case 'f':
  314. if (s3tc) ReInit(GL_RGBA4_S3TC, Tx);
  315. break;
  316. }
  317. glutPostRedisplay();
  318. }
  319. int main( int argc, char *argv[] )
  320. {
  321. float gl_version;
  322. GLint num_formats;
  323. GLint i;
  324. GLint formats[64];
  325. glutInit( &argc, argv );
  326. glutInitWindowPosition( 0, 0 );
  327. glutInitWindowSize( 400, 300 );
  328. glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
  329. if (glutCreateWindow(argv[0]) <= 0) {
  330. printf("Couldn't create window\n");
  331. exit(0);
  332. }
  333. glewInit();
  334. gl_version = atof( (const char *) glGetString( GL_VERSION ) );
  335. if ( (gl_version < 1.3)
  336. && !glutExtensionSupported("GL_ARB_texture_compression") ) {
  337. printf("Sorry, GL_ARB_texture_compression not supported\n");
  338. exit(0);
  339. }
  340. if (glutExtensionSupported("GL_3DFX_texture_compression_FXT1")) {
  341. fxt1 = GL_TRUE;
  342. }
  343. if (glutExtensionSupported("GL_EXT_texture_compression_s3tc")) {
  344. dxtc = GL_TRUE;
  345. }
  346. if (glutExtensionSupported("GL_S3_s3tc")) {
  347. s3tc = GL_TRUE;
  348. }
  349. glGetIntegerv( GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB, & num_formats );
  350. (void) memset( formats, 0, sizeof( formats ) );
  351. glGetIntegerv( GL_COMPRESSED_TEXTURE_FORMATS_ARB, formats );
  352. printf( "The following texture formats are supported:\n" );
  353. for ( i = 0 ; i < num_formats ; i++ ) {
  354. printf( "\t%s\n", TextureName( formats[i] ) );
  355. }
  356. Init();
  357. glutReshapeFunc( Reshape );
  358. glutKeyboardFunc( Key );
  359. glutDisplayFunc( Display );
  360. if (Anim)
  361. glutIdleFunc( Idle );
  362. glutMainLoop();
  363. return 0;
  364. }