Clone of mesa.
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

readpix.c 8.9KB

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