Clone of mesa.
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

manytex.c 9.9KB

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