
/*
 * glReadPixels and glCopyPixels test
 * 
 * Brian Paul   March 1, 2000  This file is in the public domain.
 */

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <GL/glut.h>

#include "readtex.h"

#define IMAGE_FILE "../images/girl.rgb"

static int ImgWidth, ImgHeight;
static int WinWidth, WinHeight;
static GLenum ImgFormat;
static GLubyte *Image = NULL;

static int APosX, APosY;  /* simple drawpixels */
static int BPosX, BPosY;  /* read/draw pixels */
static int CPosX, CPosY;  /* copypixels */

static GLboolean DrawFront = GL_FALSE;
static GLboolean ScaleAndBias = GL_FALSE;
static GLboolean Benchmark = GL_FALSE;
static GLboolean Triangle = GL_FALSE;
static GLubyte *TempImage = NULL;

#define COMBO 1
#if COMBO == 0
#define ReadFormat ImgFormat
#define ReadType GL_UNSIGNED_BYTE
#elif COMBO == 1
static GLenum ReadFormat = GL_RGBA;
static GLenum ReadType = GL_UNSIGNED_BYTE;
#elif COMBO == 2
static GLenum ReadFormat = GL_RGB;
static GLenum ReadType = GL_UNSIGNED_BYTE;
#elif COMBO == 3
static GLenum ReadFormat = GL_RGB;
static GLenum ReadType = GL_UNSIGNED_SHORT_5_6_5;
#elif COMBO == 4
static GLenum ReadFormat = GL_RGBA;
static GLenum ReadType = GL_UNSIGNED_SHORT_1_5_5_5_REV;
#elif COMBO == 5
static GLenum ReadFormat = GL_BGRA;
static GLenum ReadType = GL_UNSIGNED_SHORT_5_5_5_1;
#elif COMBO == 6
static GLenum ReadFormat = GL_BGRA;
static GLenum ReadType = GL_UNSIGNED_SHORT_4_4_4_4_REV;
#elif COMBO == 7
static GLenum ReadFormat = GL_RGBA;
static GLenum ReadType = GL_HALF_FLOAT_ARB;
#undef GL_OES_read_format
#endif


static void
Reset( void )
{
   APosX = 5;     APosY = 20;
   BPosX = APosX + ImgWidth + 5;   BPosY = 20;
   CPosX = BPosX + ImgWidth + 5;   CPosY = 20;
}


static void
PrintString(const char *s)
{
   while (*s) {
      glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
      s++;
   }
}


static void
SetupPixelTransfer(GLboolean invert)
{
   if (invert) {
      glPixelTransferf(GL_RED_SCALE, -1.0);
      glPixelTransferf(GL_RED_BIAS, 1.0);
      glPixelTransferf(GL_GREEN_SCALE, -1.0);
      glPixelTransferf(GL_GREEN_BIAS, 1.0);
      glPixelTransferf(GL_BLUE_SCALE, -1.0);
      glPixelTransferf(GL_BLUE_BIAS, 1.0);
   }
   else {
      glPixelTransferf(GL_RED_SCALE, 1.0);
      glPixelTransferf(GL_RED_BIAS, 0.0);
      glPixelTransferf(GL_GREEN_SCALE, 1.0);
      glPixelTransferf(GL_GREEN_BIAS, 0.0);
      glPixelTransferf(GL_BLUE_SCALE, 1.0);
      glPixelTransferf(GL_BLUE_BIAS, 0.0);
   }
}


/**
 * Exercise Pixel Pack parameters by reading the image in four pieces.
 */
static void
ComplexReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
                  GLenum format, GLenum type, GLvoid *pixels)
{
   const GLsizei width0 = width / 2;
   const GLsizei width1 = width - width0;
   const GLsizei height0 = height / 2;
   const GLsizei height1 = height - height0;

   glPixelStorei(GL_PACK_ROW_LENGTH, width);

   /* lower-left quadrant */
   glReadPixels(x, y, width0, height0, format, type, pixels);

   /* lower-right quadrant */
   glPixelStorei(GL_PACK_SKIP_PIXELS, width0);
   glReadPixels(x + width0, y, width1, height0, format, type, pixels);

   /* upper-left quadrant */
   glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
   glPixelStorei(GL_PACK_SKIP_ROWS, height0);
   glReadPixels(x, y + height0, width0, height1, format, type, pixels);

   /* upper-right quadrant */
   glPixelStorei(GL_PACK_SKIP_PIXELS, width0);
   glPixelStorei(GL_PACK_SKIP_ROWS, height0);
   glReadPixels(x + width0, y + height0, width1, height1, format, type, pixels);

   /* restore defaults */
   glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
   glPixelStorei(GL_PACK_SKIP_ROWS, 0);
   glPixelStorei(GL_PACK_ROW_LENGTH, ImgWidth);
}



