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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. /*
  2. * Test texture wrap modes.
  3. * Press 'b' to toggle texture image borders. You should see the same
  4. * rendering whether or not you're using borders.
  5. *
  6. * Brian Paul March 2001
  7. */
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <math.h>
  11. #include <GL/glew.h>
  12. #include <GL/glut.h>
  13. #ifndef GL_CLAMP_TO_BORDER
  14. #define GL_CLAMP_TO_BORDER 0x812D
  15. #endif
  16. #ifndef GL_MIRRORED_REPEAT
  17. #define GL_MIRRORED_REPEAT 0x8370
  18. #endif
  19. #ifndef GL_EXT_texture_mirror_clamp
  20. #define GL_MIRROR_CLAMP_EXT 0x8742
  21. #define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743
  22. #define GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912
  23. #endif
  24. #define BORDER_TEXTURE 1
  25. #define NO_BORDER_TEXTURE 2
  26. #define COLOR_TEX_CORNERS 0
  27. #define SIZE 8
  28. static GLubyte BorderImage[SIZE+2][SIZE+2][4];
  29. static GLubyte NoBorderImage[SIZE][SIZE][4];
  30. static GLuint Border = 0;
  31. #define TILE_SIZE 110
  32. #define WRAP_MODE(m) { m , # m, GL_TRUE, 1.0, { NULL, NULL } }
  33. #define WRAP_EXT(m,e1,e2,v) { m , # m, GL_FALSE, v, { e1, e2 } }
  34. struct wrap_mode {
  35. GLenum mode;
  36. const char * name;
  37. GLboolean supported;
  38. GLfloat version;
  39. const char * extension_names[2];
  40. };
  41. static struct wrap_mode modes[] = {
  42. WRAP_MODE( GL_REPEAT ),
  43. WRAP_MODE( GL_CLAMP ),
  44. WRAP_EXT ( GL_CLAMP_TO_EDGE, "GL_EXT_texture_edge_clamp",
  45. "GL_SGIS_texture_edge_clamp",
  46. 1.2 ),
  47. WRAP_EXT ( GL_CLAMP_TO_BORDER, "GL_ARB_texture_border_clamp",
  48. "GL_SGIS_texture_border_clamp",
  49. 1.3 ),
  50. WRAP_EXT ( GL_MIRRORED_REPEAT, "GL_ARB_texture_mirrored_repeat",
  51. "GL_IBM_texture_mirrored_repeat",
  52. 1.4 ),
  53. WRAP_EXT ( GL_MIRROR_CLAMP_EXT, "GL_ATI_texture_mirror_once",
  54. "GL_EXT_texture_mirror_clamp",
  55. 999.0 ),
  56. WRAP_EXT ( GL_MIRROR_CLAMP_TO_BORDER_EXT, "GL_EXT_texture_mirror_clamp",
  57. NULL,
  58. 999.0 ),
  59. WRAP_EXT ( GL_MIRROR_CLAMP_TO_EDGE_EXT, "GL_ATI_texture_mirror_once",
  60. "GL_EXT_texture_mirror_clamp",
  61. 999.0 ),
  62. { 0, NULL, GL_FALSE, 0.0, { NULL, NULL } }
  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 Display( void )
  73. {
  74. GLenum i, j;
  75. GLint offset;
  76. GLfloat version;
  77. /* Fill in the extensions that are supported.
  78. */
  79. version = atof( (char *) glGetString( GL_VERSION ) );
  80. for ( i = 0 ; modes[i].mode != 0 ; i++ ) {
  81. if ( ((modes[i].extension_names[0] != NULL)
  82. && glutExtensionSupported(modes[i].extension_names[0]))
  83. || ((modes[i].extension_names[1] != NULL)
  84. && glutExtensionSupported(modes[i].extension_names[1])) ) {
  85. modes[i].supported = GL_TRUE;
  86. }
  87. else if ( !modes[i].supported && (modes[i].version <= version) ) {
  88. fprintf( stderr, "WARNING: OpenGL library meets minimum version\n"
  89. " requirement for %s, but the\n"
  90. " extension string is not advertised.\n"
  91. " (%s%s%s)\n",
  92. modes[i].name,
  93. modes[i].extension_names[0],
  94. (modes[i].extension_names[1] != NULL)
  95. ? " or " : "",
  96. (modes[i].extension_names[1] != NULL)
  97. ? modes[i].extension_names[1] : "" );
  98. modes[i].supported = GL_TRUE;
  99. }
  100. }
  101. glClearColor(0.5, 0.5, 0.5, 1.0);
  102. glClear( GL_COLOR_BUFFER_BIT );
  103. #if 0
  104. /* draw texture as image */
  105. glDisable(GL_TEXTURE_2D);
  106. glWindowPos2iARB(1, 1);
  107. glDrawPixels(6, 6, GL_RGBA, GL_UNSIGNED_BYTE, (void *) TexImage);
  108. #endif
  109. glBindTexture(GL_TEXTURE_2D, Border ? BORDER_TEXTURE : NO_BORDER_TEXTURE);
  110. /* loop over min/mag filters */
  111. for (i = 0; i < 2; i++) {
  112. offset = 0;
  113. if (i) {
  114. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  115. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  116. }
  117. else {
  118. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  119. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  120. }
  121. /* loop over border modes */
  122. for (j = 0; modes[j].mode != 0; j++) {
  123. const GLfloat x0 = 0, y0 = 0, x1 = (TILE_SIZE - 10), y1 = (TILE_SIZE - 10);
  124. const GLfloat b = 1.2;
  125. const GLfloat s0 = -b, t0 = -b, s1 = 1.0+b, t1 = 1.0+b;
  126. if ( modes[j].supported != GL_TRUE )
  127. continue;
  128. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, modes[j].mode);
  129. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, modes[j].mode);
  130. glPushMatrix();
  131. glTranslatef(offset * TILE_SIZE + 10, i * TILE_SIZE + 40, 0);
  132. offset++;
  133. glEnable(GL_TEXTURE_2D);
  134. glColor3f(1, 1, 1);
  135. glBegin(GL_POLYGON);
  136. glTexCoord2f(s0, t0); glVertex2f(x0, y0);
  137. glTexCoord2f(s1, t0); glVertex2f(x1, y0);
  138. glTexCoord2f(s1, t1); glVertex2f(x1, y1);
  139. glTexCoord2f(s0, t1); glVertex2f(x0, y1);
  140. glEnd();
  141. /* draw red outline showing bounds of texture at s=0,1 and t=0,1 */
  142. glDisable(GL_TEXTURE_2D);
  143. glColor3f(1, 0, 0);
  144. glBegin(GL_LINE_LOOP);
  145. glVertex2f(x0 + b * (x1-x0) / (s1-s0), y0 + b * (y1-y0) / (t1-t0));
  146. glVertex2f(x1 - b * (x1-x0) / (s1-s0), y0 + b * (y1-y0) / (t1-t0));
  147. glVertex2f(x1 - b * (x1-x0) / (s1-s0), y1 - b * (y1-y0) / (t1-t0));
  148. glVertex2f(x0 + b * (x1-x0) / (s1-s0), y1 - b * (y1-y0) / (t1-t0));
  149. glEnd();
  150. glPopMatrix();
  151. }
  152. }
  153. glDisable(GL_TEXTURE_2D);
  154. glColor3f(1, 1, 1);
  155. offset = 0;
  156. for (i = 0; modes[i].mode != 0; i++) {
  157. if ( modes[i].supported ) {
  158. glWindowPos2iARB( offset * TILE_SIZE + 10, 5 + ((offset & 1) * 15) );
  159. PrintString(modes[i].name);
  160. offset++;
  161. }
  162. }
  163. glutSwapBuffers();
  164. }
  165. static void Reshape( int width, int height )
  166. {
  167. glViewport( 0, 0, width, height );
  168. glMatrixMode( GL_PROJECTION );
  169. glLoadIdentity();
  170. glOrtho(0, width, 0, height, -1, 1);
  171. glMatrixMode( GL_MODELVIEW );
  172. glLoadIdentity();
  173. }
  174. static void Key( unsigned char key, int x, int y )
  175. {
  176. (void) x;
  177. (void) y;
  178. switch (key) {
  179. case 'b':
  180. Border = !Border;
  181. printf("Texture Border Size = %d\n", Border);
  182. break;
  183. case 27:
  184. exit(0);
  185. break;
  186. }
  187. glutPostRedisplay();
  188. }
  189. static void Init( void )
  190. {
  191. static const GLubyte border[4] = { 0, 255, 0, 255 };
  192. static const GLfloat borderf[4] = { 0, 1.0, 0, 1.0 };
  193. GLint i, j;
  194. for (i = 0; i < SIZE+2; i++) {
  195. for (j = 0; j < SIZE+2; j++) {
  196. if (i == 0 || j == 0 || i == SIZE+1 || j == SIZE+1) {
  197. /* border color */
  198. BorderImage[i][j][0] = border[0];
  199. BorderImage[i][j][1] = border[1];
  200. BorderImage[i][j][2] = border[2];
  201. BorderImage[i][j][3] = border[3];
  202. }
  203. else if ((i + j) & 1) {
  204. /* white */
  205. BorderImage[i][j][0] = 255;
  206. BorderImage[i][j][1] = 255;
  207. BorderImage[i][j][2] = 255;
  208. BorderImage[i][j][3] = 255;
  209. }
  210. else {
  211. /* black */
  212. BorderImage[i][j][0] = 0;
  213. BorderImage[i][j][1] = 0;
  214. BorderImage[i][j][2] = 0;
  215. BorderImage[i][j][3] = 0;
  216. }
  217. }
  218. }
  219. glBindTexture(GL_TEXTURE_2D, BORDER_TEXTURE);
  220. #ifdef TEST_PBO_DLIST
  221. /* test fetching teximage from PBO in display list */
  222. {
  223. GLuint b = 42, l = 10;
  224. glBindBufferARB(GL_PIXEL_UNPACK_BUFFER, b);
  225. glBufferDataARB(GL_PIXEL_UNPACK_BUFFER, sizeof(BorderImage),
  226. BorderImage, GL_STREAM_DRAW);
  227. glNewList(l, GL_COMPILE);
  228. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SIZE+2, SIZE+2, 1,
  229. GL_RGBA, GL_UNSIGNED_BYTE, (void *) 0/* BorderImage*/);
  230. glEndList();
  231. glCallList(l);
  232. glBindBufferARB(GL_PIXEL_UNPACK_BUFFER, 0);
  233. }
  234. #else
  235. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SIZE+2, SIZE+2, 1,
  236. GL_RGBA, GL_UNSIGNED_BYTE, (void *) BorderImage);
  237. #endif
  238. for (i = 0; i < SIZE; i++) {
  239. for (j = 0; j < SIZE; j++) {
  240. #if COLOR_TEX_CORNERS
  241. if (i == 0 && j == 0) {
  242. /* lower-left texel = RED */
  243. NoBorderImage[i][j][0] = 255;
  244. NoBorderImage[i][j][1] = 0;
  245. NoBorderImage[i][j][2] = 0;
  246. NoBorderImage[i][j][3] = 255;
  247. }
  248. else if (i == 0 && j == SIZE-1) {
  249. /* lower-right corner = GREEN */
  250. NoBorderImage[i][j][0] = 0;
  251. NoBorderImage[i][j][1] = 255;
  252. NoBorderImage[i][j][2] = 0;
  253. NoBorderImage[i][j][3] = 255;
  254. }
  255. else if (i == SIZE-1 && j == 0) {
  256. /* upper-left corner = BLUE */
  257. NoBorderImage[i][j][0] = 0;
  258. NoBorderImage[i][j][1] = 0;
  259. NoBorderImage[i][j][2] = 255;
  260. NoBorderImage[i][j][3] = 255;
  261. }
  262. else if (i == SIZE-1 && j == SIZE-1) {
  263. /* upper-right corner = YELLOW */
  264. NoBorderImage[i][j][0] = 255;
  265. NoBorderImage[i][j][1] = 255;
  266. NoBorderImage[i][j][2] = 0;
  267. NoBorderImage[i][j][3] = 255;
  268. }
  269. else
  270. #endif
  271. if ((i + j) & 1) {
  272. /* white */
  273. NoBorderImage[i][j][0] = 255;
  274. NoBorderImage[i][j][1] = 255;
  275. NoBorderImage[i][j][2] = 255;
  276. NoBorderImage[i][j][3] = 255;
  277. }
  278. else {
  279. /* black */
  280. NoBorderImage[i][j][0] = 0;
  281. NoBorderImage[i][j][1] = 0;
  282. NoBorderImage[i][j][2] = 0;
  283. NoBorderImage[i][j][3] = 0;
  284. }
  285. }
  286. }
  287. glBindTexture(GL_TEXTURE_2D, NO_BORDER_TEXTURE);
  288. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SIZE, SIZE, 0,
  289. GL_RGBA, GL_UNSIGNED_BYTE, (void *) NoBorderImage);
  290. glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderf);
  291. }
  292. int main( int argc, char *argv[] )
  293. {
  294. glutInit( &argc, argv );
  295. glutInitWindowPosition( 0, 0 );
  296. glutInitWindowSize( 1000, 270 );
  297. glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
  298. glutCreateWindow(argv[0]);
  299. glewInit();
  300. glutReshapeFunc( Reshape );
  301. glutKeyboardFunc( Key );
  302. glutDisplayFunc( Display );
  303. Init();
  304. glutMainLoop();
  305. return 0;
  306. }