Clone of mesa.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

wincopy.c 8.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. /*
  2. * Mesa 3-D graphics library
  3. * Version: 6.5.2
  4. *
  5. * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a
  8. * copy of this software and associated documentation files (the "Software"),
  9. * to deal in the Software without restriction, including without limitation
  10. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  11. * and/or sell copies of the Software, and to permit persons to whom the
  12. * Software is furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included
  15. * in all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  18. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  20. * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  21. * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  22. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  23. */
  24. /*
  25. * This program opens two GLX windows, renders into one and uses
  26. * glCopyPixels to copy the image from the first window into the
  27. * second by means of the GLX 1.3 function glxMakeContextCurrent().
  28. * This function works just like the glXMakeCurrentReadSGI() function
  29. * in the GLX_SGI_make_current_read extension.
  30. */
  31. #define GL_GLEXT_PROTOTYPES
  32. #define GLX_GLXEXT_PROTOTYPES
  33. #include <GL/gl.h>
  34. #include <GL/glx.h>
  35. #include <X11/keysym.h>
  36. #include <stdio.h>
  37. #include <stdlib.h>
  38. #include <string.h>
  39. #include <unistd.h>
  40. #ifdef GLX_VERSION_1_3
  41. static Display *Dpy;
  42. static int ScrNum;
  43. static GLXContext Context;
  44. static Window Win[2]; /* Win[0] = source, Win[1] = dest */
  45. static GLint Width[2], Height[2];
  46. static GLboolean TestClipping = GL_FALSE;
  47. static GLfloat Angle = 0.0;
  48. static GLboolean DrawFront = GL_FALSE;
  49. PFNGLXMAKECURRENTREADSGIPROC make_context_current = NULL;
  50. static Window
  51. CreateWindow(Display *dpy, int scrnum, XVisualInfo *visinfo,
  52. int xpos, int ypos, int width, int height,
  53. const char *name)
  54. {
  55. Window win;
  56. XSetWindowAttributes attr;
  57. unsigned long mask;
  58. Window root;
  59. root = RootWindow(dpy, scrnum);
  60. /* window attributes */
  61. attr.background_pixel = 0;
  62. attr.border_pixel = 0;
  63. attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone);
  64. attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
  65. mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
  66. win = XCreateWindow(dpy, root, xpos, ypos, width, height,
  67. 0, visinfo->depth, InputOutput,
  68. visinfo->visual, mask, &attr);
  69. if (win) {
  70. XSizeHints sizehints;
  71. sizehints.x = xpos;
  72. sizehints.y = ypos;
  73. sizehints.width = width;
  74. sizehints.height = height;
  75. sizehints.flags = USSize | USPosition;
  76. XSetNormalHints(dpy, win, &sizehints);
  77. XSetStandardProperties(dpy, win, name, name,
  78. None, (char **)NULL, 0, &sizehints);
  79. XMapWindow(dpy, win);
  80. }
  81. return win;
  82. }
  83. static void
  84. Redraw(void)
  85. {
  86. /* make the first window the current one */
  87. if (! (*make_context_current)(Dpy, Win[0], Win[0], Context)) {
  88. printf("glXMakeContextCurrent failed in Redraw()\n");
  89. return;
  90. }
  91. Angle += 1.0;
  92. if (DrawFront) {
  93. glDrawBuffer(GL_FRONT);
  94. glReadBuffer(GL_FRONT);
  95. }
  96. else {
  97. glDrawBuffer(GL_BACK);
  98. glReadBuffer(GL_BACK);
  99. }
  100. glViewport(0, 0, Width[0], Height[0]);
  101. glMatrixMode(GL_PROJECTION);
  102. glLoadIdentity();
  103. glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
  104. glMatrixMode(GL_MODELVIEW);
  105. glShadeModel(GL_FLAT);
  106. glClearColor(0.5, 0.5, 0.5, 0.0);
  107. glClear(GL_COLOR_BUFFER_BIT);
  108. /* draw blue quad */
  109. glColor3f(0.3, 0.3, 1.0);
  110. glPushMatrix();
  111. glRotatef(Angle, 0, 0, 1);
  112. glBegin(GL_POLYGON);
  113. glVertex2f(-0.5, -0.25);
  114. glVertex2f( 0.5, -0.25);
  115. glVertex2f( 0.5, 0.25);
  116. glVertex2f(-0.5, 0.25);
  117. glEnd();
  118. glPopMatrix();
  119. if (DrawFront)
  120. glFinish();
  121. else
  122. glXSwapBuffers(Dpy, Win[0]);
  123. /* copy image from window 0 to window 1 */
  124. if (!(*make_context_current)(Dpy, Win[1], Win[0], Context)) {
  125. printf("glXMakeContextCurrent failed in Redraw()\n");
  126. return;
  127. }
  128. /* copy the image between windows */
  129. glClearColor(0.0, 0.0, 0.0, 0.0);
  130. glClear(GL_COLOR_BUFFER_BIT);
  131. if (TestClipping) {
  132. glWindowPos2iARB(-2, -2);
  133. glCopyPixels(-2, -2, Width[0] + 4, Height[0] + 4, GL_COLOR);
  134. }
  135. else {
  136. glWindowPos2iARB(0, 0);
  137. glCopyPixels(0, 0, Width[0], Height[0], GL_COLOR);
  138. }
  139. if (DrawFront)
  140. glFinish();
  141. else
  142. glXSwapBuffers(Dpy, Win[1]);
  143. }
  144. static void
  145. Resize(Window win, unsigned int width, unsigned int height)
  146. {
  147. int i;
  148. if (win == Win[0]) {
  149. i = 0;
  150. }
  151. else {
  152. i = 1;
  153. }
  154. Width[i] = width;
  155. Height[i] = height;
  156. if (!glXMakeCurrent(Dpy, Win[i], Context)) {
  157. printf("glXMakeCurrent failed in Resize()\n");
  158. return;
  159. }
  160. }
  161. static void
  162. EventLoop(void)
  163. {
  164. XEvent event;
  165. while (1) {
  166. if (XPending(Dpy) > 0) {
  167. XNextEvent( Dpy, &event );
  168. switch (event.type) {
  169. case Expose:
  170. Redraw();
  171. break;
  172. case ConfigureNotify:
  173. Resize(event.xany.window, event.xconfigure.width, event.xconfigure.height);
  174. break;
  175. case KeyPress:
  176. {
  177. char buf[100];
  178. KeySym keySym;
  179. XComposeStatus stat;
  180. XLookupString(&event.xkey, buf, sizeof(buf), &keySym, &stat);
  181. if (keySym == XK_Escape) {
  182. /* exit */
  183. return;
  184. }
  185. else if (buf[0] == 'f') {
  186. DrawFront = !DrawFront;
  187. printf("Drawing to %s buffer\n",
  188. DrawFront ? "GL_FRONT" : "GL_BACK");
  189. }
  190. }
  191. break;
  192. default:
  193. /*no-op*/ ;
  194. }
  195. }
  196. else {
  197. /* animate */
  198. Redraw();
  199. }
  200. }
  201. }
  202. static void
  203. Init(void)
  204. {
  205. XVisualInfo *visinfo;
  206. int attrib[] = { GLX_RGBA,
  207. GLX_RED_SIZE, 1,
  208. GLX_GREEN_SIZE, 1,
  209. GLX_BLUE_SIZE, 1,
  210. GLX_DOUBLEBUFFER,
  211. None };
  212. int major, minor;
  213. Dpy = XOpenDisplay(NULL);
  214. if (!Dpy) {
  215. printf("Couldn't open default display!\n");
  216. exit(1);
  217. }
  218. ScrNum = DefaultScreen(Dpy);
  219. glXQueryVersion(Dpy, &major, &minor);
  220. if (major * 100 + minor >= 103) {
  221. make_context_current = (PFNGLXMAKECURRENTREADSGIPROC)
  222. glXGetProcAddressARB( (GLubyte *) "glXMakeContextCurrent" );
  223. }
  224. else {
  225. const char * const glxExtensions = glXQueryExtensionsString(Dpy, ScrNum);
  226. const char * ext = strstr( glxExtensions, "GLX_SGI_make_current_read" );
  227. const size_t len = strlen( "GLX_SGI_make_current_read" );
  228. if ( (ext != NULL)
  229. && ((ext[len] == ' ') || (ext[len] == '\0')) ) {
  230. make_context_current = (PFNGLXMAKECURRENTREADSGIPROC)
  231. glXGetProcAddressARB( (GLubyte *) "glXMakeCurrentReadSGI" );
  232. }
  233. }
  234. if (make_context_current == NULL) {
  235. fprintf(stderr, "Sorry, this program requires either GLX 1.3 "
  236. "or GLX_SGI_make_current_read.\n");
  237. exit(1);
  238. }
  239. visinfo = glXChooseVisual(Dpy, ScrNum, attrib);
  240. if (!visinfo) {
  241. printf("Unable to find RGB, double-buffered visual\n");
  242. exit(1);
  243. }
  244. Context = glXCreateContext(Dpy, visinfo, NULL, True);
  245. if (!Context) {
  246. printf("Couldn't create GLX context\n");
  247. exit(1);
  248. }
  249. Win[0] = CreateWindow(Dpy, ScrNum, visinfo,
  250. 0, 0, 300, 300, "source window");
  251. Win[1] = CreateWindow(Dpy, ScrNum, visinfo,
  252. 350, 0, 300, 300, "dest window");
  253. printf("Press Esc to exit\n");
  254. printf("Press 'f' to toggle front/back buffer drawing\n");
  255. }
  256. int
  257. main(int argc, char *argv[])
  258. {
  259. if (argc > 1 && strcmp(argv[1], "-clip") == 0)
  260. TestClipping = GL_TRUE;
  261. Init();
  262. EventLoop();
  263. return 0;
  264. }
  265. #else
  266. int
  267. main(int argc, char *argv[])
  268. {
  269. printf("This program requires GLX 1.3!\n");
  270. return 0;
  271. }
  272. #endif /* GLX_VERSION_1_3 */