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

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