|
|
@@ -0,0 +1,270 @@ |
|
|
|
/* $Id: wincopy.c,v 1.1 1999/11/25 17:41:51 brianp Exp $ */ |
|
|
|
|
|
|
|
/* |
|
|
|
* Mesa 3-D graphics library |
|
|
|
* Version: 3.3 |
|
|
|
* |
|
|
|
* Copyright (C) 1999 Brian Paul All Rights Reserved. |
|
|
|
* |
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a |
|
|
|
* copy of this software and associated documentation files (the "Software"), |
|
|
|
* to deal in the Software without restriction, including without limitation |
|
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
|
|
|
* and/or sell copies of the Software, and to permit persons to whom the |
|
|
|
* Software is furnished to do so, subject to the following conditions: |
|
|
|
* |
|
|
|
* The above copyright notice and this permission notice shall be included |
|
|
|
* in all copies or substantial portions of the Software. |
|
|
|
* |
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
|
|
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
|
|
|
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN |
|
|
|
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
|
|
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
/* |
|
|
|
* This program opens two GLX windows, renders into one and uses |
|
|
|
* glCopyPixels to copy the image from the first window into the |
|
|
|
* second by means of the GLX 1.3 function glxMakeContextCurrent(). |
|
|
|
* This function works just like the glXMakeCurrentReadSGI() function |
|
|
|
* in the GLX_SGI_make_current_read extension. |
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <GL/gl.h> |
|
|
|
#include <GL/glx.h> |
|
|
|
#include <stdio.h> |
|
|
|
#include <stdlib.h> |
|
|
|
#include <unistd.h> |
|
|
|
|
|
|
|
|
|
|
|
#ifdef GLX_VERSION_1_3 |
|
|
|
|
|
|
|
|
|
|
|
static Display *Dpy; |
|
|
|
static int ScrNum; |
|
|
|
static GLXContext Context; |
|
|
|
static Window Win[2]; /* Win[0] = source, Win[1] = dest */ |
|
|
|
static GLint Width[2], Height[2]; |
|
|
|
|
|
|
|
static GLfloat Angle = 0.0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static Window |
|
|
|
CreateWindow(Display *dpy, int scrnum, XVisualInfo *visinfo, |
|
|
|
int xpos, int ypos, int width, int height, |
|
|
|
const char *name) |
|
|
|
{ |
|
|
|
Window win; |
|
|
|
XSetWindowAttributes attr; |
|
|
|
unsigned long mask; |
|
|
|
Window root; |
|
|
|
|
|
|
|
root = RootWindow(dpy, scrnum); |
|
|
|
|
|
|
|
/* window attributes */ |
|
|
|
attr.background_pixel = 0; |
|
|
|
attr.border_pixel = 0; |
|
|
|
attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone); |
|
|
|
attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; |
|
|
|
mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; |
|
|
|
|
|
|
|
win = XCreateWindow(dpy, root, xpos, ypos, width, height, |
|
|
|
0, visinfo->depth, InputOutput, |
|
|
|
visinfo->visual, mask, &attr); |
|
|
|
if (win) { |
|
|
|
XSizeHints sizehints; |
|
|
|
sizehints.x = xpos; |
|
|
|
sizehints.y = ypos; |
|
|
|
sizehints.width = width; |
|
|
|
sizehints.height = height; |
|
|
|
sizehints.flags = USSize | USPosition; |
|
|
|
XSetNormalHints(dpy, win, &sizehints); |
|
|
|
XSetStandardProperties(dpy, win, name, name, |
|
|
|
None, (char **)NULL, 0, &sizehints); |
|
|
|
|
|
|
|
XMapWindow(dpy, win); |
|
|
|
} |
|
|
|
return win; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void |
|
|
|
Redraw(void) |
|
|
|
{ |
|
|
|
/* make the first window the current one */ |
|
|
|
if (!glXMakeContextCurrent(Dpy, Win[0], Win[0], Context)) { |
|
|
|
printf("glXMakeContextCurrent failed in Redraw()\n"); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
Angle += 1.0; |
|
|
|
|
|
|
|
glViewport(0, 0, Width[0], Height[0]); |
|
|
|
glMatrixMode(GL_PROJECTION); |
|
|
|
glLoadIdentity(); |
|
|
|
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); |
|
|
|
glMatrixMode(GL_MODELVIEW); |
|
|
|
|
|
|
|
glShadeModel(GL_FLAT); |
|
|
|
glClearColor(0.5, 0.5, 0.5, 1.0); |
|
|
|
glClear(GL_COLOR_BUFFER_BIT); |
|
|
|
|
|
|
|
/* draw blue quad */ |
|
|
|
glColor3f(0.3, 0.3, 1.0); |
|
|
|
glPushMatrix(); |
|
|
|
glRotatef(Angle, 0, 0, 1); |
|
|
|
glBegin(GL_POLYGON); |
|
|
|
glVertex2f(-0.5, -0.25); |
|
|
|
glVertex2f( 0.5, -0.25); |
|
|
|
glVertex2f( 0.5, 0.25); |
|
|
|
glVertex2f(-0.5, 0.25); |
|
|
|
glEnd(); |
|
|
|
glPopMatrix(); |
|
|
|
|
|
|
|
glXSwapBuffers(Dpy, Win[0]); |
|
|
|
|
|
|
|
|
|
|
|
/* copy image from window 0 to window 1 */ |
|
|
|
if (!glXMakeContextCurrent(Dpy, Win[1], Win[0], Context)) { |
|
|
|
printf("glXMakeContextCurrent failed in Redraw()\n"); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
/* raster pos setup */ |
|
|
|
glViewport(0, 0, Width[1], Height[1]); |
|
|
|
glPushMatrix(); |
|
|
|
glLoadIdentity(); |
|
|
|
glMatrixMode(GL_PROJECTION); |
|
|
|
glPushMatrix(); |
|
|
|
glLoadIdentity(); |
|
|
|
glOrtho(-1, 1, -1, 1, -1, 1); |
|
|
|
glRasterPos2f(-1, -1); |
|
|
|
|
|
|
|
/* copy the image between windows */ |
|
|
|
glDrawBuffer(GL_FRONT); |
|
|
|
glCopyPixels(0, 0, Width[0], Height[0], GL_COLOR); |
|
|
|
glDrawBuffer(GL_BACK); |
|
|
|
|
|
|
|
glPopMatrix(); |
|
|
|
glMatrixMode(GL_MODELVIEW); |
|
|
|
glPopMatrix(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void |
|
|
|
Resize(Window win, unsigned int width, unsigned int height) |
|
|
|
{ |
|
|
|
int i; |
|
|
|
if (win == Win[0]) { |
|
|
|
i = 0; |
|
|
|
} |
|
|
|
else { |
|
|
|
i = 1; |
|
|
|
} |
|
|
|
Width[i] = width; |
|
|
|
Height[i] = height; |
|
|
|
if (!glXMakeCurrent(Dpy, Win[i], Context)) { |
|
|
|
printf("glXMakeCurrent failed in Resize()\n"); |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void |
|
|
|
EventLoop(void) |
|
|
|
{ |
|
|
|
XEvent event; |
|
|
|
while (1) { |
|
|
|
if (XPending(Dpy) > 0) { |
|
|
|
XNextEvent( Dpy, &event ); |
|
|
|
switch (event.type) { |
|
|
|
case Expose: |
|
|
|
Redraw(); |
|
|
|
break; |
|
|
|
case ConfigureNotify: |
|
|
|
Resize(event.xany.window, event.xconfigure.width, event.xconfigure.height); |
|
|
|
break; |
|
|
|
case KeyPress: |
|
|
|
return; |
|
|
|
default: |
|
|
|
/*no-op*/ ; |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
/* animate */ |
|
|
|
Redraw(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void |
|
|
|
Init(void) |
|
|
|
{ |
|
|
|
XVisualInfo *visinfo; |
|
|
|
int attrib[] = { GLX_RGBA, |
|
|
|
GLX_RED_SIZE, 1, |
|
|
|
GLX_GREEN_SIZE, 1, |
|
|
|
GLX_BLUE_SIZE, 1, |
|
|
|
GLX_DOUBLEBUFFER, |
|
|
|
None }; |
|
|
|
|
|
|
|
Dpy = XOpenDisplay(NULL); |
|
|
|
if (!Dpy) { |
|
|
|
printf("Couldn't open default display!\n"); |
|
|
|
exit(1); |
|
|
|
} |
|
|
|
|
|
|
|
ScrNum = DefaultScreen(Dpy); |
|
|
|
|
|
|
|
visinfo = glXChooseVisual(Dpy, ScrNum, attrib); |
|
|
|
if (!visinfo) { |
|
|
|
printf("Unable to find RGB, double-buffered visual\n"); |
|
|
|
exit(1); |
|
|
|
} |
|
|
|
|
|
|
|
Context = glXCreateContext(Dpy, visinfo, NULL, True); |
|
|
|
if (!Context) { |
|
|
|
printf("Couldn't create GLX context\n"); |
|
|
|
exit(1); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Win[0] = CreateWindow(Dpy, ScrNum, visinfo, |
|
|
|
0, 0, 300, 300, "source window"); |
|
|
|
|
|
|
|
Win[1] = CreateWindow(Dpy, ScrNum, visinfo, |
|
|
|
350, 0, 300, 300, "dest window"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int |
|
|
|
main(int argc, char *argv[]) |
|
|
|
{ |
|
|
|
Init(); |
|
|
|
EventLoop(); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#else |
|
|
|
|
|
|
|
|
|
|
|
int |
|
|
|
main(int argc, char *argv[]) |
|
|
|
{ |
|
|
|
printf("This program requires GLX 1.3!\n"); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#endif /* GLX_VERSION_1_3 */ |