1 /*
2  * GL_EXT_pixel_buffer_object test
3  *
4  * Brian Paul
5  * 11 March 2004
6  */
7 
8 
9 #include <assert.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <math.h>
13 #include <glad/glad.h>
14 #include "glut_wrap.h"
15 
16 #include "../util/readtex.c"  /* a hack, I know */
17 
18 #define IMAGE_FILE DEMOS_DATA_DIR "girl.rgb"
19 
20 static int ImgWidth, ImgHeight;
21 static GLenum ImgFormat;
22 static GLubyte *Image = NULL;
23 
24 static int APosX, APosY;  /* simple drawpixels */
25 static int BPosX, BPosY;  /* read/draw pixels */
26 static int CPosX, CPosY;  /* copypixels */
27 
28 static GLboolean DrawFront = GL_FALSE;
29 static GLboolean ScaleAndBias = GL_FALSE;
30 static GLboolean Benchmark = GL_FALSE;
31 
32 static GLuint DrawPBO, TempPBO;
33 
34 
35 static GLenum ReadFormat = GL_BGRA;
36 static GLenum ReadType = GL_UNSIGNED_INT_8_8_8_8_REV;
37 
38 
39 
40 static void
CheckError(int line)41 CheckError(int line)
42 {
43    GLenum err = glGetError();
44    if (err) {
45       printf("GL Error 0x%x at line %d\n", (int) err, line);
46    }
47 }
48 
49 
50 static void
Reset(void)51 Reset( void )
52 {
53    APosX = 5;     APosY = 20;
54    BPosX = APosX + ImgWidth + 5;   BPosY = 20;
55    CPosX = BPosX + ImgWidth + 5;   CPosY = 20;
56 }
57 
58 
59 static void
PrintString(const char * s)60 PrintString(const char *s)
61 {
62    while (*s) {
63       glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
64       s++;
65    }
66 }
67 
68 
69 static void
SetupPixelTransfer(GLboolean invert)70 SetupPixelTransfer(GLboolean invert)
71 {
72    if (invert) {
73       glPixelTransferf(GL_RED_SCALE, -1.0);
74       glPixelTransferf(GL_RED_BIAS, 1.0);
75       glPixelTransferf(GL_GREEN_SCALE, -1.0);
76       glPixelTransferf(GL_GREEN_BIAS, 1.0);
77       glPixelTransferf(GL_BLUE_SCALE, -1.0);
78       glPixelTransferf(GL_BLUE_BIAS, 1.0);
79    }
80    else {
81       glPixelTransferf(GL_RED_SCALE, 1.0);
82       glPixelTransferf(GL_RED_BIAS, 0.0);
83       glPixelTransferf(GL_GREEN_SCALE, 1.0);
84       glPixelTransferf(GL_GREEN_BIAS, 0.0);
85       glPixelTransferf(GL_BLUE_SCALE, 1.0);
86       glPixelTransferf(GL_BLUE_BIAS, 0.0);
87    }
88 }
89 
90 
91 static void
Display(void)92 Display( void )
93 {
94    glClearColor(.3, .3, .3, 1);
95    glClear( GL_COLOR_BUFFER_BIT );
96 
97    CheckError(__LINE__);
98 
99    /** Unbind UNPACK pixel buffer before calling glBitmap */
100    glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0);
101 
102    glRasterPos2i(5, ImgHeight+25);
103    PrintString("f = toggle front/back  s = toggle scale/bias  b = benchmark");
104 
105    glRasterPos2i(5, ImgHeight+40);
106    PrintString("GL_EXT_pixel_buffer_object test");
107 
108    /* draw original image */
109    glRasterPos2i(APosX, 5);
110    PrintString("Original");
111    glRasterPos2i(APosX, APosY);
112    glEnable(GL_DITHER);
113    SetupPixelTransfer(GL_FALSE);
114    /*** Draw from the DrawPBO */
115    glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, DrawPBO);
116    glDrawPixels(ImgWidth, ImgHeight, ImgFormat, GL_UNSIGNED_BYTE, 0);
117    glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0);
118 
119    CheckError(__LINE__);
120 
121    /* do readpixels, drawpixels */
122    glRasterPos2i(BPosX, 5);
123    PrintString("Read/DrawPixels");
124    SetupPixelTransfer(ScaleAndBias);
125    /*** read into the Temp PBO */
126    glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, TempPBO);
127    CheckError(__LINE__);
128    if (Benchmark) {
129       GLint reads = 0;
130       GLint endTime;
131       GLint startTime = glutGet(GLUT_ELAPSED_TIME);
132       GLdouble seconds, pixelsPerSecond;
133       printf("Benchmarking...\n");
134       do {
135          glReadPixels(APosX, APosY, ImgWidth, ImgHeight,
136                       ReadFormat, ReadType, 0);
137          reads++;
138          endTime = glutGet(GLUT_ELAPSED_TIME);
139       } while (endTime - startTime < 4000);   /* 4 seconds */
140       seconds = (double) (endTime - startTime) / 1000.0;
141       pixelsPerSecond = reads * ImgWidth * ImgHeight / seconds;
142       printf("Result:  %d reads in %f seconds = %f pixels/sec\n",
143              reads, seconds, pixelsPerSecond);
144       Benchmark = GL_FALSE;
145    }
146    else {
147       glReadPixels(APosX, APosY, ImgWidth, ImgHeight,
148                    ReadFormat, ReadType, 0);
149    }
150    CheckError(__LINE__);
151    glRasterPos2i(BPosX, BPosY);
152    glDisable(GL_DITHER);
153    SetupPixelTransfer(GL_FALSE);
154 
155    CheckError(__LINE__);
156 
157    /*** draw from the Temp PBO */
158    glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, TempPBO);
159    glDrawPixels(ImgWidth, ImgHeight, ReadFormat, ReadType, 0);
160    glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0);
161 
162    CheckError(__LINE__);
163 
164    /* do copypixels */
165    glRasterPos2i(CPosX, 5);
166    PrintString("CopyPixels");
167    glRasterPos2i(CPosX, CPosY);
168    glDisable(GL_DITHER);
169    SetupPixelTransfer(ScaleAndBias);
170    glCopyPixels(APosX, APosY, ImgWidth, ImgHeight, GL_COLOR);
171 
172    CheckError(__LINE__);
173 
174    if (!DrawFront)
175       glutSwapBuffers();
176    else
177       glFinish();
178 }
179 
180 
181 static void
Reshape(int width,int height)182 Reshape( int width, int height )
183 {
184    glViewport( 0, 0, width, height );
185    glMatrixMode( GL_PROJECTION );
186    glLoadIdentity();
187    glOrtho( 0.0, width, 0.0, height, -1.0, 1.0 );
188    glMatrixMode( GL_MODELVIEW );
189    glLoadIdentity();
190 }
191 
192 
193 static void
Key(unsigned char key,int x,int y)194 Key( unsigned char key, int x, int y )
195 {
196    (void) x;
197    (void) y;
198    switch (key) {
199       case 'b':
200          Benchmark = GL_TRUE;
201          break;
202       case 's':
203          ScaleAndBias = !ScaleAndBias;
204          break;
205       case 'f':
206          DrawFront = !DrawFront;
207          if (DrawFront) {
208             glDrawBuffer(GL_FRONT);
209             glReadBuffer(GL_FRONT);
210          }
211          else {
212             glDrawBuffer(GL_BACK);
213             glReadBuffer(GL_BACK);
214          }
215          printf("glDrawBuffer(%s)\n", DrawFront ? "GL_FRONT" : "GL_BACK");
216          break;
217       case 27:
218          exit(0);
219          break;
220    }
221    glutPostRedisplay();
222 }
223 
224 
225 static void
Init(void)226 Init(void)
227 {
228    printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
229    printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
230 
231    if (!glutExtensionSupported("GL_EXT_pixel_buffer_object")) {
232       printf("Sorry, this demo requires GL_EXT_pixel_buffer_object\n");
233       exit(0);
234    }
235 
236    Image = LoadRGBImage( IMAGE_FILE, &ImgWidth, &ImgHeight, &ImgFormat );
237    if (!Image) {
238       printf("Couldn't read %s\n", IMAGE_FILE);
239       exit(0);
240    }
241 
242    printf("Loaded %d by %d image\n", ImgWidth, ImgHeight );
243 
244    if (ImgFormat == GL_RGB) {
245       /* convert to RGBA */
246       int i;
247       GLubyte *image2 = (GLubyte *) malloc(ImgWidth * ImgHeight * 4);
248       printf("Converting RGB image to RGBA\n");
249       for (i = 0; i < ImgWidth * ImgHeight; i++) {
250          image2[i*4+0] = Image[i*3+0];
251          image2[i*4+1] = Image[i*3+1];
252          image2[i*4+2] = Image[i*3+2];
253          image2[i*4+3] = 255;
254       }
255       free(Image);
256       Image = image2;
257       ImgFormat = GL_RGBA;
258    }
259 
260    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
261    glPixelStorei(GL_UNPACK_ROW_LENGTH, ImgWidth);
262    glPixelStorei(GL_PACK_ALIGNMENT, 1);
263    glPixelStorei(GL_PACK_ROW_LENGTH, ImgWidth);
264 
265    Reset();
266 
267    /* put image into DrawPBO */
268    glGenBuffersARB(1, &DrawPBO);
269    glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, DrawPBO);
270    glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_EXT,
271                    ImgWidth * ImgHeight * 4, Image, GL_STATIC_DRAW);
272 
273    /* Setup TempPBO - used for glReadPixels & glDrawPixels */
274    glGenBuffersARB(1, &TempPBO);
275    glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, TempPBO);
276    glBufferDataARB(GL_PIXEL_PACK_BUFFER_EXT,
277                    ImgWidth * ImgHeight * 4, NULL, GL_DYNAMIC_COPY);
278 
279 }
280 
281 
282 int
main(int argc,char * argv[])283 main( int argc, char *argv[] )
284 {
285    glutInit( &argc, argv );
286    glutInitWindowPosition( 0, 0 );
287    glutInitWindowSize( 750, 250 );
288    glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
289    glutCreateWindow(argv[0]);
290    gladLoadGL();
291    Init();
292    glutReshapeFunc( Reshape );
293    glutKeyboardFunc( Key );
294    glutDisplayFunc( Display );
295    glutMainLoop();
296    return 0;
297 }
298