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.

readpix.c 9.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. /*
  2. * glReadPixels and glCopyPixels test
  3. *
  4. * Brian Paul March 1, 2000 This file is in the public domain.
  5. */
  6. #include <assert.h>
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <math.h>
  10. #include <string.h>
  11. #include <GL/glut.h>
  12. #include "readtex.h"
  13. #define IMAGE_FILE "../images/girl.rgb"
  14. static int ImgWidth, ImgHeight;
  15. static GLenum ImgFormat;
  16. static GLubyte *Image = NULL;
  17. static int APosX, APosY; /* simple drawpixels */
  18. static int BPosX, BPosY; /* read/draw pixels */
  19. static int CPosX, CPosY; /* copypixels */
  20. static GLboolean DrawFront = GL_FALSE;
  21. static GLboolean ScaleAndBias = GL_FALSE;
  22. static GLboolean Benchmark = GL_FALSE;
  23. static GLubyte *TempImage = NULL;
  24. #define COMBO 1
  25. #if COMBO == 0
  26. #define ReadFormat ImgFormat
  27. #define ReadType GL_UNSIGNED_BYTE
  28. #elif COMBO == 1
  29. static GLenum ReadFormat = GL_RGBA;
  30. static GLenum ReadType = GL_UNSIGNED_BYTE;
  31. #elif COMBO == 2
  32. static GLenum ReadFormat = GL_RGB;
  33. static GLenum ReadType = GL_UNSIGNED_BYTE;
  34. #elif COMBO == 3
  35. static GLenum ReadFormat = GL_RGB;
  36. static GLenum ReadType = GL_UNSIGNED_SHORT_5_6_5;
  37. #elif COMBO == 4
  38. static GLenum ReadFormat = GL_RGBA;
  39. static GLenum ReadType = GL_UNSIGNED_SHORT_1_5_5_5_REV;
  40. #elif COMBO == 5
  41. static GLenum ReadFormat = GL_BGRA;
  42. static GLenum ReadType = GL_UNSIGNED_SHORT_5_5_5_1;
  43. #elif COMBO == 6
  44. static GLenum ReadFormat = GL_BGRA;
  45. static GLenum ReadType = GL_UNSIGNED_SHORT_4_4_4_4_REV;
  46. #elif COMBO == 7
  47. static GLenum ReadFormat = GL_RGBA;
  48. static GLenum ReadType = GL_HALF_FLOAT_ARB;
  49. #undef GL_OES_read_format
  50. #endif
  51. static void
  52. Reset( void )
  53. {
  54. APosX = 5; APosY = 20;
  55. BPosX = APosX + ImgWidth + 5; BPosY = 20;
  56. CPosX = BPosX + ImgWidth + 5; CPosY = 20;
  57. }
  58. static void
  59. PrintString(const char *s)
  60. {
  61. while (*s) {
  62. glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
  63. s++;
  64. }
  65. }
  66. static void
  67. SetupPixelTransfer(GLboolean invert)
  68. {
  69. if (invert) {
  70. glPixelTransferf(GL_RED_SCALE, -1.0);
  71. glPixelTransferf(GL_RED_BIAS, 1.0);
  72. glPixelTransferf(GL_GREEN_SCALE, -1.0);
  73. glPixelTransferf(GL_GREEN_BIAS, 1.0);
  74. glPixelTransferf(GL_BLUE_SCALE, -1.0);
  75. glPixelTransferf(GL_BLUE_BIAS, 1.0);
  76. }
  77. else {
  78. glPixelTransferf(GL_RED_SCALE, 1.0);
  79. glPixelTransferf(GL_RED_BIAS, 0.0);
  80. glPixelTransferf(GL_GREEN_SCALE, 1.0);
  81. glPixelTransferf(GL_GREEN_BIAS, 0.0);
  82. glPixelTransferf(GL_BLUE_SCALE, 1.0);
  83. glPixelTransferf(GL_BLUE_BIAS, 0.0);
  84. }
  85. }
  86. /**
  87. * Exercise Pixel Pack parameters by reading the image in four pieces.
  88. */
  89. static void
  90. ComplexReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
  91. GLenum format, GLenum type, GLvoid *pixels)
  92. {
  93. const GLsizei width0 = width / 2;
  94. const GLsizei width1 = width - width0;
  95. const GLsizei height0 = height / 2;
  96. const GLsizei height1 = height - height0;
  97. glPixelStorei(GL_PACK_ROW_LENGTH, width);
  98. /* lower-left quadrant */
  99. glReadPixels(x, y, width0, height0, format, type, pixels);
  100. /* lower-right quadrant */
  101. glPixelStorei(GL_PACK_SKIP_PIXELS, width0);
  102. glReadPixels(x + width0, y, width1, height0, format, type, pixels);
  103. /* upper-left quadrant */
  104. glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
  105. glPixelStorei(GL_PACK_SKIP_ROWS, height0);
  106. glReadPixels(x, y + height0, width0, height1, format, type, pixels);
  107. /* upper-right quadrant */
  108. glPixelStorei(GL_PACK_SKIP_PIXELS, width0);
  109. glPixelStorei(GL_PACK_SKIP_ROWS, height0);
  110. glReadPixels(x + width0, y + height0, width1, height1, format, type, pixels);
  111. /* restore defaults */
  112. glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
  113. glPixelStorei(GL_PACK_SKIP_ROWS, 0);
  114. glPixelStorei(GL_PACK_ROW_LENGTH, ImgWidth);
  115. }
  116. static void
  117. Display( void )
  118. {
  119. glClearColor(.3, .3, .3, 1);
  120. glClear( GL_COLOR_BUFFER_BIT );
  121. glRasterPos2i(5, ImgHeight+25);
  122. PrintString("f = toggle front/back s = toggle scale/bias b = benchmark");
  123. /* draw original image */
  124. glRasterPos2i(APosX, 5);
  125. PrintString("Original");
  126. glRasterPos2i(APosX, APosY);
  127. glEnable(GL_DITHER);
  128. SetupPixelTransfer(GL_FALSE);
  129. glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  130. glDrawPixels(ImgWidth, ImgHeight, ImgFormat, GL_UNSIGNED_BYTE, Image);
  131. /* might try alignment=4 here for testing */
  132. glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  133. glPixelStorei(GL_PACK_ALIGNMENT, 1);
  134. /* do readpixels, drawpixels */
  135. glRasterPos2i(BPosX, 5);
  136. PrintString("Read/DrawPixels");
  137. SetupPixelTransfer(ScaleAndBias);
  138. if (Benchmark) {
  139. GLint reads = 0;
  140. GLint endTime;
  141. GLint startTime = glutGet(GLUT_ELAPSED_TIME);
  142. GLdouble seconds, pixelsPerSecond;
  143. printf("Benchmarking...\n");
  144. do {
  145. glReadPixels(APosX, APosY, ImgWidth, ImgHeight,
  146. ReadFormat, ReadType, TempImage);
  147. reads++;
  148. endTime = glutGet(GLUT_ELAPSED_TIME);
  149. } while (endTime - startTime < 4000); /* 4 seconds */
  150. seconds = (double) (endTime - startTime) / 1000.0;
  151. pixelsPerSecond = reads * ImgWidth * ImgHeight / seconds;
  152. printf("Result: %d reads in %f seconds = %f pixels/sec\n",
  153. reads, seconds, pixelsPerSecond);
  154. Benchmark = GL_FALSE;
  155. }
  156. else {
  157. /* clear the temporary image to white (helpful for debugging */
  158. memset(TempImage, 255, ImgWidth * ImgHeight * 4);
  159. #if 1
  160. glReadPixels(APosX, APosY, ImgWidth, ImgHeight,
  161. ReadFormat, ReadType, TempImage);
  162. (void) ComplexReadPixels;
  163. #else
  164. /* you might use this when debugging */
  165. ComplexReadPixels(APosX, APosY, ImgWidth, ImgHeight,
  166. ReadFormat, ReadType, TempImage);
  167. #endif
  168. }
  169. glRasterPos2i(BPosX, BPosY);
  170. glDisable(GL_DITHER);
  171. SetupPixelTransfer(GL_FALSE);
  172. glDrawPixels(ImgWidth, ImgHeight, ReadFormat, ReadType, TempImage);
  173. /* do copypixels */
  174. glRasterPos2i(CPosX, 5);
  175. PrintString("CopyPixels");
  176. glRasterPos2i(CPosX, CPosY);
  177. glDisable(GL_DITHER);
  178. SetupPixelTransfer(ScaleAndBias);
  179. glCopyPixels(APosX, APosY, ImgWidth, ImgHeight, GL_COLOR);
  180. if (!DrawFront)
  181. glutSwapBuffers();
  182. else
  183. glFinish();
  184. }
  185. static void
  186. Reshape( int width, int height )
  187. {
  188. glViewport( 0, 0, width, height );
  189. glMatrixMode( GL_PROJECTION );
  190. glLoadIdentity();
  191. glOrtho( 0.0, width, 0.0, height, -1.0, 1.0 );
  192. glMatrixMode( GL_MODELVIEW );
  193. glLoadIdentity();
  194. }
  195. static void
  196. Key( unsigned char key, int x, int y )
  197. {
  198. (void) x;
  199. (void) y;
  200. switch (key) {
  201. case 'b':
  202. Benchmark = GL_TRUE;
  203. break;
  204. case 's':
  205. ScaleAndBias = !ScaleAndBias;
  206. break;
  207. case 'f':
  208. DrawFront = !DrawFront;
  209. if (DrawFront) {
  210. glDrawBuffer(GL_FRONT);
  211. glReadBuffer(GL_FRONT);
  212. }
  213. else {
  214. glDrawBuffer(GL_BACK);
  215. glReadBuffer(GL_BACK);
  216. }
  217. printf("glDrawBuffer(%s)\n", DrawFront ? "GL_FRONT" : "GL_BACK");
  218. break;
  219. case 27:
  220. exit(0);
  221. break;
  222. }
  223. glutPostRedisplay();
  224. }
  225. static void
  226. Init( GLboolean ciMode )
  227. {
  228. GLboolean have_read_format = GL_FALSE;
  229. printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
  230. printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
  231. Image = LoadRGBImage( IMAGE_FILE, &ImgWidth, &ImgHeight, &ImgFormat );
  232. if (!Image) {
  233. printf("Couldn't read %s\n", IMAGE_FILE);
  234. exit(0);
  235. }
  236. if (ciMode) {
  237. /* Convert RGB image to grayscale */
  238. GLubyte *indexImage = (GLubyte *) malloc( ImgWidth * ImgHeight );
  239. GLint i;
  240. for (i=0; i<ImgWidth*ImgHeight; i++) {
  241. int gray = Image[i*3] + Image[i*3+1] + Image[i*3+2];
  242. indexImage[i] = gray / 3;
  243. }
  244. free(Image);
  245. Image = indexImage;
  246. ImgFormat = GL_COLOR_INDEX;
  247. for (i=0;i<255;i++) {
  248. float g = i / 255.0;
  249. glutSetColor(i, g, g, g);
  250. }
  251. }
  252. #ifdef GL_OES_read_format
  253. if ( glutExtensionSupported( "GL_OES_read_format" ) ) {
  254. glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE_OES, (GLint *) &ReadType);
  255. glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES, (GLint *) &ReadFormat);
  256. have_read_format = GL_TRUE;
  257. }
  258. #endif
  259. printf( "GL_OES_read_format %ssupported. "
  260. "Using type / format = 0x%04x / 0x%04x\n",
  261. (have_read_format) ? "" : "not ",
  262. ReadType, ReadFormat );
  263. printf("Loaded %d by %d image\n", ImgWidth, ImgHeight );
  264. glPixelStorei(GL_UNPACK_ROW_LENGTH, ImgWidth);
  265. glPixelStorei(GL_PACK_ROW_LENGTH, ImgWidth);
  266. Reset();
  267. /* allocate large TempImage to store and image data type, plus an
  268. * extra 1KB in case we're tinkering with pack alignment.
  269. */
  270. TempImage = (GLubyte *) malloc(ImgWidth * ImgHeight * 4 * 4
  271. + 1000);
  272. assert(TempImage);
  273. }
  274. int
  275. main( int argc, char *argv[] )
  276. {
  277. GLboolean ciMode = GL_FALSE;
  278. if (argc > 1 && strcmp(argv[1], "-ci")==0) {
  279. ciMode = GL_TRUE;
  280. }
  281. glutInit( &argc, argv );
  282. glutInitWindowPosition( 0, 0 );
  283. glutInitWindowSize( 750, 250 );
  284. if (ciMode)
  285. glutInitDisplayMode( GLUT_INDEX | GLUT_DOUBLE );
  286. else
  287. glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
  288. glutCreateWindow(argv[0]);
  289. Init(ciMode);
  290. glutReshapeFunc( Reshape );
  291. glutKeyboardFunc( Key );
  292. glutDisplayFunc( Display );
  293. glutMainLoop();
  294. return 0;
  295. }