static void
Display( void )
{
   glClearColor(.3, .3, .3, 1);
   glClear( GL_COLOR_BUFFER_BIT );

   glRasterPos2i(5, ImgHeight+25);
   PrintString("f = toggle front/back  s = toggle scale/bias  b = benchmark");

   /* draw original image */
   glRasterPos2i(APosX, 5);
   PrintString("Original");
   if (!Triangle) {
      glRasterPos2i(APosX, APosY);
      glEnable(GL_DITHER);
      SetupPixelTransfer(GL_FALSE);
      glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
      glDrawPixels(ImgWidth, ImgHeight, ImgFormat, GL_UNSIGNED_BYTE, Image);
   }
   else {
      float z = 0;

      glViewport(APosX, APosY, ImgWidth, ImgHeight);
      glMatrixMode( GL_PROJECTION );
      glLoadIdentity();
      glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
      glDisable(GL_CULL_FACE);

      /* Red should never be seen
       */
      glBegin(GL_POLYGON);
      glColor3f(1,0,0); 
      glVertex3f(-2, -2, z);
      glVertex3f(-2, 2, z);
      glVertex3f(2, 2, z);
      glVertex3f(2, -2, z);
      glEnd();

      /* Blue background
       */
      glBegin(GL_POLYGON);
      glColor3f(.5,.5,1); 
      glVertex3f(-1, -1, z);
      glVertex3f(-1, 1, z);
      glVertex3f(1, 1, z);
      glVertex3f(1, -1, z);
      glEnd();

      /* Triangle
       */
      glBegin(GL_TRIANGLES);
      glColor3f(.8,0,0); 
      glVertex3f(-0.9, -0.9, z);
      glColor3f(0,.9,0); 
      glVertex3f( 0.9, -0.9, z);
      glColor3f(0,0,.7); 
      glVertex3f( 0.0,  0.9, z);
      glEnd();
      
      glColor3f(1,1,1);

      glViewport( 0, 0, WinWidth, WinHeight );
      glMatrixMode( GL_PROJECTION );
      glLoadIdentity();
      glOrtho( 0.0, WinWidth, 0.0, WinHeight, -1.0, 1.0 );
   }

   /* might try alignment=4 here for testing */
   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   glPixelStorei(GL_PACK_ALIGNMENT, 1);

   /* do readpixels, drawpixels */
   glRasterPos2i(BPosX, 5);
   PrintString("Read/DrawPixels");
   SetupPixelTransfer(ScaleAndBias);
   if (Benchmark) {
      GLint reads = 0;
      GLint endTime;
      GLint startTime = glutGet(GLUT_ELAPSED_TIME);
      GLdouble seconds, mpixels, mpixelsPerSecond;
      printf("Benchmarking...\n");
      do {
         glReadPixels(APosX, APosY, ImgWidth, ImgHeight,
                      ReadFormat, ReadType, TempImage);
         reads++;
         endTime = glutGet(GLUT_ELAPSED_TIME);
      } while (endTime - startTime < 4000);   /* 4 seconds */
      seconds = (double) (endTime - startTime) / 1000.0;
      mpixels = reads * (ImgWidth * ImgHeight / (1000.0 * 1000.0));
      mpixelsPerSecond = mpixels / seconds;
      printf("Result:  %d reads in %f seconds = %f Mpixels/sec\n",
             reads, seconds, mpixelsPerSecond);
      Benchmark = GL_FALSE;
   }
   else {
      /* clear the temporary image to white (helpful for debugging */
      memset(TempImage, 255, ImgWidth * ImgHeight * 4);
#if 1
      glReadPixels(APosX, APosY, ImgWidth, ImgHeight,
                   ReadFormat, ReadType, TempImage);
      (void) ComplexReadPixels;
#else
      /* you might use this when debugging */
      ComplexReadPixels(APosX, APosY, ImgWidth, ImgHeight,
                        ReadFormat, ReadType, TempImage);
#endif
   }
   glRasterPos2i(BPosX, BPosY);
   glDisable(GL_DITHER);
   SetupPixelTransfer(GL_FALSE);
   glDrawPixels(ImgWidth, ImgHeight, ReadFormat, ReadType, TempImage);

   /* do copypixels */
   glRasterPos2i(CPosX, 5);
   PrintString("CopyPixels");
   glRasterPos2i(CPosX, CPosY);
   glDisable(GL_DITHER);
   SetupPixelTransfer(ScaleAndBias);
   glCopyPixels(APosX, APosY, ImgWidth, ImgHeight, GL_COLOR);

   if (!DrawFront)
      glutSwapBuffers();
   else
      glFinish();
}


