1
2////////////////////////////////////////////////////////////
3// Headers
4////////////////////////////////////////////////////////////
5#include <SFML/Window.hpp>
6#include <SFML/System/Err.hpp>
7
8#define GLAD_GL_IMPLEMENTATION
9#include "gl.h"
10
11#include <X11/Xlib.h>
12#include <iostream>
13#include <cmath>
14
15
16////////////////////////////////////////////////////////////
17/// Initialize OpenGL states into the specified view
18///
19/// \param Window Target window to initialize
20///
21////////////////////////////////////////////////////////////
22void initialize(sf::Window& window)
23{
24 // Activate the window
25 window.setActive();
26
27 // Setup OpenGL states
28 // Set color and depth clear value
29
30#ifdef SFML_OPENGL_ES
31 glClearDepthf(1.f);
32#else
33 glClearDepth(1.f);
34#endif
35
36 glClearColor(0.f, 0.5f, 0.5f, 0.f);
37
38 // Enable Z-buffer read and write
39 glEnable(GL_DEPTH_TEST);
40 glDepthMask(GL_TRUE);
41
42 // Setup a perspective projection
43 glMatrixMode(GL_PROJECTION);
44 glLoadIdentity();
45 static const float pi = 3.141592654f;
46 float extent = std::tan(90.0f * pi / 360.0f);
47
48#ifdef SFML_OPENGL_ES
49 glFrustumf(-extent, extent, -extent, extent, 1.0f, 500.0f);
50#else
51 glFrustum(-extent, extent, -extent, extent, 1.0f, 500.0f);
52#endif
53
54 // Enable position and texture coordinates vertex components
55 glEnableClientState(GL_VERTEX_ARRAY);
56 glEnableClientState(GL_COLOR_ARRAY);
57}
58
59////////////////////////////////////////////////////////////
60/// Draw the OpenGL scene (a rotating cube) into
61/// the specified view
62///
63/// \param window Target window for rendering
64/// \param elapsedTime Time elapsed since the last draw
65///
66////////////////////////////////////////////////////////////
67void draw(sf::Window& window, float elapsedTime)
68{
69 // Activate the window
70 window.setActive();
71
72 // Clear color and depth buffers
73 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
74
75 // Apply some transformations
76 glMatrixMode(GL_MODELVIEW);
77 glLoadIdentity();
78 glTranslatef(0.f, 0.f, -200.f);
79 glRotatef(elapsedTime * 10.f, 1.f, 0.f, 0.f);
80 glRotatef(elapsedTime * 6.f, 0.f, 1.f, 0.f);
81 glRotatef(elapsedTime * 18.f, 0.f, 0.f, 1.f);
82
83 // Define a 3D cube (6 faces made of 2 triangles composed by 3 vertices)
84 static const GLfloat cube[] =
85 {
86 // positions // colors
87 -50, -50, -50, 1, 1, 0,
88 -50, 50, -50, 1, 1, 0,
89 -50, -50, 50, 1, 1, 0,
90 -50, -50, 50, 1, 1, 0,
91 -50, 50, -50, 1, 1, 0,
92 -50, 50, 50, 1, 1, 0,
93
94 50, -50, -50, 1, 1, 0,
95 50, 50, -50, 1, 1, 0,
96 50, -50, 50, 1, 1, 0,
97 50, -50, 50, 1, 1, 0,
98 50, 50, -50, 1, 1, 0,
99 50, 50, 50, 1, 1, 0,
100
101 -50, -50, -50, 1, 0, 1,
102 50, -50, -50, 1, 0, 1,
103 -50, -50, 50, 1, 0, 1,
104 -50, -50, 50, 1, 0, 1,
105 50, -50, -50, 1, 0, 1,
106 50, -50, 50, 1, 0, 1,
107
108 -50, 50, -50, 1, 0, 1,
109 50, 50, -50, 1, 0, 1,
110 -50, 50, 50, 1, 0, 1,
111 -50, 50, 50, 1, 0, 1,
112 50, 50, -50, 1, 0, 1,
113 50, 50, 50, 1, 0, 1,
114
115 -50, -50, -50, 0, 1, 1,
116 50, -50, -50, 0, 1, 1,
117 -50, 50, -50, 0, 1, 1,
118 -50, 50, -50, 0, 1, 1,
119 50, -50, -50, 0, 1, 1,
120 50, 50, -50, 0, 1, 1,
121
122 -50, -50, 50, 0, 1, 1,
123 50, -50, 50, 0, 1, 1,
124 -50, 50, 50, 0, 1, 1,
125 -50, 50, 50, 0, 1, 1,
126 50, -50, 50, 0, 1, 1,
127 50, 50, 50, 0, 1, 1
128 };
129
130 // Draw the cube
131 glVertexPointer(3, GL_FLOAT, 6 * sizeof(GLfloat), cube);
132 glColorPointer(3, GL_FLOAT, 6 * sizeof(GLfloat), cube + 3);
133 glDrawArrays(GL_TRIANGLES, 0, 36);
134}
135
136
137////////////////////////////////////////////////////////////
138/// Entry point of application
139///
140/// \return Error code
141///
142////////////////////////////////////////////////////////////
143int main()
144{
145 // Open a connection with the X server
146 Display* display = XOpenDisplay(NULL);
147 if (!display)
148 return EXIT_FAILURE;
149
150 // Get the default screen
151 int screen = DefaultScreen(display);
152
153 // Let's create the main window
154 XSetWindowAttributes attributes;
155 attributes.background_pixel = BlackPixel(display, screen);
156 attributes.event_mask = KeyPressMask;
157 Window window = XCreateWindow(display, RootWindow(display, screen),
158 0, 0, 650, 330, 0,
159 DefaultDepth(display, screen),
160 InputOutput,
161 DefaultVisual(display, screen),
162 CWBackPixel | CWEventMask, &attributes);
163 if (!window)
164 return EXIT_FAILURE;
165
166 // Set the window's name
167 XStoreName(display, window , "SFML Window");
168
169 // Let's create the windows which will serve as containers for our SFML views
170 Window view1 = XCreateWindow(display, window,
171 10, 10, 310, 310, 0,
172 DefaultDepth(display, screen),
173 InputOutput,
174 DefaultVisual(display, screen),
175 0, NULL);
176 Window view2 = XCreateWindow(display, window,
177 330, 10, 310, 310, 0,
178 DefaultDepth(display, screen),
179 InputOutput,
180 DefaultVisual(display, screen),
181 0, NULL);
182
183 // Show our windows
184 XMapWindow(display, window);
185 XFlush(display);
186
187 // Create our SFML views
188 sf::Window sfmlView1(view1);
189 sf::Window sfmlView2(view2);
190
191 // Create a clock for measuring elapsed time
192 sf::Clock clock;
193
194 // Load OpenGL or OpenGL ES entry points using glad
195 sfmlView1.setActive();
196
197#ifdef SFML_OPENGL_ES
198 gladLoadGLES1(reinterpret_cast<GLADloadfunc>(sf::Context::getFunction));
199#else
200 gladLoadGL(reinterpret_cast<GLADloadfunc>(sf::Context::getFunction));
201#endif
202
203 // Initialize our views
204 initialize(sfmlView1);
205 initialize(sfmlView2);
206
207 // Start the event loop
208 bool running = true;
209 while (running)
210 {
211 while (XPending(display))
212 {
213 // Get the next pending event
214 XEvent event;
215 XNextEvent(display, &event);
216
217 // Process it
218 switch (event.type)
219 {
220 // Any key is pressed: quit
221 case KeyPress:
222 running = false;
223 break;
224 }
225 }
226
227 // Draw something into our views
228 draw(sfmlView1, clock.getElapsedTime().asSeconds());
229 draw(sfmlView2, clock.getElapsedTime().asSeconds() * 0.3f);
230
231 // Display the views on screen
232 sfmlView1.display();
233 sfmlView2.display();
234 }
235
236 // Close our SFML views before destroying the underlying window
237 sfmlView1.close();
238 sfmlView2.close();
239
240 // Destroy the window
241 XDestroyWindow(display, window);
242
243 // Close the display
244 XCloseDisplay(display);
245
246 return EXIT_SUCCESS;
247}
248