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.

manytex.c 9.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. /* $Id: manytex.c,v 1.5 2005/09/15 01:58:39 brianp Exp $ */
  2. /*
  3. * test handling of many texture maps
  4. * Also tests texture priority and residency.
  5. *
  6. * Brian Paul
  7. * August 2, 2000
  8. */
  9. #include <assert.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <math.h>
  14. #include <GL/glut.h>
  15. static GLint NumTextures = 20;
  16. static GLuint *TextureID = NULL;
  17. static GLint *TextureWidth = NULL, *TextureHeight = NULL;
  18. static GLboolean *TextureResidency = NULL;
  19. static GLint TexWidth = 128, TexHeight = 128;
  20. static GLfloat Zrot = 0;
  21. static GLboolean Anim = GL_TRUE;
  22. static GLint WinWidth = 500, WinHeight = 400;
  23. static GLboolean MipMap = GL_FALSE;
  24. static GLboolean LinearFilter = GL_FALSE;
  25. static GLboolean RandomSize = GL_FALSE;
  26. static GLint Rows, Columns;
  27. static GLint LowPriorityCount = 0;
  28. static void Idle( void )
  29. {
  30. Zrot += 1.0;
  31. glutPostRedisplay();
  32. }
  33. static void Display( void )
  34. {
  35. GLfloat spacing = WinWidth / Columns;
  36. GLfloat size = spacing * 0.4;
  37. GLint i;
  38. /* test residency */
  39. if (0)
  40. {
  41. GLboolean b;
  42. GLint i, resident;
  43. b = glAreTexturesResident(NumTextures, TextureID, TextureResidency);
  44. if (b) {
  45. printf("all resident\n");
  46. }
  47. else {
  48. resident = 0;
  49. for (i = 0; i < NumTextures; i++) {
  50. if (TextureResidency[i]) {
  51. resident++;
  52. }
  53. }
  54. printf("%d of %d texture resident\n", resident, NumTextures);
  55. }
  56. }
  57. /* render the textured quads */
  58. glClear( GL_COLOR_BUFFER_BIT );
  59. for (i = 0; i < NumTextures; i++) {
  60. GLint row = i / Columns;
  61. GLint col = i % Columns;
  62. GLfloat x = col * spacing + spacing * 0.5;
  63. GLfloat y = row * spacing + spacing * 0.5;
  64. GLfloat maxDim = (TextureWidth[i] > TextureHeight[i])
  65. ? TextureWidth[i] : TextureHeight[i];
  66. GLfloat w = TextureWidth[i] / maxDim;
  67. GLfloat h = TextureHeight[i] / maxDim;
  68. glPushMatrix();
  69. glTranslatef(x, y, 0.0);
  70. glRotatef(Zrot, 0, 0, 1);
  71. glScalef(size, size, 1);
  72. glBindTexture(GL_TEXTURE_2D, TextureID[i]);
  73. glBegin(GL_POLYGON);
  74. #if 0
  75. glTexCoord2f(0, 0); glVertex2f(-1, -1);
  76. glTexCoord2f(1, 0); glVertex2f( 1, -1);
  77. glTexCoord2f(1, 1); glVertex2f( 1, 1);
  78. glTexCoord2f(0, 1); glVertex2f(-1, 1);
  79. #else
  80. glTexCoord2f(0, 0); glVertex2f(-w, -h);
  81. glTexCoord2f(1, 0); glVertex2f( w, -h);
  82. glTexCoord2f(1, 1); glVertex2f( w, h);
  83. glTexCoord2f(0, 1); glVertex2f(-w, h);
  84. #endif
  85. glEnd();
  86. glPopMatrix();
  87. }
  88. glutSwapBuffers();
  89. }
  90. static void Reshape( int width, int height )
  91. {
  92. WinWidth = width;
  93. WinHeight = height;
  94. glViewport( 0, 0, width, height );
  95. glMatrixMode( GL_PROJECTION );
  96. glLoadIdentity();
  97. glOrtho(0, width, 0, height, -1, 1);
  98. glMatrixMode( GL_MODELVIEW );
  99. glLoadIdentity();
  100. }
  101. /*
  102. * Return a random int in [min, max].
  103. */
  104. static int RandomInt(int min, int max)
  105. {
  106. int i = rand();
  107. int j = i % (max - min + 1);
  108. return min + j;
  109. }
  110. static void Init( void )
  111. {
  112. GLint i;
  113. if (RandomSize) {
  114. printf("Creating %d %s random-size textures, ", NumTextures,
  115. MipMap ? "Mipmapped" : "non-Mipmapped");
  116. }
  117. else {
  118. printf("Creating %d %s %d x %d textures, ", NumTextures,
  119. MipMap ? "Mipmapped" : "non-Mipmapped",
  120. TexWidth, TexHeight);
  121. }
  122. if (LinearFilter) {
  123. printf("bilinear filtering\n");
  124. }
  125. else {
  126. printf("nearest filtering\n");
  127. }
  128. /* compute number of rows and columns of rects */
  129. {
  130. GLfloat area = (GLfloat) (WinWidth * WinHeight) / (GLfloat) NumTextures;
  131. GLfloat edgeLen = sqrt(area);
  132. Columns = WinWidth / edgeLen;
  133. Rows = (NumTextures + Columns - 1) / Columns;
  134. printf("Rows: %d Cols: %d\n", Rows, Columns);
  135. }
  136. if (!TextureID) {
  137. TextureID = (GLuint *) malloc(sizeof(GLuint) * NumTextures);
  138. assert(TextureID);
  139. glGenTextures(NumTextures, TextureID);
  140. }
  141. if (!TextureResidency) {
  142. TextureResidency = (GLboolean *) malloc(sizeof(GLboolean) * NumTextures);
  143. assert(TextureResidency);
  144. }
  145. if (!TextureWidth) {
  146. TextureWidth = (GLint *) malloc(sizeof(GLint) * NumTextures);
  147. assert(TextureWidth);
  148. }
  149. if (!TextureHeight) {
  150. TextureHeight = (GLint *) malloc(sizeof(GLint) * NumTextures);
  151. assert(TextureHeight);
  152. }
  153. for (i = 0; i < NumTextures; i++) {
  154. GLubyte color[4];
  155. GLubyte *texImage;
  156. GLint j, row, col;
  157. row = i / Columns;
  158. col = i % Columns;
  159. glBindTexture(GL_TEXTURE_2D, TextureID[i]);
  160. if (i < LowPriorityCount)
  161. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_PRIORITY, 0.5F);
  162. if (RandomSize) {
  163. #if 0
  164. int k = (glutGet(GLUT_ELAPSED_TIME) % 7) + 2;
  165. TexWidth = 1 << k;
  166. TexHeight = 1 << k;
  167. #else
  168. TexWidth = 1 << RandomInt(2, 7);
  169. TexHeight = 1 << RandomInt(2, 7);
  170. printf("Random size of %3d: %d x %d\n", i, TexWidth, TexHeight);
  171. #endif
  172. }
  173. TextureWidth[i] = TexWidth;
  174. TextureHeight[i] = TexHeight;
  175. texImage = (GLubyte*) malloc(4 * TexWidth * TexHeight * sizeof(GLubyte));
  176. assert(texImage);
  177. /* determine texture color */
  178. color[0] = (GLint) (255.0 * ((float) col / (Columns - 1)));
  179. color[1] = 127;
  180. color[2] = (GLint) (255.0 * ((float) row / (Rows - 1)));
  181. color[3] = 255;
  182. /* fill in solid-colored teximage */
  183. for (j = 0; j < TexWidth * TexHeight; j++) {
  184. texImage[j*4+0] = color[0];
  185. texImage[j*4+1] = color[1];
  186. texImage[j*4+2] = color[2];
  187. texImage[j*4+3] = color[3];
  188. }
  189. if (MipMap) {
  190. GLint level = 0;
  191. GLint w = TexWidth, h = TexHeight;
  192. while (1) {
  193. glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, w, h, 0,
  194. GL_RGBA, GL_UNSIGNED_BYTE, texImage);
  195. if (w == 1 && h == 1)
  196. break;
  197. if (w > 1)
  198. w /= 2;
  199. if (h > 1)
  200. h /= 2;
  201. level++;
  202. /*printf("%d: %d x %d\n", level, w, h);*/
  203. }
  204. if (LinearFilter) {
  205. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
  206. GL_LINEAR_MIPMAP_LINEAR);
  207. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  208. }
  209. else {
  210. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
  211. GL_NEAREST_MIPMAP_NEAREST);
  212. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  213. }
  214. }
  215. else {
  216. /* Set corners to white */
  217. int k = 0;
  218. texImage[k+0] = texImage[k+1] = texImage[k+2] = texImage[k+3] = 255;
  219. k = (TexWidth - 1) * 4;
  220. texImage[k+0] = texImage[k+1] = texImage[k+2] = texImage[k+3] = 255;
  221. k = (TexWidth * TexHeight - TexWidth) * 4;
  222. texImage[k+0] = texImage[k+1] = texImage[k+2] = texImage[k+3] = 255;
  223. k = (TexWidth * TexHeight - 1) * 4;
  224. texImage[k+0] = texImage[k+1] = texImage[k+2] = texImage[k+3] = 255;
  225. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TexWidth, TexHeight, 0,
  226. GL_RGBA, GL_UNSIGNED_BYTE, texImage);
  227. if (LinearFilter) {
  228. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  229. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  230. }
  231. else {
  232. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  233. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  234. }
  235. }
  236. free(texImage);
  237. }
  238. glEnable(GL_TEXTURE_2D);
  239. }
  240. static void Key( unsigned char key, int x, int y )
  241. {
  242. const GLfloat step = 3.0;
  243. (void) x;
  244. (void) y;
  245. switch (key) {
  246. case 'a':
  247. Anim = !Anim;
  248. if (Anim)
  249. glutIdleFunc(Idle);
  250. else
  251. glutIdleFunc(NULL);
  252. break;
  253. case 's':
  254. Idle();
  255. break;
  256. case 'z':
  257. Zrot -= step;
  258. break;
  259. case 'Z':
  260. Zrot += step;
  261. break;
  262. case ' ':
  263. Init();
  264. break;
  265. case 27:
  266. exit(0);
  267. break;
  268. }
  269. glutPostRedisplay();
  270. }
  271. int main( int argc, char *argv[] )
  272. {
  273. GLint i;
  274. glutInit( &argc, argv );
  275. glutInitWindowPosition( 0, 0 );
  276. glutInitWindowSize( WinWidth, WinHeight );
  277. glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
  278. glutCreateWindow(argv[0]);
  279. glutReshapeFunc( Reshape );
  280. glutKeyboardFunc( Key );
  281. glutDisplayFunc( Display );
  282. if (Anim)
  283. glutIdleFunc(Idle);
  284. for (i = 1; i < argc; i++) {
  285. if (strcmp(argv[i], "-n") == 0) {
  286. NumTextures = atoi(argv[i+1]);
  287. if (NumTextures <= 0) {
  288. printf("Error, bad number of textures\n");
  289. return 1;
  290. }
  291. i++;
  292. }
  293. else if (strcmp(argv[i], "-mipmap") == 0) {
  294. MipMap = GL_TRUE;
  295. }
  296. else if (strcmp(argv[i], "-linear") == 0) {
  297. LinearFilter = GL_TRUE;
  298. }
  299. else if (strcmp(argv[i], "-size") == 0) {
  300. TexWidth = atoi(argv[i+1]);
  301. TexHeight = atoi(argv[i+2]);
  302. assert(TexWidth >= 1);
  303. assert(TexHeight >= 1);
  304. i += 2;
  305. }
  306. else if (strcmp(argv[i], "-randomsize") == 0) {
  307. RandomSize = GL_TRUE;
  308. }
  309. else if (strcmp(argv[i], "-lowpri") == 0) {
  310. LowPriorityCount = atoi(argv[i+1]);
  311. i++;
  312. }
  313. else {
  314. printf("Usage:\n");
  315. printf(" manytex [options]\n");
  316. printf("Options:\n");
  317. printf(" -n <number of texture objects>\n");
  318. printf(" -size <width> <height> - specify texture size\n");
  319. printf(" -randomsize - use random size textures\n");
  320. printf(" -mipmap - generate mipmaps\n");
  321. printf(" -linear - use linear filtering instead of nearest\n");
  322. printf(" -lowpri <n> - Set lower priority on <n> textures\n");
  323. return 0;
  324. }
  325. }
  326. Init();
  327. glutMainLoop();
  328. return 0;
  329. }