static void
Reshape( int width, int height )
{
   WinWidth = width;
   WinHeight = height;

   glViewport( 0, 0, width, height );
   glMatrixMode( GL_PROJECTION );
   glLoadIdentity();
   glOrtho( 0.0, width, 0.0, height, -1.0, 1.0 );
   glMatrixMode( GL_MODELVIEW );
   glLoadIdentity();
}


static void
Key( unsigned char key, int x, int y )
{
   (void) x;
   (void) y;
   switch (key) {
      case 'b':
         Benchmark = GL_TRUE;
         break;
      case 't':
         Triangle = !Triangle;
         break;
      case 's':
         ScaleAndBias = !ScaleAndBias;
         break;
      case 'f':
         DrawFront = !DrawFront;
         if (DrawFront) {
            glDrawBuffer(GL_FRONT);
            glReadBuffer(GL_FRONT);
         }
         else {
            glDrawBuffer(GL_BACK);
            glReadBuffer(GL_BACK);
         }
         printf("glDrawBuffer(%s)\n", DrawFront ? "GL_FRONT" : "GL_BACK");
         break;
      case 27:
         exit(0);
         break;
   }
   glutPostRedisplay();
}


static void
Init( GLboolean ciMode )
{
   GLboolean have_read_format = GL_FALSE;

   printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
   printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));

   Image = LoadRGBImage( IMAGE_FILE, &ImgWidth, &ImgHeight, &ImgFormat );
   if (!Image) {
      printf("Couldn't read %s\n", IMAGE_FILE);
      exit(0);
   }

   if (ciMode) {
      /* Convert RGB image to grayscale */
      GLubyte *indexImage = (GLubyte *) malloc( ImgWidth * ImgHeight );
      GLint i;
      for (i=0; i<ImgWidth*ImgHeight; i++) {
         int gray = Image[i*3] + Image[i*3+1] + Image[i*3+2];
         indexImage[i] = gray / 3;
      }
      free(Image);
      Image = indexImage;
      ImgFormat = GL_COLOR_INDEX;

      for (i=0;i<255;i++) {
         float g = i / 255.0;
         glutSetColor(i, g, g, g);
      }
   }

#ifdef GL_OES_read_format
   if ( glutExtensionSupported( "GL_OES_read_format" ) ) {
      glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE_OES,   (GLint *) &ReadType);
      glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES, (GLint *) &ReadFormat);

      have_read_format = GL_TRUE;
   }
#endif

   printf( "GL_OES_read_format %ssupported.  "
	   "Using type / format = 0x%04x / 0x%04x\n",
	   (have_read_format) ? "" : "not ",
	   ReadType, ReadFormat );

   printf("Loaded %d by %d image\n", ImgWidth, ImgHeight );

   glPixelStorei(GL_UNPACK_ROW_LENGTH, ImgWidth);
   glPixelStorei(GL_PACK_ROW_LENGTH, ImgWidth);

   Reset();

   /* allocate large TempImage to store and image data type, plus an
    * extra 1KB in case we're tinkering with pack alignment.
    */
   TempImage = (GLubyte *) malloc(ImgWidth * ImgHeight * 4 * 4
                                  + 1000);
   assert(TempImage);
}


int
main( int argc, char *argv[] )
{
   GLboolean ciMode = GL_FALSE;
   glutInitWindowSize( 750, 250 );
   glutInit( &argc, argv );
   if (argc > 1 && strcmp(argv[1], "-ci")==0) {
      ciMode = GL_TRUE;
   }
   if (ciMode)
      glutInitDisplayMode( GLUT_INDEX | GLUT_DOUBLE );
   else
      glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
   glutCreateWindow(argv[0]);
   Init(ciMode);
   glutReshapeFunc( Reshape );
   glutKeyboardFunc( Key );
   glutDisplayFunc( Display );
   glutMainLoop();
   return 0;
}
