GLX/GteWindowSystem.cpp
Go to the documentation of this file.
1 // David Eberly, Geometric Tools, Redmond WA 98052
2 // Copyright (c) 1998-2017
3 // Distributed under the Boost Software License, Version 1.0.
4 // http://www.boost.org/LICENSE_1_0.txt
5 // http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
6 // File Version: 3.0.1 (2016/07/01)
7 
8 #include <GTEnginePCH.h>
13 #include <X11/Xlib.h>
14 #include <GL/glx.h>
15 using namespace gte;
16 
18 
20 {
21  XCloseDisplay(mDisplay);
22 }
23 
25  :
26  mDisplayName("GTEngineWindow"),
27  mDisplay(nullptr)
28 {
29  // Connect to the X server.
30  mDisplay = XOpenDisplay(0);
31  if (!mDisplay)
32  {
33  LogError("XOpenDisplay failed.");
34  return;
35  }
36 
37  // Make sure the X server has OpenGL GLX extensions.
38  int errorBase, eventBase;
39  Bool success = glXQueryExtension(mDisplay, &errorBase, &eventBase);
40  if (!success)
41  {
42  LogError("glXQueryExtension failed, errorBase = "
43  + std::to_string(errorBase)
44  + ", eventBase = "
45  + std::to_string(eventBase)
46  + ".");
47  return;
48  }
49 }
50 
51 bool WindowSystem::Create(_XDisplay*& display, __GLXcontextRec*& context, unsigned long& window)
52 {
53  display = mDisplay;
54  context = nullptr;
55  window = 0;
56 
57  // Select the attributes for the frame buffer.
58  int attributes[256];
59 
60  // Create a 32-bit RGBA buffer.
61  int i = 0;
62  attributes[i++] = GLX_RGBA;
63  attributes[i++] = GLX_RED_SIZE;
64  attributes[i++] = 8;
65  attributes[i++] = GLX_GREEN_SIZE;
66  attributes[i++] = 8;
67  attributes[i++] = GLX_BLUE_SIZE;
68  attributes[i++] = 8;
69  attributes[i++] = GLX_ALPHA_SIZE;
70  attributes[i++] = 8;
71 
72  // depthStencilFormat is ignored, create 24-8 depthstencil buffer.
73  attributes[i++] = GLX_DEPTH_SIZE;
74  attributes[i++] = 24;
75  attributes[i++] = GLX_STENCIL_SIZE;
76  attributes[i++] = 8;
77 
78  // Use double buffering.
79  attributes[i++] = GLX_DOUBLEBUFFER;
80  attributes[i++] = 1;
81 
82  // The list is zero terminated.
83  attributes[i] = 0;
84 
85  // Get an OpenGL-capable visual.
86  int screen = DefaultScreen(mDisplay);
87  XVisualInfo* visualInfo = glXChooseVisual(mDisplay, screen, attributes);
88  if (!visualInfo)
89  {
90  LogError("glXChooseVisual failed.");
91  return false;
92  }
93 
94  // Create an OpenGL rendering context.
95  GLXContext sharedList = nullptr;
96  Bool directRender = True;
97  context = glXCreateContext(mDisplay, visualInfo, sharedList, directRender);
98  if (!context)
99  {
100  LogError("glXCreateContext failed.");
101  return false;
102  }
103 
104  // Create an X Window with the visual information created by the renderer
105  // constructor. The visual information might not be the default, so
106  // create an X colormap to use.
107  XID rootWindow = RootWindow(mDisplay, visualInfo->screen);
108  Colormap colorMap = XCreateColormap(mDisplay, rootWindow, visualInfo->visual, AllocNone);
109 
110  // Set the event mask to include exposure (paint), button presses (mouse),
111  // and key presses (keyboard).
112  XSetWindowAttributes windowAttributes;
113  windowAttributes.colormap = colorMap;
114  windowAttributes.border_pixel = 0;
115  windowAttributes.event_mask =
116  ButtonPressMask |
117  ButtonReleaseMask |
118  PointerMotionMask |
119  Button1MotionMask |
120  Button2MotionMask |
121  Button3MotionMask |
122  KeyPressMask |
123  KeyReleaseMask |
124  ExposureMask |
125  StructureNotifyMask;
126 
127  unsigned int xOrigin = 0, yOrigin = 0, xSize = 16, ySize = 16;
128  unsigned int borderWidth = 0;
129  unsigned long valueMask = CWBorderPixel | CWColormap | CWEventMask;
130  window = XCreateWindow(mDisplay, rootWindow, xOrigin,
131  yOrigin, xSize, ySize, borderWidth,
132  visualInfo->depth, InputOutput, visualInfo->visual, valueMask, &windowAttributes);
133 
134  XSizeHints hints;
135  hints.flags = PPosition | PSize;
136  hints.x = xOrigin;
137  hints.y = yOrigin;
138  hints.width = xSize;
139  hints.height = ySize;
140  XSetNormalHints(mDisplay, window, &hints);
141 
142  std::string title = "GL4ComputeWindowClass";
143  Pixmap iconPixmap = None;
144  int numArguments = 0;
145  char** arguments = nullptr;
146  XSetStandardProperties(mDisplay, window, title.c_str(),
147  title.c_str(), iconPixmap, arguments, numArguments, &hints);
148 
149  // Intercept the close-window event when the user selects the
150  // window close button. The event is a "client message".
151  Atom wmDelete = XInternAtom(mDisplay, "WM_DELETE_WINDOW", False);
152  XSetWMProtocols(mDisplay, window, &wmDelete, 1);
153  return true;
154 }
155 
157 {
158  // Select the attributes for the frame buffer.
159  int attributes[256];
160 
161  // Create a 32-bit RGBA buffer.
162  int i = 0;
163  attributes[i++] = GLX_RGBA;
164  attributes[i++] = GLX_RED_SIZE;
165  attributes[i++] = 8;
166  attributes[i++] = GLX_GREEN_SIZE;
167  attributes[i++] = 8;
168  attributes[i++] = GLX_BLUE_SIZE;
169  attributes[i++] = 8;
170  attributes[i++] = GLX_ALPHA_SIZE;
171  attributes[i++] = 8;
172 
173  // depthStencilFormat is ignored, create 24-8 depthstencil buffer.
174  attributes[i++] = GLX_DEPTH_SIZE;
175  attributes[i++] = 24;
176  attributes[i++] = GLX_STENCIL_SIZE;
177  attributes[i++] = 8;
178 
179  // Use double buffering.
180  attributes[i++] = GLX_DOUBLEBUFFER;
181  attributes[i++] = 1;
182 
183  // The list is zero terminated.
184  attributes[i] = 0;
185 
186  // Get an OpenGL-capable visual.
187  int screen = DefaultScreen(mDisplay);
188  XVisualInfo* visualInfo = glXChooseVisual(mDisplay, screen, attributes);
189  if (!visualInfo)
190  {
191  LogError("glXChooseVisual failed.");
192  parameters.created = false;
193  return;
194  }
195 
196  // Create an OpenGL rendering context.
197  GLXContext sharedList = nullptr;
198  Bool directRender = True;
199  GLXContext context = glXCreateContext(mDisplay, visualInfo, sharedList, directRender);
200  if (!context)
201  {
202  LogError("glXCreateContext failed.");
203  parameters.created = false;
204  return;
205  }
206 
207  // Create an X Window with the visual information created by the renderer
208  // constructor. The visual information might not be the default, so
209  // create an X colormap to use.
210  XID rootWindow = RootWindow(mDisplay, visualInfo->screen);
211  Colormap colorMap = XCreateColormap(mDisplay, rootWindow, visualInfo->visual, AllocNone);
212 
213  // Set the event mask to include exposure (paint), button presses (mouse),
214  // and key presses (keyboard).
215  XSetWindowAttributes windowAttributes;
216  windowAttributes.colormap = colorMap;
217  windowAttributes.border_pixel = 0;
218  windowAttributes.event_mask =
219  ButtonPressMask |
220  ButtonReleaseMask |
221  PointerMotionMask |
222  Button1MotionMask |
223  Button2MotionMask |
224  Button3MotionMask |
225  KeyPressMask |
226  KeyReleaseMask |
227  ExposureMask |
228  StructureNotifyMask;
229 
230  unsigned int borderWidth = 0;
231  unsigned long valueMask = CWBorderPixel | CWColormap | CWEventMask;
232  parameters.window = XCreateWindow(mDisplay, rootWindow, parameters.xOrigin,
233  parameters.yOrigin, parameters.xSize, parameters.ySize, borderWidth,
234  visualInfo->depth, InputOutput, visualInfo->visual, valueMask, &windowAttributes);
235 
236  XSizeHints hints;
237  hints.flags = PPosition | PSize;
238  hints.x = parameters.xOrigin;
239  hints.y = parameters.yOrigin;
240  hints.width = parameters.xSize;
241  hints.height = parameters.ySize;
242  XSetNormalHints(mDisplay, parameters.window, &hints);
243 
244  std::string title(parameters.title.begin(), parameters.title.end());
245  Pixmap iconPixmap = None;
246  int numArguments = 0;
247  char** arguments = nullptr;
248  XSetStandardProperties(mDisplay, parameters.window, title.c_str(),
249  title.c_str(), iconPixmap, arguments, numArguments, &hints);
250 
251  // Intercept the close-window event when the user selects the
252  // window close button. The event is a "client message".
253  Atom wmDelete = XInternAtom(mDisplay, "WM_DELETE_WINDOW", False);
254  XSetWMProtocols(mDisplay, parameters.window, &wmDelete, 1);
255 
256  // Create a GLX rendering engine.
257  auto engine = std::make_shared<GLXEngine>(mDisplay, parameters.window, context,
258  parameters.xSize, parameters.ySize, (parameters.deviceCreationFlags != 0));
259  if (!engine->MeetsRequirements())
260  {
261  LogError("OpenGL 4.3 or later is required.");
262  parameters.display = nullptr;
263  parameters.engine = nullptr;
264  parameters.factory = nullptr;
265  parameters.created = false;
266  return;
267  }
268 
269  if (engine->GetDisplay())
270  {
271  parameters.display = mDisplay;
272  parameters.engine = engine;
273  parameters.factory = std::make_shared<GLSLProgramFactory>();
274  parameters.created = true;
275  }
276  else
277  {
278  LogError("Cannot create graphics engine.");
279  parameters.display = nullptr;
280  parameters.window = 0;
281  parameters.engine = nullptr;
282  parameters.factory = nullptr;
283  parameters.created = false;
284  }
285 }
void CreateFrom(Window::Parameters &parameters)
GLsizei const GLchar *const * string
Definition: glcorearb.h:809
std::shared_ptr< ProgramFactory > factory
Definition: GteWindowBase.h:35
#define LogError(message)
Definition: GteLogger.h:92
unsigned int deviceCreationFlags
Definition: GLX/GteWindow.h:31
std::shared_ptr< WindowType > Create(typename WindowType::Parameters &parameters)
char const * mDisplayName
std::shared_ptr< BaseEngine > engine
Definition: GteWindowBase.h:34
GTE_IMPEXP WindowSystem TheWindowSystem


geometric_tools_engine
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 04:00:02