-/* $Id: readpix.c,v 1.3 2000/03/31 01:01:31 brianp Exp $ */
/*
* glReadPixels and glCopyPixels test
* Brian Paul March 1, 2000 This file is in the public domain.
*/
-/*
- * $Log: readpix.c,v $
- * Revision 1.3 2000/03/31 01:01:31 brianp
- * tweaks to allow different read formats/types
- *
- * Revision 1.2 2000/03/23 19:47:25 brianp
- * added benchmarking
- *
- * Revision 1.1 2000/03/01 16:23:14 brianp
- * test glDraw/Read/CopyPixels()
- *
- */
-
-
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
+#include <string.h>
#include <GL/glut.h>
-#include "../util/readtex.c" /* a hack, I know */
+#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 GLboolean DrawFront = GL_FALSE;
static GLboolean ScaleAndBias = GL_FALSE;
static GLboolean Benchmark = GL_FALSE;
+static GLboolean Triangle = GL_FALSE;
static GLubyte *TempImage = NULL;
-#if 1
+#define COMBO 1
+#if COMBO == 0
#define ReadFormat ImgFormat
#define ReadType GL_UNSIGNED_BYTE
-#endif
-#if 0
+#elif COMBO == 1
static GLenum ReadFormat = GL_RGBA;
static GLenum ReadType = GL_UNSIGNED_BYTE;
-#endif
-#if 0
+#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
}
+/**
+ * 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);
/* draw original image */
glRasterPos2i(APosX, 5);
PrintString("Original");
- glRasterPos2i(APosX, APosY);
- glEnable(GL_DITHER);
- SetupPixelTransfer(GL_FALSE);
- glDrawPixels(ImgWidth, ImgHeight, ImgFormat, GL_UNSIGNED_BYTE, Image);
+ 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);
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);
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();
case 'b':
Benchmark = GL_TRUE;
break;
+ case 't':
+ Triangle = !Triangle;
+ break;
case 's':
ScaleAndBias = !ScaleAndBias;
break;
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));
if (ciMode) {
/* Convert RGB image to grayscale */
- GLubyte *indexImage = malloc( ImgWidth * ImgHeight );
+ 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];
}
}
+#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_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_ROW_LENGTH, ImgWidth);
- glPixelStorei(GL_PACK_ALIGNMENT, 1);
glPixelStorei(GL_PACK_ROW_LENGTH, ImgWidth);
Reset();
- TempImage = (GLubyte *) malloc(ImgWidth * ImgHeight * 4 * sizeof(GLubyte));
+ /* 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);
}