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.

sharedtex.c 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. /* $Id: sharedtex.c,v 1.2 2002/01/16 14:32:46 joukj Exp $ */
  2. /*
  3. * Test sharing of display lists and texture objects between GLX contests.
  4. * Brian Paul
  5. * Summer 2000
  6. *
  7. *
  8. * Copyright (C) 2000 Brian Paul All Rights Reserved.
  9. *
  10. * Permission is hereby granted, free of charge, to any person obtaining a
  11. * copy of this software and associated documentation files (the "Software"),
  12. * to deal in the Software without restriction, including without limitation
  13. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  14. * and/or sell copies of the Software, and to permit persons to whom the
  15. * Software is furnished to do so, subject to the following conditions:
  16. *
  17. * The above copyright notice and this permission notice shall be included
  18. * in all copies or substantial portions of the Software.
  19. *
  20. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  21. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  22. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  23. * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  24. * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  25. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  26. */
  27. #include <GL/gl.h>
  28. #include <GL/glx.h>
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31. #include <unistd.h>
  32. #include <string.h>
  33. struct window {
  34. char DisplayName[1000];
  35. Display *Dpy;
  36. Window Win;
  37. GLXContext Context;
  38. float Angle;
  39. int Id;
  40. };
  41. #define MAX_WINDOWS 20
  42. static struct window Windows[MAX_WINDOWS];
  43. static int NumWindows = 0;
  44. static GLuint Textures[3];
  45. static GLuint CubeList;
  46. static void
  47. Error(const char *display, const char *msg)
  48. {
  49. fprintf(stderr, "Error on display %s - %s\n", display, msg);
  50. exit(1);
  51. }
  52. static struct window *
  53. AddWindow(const char *displayName, int xpos, int ypos,
  54. const struct window *shareWindow)
  55. {
  56. Display *dpy;
  57. Window win;
  58. GLXContext ctx;
  59. int attrib[] = { GLX_RGBA,
  60. GLX_RED_SIZE, 1,
  61. GLX_GREEN_SIZE, 1,
  62. GLX_BLUE_SIZE, 1,
  63. GLX_DOUBLEBUFFER,
  64. GLX_DEPTH_SIZE, 1,
  65. None };
  66. int scrnum;
  67. XSetWindowAttributes attr;
  68. unsigned long mask;
  69. Window root;
  70. XVisualInfo *visinfo;
  71. int width = 300, height = 300;
  72. if (NumWindows >= MAX_WINDOWS)
  73. return NULL;
  74. dpy = XOpenDisplay(displayName);
  75. if (!dpy) {
  76. Error(displayName, "Unable to open display");
  77. return NULL;
  78. }
  79. scrnum = DefaultScreen(dpy);
  80. root = RootWindow(dpy, scrnum);
  81. visinfo = glXChooseVisual(dpy, scrnum, attrib);
  82. if (!visinfo) {
  83. Error(displayName, "Unable to find RGB, double-buffered visual");
  84. return NULL;
  85. }
  86. /* window attributes */
  87. attr.background_pixel = 0;
  88. attr.border_pixel = 0;
  89. attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone);
  90. attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
  91. mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
  92. win = XCreateWindow(dpy, root, xpos, ypos, width, height,
  93. 0, visinfo->depth, InputOutput,
  94. visinfo->visual, mask, &attr);
  95. if (!win) {
  96. Error(displayName, "Couldn't create window");
  97. return NULL;
  98. }
  99. {
  100. XSizeHints sizehints;
  101. sizehints.x = xpos;
  102. sizehints.y = ypos;
  103. sizehints.width = width;
  104. sizehints.height = height;
  105. sizehints.flags = USSize | USPosition;
  106. XSetNormalHints(dpy, win, &sizehints);
  107. XSetStandardProperties(dpy, win, displayName, displayName,
  108. None, (char **)NULL, 0, &sizehints);
  109. }
  110. ctx = glXCreateContext(dpy, visinfo,
  111. shareWindow ? shareWindow->Context : NULL,
  112. True);
  113. if (!ctx) {
  114. Error(displayName, "Couldn't create GLX context");
  115. return NULL;
  116. }
  117. XMapWindow(dpy, win);
  118. if (!glXMakeCurrent(dpy, win, ctx)) {
  119. Error(displayName, "glXMakeCurrent failed");
  120. printf("glXMakeCurrent failed in Redraw()\n");
  121. return NULL;
  122. }
  123. /* save the info for this window */
  124. {
  125. static int id = 0;
  126. struct window *h = &Windows[NumWindows];
  127. strcpy(h->DisplayName, displayName);
  128. h->Dpy = dpy;
  129. h->Win = win;
  130. h->Context = ctx;
  131. h->Angle = 0.0;
  132. h->Id = id++;
  133. NumWindows++;
  134. return &Windows[NumWindows-1];
  135. }
  136. }
  137. static void
  138. InitGLstuff(struct window *h)
  139. {
  140. if (!glXMakeCurrent(h->Dpy, h->Win, h->Context)) {
  141. Error(h->DisplayName, "glXMakeCurrent failed in InitGLstuff");
  142. return;
  143. }
  144. glGenTextures(3, Textures);
  145. /* setup first texture object */
  146. {
  147. GLubyte image[16][16][4];
  148. GLint i, j;
  149. glBindTexture(GL_TEXTURE_2D, Textures[0]);
  150. /* red/white checkerboard */
  151. for (i = 0; i < 16; i++) {
  152. for (j = 0; j < 16; j++) {
  153. if ((i ^ j) & 1) {
  154. image[i][j][0] = 255;
  155. image[i][j][1] = 255;
  156. image[i][j][2] = 255;
  157. image[i][j][3] = 255;
  158. }
  159. else {
  160. image[i][j][0] = 255;
  161. image[i][j][1] = 0;
  162. image[i][j][2] = 0;
  163. image[i][j][3] = 255;
  164. }
  165. }
  166. }
  167. glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  168. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
  169. GL_UNSIGNED_BYTE, image);
  170. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  171. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  172. }
  173. /* setup second texture object */
  174. {
  175. GLubyte image[8][8][3];
  176. GLint i, j;
  177. glBindTexture(GL_TEXTURE_2D, Textures[1]);
  178. /* green/yellow checkerboard */
  179. for (i = 0; i < 8; i++) {
  180. for (j = 0; j < 8; j++) {
  181. if ((i ^ j) & 1) {
  182. image[i][j][0] = 0;
  183. image[i][j][1] = 255;
  184. image[i][j][2] = 0;
  185. }
  186. else {
  187. image[i][j][0] = 255;
  188. image[i][j][1] = 255;
  189. image[i][j][2] = 0;
  190. }
  191. }
  192. }
  193. glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
  194. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 8, 8, 0, GL_RGB,
  195. GL_UNSIGNED_BYTE, image);
  196. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  197. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  198. }
  199. /* setup second texture object */
  200. {
  201. GLubyte image[4][4][3];
  202. GLint i, j;
  203. glBindTexture(GL_TEXTURE_2D, Textures[2]);
  204. /* blue/gray checkerboard */
  205. for (i = 0; i < 4; i++) {
  206. for (j = 0; j < 4; j++) {
  207. if ((i ^ j) & 1) {
  208. image[i][j][0] = 0;
  209. image[i][j][1] = 0;
  210. image[i][j][2] = 255;
  211. }
  212. else {
  213. image[i][j][0] = 200;
  214. image[i][j][1] = 200;
  215. image[i][j][2] = 200;
  216. }
  217. }
  218. }
  219. glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
  220. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 4, 4, 0, GL_RGB,
  221. GL_UNSIGNED_BYTE, image);
  222. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  223. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  224. }
  225. /* Now make the cube object display list */
  226. CubeList = glGenLists(1);
  227. glNewList(CubeList, GL_COMPILE);
  228. {
  229. glBindTexture(GL_TEXTURE_2D, Textures[0]);
  230. glBegin(GL_POLYGON);
  231. glTexCoord2f(0, 0); glVertex3f(-1, -1, -1);
  232. glTexCoord2f(1, 0); glVertex3f(-1, 1, -1);
  233. glTexCoord2f(1, 1); glVertex3f(-1, 1, 1);
  234. glTexCoord2f(0, 1); glVertex3f(-1, -1, 1);
  235. glEnd();
  236. glBegin(GL_POLYGON);
  237. glTexCoord2f(0, 0); glVertex3f(1, -1, -1);
  238. glTexCoord2f(1, 0); glVertex3f(1, 1, -1);
  239. glTexCoord2f(1, 1); glVertex3f(1, 1, 1);
  240. glTexCoord2f(0, 1); glVertex3f(1, -1, 1);
  241. glEnd();
  242. glBindTexture(GL_TEXTURE_2D, Textures[1]);
  243. glBegin(GL_POLYGON);
  244. glTexCoord2f(0, 0); glVertex3f(-1, -1, -1);
  245. glTexCoord2f(1, 0); glVertex3f( 1, -1, -1);
  246. glTexCoord2f(1, 1); glVertex3f( 1, -1, 1);
  247. glTexCoord2f(0, 1); glVertex3f(-1, -1, 1);
  248. glEnd();
  249. glBegin(GL_POLYGON);
  250. glTexCoord2f(0, 0); glVertex3f(-1, 1, -1);
  251. glTexCoord2f(1, 0); glVertex3f( 1, 1, -1);
  252. glTexCoord2f(1, 1); glVertex3f( 1, 1, 1);
  253. glTexCoord2f(0, 1); glVertex3f(-1, 1, 1);
  254. glEnd();
  255. glBindTexture(GL_TEXTURE_2D, Textures[2]);
  256. glBegin(GL_POLYGON);
  257. glTexCoord2f(0, 0); glVertex3f(-1, -1, -1);
  258. glTexCoord2f(1, 0); glVertex3f( 1, -1, -1);
  259. glTexCoord2f(1, 1); glVertex3f( 1, 1, -1);
  260. glTexCoord2f(0, 1); glVertex3f(-1, 1, -1);
  261. glEnd();
  262. glBegin(GL_POLYGON);
  263. glTexCoord2f(0, 0); glVertex3f(-1, -1, 1);
  264. glTexCoord2f(1, 0); glVertex3f( 1, -1, 1);
  265. glTexCoord2f(1, 1); glVertex3f( 1, 1, 1);
  266. glTexCoord2f(0, 1); glVertex3f(-1, 1, 1);
  267. glEnd();
  268. }
  269. glEndList();
  270. printf("GL_RENDERER: %s\n", (char *) glGetString(GL_RENDERER));
  271. printf("GL_VERSION: %s\n", (char *) glGetString(GL_VERSION));
  272. printf("GL_VENDOR: %s\n", (char *) glGetString(GL_VENDOR));
  273. }
  274. static void
  275. Redraw(struct window *h)
  276. {
  277. if (!glXMakeCurrent(h->Dpy, h->Win, h->Context)) {
  278. Error(h->DisplayName, "glXMakeCurrent failed");
  279. printf("glXMakeCurrent failed in Redraw()\n");
  280. return;
  281. }
  282. h->Angle += 1.0;
  283. glShadeModel(GL_FLAT);
  284. glClearColor(0.25, 0.25, 0.25, 1.0);
  285. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  286. glEnable(GL_TEXTURE_2D);
  287. glEnable(GL_DEPTH_TEST);
  288. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  289. glColor3f(1, 1, 1);
  290. glPushMatrix();
  291. if (h->Id == 0)
  292. glRotatef(h->Angle, 0, 1, -1);
  293. else if (h->Id == 1)
  294. glRotatef(-(h->Angle), 0, 1, -1);
  295. else if (h->Id == 2)
  296. glRotatef(h->Angle, 0, 1, 1);
  297. else if (h->Id == 3)
  298. glRotatef(-(h->Angle), 0, 1, 1);
  299. glCallList(CubeList);
  300. glPopMatrix();
  301. glXSwapBuffers(h->Dpy, h->Win);
  302. }
  303. static void
  304. Resize(const struct window *h, unsigned int width, unsigned int height)
  305. {
  306. if (!glXMakeCurrent(h->Dpy, h->Win, h->Context)) {
  307. Error(h->DisplayName, "glXMakeCurrent failed in Resize()");
  308. return;
  309. }
  310. glViewport(0, 0, width, height);
  311. glMatrixMode(GL_PROJECTION);
  312. glLoadIdentity();
  313. glFrustum(-1, 1, -1, 1, 2, 10);
  314. glMatrixMode(GL_MODELVIEW);
  315. glLoadIdentity();
  316. glTranslatef(0, 0, -3.5);
  317. }
  318. static void
  319. EventLoop(void)
  320. {
  321. while (1) {
  322. int i;
  323. for (i = 0; i < NumWindows; i++) {
  324. struct window *h = &Windows[i];
  325. while (XPending(h->Dpy) > 0) {
  326. XEvent event;
  327. XNextEvent(h->Dpy, &event);
  328. if (event.xany.window == h->Win) {
  329. switch (event.type) {
  330. case Expose:
  331. Redraw(h);
  332. break;
  333. case ConfigureNotify:
  334. Resize(h, event.xconfigure.width, event.xconfigure.height);
  335. break;
  336. case KeyPress:
  337. return;
  338. default:
  339. /*no-op*/ ;
  340. }
  341. }
  342. else {
  343. printf("window mismatch\n");
  344. }
  345. }
  346. Redraw(h);
  347. }
  348. usleep(1);
  349. }
  350. }
  351. static void
  352. PrintInfo(const struct window *h)
  353. {
  354. printf("Name: %s\n", h->DisplayName);
  355. printf(" Display: 0x%x\n", h->Dpy);
  356. printf(" Window: 0x%x\n", h->Win);
  357. printf(" Context: 0x%x\n", h->Context);
  358. }
  359. int
  360. main(int argc, char *argv[])
  361. {
  362. int i;
  363. struct window *h0, *h1, *h2, *h3;
  364. /* four windows and contexts sharing display lists and texture objects */
  365. h0 = AddWindow(":0", 10, 10, NULL);
  366. h1 = AddWindow(":0", 330, 10, h0);
  367. h2 = AddWindow(":0", 10, 350, h0);
  368. h3 = AddWindow(":0", 330, 350, h0);
  369. InitGLstuff(h0);
  370. EventLoop();
  371. return 0;
  372. }