2014-09-30 22:07:25 +08:00
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////
|
|
|
|
// Headers
|
|
|
|
////////////////////////////////////////////////////////////
|
|
|
|
#include <SFML/Window.hpp>
|
2014-04-24 18:55:47 +08:00
|
|
|
#include <SFML/System/Err.hpp>
|
2015-01-13 01:15:11 +08:00
|
|
|
#include <SFML/OpenGL.hpp>
|
2014-04-24 18:55:47 +08:00
|
|
|
#include <X11/Xlib-xcb.h>
|
2014-09-30 22:07:25 +08:00
|
|
|
#include <iostream>
|
2015-01-13 01:15:11 +08:00
|
|
|
#include <cmath>
|
2014-09-30 22:07:25 +08:00
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////
|
|
|
|
/// Initialize OpenGL states into the specified view
|
|
|
|
///
|
|
|
|
/// \param Window Target window to initialize
|
|
|
|
///
|
|
|
|
////////////////////////////////////////////////////////////
|
|
|
|
void initialize(sf::Window& window)
|
|
|
|
{
|
|
|
|
// Activate the window
|
|
|
|
window.setActive();
|
|
|
|
|
|
|
|
// Setup OpenGL states
|
|
|
|
// Set color and depth clear value
|
|
|
|
glClearDepth(1.f);
|
|
|
|
glClearColor(0.f, 0.5f, 0.5f, 0.f);
|
|
|
|
|
|
|
|
// Enable Z-buffer read and write
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
glDepthMask(GL_TRUE);
|
|
|
|
|
|
|
|
// Setup a perspective projection
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
|
|
glLoadIdentity();
|
2015-01-13 01:15:11 +08:00
|
|
|
static const double pi = 3.141592654;
|
|
|
|
GLdouble extent = std::tan(90.0 * pi / 360.0);
|
|
|
|
glFrustum(-extent, extent, -extent, extent, 1.0, 500.0);
|
2015-01-13 01:15:46 +08:00
|
|
|
|
|
|
|
// Enable position and texture coordinates vertex components
|
|
|
|
glEnableClientState(GL_VERTEX_ARRAY);
|
|
|
|
glEnableClientState(GL_COLOR_ARRAY);
|
2014-09-30 22:07:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////
|
|
|
|
/// Draw the OpenGL scene (a rotating cube) into
|
|
|
|
/// the specified view
|
|
|
|
///
|
|
|
|
/// \param window Target window for rendering
|
|
|
|
/// \param elapsedTime Time elapsed since the last draw
|
|
|
|
///
|
|
|
|
////////////////////////////////////////////////////////////
|
|
|
|
void draw(sf::Window& window, float elapsedTime)
|
|
|
|
{
|
|
|
|
// Activate the window
|
|
|
|
window.setActive();
|
|
|
|
|
|
|
|
// Clear color and depth buffers
|
|
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
|
|
|
|
|
// Apply some transformations
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glLoadIdentity();
|
|
|
|
glTranslatef(0.f, 0.f, -200.f);
|
2014-04-24 18:55:47 +08:00
|
|
|
glRotatef(elapsedTime * 10.f, 1.f, 0.f, 0.f);
|
|
|
|
glRotatef(elapsedTime * 6.f, 0.f, 1.f, 0.f);
|
|
|
|
glRotatef(elapsedTime * 18.f, 0.f, 0.f, 1.f);
|
2014-09-30 22:07:25 +08:00
|
|
|
|
2015-01-13 01:15:46 +08:00
|
|
|
// Define a 3D cube (6 faces made of 2 triangles composed by 3 vertices)
|
|
|
|
static const GLfloat cube[] =
|
|
|
|
{
|
|
|
|
// positions // colors
|
|
|
|
-50, -50, -50, 1, 1, 0,
|
|
|
|
-50, 50, -50, 1, 1, 0,
|
|
|
|
-50, -50, 50, 1, 1, 0,
|
|
|
|
-50, -50, 50, 1, 1, 0,
|
|
|
|
-50, 50, -50, 1, 1, 0,
|
|
|
|
-50, 50, 50, 1, 1, 0,
|
|
|
|
|
|
|
|
50, -50, -50, 1, 1, 0,
|
|
|
|
50, 50, -50, 1, 1, 0,
|
|
|
|
50, -50, 50, 1, 1, 0,
|
|
|
|
50, -50, 50, 1, 1, 0,
|
|
|
|
50, 50, -50, 1, 1, 0,
|
|
|
|
50, 50, 50, 1, 1, 0,
|
|
|
|
|
|
|
|
-50, -50, -50, 1, 0, 1,
|
|
|
|
50, -50, -50, 1, 0, 1,
|
|
|
|
-50, -50, 50, 1, 0, 1,
|
|
|
|
-50, -50, 50, 1, 0, 1,
|
|
|
|
50, -50, -50, 1, 0, 1,
|
|
|
|
50, -50, 50, 1, 0, 1,
|
|
|
|
|
|
|
|
-50, 50, -50, 1, 0, 1,
|
|
|
|
50, 50, -50, 1, 0, 1,
|
|
|
|
-50, 50, 50, 1, 0, 1,
|
|
|
|
-50, 50, 50, 1, 0, 1,
|
|
|
|
50, 50, -50, 1, 0, 1,
|
|
|
|
50, 50, 50, 1, 0, 1,
|
|
|
|
|
|
|
|
-50, -50, -50, 0, 1, 1,
|
|
|
|
50, -50, -50, 0, 1, 1,
|
|
|
|
-50, 50, -50, 0, 1, 1,
|
|
|
|
-50, 50, -50, 0, 1, 1,
|
|
|
|
50, -50, -50, 0, 1, 1,
|
|
|
|
50, 50, -50, 0, 1, 1,
|
|
|
|
|
|
|
|
-50, -50, 50, 0, 1, 1,
|
|
|
|
50, -50, 50, 0, 1, 1,
|
|
|
|
-50, 50, 50, 0, 1, 1,
|
|
|
|
-50, 50, 50, 0, 1, 1,
|
|
|
|
50, -50, 50, 0, 1, 1,
|
|
|
|
50, 50, 50, 0, 1, 1
|
|
|
|
};
|
|
|
|
|
|
|
|
// Draw the cube
|
|
|
|
glVertexPointer(3, GL_FLOAT, 6 * sizeof(GLfloat), cube);
|
|
|
|
glColorPointer(3, GL_FLOAT, 6 * sizeof(GLfloat), cube + 3);
|
|
|
|
glDrawArrays(GL_TRIANGLES, 0, 36);
|
2014-09-30 22:07:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////
|
|
|
|
/// Entry point of application
|
|
|
|
///
|
|
|
|
/// \return Error code
|
|
|
|
///
|
|
|
|
////////////////////////////////////////////////////////////
|
|
|
|
int main()
|
|
|
|
{
|
|
|
|
// Open a connection with the X server
|
|
|
|
Display* display = XOpenDisplay(NULL);
|
|
|
|
if (!display)
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
|
2014-04-24 18:55:47 +08:00
|
|
|
// Get the XCB connection for the opened display.
|
|
|
|
xcb_connection_t* xcbConnection = XGetXCBConnection(display);
|
|
|
|
|
|
|
|
if (!xcbConnection)
|
|
|
|
{
|
|
|
|
sf::err() << "Failed to get the XCB connection for opened display." << std::endl;
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get XCB screen.
|
|
|
|
const xcb_setup_t* xcbSetup = xcb_get_setup(xcbConnection);
|
|
|
|
xcb_screen_iterator_t xcbScreenIter = xcb_setup_roots_iterator(xcbSetup);
|
|
|
|
xcb_screen_t* screen = xcbScreenIter.data;
|
|
|
|
|
|
|
|
if (!screen)
|
|
|
|
{
|
|
|
|
sf::err() << "Failed to get the XCB screen." << std::endl;
|
2014-09-30 22:07:25 +08:00
|
|
|
return EXIT_FAILURE;
|
2014-04-24 18:55:47 +08:00
|
|
|
}
|
2014-09-30 22:07:25 +08:00
|
|
|
|
2014-04-24 18:55:47 +08:00
|
|
|
// Generate the XCB window IDs.
|
|
|
|
xcb_window_t rootWindowId = xcb_generate_id(xcbConnection);
|
|
|
|
xcb_window_t view1WindowId = xcb_generate_id(xcbConnection);
|
|
|
|
xcb_window_t view2WindowId = xcb_generate_id(xcbConnection);
|
|
|
|
|
|
|
|
// Create the root window with a black background.
|
|
|
|
uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
|
|
|
|
uint32_t attributes[2] = {screen->black_pixel, XCB_EVENT_MASK_KEY_PRESS};
|
|
|
|
|
|
|
|
xcb_create_window(xcbConnection,
|
|
|
|
XCB_COPY_FROM_PARENT,
|
|
|
|
rootWindowId,
|
|
|
|
screen->root,
|
|
|
|
0, 0, 650, 330,
|
|
|
|
0,
|
|
|
|
XCB_WINDOW_CLASS_INPUT_OUTPUT,
|
|
|
|
screen->root_visual,
|
|
|
|
mask, attributes);
|
|
|
|
|
|
|
|
// Create windows for the SFML views.
|
|
|
|
xcb_create_window(xcbConnection,
|
|
|
|
XCB_COPY_FROM_PARENT,
|
|
|
|
view1WindowId,
|
|
|
|
rootWindowId,
|
|
|
|
10, 10, 310, 310,
|
|
|
|
0,
|
|
|
|
XCB_WINDOW_CLASS_INPUT_OUTPUT,
|
|
|
|
screen->root_visual,
|
|
|
|
mask, attributes);
|
|
|
|
|
|
|
|
xcb_create_window(xcbConnection,
|
|
|
|
XCB_COPY_FROM_PARENT,
|
|
|
|
view2WindowId,
|
|
|
|
rootWindowId,
|
|
|
|
330, 10, 310, 310,
|
|
|
|
0,
|
|
|
|
XCB_WINDOW_CLASS_INPUT_OUTPUT,
|
|
|
|
screen->root_visual,
|
|
|
|
mask, attributes);
|
|
|
|
|
|
|
|
// Map windows to screen.
|
|
|
|
xcb_map_window(xcbConnection, rootWindowId);
|
|
|
|
xcb_map_window(xcbConnection, view1WindowId);
|
|
|
|
xcb_map_window(xcbConnection, view2WindowId);
|
|
|
|
|
|
|
|
// Flush commands.
|
|
|
|
xcb_flush(xcbConnection);
|
2014-09-30 22:07:25 +08:00
|
|
|
|
|
|
|
// Create our SFML views
|
2014-04-24 18:55:47 +08:00
|
|
|
sf::Window sfmlView1(view1WindowId);
|
|
|
|
sf::Window sfmlView2(view2WindowId);
|
2014-09-30 22:07:25 +08:00
|
|
|
|
|
|
|
// Create a clock for measuring elapsed time
|
|
|
|
sf::Clock clock;
|
|
|
|
|
|
|
|
// Initialize our views
|
2014-04-24 18:55:47 +08:00
|
|
|
initialize(sfmlView1);
|
|
|
|
initialize(sfmlView2);
|
2014-09-30 22:07:25 +08:00
|
|
|
|
|
|
|
// Start the event loop
|
|
|
|
bool running = true;
|
2014-04-24 18:55:47 +08:00
|
|
|
xcb_generic_event_t* event = NULL;
|
|
|
|
|
2014-09-30 22:07:25 +08:00
|
|
|
while (running)
|
|
|
|
{
|
2015-01-06 05:23:16 +08:00
|
|
|
while ((event = xcb_poll_for_event(xcbConnection)))
|
2014-09-30 22:07:25 +08:00
|
|
|
{
|
2014-04-24 18:55:47 +08:00
|
|
|
running = false;
|
2014-09-30 22:07:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Draw something into our views
|
2014-04-24 18:55:47 +08:00
|
|
|
draw(sfmlView1, clock.getElapsedTime().asSeconds());
|
|
|
|
draw(sfmlView2, clock.getElapsedTime().asSeconds() * 0.3f);
|
2014-09-30 22:07:25 +08:00
|
|
|
|
|
|
|
// Display the views on screen
|
2014-04-24 18:55:47 +08:00
|
|
|
sfmlView1.display();
|
|
|
|
sfmlView2.display();
|
2014-09-30 22:07:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return EXIT_SUCCESS;
|
|
|
|
}
|