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 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393
  1. /*
  2. * test handling of many texture maps
  3. * Also tests texture priority and residency.
  4. *
  5. * Brian Paul
  6. * August 2, 2000
  7. */
  8. #include <assert.h>
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <math.h>
  13. #include <GL/glut.h>
  14. static GLint NumTextures = 20;
  15. static GLuint *TextureID = NULL;
  16. static GLint *TextureWidth = NULL, *TextureHeight = NULL;
  17. static GLboolean *TextureResidency = NULL;
  18. static GLint TexWidth = 128, TexHeight = 128;
  19. static GLfloat Zrot = 0;
  20. static GLboolean Anim = GL_TRUE;
  21. static GLint WinWidth = 500, WinHeight = 400;
  22. static GLboolean MipMap = GL_FALSE;
  23. static GLboolean LinearFilter = GL_FALSE;
  24. static GLboolean RandomSize = GL_FALSE;
  25. static GLint Rows, Columns;
  26. static GLint LowPriorityCount = 0;
  27. static GLint Win;
  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 DeleteTextures(void)
  111. {
  112. glDeleteTextures(NumTextures, TextureID);
  113. free(TextureID);
  114. TextureID = NULL;
  115. }
  116. static void Init( void )
  117. {
  118. GLint i;
  119. if (RandomSize) {
  120. printf("Creating %d %s random-size textures, ", NumTextures,
  121. MipMap ? "Mipmapped" : "non-Mipmapped");
  122. }
  123. else {
  124. printf("Creating %d %s %d x %d textures, ", NumTextures,
  125. MipMap ? "Mipmapped" : "non-Mipmapped",
  126. TexWidth, TexHeight);
  127. }
  128. if (LinearFilter) {
  129. printf("bilinear filtering\n");
  130. }
  131. else {
  132. printf("nearest filtering\n");
  133. }
  134. /* compute number of rows and columns of rects */
  135. {
  136. GLfloat area = (GLfloat) (WinWidth * WinHeight) / (GLfloat) NumTextures;
  137. GLfloat edgeLen = sqrt(area);
  138. Columns = WinWidth / edgeLen;
  139. Rows = (NumTextures + Columns - 1) / Columns;
  140. printf("Rows: %d Cols: %d\n", Rows, Columns);
  141. }
  142. if (!TextureID) {
  143. TextureID = (GLuint *) malloc(sizeof(GLuint) * NumTextures);
  144. assert(TextureID);
  145. glGenTextures(NumTextures, TextureID);
  146. }
  147. if (!TextureResidency) {
  148. TextureResidency = (GLboolean *) malloc(sizeof(GLboolean) * NumTextures);
  149. assert(TextureResidency);
  150. }
  151. if (!TextureWidth) {
  152. TextureWidth = (GLint *) malloc(sizeof(GLint) * NumTextures);
  153. assert(TextureWidth);
  154. }
  155. if (!TextureHeight) {
  156. TextureHeight = (GLint *) malloc(sizeof(GLint) * NumTextures);
  157. assert(TextureHeight);
  158. }
  159. for (i = 0; i < NumTextures; i++) {
  160. GLubyte color[4];
  161. GLubyte *texImage;
  162. GLint j, row, col;
  163. row = i / Columns;
  164. col = i % Columns;
  165. glBindTexture(GL_TEXTURE_2D, TextureID[i]);
  166. if (i < LowPriorityCount)
  167. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_PRIORITY, 0.5F);
  168. if (RandomSize) {
  169. #if 0
  170. int k = (glutGet(GLUT_ELAPSED_TIME) % 7) + 2;
  171. TexWidth = 1 << k;
  172. TexHeight = 1 << k;
  173. #else
  174. TexWidth = 1 << RandomInt(2, 7);
  175. TexHeight = 1 << RandomInt(2, 7);
  176. printf("Random size of %3d: %d x %d\n", i, TexWidth, TexHeight);
  177. #endif
  178. }
  179. TextureWidth[i] = TexWidth;
  180. TextureHeight[i] = TexHeight;
  181. texImage = (GLubyte*) malloc(4 * TexWidth * TexHeight * sizeof(GLubyte));
  182. assert(texImage);
  183. /* determine texture color */
  184. color[0] = (GLint) (255.0 * ((float) col / (Columns - 1)));
  185. color[1] = 127;
  186. color[2] = (GLint) (255.0 * ((float) row / (Rows - 1)));
  187. color[3] = 255;
  188. /* fill in solid-colored teximage */
  189. for (j = 0; j < TexWidth * TexHeight; j++) {
  190. texImage[j*4+0] = color[0];
  191. texImage[j*4+1] = color[1];
  192. texImage[j*4+2] = color[2];
  193. texImage[j*4+3] = color[3];
  194. }
  195. if (MipMap) {
  196. GLint level = 0;
  197. GLint w = TexWidth, h = TexHeight;
  198. while (1) {
  199. glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, w, h, 0,
  200. GL_RGBA, GL_UNSIGNED_BYTE, texImage);
  201. if (w == 1 && h == 1)
  202. break;
  203. if (w > 1)
  204. w /= 2;
  205. if (h > 1)
  206. h /= 2;
  207. level++;
  208. /*printf("%d: %d x %d\n", level, w, h);*/
  209. }
  210. if (LinearFilter) {
  211. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
  212. GL_LINEAR_MIPMAP_LINEAR);
  213. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  214. }
  215. else {
  216. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
  217. GL_NEAREST_MIPMAP_NEAREST);
  218. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  219. }
  220. }
  221. else {
  222. /* Set corners to white */
  223. int k = 0;
  224. texImage[k+0] = texImage[k+1] = texImage[k+2] = texImage[k+3] = 255;
  225. k = (TexWidth - 1) * 4;
  226. texImage[k+0] = texImage[k+1] = texImage[k+2] = texImage[k+3] = 255;
  227. k = (TexWidth * TexHeight - TexWidth) * 4;
  228. texImage[k+0] = texImage[k+1] = texImage[k+2] = texImage[k+3] = 255;
  229. k = (TexWidth * TexHeight - 1) * 4;
  230. texImage[k+0] = texImage[k+1] = texImage[k+2] = texImage[k+3] = 255;
  231. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TexWidth, TexHeight, 0,
  232. GL_RGBA, GL_UNSIGNED_BYTE, texImage);
  233. if (LinearFilter) {
  234. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  235. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  236. }
  237. else {
  238. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  239. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  240. }
  241. }
  242. free(texImage);
  243. }
  244. glEnable(GL_TEXTURE_2D);
  245. }
  246. static void Key( unsigned char key, int x, int y )
  247. {
  248. const GLfloat step = 3.0;
  249. (void) x;
  250. (void) y;
  251. switch (key) {
  252. case 'a':
  253. Anim = !Anim;
  254. if (Anim)
  255. glutIdleFunc(Idle);
  256. else
  257. glutIdleFunc(NULL);
  258. break;
  259. case 's':
  260. Idle();
  261. break;
  262. case 'z':
  263. Zrot -= step;
  264. break;
  265. case 'Z':
  266. Zrot += step;
  267. break;
  268. case ' ':
  269. DeleteTextures();
  270. Init();
  271. break;
  272. case 27:
  273. DeleteTextures();
  274. glutDestroyWindow(Win);
  275. exit(0);
  276. break;
  277. }
  278. glutPostRedisplay();
  279. }
  280. int main( int argc, char *argv[] )
  281. {
  282. GLint i;
  283. glutInit( &argc, argv );
  284. glutInitWindowPosition( 0, 0 );
  285. glutInitWindowSize( WinWidth, WinHeight );
  286. glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
  287. Win = glutCreateWindow(argv[0]);
  288. glutReshapeFunc( Reshape );
  289. glutKeyboardFunc( Key );
  290. glutDisplayFunc( Display );
  291. if (Anim)
  292. glutIdleFunc(Idle);
  293. for (i = 1; i < argc; i++) {
  294. if (strcmp(argv[i], "-n") == 0) {
  295. NumTextures = atoi(argv[i+1]);
  296. if (NumTextures <= 0) {
  297. printf("Error, bad number of textures\n");
  298. return 1;
  299. }
  300. i++;
  301. }
  302. else if (strcmp(argv[i], "-mipmap") == 0) {
  303. MipMap = GL_TRUE;
  304. }
  305. else if (strcmp(argv[i], "-linear") == 0) {
  306. LinearFilter = GL_TRUE;
  307. }
  308. else if (strcmp(argv[i], "-size") == 0) {
  309. TexWidth = atoi(argv[i+1]);
  310. TexHeight = atoi(argv[i+2]);
  311. assert(TexWidth >= 1);
  312. assert(TexHeight >= 1);
  313. i += 2;
  314. }
  315. else if (strcmp(argv[i], "-randomsize") == 0) {
  316. RandomSize = GL_TRUE;
  317. }
  318. else if (strcmp(argv[i], "-lowpri") == 0) {
  319. LowPriorityCount = atoi(argv[i+1]);
  320. i++;
  321. }
  322. else {
  323. printf("Usage:\n");
  324. printf(" manytex [options]\n");
  325. printf("Options:\n");
  326. printf(" -n <number of texture objects>\n");
  327. printf(" -size <width> <height> - specify texture size\n");
  328. printf(" -randomsize - use random size textures\n");
  329. printf(" -mipmap - generate mipmaps\n");
  330. printf(" -linear - use linear filtering instead of nearest\n");
  331. printf(" -lowpri <n> - Set lower priority on <n> textures\n");
  332. return 0;
  333. }
  334. }
  335. Init();
  336. glutMainLoop();
  337. return 0;
  338. }