2 /* Pixeltest for lines.
6 * glReadPixels and glCopyPixels test by Brian Paul.
14 #include <GL/glew.h> /* for GL_UNSIGNED_SHORT_5_6_5 */
15 #include "glut_wrap.h"
18 static int ImgWidth
, ImgHeight
;
19 static int WinWidth
, WinHeight
;
21 static int APosX
, APosY
; /* simple drawpixels */
22 static int BPosX
, BPosY
; /* read/draw pixels */
23 int MouseButton
, MouseY
, MouseX
; /* mouse control */
24 float x0offset
= 0.0f
; /* for line translation */
25 float y0offset
= 0.0f
;
26 float x1offset
= 0.0f
;
27 float y1offset
= 0.0f
;
37 #define STEP 16 /* subpixel resolution 1/STEP */
38 #define SIZE 128 /* of non-zoomed drawing region */
39 #define ZOOM 32 /* scale factor for zooming */
42 static GLboolean DrawFront
= GL_FALSE
;
43 GLushort TempImage
[SIZE
][SIZE
]; /* original 128 by 128 pixel image */
44 GLushort myImage
[SIZE
*ZOOM
][SIZE
*ZOOM
]; /* zoom by a factor of 32 */
46 static GLenum ReadFormat
= GL_RGB
;
47 static GLenum ReadType
= GL_UNSIGNED_SHORT_5_6_5
;
52 APosX
= 8; APosY
= 24;
53 MouseX
= 8; MouseY
= 24;
54 BPosX
= APosX
+ ImgWidth
+ 40; BPosY
= 24;
59 PrintString(const char *s
)
62 glutBitmapCharacter(GLUT_BITMAP_8_BY_13
, (int) *s
);
68 drawzoomline(int x0
, int y0
, int x1
, int y1
, GLushort color
)
70 /* Use the Bresenham Line Algorithm here. */
71 GLboolean steep
= (abs(y1
- y0
) > abs(x1
- x0
));
98 deltay
= abs(y1
- y0
);
100 deltaerr
= (float)deltay
/ (float)deltax
;
108 for (x
= x0
; x
< x1
; x
++) {
111 myImage
[y
][x
] = color
;
112 myImage
[y
+1][x
] = color
;
115 myImage
[x
][y
] = color
;
116 myImage
[x
+1][y
] = color
;
119 error
= error
+ deltaerr
;
128 drawline(float xf0
, float yf0
, float xf1
, float yf1
, GLushort color
)
130 /* map line endpoints on to relevant pixel grids */
136 drawzoomline(x0
, y0
, x1
, y1
, color
);
140 plot(int x
, int y
, GLushort color
)
144 for (i
=0; i
<ZOOM
; i
++) {
145 for (j
=0; j
<ZOOM
; j
++) {
146 if (i
== 0 || j
== 0) {
147 /* draws the gridlines, use top-left rule */
148 myImage
[x
*ZOOM
+i
][y
*ZOOM
+j
] = 0;
150 else if ((i
>= 13 && i
<= 19 && j
== 16 ) || (j
>= 13 && j
<= 19 && i
== 16) ){
151 /* draws the pixel centre */
152 myImage
[x
*ZOOM
+i
][y
*ZOOM
+j
] = 0;
154 else if ( (i
+ j
== 15) || fabsf(i
- j
) == 16 || (i
+ j
== 47) ){
155 /* draws the pixel diamond, to test diamond exit rule */
156 myImage
[x
*ZOOM
+i
][y
*ZOOM
+j
] = 0;
159 myImage
[x
*ZOOM
+i
][y
*ZOOM
+j
]= color
;
166 drawMagnifiedView(void)
168 float halfwidth
= width
/2;
171 /* Sets up pixel grid for each pixel
173 for (i
=0; i
<128; i
++){
174 for (j
=0; j
<128; j
++){
175 plot(i
, j
, TempImage
[i
][j
]);
179 /* Draws the actual line on zoomed version */
180 drawline(line
.x0
+x0offset
+APosX
-MouseX
, line
.y0
+y0offset
+APosY
-MouseY
,
181 line
.x1
+x1offset
+APosX
-MouseX
, line
.y1
+y1offset
+APosY
-MouseY
, 0);
183 /* Draws bounding line area */
184 if (fabsf(line
.x0
+ x0offset
- line
.x1
- x1offset
) >=
185 fabsf(line
.y0
+ y0offset
- line
.y1
- y1offset
)) {
187 drawline(line
.x0
+x0offset
+APosX
-MouseX
, line
.y0
+y0offset
+APosY
-MouseY
+halfwidth
,
188 line
.x1
+x1offset
+APosX
-MouseX
, line
.y1
+y1offset
+APosY
-MouseY
+halfwidth
, 0xffff);
189 drawline(line
.x0
+x0offset
+APosX
-MouseX
, line
.y0
+y0offset
+APosY
-MouseY
-halfwidth
,
190 line
.x1
+x1offset
+APosX
-MouseX
, line
.y1
+y1offset
+APosY
-MouseY
-halfwidth
, 0xffff);
191 drawline(line
.x0
+x0offset
+APosX
-MouseX
, line
.y0
+y0offset
+APosY
-MouseY
+halfwidth
,
192 line
.x0
+x0offset
+APosX
-MouseX
, line
.y0
+y0offset
+APosY
-MouseY
-halfwidth
, 0xffff);
193 drawline(line
.x1
+x1offset
+APosX
-MouseX
, line
.y1
+y1offset
+APosY
-MouseY
+halfwidth
,
194 line
.x1
+x1offset
+APosX
-MouseX
, line
.y1
+y1offset
+APosY
-MouseY
-halfwidth
, 0xffff);
198 drawline(line
.x0
+x0offset
+APosX
-MouseX
+halfwidth
, line
.y0
+y0offset
+APosY
-MouseY
,
199 line
.x1
+x1offset
+APosX
-MouseX
+halfwidth
, line
.y1
+y1offset
+APosY
-MouseY
, 0xffff);
200 drawline(line
.x0
+x0offset
+APosX
-MouseX
-halfwidth
, line
.y0
+y0offset
+APosY
-MouseY
,
201 line
.x1
+x1offset
+APosX
-MouseX
-halfwidth
, line
.y1
+y1offset
+APosY
-MouseY
, 0xffff);
202 drawline(line
.x0
+x0offset
+APosX
-MouseX
+halfwidth
, line
.y0
+y0offset
+APosY
-MouseY
,
203 line
.x0
+x0offset
+APosX
-MouseX
-halfwidth
, line
.y0
+y0offset
+APosY
-MouseY
, 0xffff);
204 drawline(line
.x1
+x1offset
+APosX
-MouseX
+halfwidth
, line
.y1
+y1offset
+APosY
-MouseY
,
205 line
.x1
+x1offset
+APosX
-MouseX
-halfwidth
, line
.y1
+y1offset
+APosY
-MouseY
, 0xffff);
214 glClearColor(.3, .3, .3, 1);
215 glClear( GL_COLOR_BUFFER_BIT
);
217 /* draw original image */
219 glViewport(APosX
, APosY
, ImgWidth
, ImgHeight
);
220 glMatrixMode( GL_PROJECTION
);
222 /* transformation to match the pixel array */
223 glOrtho(0, ImgWidth
, 0, ImgHeight
, -1.0, 1.0);
224 glDisable(GL_CULL_FACE
);
231 glVertex3f(0, 150, z
);
232 glVertex3f(150, 150, z
);
233 glVertex3f(150, 0, z
);
241 glVertex3f(line
.x0
+x0offset
, line
.y0
+y0offset
, z
);
243 glVertex3f(line
.x1
+x1offset
, line
.y1
+y1offset
, z
);
248 glViewport( 0, 0, WinWidth
, WinHeight
);
249 glMatrixMode( GL_PROJECTION
);
251 glOrtho( 0.0, WinWidth
, 0.0, WinHeight
, -1.0, 1.0 );
253 /* might try alignment=4 here for testing */
254 glPixelStorei(GL_UNPACK_ALIGNMENT
, 1);
255 glPixelStorei(GL_PACK_ALIGNMENT
, 1);
259 glBegin(GL_LINE_STRIP
);
260 glVertex3f(590, 800, 0);
261 glVertex3f(590, 670, 0);
262 glVertex3f(990, 670, 0);
263 glVertex3f(990, 800, 0);
264 glVertex3f(590, 800, 0);
267 glRasterPos2i(600, 780);
269 glRasterPos2i(600, 760);
270 PrintString(" Change linewidth: v/b");
271 glRasterPos2i(600, 740);
272 PrintString(" Move whole line: UP/DOWN/LEFT/RIGHT arrow keys");
273 glRasterPos2i(600, 720);
274 PrintString(" Move endpoint: i/k/j/l");
275 glRasterPos2i(600, 700);
276 PrintString(" Move startpoint: w/s/a/d");
277 glRasterPos2i(600, 680);
278 PrintString(" Change view: drag/click mouse");
280 glRasterPos2i(8, ImgHeight
+30);
281 PrintString("Zoom Pixel Test");
283 glRasterPos2i(APosX
, 5);
284 PrintString("Original");
286 /* do readpixels, drawpixels */
287 glRasterPos2i(BPosX
, 5);
288 PrintString("Read/DrawPixels");
290 /* clear the temporary image to white (helpful for debugging */
291 memset(TempImage
, 255, sizeof TempImage
);
293 /* Read pixels from the color buffer */
294 glReadPixels(MouseX
, MouseY
, ImgWidth
, ImgHeight
,
295 ReadFormat
, ReadType
, TempImage
);
297 glRasterPos2i(BPosX
, BPosY
);
298 glDisable(GL_DITHER
);
301 /* Write pixels to the frame buffer */
302 glDrawPixels(ImgWidth
*5, ImgHeight
*5, ReadFormat
, ReadType
, myImage
);
312 Reshape( int width
, int height
)
317 glViewport( 0, 0, width
, height
);
318 glMatrixMode( GL_PROJECTION
);
320 glOrtho( 0.0, width
, 0.0, height
, -1.0, 1.0 );
321 glMatrixMode( GL_MODELVIEW
);
327 Key( unsigned char key
, int x
, int y
)
331 y0offset
+= 1.0/(float)STEP
;
334 y0offset
-= 1.0/(float)STEP
;
337 x0offset
+= 1.0/(float)STEP
;
340 x0offset
-= 1.0/(float)STEP
;
343 y1offset
+= 1.0/(float)STEP
;
346 y1offset
-= 1.0/(float)STEP
;
349 x1offset
+= 1.0/(float)STEP
;
352 x1offset
-= 1.0/(float)STEP
;
355 width
+= 1.0/(float) STEP
;
356 printf("width = %f\n", width
);
359 width
-= 1.0/(float) STEP
;
360 printf("width = %f\n", width
);
372 SpecialKey( int k
, int x
, int y
)
376 y0offset
+= 1.0/(float)STEP
;
377 y1offset
+= 1.0/(float)STEP
;
380 y0offset
-= 1.0/(float)STEP
;
381 y1offset
-= 1.0/(float)STEP
;
384 x0offset
+= 1.0/(float)STEP
;
385 x1offset
+= 1.0/(float)STEP
;
388 x0offset
-= 1.0/(float)STEP
;
389 x1offset
-= 1.0/(float)STEP
;
398 Mouse(int button
, int state
, int x
, int y
)
400 /* if left mouse button is pressed and dragged
401 * then change screen view
403 if (state
== GLUT_DOWN
&&
404 button
== GLUT_LEFT_BUTTON
&&
409 MouseY
= WinHeight
- y
;
415 processMouseMotion(int x
, int y
)
418 MouseY
= WinHeight
- y
;
425 printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION
));
426 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER
));
439 glutSetCursor(GLUT_CURSOR_CROSSHAIR
);
441 glPixelStorei(GL_UNPACK_ROW_LENGTH
, ImgWidth
*ZOOM
);
442 glPixelStorei(GL_PACK_ROW_LENGTH
, ImgWidth
);
449 main( int argc
, char *argv
[] )
451 glutInitWindowSize( 1000, 800 );
452 glutInit( &argc
, argv
);
454 glutInitDisplayMode( GLUT_RGB
| GLUT_DOUBLE
);
455 glutCreateWindow(argv
[0]);
457 glutReshapeFunc( Reshape
);
458 glutKeyboardFunc (Key
);
459 glutSpecialFunc(SpecialKey
);
460 glutDisplayFunc( Display
);
462 glutMouseFunc(Mouse
);
463 glutMotionFunc(processMouseMotion
);