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

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