Source code changes.
* Changed newlines to \n. * Removed whitespace before colons. * Fixed several alignments.
This commit is contained in:
parent
b27cbd5036
commit
f24ca9a840
268 changed files with 40227 additions and 40227 deletions
|
@ -1,18 +1,18 @@
|
|||
|
||||
|
||||
# add the examples subdirectories
|
||||
add_subdirectory(ftp)
|
||||
add_subdirectory(opengl)
|
||||
add_subdirectory(pong)
|
||||
add_subdirectory(shader)
|
||||
add_subdirectory(sockets)
|
||||
add_subdirectory(sound)
|
||||
add_subdirectory(sound_capture)
|
||||
add_subdirectory(voip)
|
||||
add_subdirectory(window)
|
||||
if(SFML_OS_WINDOWS)
|
||||
add_subdirectory(win32)
|
||||
elseif(SFML_OS_LINUX OR SFML_OS_FREEBSD)
|
||||
add_subdirectory(ftp)
|
||||
add_subdirectory(opengl)
|
||||
add_subdirectory(pong)
|
||||
add_subdirectory(shader)
|
||||
add_subdirectory(sockets)
|
||||
add_subdirectory(sound)
|
||||
add_subdirectory(sound_capture)
|
||||
add_subdirectory(voip)
|
||||
add_subdirectory(window)
|
||||
if(SFML_OS_WINDOWS)
|
||||
add_subdirectory(win32)
|
||||
elseif(SFML_OS_LINUX OR SFML_OS_FREEBSD)
|
||||
add_subdirectory(X11)
|
||||
elseif(SFML_OS_MACOSX)
|
||||
add_subdirectory(cocoa)
|
||||
endif()
|
||||
elseif(SFML_OS_MACOSX)
|
||||
add_subdirectory(cocoa)
|
||||
endif()
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
|
||||
set(SRCROOT ${PROJECT_SOURCE_DIR}/examples/X11)
|
||||
|
||||
# all source files
|
||||
set(SRC ${SRCROOT}/X11.cpp)
|
||||
|
||||
# find OpenGL, GLU and X11
|
||||
find_package(OpenGL REQUIRED)
|
||||
include_directories(${OPENGL_INCLUDE_DIR})
|
||||
find_package(X11 REQUIRED)
|
||||
include_directories(${X11_INCLUDE_DIR})
|
||||
|
||||
# define the X11 target
|
||||
sfml_add_example(X11 GUI_APP
|
||||
SOURCES ${SRC}
|
||||
DEPENDS sfml-window sfml-system ${OPENGL_LIBRARIES} ${X11_LIBRARIES})
|
||||
|
||||
set(SRCROOT ${PROJECT_SOURCE_DIR}/examples/X11)
|
||||
|
||||
# all source files
|
||||
set(SRC ${SRCROOT}/X11.cpp)
|
||||
|
||||
# find OpenGL, GLU and X11
|
||||
find_package(OpenGL REQUIRED)
|
||||
include_directories(${OPENGL_INCLUDE_DIR})
|
||||
find_package(X11 REQUIRED)
|
||||
include_directories(${X11_INCLUDE_DIR})
|
||||
|
||||
# define the X11 target
|
||||
sfml_add_example(X11 GUI_APP
|
||||
SOURCES ${SRC}
|
||||
DEPENDS sfml-window sfml-system ${OPENGL_LIBRARIES} ${X11_LIBRARIES})
|
||||
|
|
|
@ -1,199 +1,199 @@
|
|||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Window.hpp>
|
||||
#include <X11/Xlib.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// 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();
|
||||
gluPerspective(90.f, 1.f, 1.f, 500.f);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// 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);
|
||||
glRotatef(elapsedTime * 0.05f, 1.f, 0.f, 0.f);
|
||||
glRotatef(elapsedTime * 0.03f, 0.f, 1.f, 0.f);
|
||||
glRotatef(elapsedTime * 0.09f, 0.f, 0.f, 1.f);
|
||||
|
||||
// Draw a cube
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
glColor3f(1.f, 1.f, 0.f);
|
||||
glVertex3f(-50.f, -50.f, -50.f);
|
||||
glVertex3f(-50.f, 50.f, -50.f);
|
||||
glVertex3f( 50.f, 50.f, -50.f);
|
||||
glVertex3f( 50.f, -50.f, -50.f);
|
||||
|
||||
glColor3f(1.f, 1.f, 0.f);
|
||||
glVertex3f(-50.f, -50.f, 50.f);
|
||||
glVertex3f(-50.f, 50.f, 50.f);
|
||||
glVertex3f( 50.f, 50.f, 50.f);
|
||||
glVertex3f( 50.f, -50.f, 50.f);
|
||||
|
||||
glColor3f(0.f, 1.f, 1.f);
|
||||
glVertex3f(-50.f, -50.f, -50.f);
|
||||
glVertex3f(-50.f, 50.f, -50.f);
|
||||
glVertex3f(-50.f, 50.f, 50.f);
|
||||
glVertex3f(-50.f, -50.f, 50.f);
|
||||
|
||||
glColor3f(0.f, 1.f, 1.f);
|
||||
glVertex3f(50.f, -50.f, -50.f);
|
||||
glVertex3f(50.f, 50.f, -50.f);
|
||||
glVertex3f(50.f, 50.f, 50.f);
|
||||
glVertex3f(50.f, -50.f, 50.f);
|
||||
|
||||
glColor3f(1.f, 0.f, 1.f);
|
||||
glVertex3f(-50.f, -50.f, 50.f);
|
||||
glVertex3f(-50.f, -50.f, -50.f);
|
||||
glVertex3f( 50.f, -50.f, -50.f);
|
||||
glVertex3f( 50.f, -50.f, 50.f);
|
||||
|
||||
glColor3f(1.f, 0.f, 1.f);
|
||||
glVertex3f(-50.f, 50.f, 50.f);
|
||||
glVertex3f(-50.f, 50.f, -50.f);
|
||||
glVertex3f( 50.f, 50.f, -50.f);
|
||||
glVertex3f( 50.f, 50.f, 50.f);
|
||||
|
||||
glEnd();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// 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;
|
||||
|
||||
// Get the default screen
|
||||
int screen = DefaultScreen(display);
|
||||
|
||||
// Let's create the main window
|
||||
XSetWindowAttributes attributes;
|
||||
attributes.background_pixel = BlackPixel(display, screen);
|
||||
attributes.event_mask = KeyPressMask;
|
||||
Window window = XCreateWindow(display, RootWindow(display, screen),
|
||||
0, 0, 650, 330, 0,
|
||||
DefaultDepth(display, screen),
|
||||
InputOutput,
|
||||
DefaultVisual(display, screen),
|
||||
CWBackPixel | CWEventMask, &attributes);
|
||||
if (!window)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
// Set the window's name
|
||||
XStoreName(display, window , "SFML Window");
|
||||
|
||||
// Let's create the windows which will serve as containers for our SFML views
|
||||
Window view1 = XCreateWindow(display, window,
|
||||
10, 10, 310, 310, 0,
|
||||
DefaultDepth(display, screen),
|
||||
InputOutput,
|
||||
DefaultVisual(display, screen),
|
||||
0, NULL);
|
||||
Window view2 = XCreateWindow(display, window,
|
||||
330, 10, 310, 310, 0,
|
||||
DefaultDepth(display, screen),
|
||||
InputOutput,
|
||||
DefaultVisual(display, screen),
|
||||
0, NULL);
|
||||
|
||||
// Show our windows
|
||||
XMapWindow(display, window);
|
||||
XFlush(display);
|
||||
|
||||
// Create our SFML views
|
||||
sf::Window SFMLView1(view1);
|
||||
sf::Window SFMLView2(view2);
|
||||
|
||||
// Create a clock for measuring elapsed time
|
||||
sf::Clock clock;
|
||||
|
||||
// Initialize our views
|
||||
initialize(SFMLView1);
|
||||
initialize(SFMLView2);
|
||||
|
||||
// Start the event loop
|
||||
bool running = true;
|
||||
while (running)
|
||||
{
|
||||
while (XPending(display))
|
||||
{
|
||||
// Get the next pending event
|
||||
XEvent event;
|
||||
XNextEvent(display, &event);
|
||||
|
||||
// Process it
|
||||
switch (event.type)
|
||||
{
|
||||
// Any key is pressed : quit
|
||||
case KeyPress :
|
||||
running = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Draw something into our views
|
||||
draw(SFMLView1, clock.getElapsedTime().asSeconds());
|
||||
draw(SFMLView2, clock.getElapsedTime().asSeconds() * 0.3f);
|
||||
|
||||
// Display the views on screen
|
||||
SFMLView1.display();
|
||||
SFMLView2.display();
|
||||
}
|
||||
|
||||
// Close the display
|
||||
XCloseDisplay(display);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Window.hpp>
|
||||
#include <X11/Xlib.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// 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();
|
||||
gluPerspective(90.f, 1.f, 1.f, 500.f);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// 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);
|
||||
glRotatef(elapsedTime * 0.05f, 1.f, 0.f, 0.f);
|
||||
glRotatef(elapsedTime * 0.03f, 0.f, 1.f, 0.f);
|
||||
glRotatef(elapsedTime * 0.09f, 0.f, 0.f, 1.f);
|
||||
|
||||
// Draw a cube
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
glColor3f(1.f, 1.f, 0.f);
|
||||
glVertex3f(-50.f, -50.f, -50.f);
|
||||
glVertex3f(-50.f, 50.f, -50.f);
|
||||
glVertex3f( 50.f, 50.f, -50.f);
|
||||
glVertex3f( 50.f, -50.f, -50.f);
|
||||
|
||||
glColor3f(1.f, 1.f, 0.f);
|
||||
glVertex3f(-50.f, -50.f, 50.f);
|
||||
glVertex3f(-50.f, 50.f, 50.f);
|
||||
glVertex3f( 50.f, 50.f, 50.f);
|
||||
glVertex3f( 50.f, -50.f, 50.f);
|
||||
|
||||
glColor3f(0.f, 1.f, 1.f);
|
||||
glVertex3f(-50.f, -50.f, -50.f);
|
||||
glVertex3f(-50.f, 50.f, -50.f);
|
||||
glVertex3f(-50.f, 50.f, 50.f);
|
||||
glVertex3f(-50.f, -50.f, 50.f);
|
||||
|
||||
glColor3f(0.f, 1.f, 1.f);
|
||||
glVertex3f(50.f, -50.f, -50.f);
|
||||
glVertex3f(50.f, 50.f, -50.f);
|
||||
glVertex3f(50.f, 50.f, 50.f);
|
||||
glVertex3f(50.f, -50.f, 50.f);
|
||||
|
||||
glColor3f(1.f, 0.f, 1.f);
|
||||
glVertex3f(-50.f, -50.f, 50.f);
|
||||
glVertex3f(-50.f, -50.f, -50.f);
|
||||
glVertex3f( 50.f, -50.f, -50.f);
|
||||
glVertex3f( 50.f, -50.f, 50.f);
|
||||
|
||||
glColor3f(1.f, 0.f, 1.f);
|
||||
glVertex3f(-50.f, 50.f, 50.f);
|
||||
glVertex3f(-50.f, 50.f, -50.f);
|
||||
glVertex3f( 50.f, 50.f, -50.f);
|
||||
glVertex3f( 50.f, 50.f, 50.f);
|
||||
|
||||
glEnd();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// 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;
|
||||
|
||||
// Get the default screen
|
||||
int screen = DefaultScreen(display);
|
||||
|
||||
// Let's create the main window
|
||||
XSetWindowAttributes attributes;
|
||||
attributes.background_pixel = BlackPixel(display, screen);
|
||||
attributes.event_mask = KeyPressMask;
|
||||
Window window = XCreateWindow(display, RootWindow(display, screen),
|
||||
0, 0, 650, 330, 0,
|
||||
DefaultDepth(display, screen),
|
||||
InputOutput,
|
||||
DefaultVisual(display, screen),
|
||||
CWBackPixel | CWEventMask, &attributes);
|
||||
if (!window)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
// Set the window's name
|
||||
XStoreName(display, window , "SFML Window");
|
||||
|
||||
// Let's create the windows which will serve as containers for our SFML views
|
||||
Window view1 = XCreateWindow(display, window,
|
||||
10, 10, 310, 310, 0,
|
||||
DefaultDepth(display, screen),
|
||||
InputOutput,
|
||||
DefaultVisual(display, screen),
|
||||
0, NULL);
|
||||
Window view2 = XCreateWindow(display, window,
|
||||
330, 10, 310, 310, 0,
|
||||
DefaultDepth(display, screen),
|
||||
InputOutput,
|
||||
DefaultVisual(display, screen),
|
||||
0, NULL);
|
||||
|
||||
// Show our windows
|
||||
XMapWindow(display, window);
|
||||
XFlush(display);
|
||||
|
||||
// Create our SFML views
|
||||
sf::Window SFMLView1(view1);
|
||||
sf::Window SFMLView2(view2);
|
||||
|
||||
// Create a clock for measuring elapsed time
|
||||
sf::Clock clock;
|
||||
|
||||
// Initialize our views
|
||||
initialize(SFMLView1);
|
||||
initialize(SFMLView2);
|
||||
|
||||
// Start the event loop
|
||||
bool running = true;
|
||||
while (running)
|
||||
{
|
||||
while (XPending(display))
|
||||
{
|
||||
// Get the next pending event
|
||||
XEvent event;
|
||||
XNextEvent(display, &event);
|
||||
|
||||
// Process it
|
||||
switch (event.type)
|
||||
{
|
||||
// Any key is pressed: quit
|
||||
case KeyPress:
|
||||
running = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Draw something into our views
|
||||
draw(SFMLView1, clock.getElapsedTime().asSeconds());
|
||||
draw(SFMLView2, clock.getElapsedTime().asSeconds() * 0.3f);
|
||||
|
||||
// Display the views on screen
|
||||
SFMLView1.display();
|
||||
SFMLView2.display();
|
||||
}
|
||||
|
||||
// Close the display
|
||||
XCloseDisplay(display);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
|
||||
set(SRCROOT ${PROJECT_SOURCE_DIR}/examples/cocoa)
|
||||
|
||||
# all source files
|
||||
set(SRC ${SRCROOT}/CocoaAppDelegate.h
|
||||
|
||||
set(SRCROOT ${PROJECT_SOURCE_DIR}/examples/cocoa)
|
||||
|
||||
# all source files
|
||||
set(SRC ${SRCROOT}/CocoaAppDelegate.h
|
||||
${SRCROOT}/CocoaAppDelegate.mm
|
||||
${SRCROOT}/NSString+stdstring.h
|
||||
${SRCROOT}/NSString+stdstring.mm
|
||||
|
@ -28,9 +28,9 @@ set_target_properties(cocoa PROPERTIES
|
|||
MACOSX_BUNDLE_INFO_PLIST ${SRCROOT}/resources/Cocoa-Info.plist)
|
||||
target_link_libraries(cocoa "-framework Cocoa -framework Foundation"
|
||||
sfml-system sfml-window sfml-graphics)
|
||||
|
||||
# set the target's folder (for IDEs that support it, e.g. Visual Studio)
|
||||
set_target_properties(cocoa PROPERTIES FOLDER "Examples")
|
||||
|
||||
# set the target's folder (for IDEs that support it, e.g. Visual Studio)
|
||||
set_target_properties(cocoa PROPERTIES FOLDER "Examples")
|
||||
|
||||
# compile XIB files
|
||||
find_program(IBTOOL ibtool HINTS "/usr/bin" "${OSX_DEVELOPER_ROOT}/usr/bin")
|
||||
|
@ -48,20 +48,20 @@ foreach(XIB ${XIBS})
|
|||
--compile ${XIB_OUTPUT_PATH}/${XIB}.nib
|
||||
${XIB_INPUT_PATH}/${XIB}.xib
|
||||
COMMENT "Compiling ${XIB}.xib")
|
||||
# deactivated options : --warnings --notices
|
||||
# deactivated options: --warnings --notices
|
||||
endforeach()
|
||||
|
||||
# add install rule
|
||||
install(TARGETS cocoa
|
||||
install(TARGETS cocoa
|
||||
BUNDLE DESTINATION ${INSTALL_MISC_DIR}/examples/cocoa
|
||||
COMPONENT examples)
|
||||
COMPONENT examples)
|
||||
|
||||
#
|
||||
#
|
||||
# define the cocoa target
|
||||
# sfml_add_example is not compatible with application bundles !
|
||||
#
|
||||
#sfml_add_example(cocoa
|
||||
# SOURCES ${SRC}
|
||||
#
|
||||
#sfml_add_example(cocoa
|
||||
# SOURCES ${SRC}
|
||||
# DEPENDS sfml-system sfml-window sfml-graphics)
|
||||
#
|
||||
|
||||
|
||||
|
|
|
@ -27,11 +27,11 @@
|
|||
#import <SFML/Graphics.hpp>
|
||||
|
||||
/*
|
||||
* NB : We need pointers for C++ objects fields in Obj-C interface !
|
||||
* The recommended way is to use PIMP idiom.
|
||||
* NB: We need pointers for C++ objects fields in Obj-C interface !
|
||||
* The recommended way is to use PIMPL idiom.
|
||||
*
|
||||
* It's elegant. Moreover, we do no constrain
|
||||
* other file including this one to be Obj-C++.
|
||||
* It's elegant. Moreover, we do no constrain
|
||||
* other file including this one to be Obj-C++.
|
||||
*/
|
||||
|
||||
struct SFMLmainWindow;
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
|
||||
set(SRCROOT ${PROJECT_SOURCE_DIR}/examples/ftp)
|
||||
|
||||
# all source files
|
||||
set(SRC ${SRCROOT}/Ftp.cpp)
|
||||
|
||||
# define the ftp target
|
||||
sfml_add_example(ftp
|
||||
SOURCES ${SRC}
|
||||
DEPENDS sfml-network sfml-system)
|
||||
|
||||
set(SRCROOT ${PROJECT_SOURCE_DIR}/examples/ftp)
|
||||
|
||||
# all source files
|
||||
set(SRC ${SRCROOT}/Ftp.cpp)
|
||||
|
||||
# define the ftp target
|
||||
sfml_add_example(ftp
|
||||
SOURCES ${SRC}
|
||||
DEPENDS sfml-network sfml-system)
|
||||
|
|
|
@ -1,206 +1,206 @@
|
|||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Network.hpp>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Print a FTP response into a standard output stream
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
std::ostream& operator <<(std::ostream& stream, const sf::Ftp::Response& response)
|
||||
{
|
||||
return stream << response.getStatus() << response.getMessage();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Entry point of application
|
||||
///
|
||||
/// \return Application exit code
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
int main()
|
||||
{
|
||||
// Choose the server address
|
||||
sf::IpAddress address;
|
||||
do
|
||||
{
|
||||
std::cout << "Enter the FTP server address : ";
|
||||
std::cin >> address;
|
||||
}
|
||||
while (address == sf::IpAddress::None);
|
||||
|
||||
// Connect to the server
|
||||
sf::Ftp server;
|
||||
sf::Ftp::Response connectResponse = server.connect(address);
|
||||
std::cout << connectResponse << std::endl;
|
||||
if (!connectResponse.isOk())
|
||||
return EXIT_FAILURE;
|
||||
|
||||
// Ask for user name and password
|
||||
std::string user, password;
|
||||
std::cout << "User name : ";
|
||||
std::cin >> user;
|
||||
std::cout << "Password : ";
|
||||
std::cin >> password;
|
||||
|
||||
// Login to the server
|
||||
sf::Ftp::Response loginResponse = server.login(user, password);
|
||||
std::cout << loginResponse << std::endl;
|
||||
if (!loginResponse.isOk())
|
||||
return EXIT_FAILURE;
|
||||
|
||||
// Main menu
|
||||
int choice = 0;
|
||||
do
|
||||
{
|
||||
// Main FTP menu
|
||||
std::cout << std::endl;
|
||||
std::cout << "Choose an action:" << std::endl;
|
||||
std::cout << "1. Print working directory" << std::endl;
|
||||
std::cout << "2. Print contents of working directory" << std::endl;
|
||||
std::cout << "3. Change directory" << std::endl;
|
||||
std::cout << "4. Create directory" << std::endl;
|
||||
std::cout << "5. Delete directory" << std::endl;
|
||||
std::cout << "6. Rename file" << std::endl;
|
||||
std::cout << "7. Remove file" << std::endl;
|
||||
std::cout << "8. Download file" << std::endl;
|
||||
std::cout << "9. Upload file" << std::endl;
|
||||
std::cout << "0. Disconnect" << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << "Your choice: ";
|
||||
std::cin >> choice;
|
||||
std::cout << std::endl;
|
||||
|
||||
switch (choice)
|
||||
{
|
||||
default :
|
||||
{
|
||||
// Wrong choice
|
||||
std::cout << "Invalid choice!" << std::endl;
|
||||
std::cin.clear();
|
||||
std::cin.ignore(10000, '\n');
|
||||
break;
|
||||
}
|
||||
|
||||
case 1 :
|
||||
{
|
||||
// Print the current server directory
|
||||
sf::Ftp::DirectoryResponse response = server.getWorkingDirectory();
|
||||
std::cout << response << std::endl;
|
||||
std::cout << "Current directory is " << response.getDirectory() << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
case 2 :
|
||||
{
|
||||
// Print the contents of the current server directory
|
||||
sf::Ftp::ListingResponse response = server.getDirectoryListing();
|
||||
std::cout << response << std::endl;
|
||||
const std::vector<std::string>& names = response.getListing();
|
||||
for (std::vector<std::string>::const_iterator it = names.begin(); it != names.end(); ++it)
|
||||
std::cout << *it << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
case 3 :
|
||||
{
|
||||
// Change the current directory
|
||||
std::string directory;
|
||||
std::cout << "Choose a directory: ";
|
||||
std::cin >> directory;
|
||||
std::cout << server.changeDirectory(directory) << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
case 4 :
|
||||
{
|
||||
// Create a new directory
|
||||
std::string directory;
|
||||
std::cout << "Name of the directory to create: ";
|
||||
std::cin >> directory;
|
||||
std::cout << server.createDirectory(directory) << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
case 5 :
|
||||
{
|
||||
// Remove an existing directory
|
||||
std::string directory;
|
||||
std::cout << "Name of the directory to remove: ";
|
||||
std::cin >> directory;
|
||||
std::cout << server.deleteDirectory(directory) << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
case 6 :
|
||||
{
|
||||
// Rename a file
|
||||
std::string source, destination;
|
||||
std::cout << "Name of the file to rename: ";
|
||||
std::cin >> source;
|
||||
std::cout << "New name: ";
|
||||
std::cin >> destination;
|
||||
std::cout << server.renameFile(source, destination) << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
case 7 :
|
||||
{
|
||||
// Remove an existing directory
|
||||
std::string filename;
|
||||
std::cout << "Name of the file to remove: ";
|
||||
std::cin >> filename;
|
||||
std::cout << server.deleteFile(filename) << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
case 8 :
|
||||
{
|
||||
// Download a file from server
|
||||
std::string filename, directory;
|
||||
std::cout << "Filename of the file to download (relative to current directory): ";
|
||||
std::cin >> filename;
|
||||
std::cout << "Directory to download the file to: ";
|
||||
std::cin >> directory;
|
||||
std::cout << server.download(filename, directory) << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
case 9 :
|
||||
{
|
||||
// Upload a file to server
|
||||
std::string filename, directory;
|
||||
std::cout << "Path of the file to upload (absolute or relative to working directory): ";
|
||||
std::cin >> filename;
|
||||
std::cout << "Directory to upload the file to (relative to current directory): ";
|
||||
std::cin >> directory;
|
||||
std::cout << server.upload(filename, directory) << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
case 0 :
|
||||
{
|
||||
// Disconnect
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} while (choice != 0);
|
||||
|
||||
// Disconnect from the server
|
||||
std::cout << "Disconnecting from server..." << std::endl;
|
||||
std::cout << server.disconnect() << std::endl;
|
||||
|
||||
// Wait until the user presses 'enter' key
|
||||
std::cout << "Press enter to exit..." << std::endl;
|
||||
std::cin.ignore(10000, '\n');
|
||||
std::cin.ignore(10000, '\n');
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Network.hpp>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Print a FTP response into a standard output stream
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
std::ostream& operator <<(std::ostream& stream, const sf::Ftp::Response& response)
|
||||
{
|
||||
return stream << response.getStatus() << response.getMessage();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Entry point of application
|
||||
///
|
||||
/// \return Application exit code
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
int main()
|
||||
{
|
||||
// Choose the server address
|
||||
sf::IpAddress address;
|
||||
do
|
||||
{
|
||||
std::cout << "Enter the FTP server address: ";
|
||||
std::cin >> address;
|
||||
}
|
||||
while (address == sf::IpAddress::None);
|
||||
|
||||
// Connect to the server
|
||||
sf::Ftp server;
|
||||
sf::Ftp::Response connectResponse = server.connect(address);
|
||||
std::cout << connectResponse << std::endl;
|
||||
if (!connectResponse.isOk())
|
||||
return EXIT_FAILURE;
|
||||
|
||||
// Ask for user name and password
|
||||
std::string user, password;
|
||||
std::cout << "User name: ";
|
||||
std::cin >> user;
|
||||
std::cout << "Password: ";
|
||||
std::cin >> password;
|
||||
|
||||
// Login to the server
|
||||
sf::Ftp::Response loginResponse = server.login(user, password);
|
||||
std::cout << loginResponse << std::endl;
|
||||
if (!loginResponse.isOk())
|
||||
return EXIT_FAILURE;
|
||||
|
||||
// Main menu
|
||||
int choice = 0;
|
||||
do
|
||||
{
|
||||
// Main FTP menu
|
||||
std::cout << std::endl;
|
||||
std::cout << "Choose an action:" << std::endl;
|
||||
std::cout << "1. Print working directory" << std::endl;
|
||||
std::cout << "2. Print contents of working directory" << std::endl;
|
||||
std::cout << "3. Change directory" << std::endl;
|
||||
std::cout << "4. Create directory" << std::endl;
|
||||
std::cout << "5. Delete directory" << std::endl;
|
||||
std::cout << "6. Rename file" << std::endl;
|
||||
std::cout << "7. Remove file" << std::endl;
|
||||
std::cout << "8. Download file" << std::endl;
|
||||
std::cout << "9. Upload file" << std::endl;
|
||||
std::cout << "0. Disconnect" << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << "Your choice: ";
|
||||
std::cin >> choice;
|
||||
std::cout << std::endl;
|
||||
|
||||
switch (choice)
|
||||
{
|
||||
default:
|
||||
{
|
||||
// Wrong choice
|
||||
std::cout << "Invalid choice!" << std::endl;
|
||||
std::cin.clear();
|
||||
std::cin.ignore(10000, '\n');
|
||||
break;
|
||||
}
|
||||
|
||||
case 1:
|
||||
{
|
||||
// Print the current server directory
|
||||
sf::Ftp::DirectoryResponse response = server.getWorkingDirectory();
|
||||
std::cout << response << std::endl;
|
||||
std::cout << "Current directory is " << response.getDirectory() << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
// Print the contents of the current server directory
|
||||
sf::Ftp::ListingResponse response = server.getDirectoryListing();
|
||||
std::cout << response << std::endl;
|
||||
const std::vector<std::string>& names = response.getListing();
|
||||
for (std::vector<std::string>::const_iterator it = names.begin(); it != names.end(); ++it)
|
||||
std::cout << *it << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
case 3:
|
||||
{
|
||||
// Change the current directory
|
||||
std::string directory;
|
||||
std::cout << "Choose a directory: ";
|
||||
std::cin >> directory;
|
||||
std::cout << server.changeDirectory(directory) << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
case 4:
|
||||
{
|
||||
// Create a new directory
|
||||
std::string directory;
|
||||
std::cout << "Name of the directory to create: ";
|
||||
std::cin >> directory;
|
||||
std::cout << server.createDirectory(directory) << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
case 5:
|
||||
{
|
||||
// Remove an existing directory
|
||||
std::string directory;
|
||||
std::cout << "Name of the directory to remove: ";
|
||||
std::cin >> directory;
|
||||
std::cout << server.deleteDirectory(directory) << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
case 6:
|
||||
{
|
||||
// Rename a file
|
||||
std::string source, destination;
|
||||
std::cout << "Name of the file to rename: ";
|
||||
std::cin >> source;
|
||||
std::cout << "New name: ";
|
||||
std::cin >> destination;
|
||||
std::cout << server.renameFile(source, destination) << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
case 7:
|
||||
{
|
||||
// Remove an existing directory
|
||||
std::string filename;
|
||||
std::cout << "Name of the file to remove: ";
|
||||
std::cin >> filename;
|
||||
std::cout << server.deleteFile(filename) << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
case 8:
|
||||
{
|
||||
// Download a file from server
|
||||
std::string filename, directory;
|
||||
std::cout << "Filename of the file to download (relative to current directory): ";
|
||||
std::cin >> filename;
|
||||
std::cout << "Directory to download the file to: ";
|
||||
std::cin >> directory;
|
||||
std::cout << server.download(filename, directory) << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
case 9:
|
||||
{
|
||||
// Upload a file to server
|
||||
std::string filename, directory;
|
||||
std::cout << "Path of the file to upload (absolute or relative to working directory): ";
|
||||
std::cin >> filename;
|
||||
std::cout << "Directory to upload the file to (relative to current directory): ";
|
||||
std::cin >> directory;
|
||||
std::cout << server.upload(filename, directory) << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
case 0:
|
||||
{
|
||||
// Disconnect
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} while (choice != 0);
|
||||
|
||||
// Disconnect from the server
|
||||
std::cout << "Disconnecting from server..." << std::endl;
|
||||
std::cout << server.disconnect() << std::endl;
|
||||
|
||||
// Wait until the user presses 'enter' key
|
||||
std::cout << "Press enter to exit..." << std::endl;
|
||||
std::cin.ignore(10000, '\n');
|
||||
std::cin.ignore(10000, '\n');
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
|
||||
set(SRCROOT ${PROJECT_SOURCE_DIR}/examples/opengl)
|
||||
|
||||
# all source files
|
||||
set(SRC ${SRCROOT}/OpenGL.cpp)
|
||||
|
||||
# find OpenGL and GLU
|
||||
find_package(OpenGL REQUIRED)
|
||||
include_directories(${OPENGL_INCLUDE_DIR})
|
||||
set(ADDITIONAL_LIBRARIES ${OPENGL_LIBRARIES})
|
||||
|
||||
# define the opengl target
|
||||
sfml_add_example(opengl GUI_APP
|
||||
SOURCES ${SRC}
|
||||
DEPENDS sfml-graphics sfml-window sfml-system ${ADDITIONAL_LIBRARIES})
|
||||
|
||||
set(SRCROOT ${PROJECT_SOURCE_DIR}/examples/opengl)
|
||||
|
||||
# all source files
|
||||
set(SRC ${SRCROOT}/OpenGL.cpp)
|
||||
|
||||
# find OpenGL and GLU
|
||||
find_package(OpenGL REQUIRED)
|
||||
include_directories(${OPENGL_INCLUDE_DIR})
|
||||
set(ADDITIONAL_LIBRARIES ${OPENGL_LIBRARIES})
|
||||
|
||||
# define the opengl target
|
||||
sfml_add_example(opengl GUI_APP
|
||||
SOURCES ${SRC}
|
||||
DEPENDS sfml-graphics sfml-window sfml-system ${ADDITIONAL_LIBRARIES})
|
||||
|
|
|
@ -1,198 +1,198 @@
|
|||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include <SFML/OpenGL.hpp>
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Entry point of application
|
||||
///
|
||||
/// \return Application exit code
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
int main()
|
||||
{
|
||||
// Request a 32-bits depth buffer when creating the window
|
||||
sf::ContextSettings contextSettings;
|
||||
contextSettings.depthBits = 32;
|
||||
|
||||
// Create the main window
|
||||
sf::RenderWindow window(sf::VideoMode(800, 600), "SFML graphics with OpenGL", sf::Style::Default, contextSettings);
|
||||
window.setVerticalSyncEnabled(true);
|
||||
|
||||
// Create a sprite for the background
|
||||
sf::Texture backgroundTexture;
|
||||
if (!backgroundTexture.loadFromFile("resources/background.jpg"))
|
||||
return EXIT_FAILURE;
|
||||
sf::Sprite background(backgroundTexture);
|
||||
|
||||
// Create some text to draw on top of our OpenGL object
|
||||
sf::Font font;
|
||||
if (!font.loadFromFile("resources/sansation.ttf"))
|
||||
return EXIT_FAILURE;
|
||||
sf::Text text("SFML / OpenGL demo", font);
|
||||
text.setColor(sf::Color(255, 255, 255, 170));
|
||||
text.setPosition(250.f, 450.f);
|
||||
|
||||
// Make the window the active target for OpenGL calls
|
||||
// Note: If using sf::Texture or sf::Shader with OpenGL,
|
||||
// be sure to call sf::Texture::getMaximumSize() and/or
|
||||
// sf::Shader::isAvailable() at least once before calling
|
||||
// setActive(), as those functions will cause a context switch
|
||||
window.setActive();
|
||||
|
||||
// Load an OpenGL texture.
|
||||
// We could directly use a sf::Texture as an OpenGL texture (with its Bind() member function),
|
||||
// but here we want more control on it (generate mipmaps, ...) so we create a new one from an image
|
||||
GLuint texture = 0;
|
||||
{
|
||||
sf::Image image;
|
||||
if (!image.loadFromFile("resources/texture.jpg"))
|
||||
return EXIT_FAILURE;
|
||||
glGenTextures(1, &texture);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, image.getSize().x, image.getSize().y, GL_RGBA, GL_UNSIGNED_BYTE, image.getPixelsPtr());
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
}
|
||||
|
||||
// Enable Z-buffer read and write
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_TRUE);
|
||||
glClearDepth(1.f);
|
||||
|
||||
// Disable lighting
|
||||
glDisable(GL_LIGHTING);
|
||||
|
||||
// Configure the viewport (the same size as the window)
|
||||
glViewport(0, 0, window.getSize().x, window.getSize().y);
|
||||
|
||||
// Setup a perspective projection
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
GLfloat ratio = static_cast<float>(window.getSize().x) / window.getSize().y;
|
||||
glFrustum(-ratio, ratio, -1.f, 1.f, 1.f, 500.f);
|
||||
|
||||
// Bind the texture
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
|
||||
// Define a 3D cube (6 faces made of 2 triangles composed by 3 vertices)
|
||||
GLfloat cube[] =
|
||||
{
|
||||
// positions // texture coordinates
|
||||
-20, -20, -20, 0, 0,
|
||||
-20, 20, -20, 1, 0,
|
||||
-20, -20, 20, 0, 1,
|
||||
-20, -20, 20, 0, 1,
|
||||
-20, 20, -20, 1, 0,
|
||||
-20, 20, 20, 1, 1,
|
||||
|
||||
20, -20, -20, 0, 0,
|
||||
20, 20, -20, 1, 0,
|
||||
20, -20, 20, 0, 1,
|
||||
20, -20, 20, 0, 1,
|
||||
20, 20, -20, 1, 0,
|
||||
20, 20, 20, 1, 1,
|
||||
|
||||
-20, -20, -20, 0, 0,
|
||||
20, -20, -20, 1, 0,
|
||||
-20, -20, 20, 0, 1,
|
||||
-20, -20, 20, 0, 1,
|
||||
20, -20, -20, 1, 0,
|
||||
20, -20, 20, 1, 1,
|
||||
|
||||
-20, 20, -20, 0, 0,
|
||||
20, 20, -20, 1, 0,
|
||||
-20, 20, 20, 0, 1,
|
||||
-20, 20, 20, 0, 1,
|
||||
20, 20, -20, 1, 0,
|
||||
20, 20, 20, 1, 1,
|
||||
|
||||
-20, -20, -20, 0, 0,
|
||||
20, -20, -20, 1, 0,
|
||||
-20, 20, -20, 0, 1,
|
||||
-20, 20, -20, 0, 1,
|
||||
20, -20, -20, 1, 0,
|
||||
20, 20, -20, 1, 1,
|
||||
|
||||
-20, -20, 20, 0, 0,
|
||||
20, -20, 20, 1, 0,
|
||||
-20, 20, 20, 0, 1,
|
||||
-20, 20, 20, 0, 1,
|
||||
20, -20, 20, 1, 0,
|
||||
20, 20, 20, 1, 1
|
||||
};
|
||||
|
||||
// Enable position and texture coordinates vertex components
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glVertexPointer(3, GL_FLOAT, 5 * sizeof(GLfloat), cube);
|
||||
glTexCoordPointer(2, GL_FLOAT, 5 * sizeof(GLfloat), cube + 3);
|
||||
|
||||
// Disable normal and color vertex components
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
|
||||
// Create a clock for measuring the time elapsed
|
||||
sf::Clock clock;
|
||||
|
||||
// Start game loop
|
||||
while (window.isOpen())
|
||||
{
|
||||
// Process events
|
||||
sf::Event event;
|
||||
while (window.pollEvent(event))
|
||||
{
|
||||
// Close window : exit
|
||||
if (event.type == sf::Event::Closed)
|
||||
window.close();
|
||||
|
||||
// Escape key : exit
|
||||
if ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Escape))
|
||||
window.close();
|
||||
|
||||
// Adjust the viewport when the window is resized
|
||||
if (event.type == sf::Event::Resized)
|
||||
glViewport(0, 0, event.size.width, event.size.height);
|
||||
}
|
||||
|
||||
// Draw the background
|
||||
window.pushGLStates();
|
||||
window.draw(background);
|
||||
window.popGLStates();
|
||||
|
||||
// Clear the depth buffer
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// We get the position of the mouse cursor, so that we can move the box accordingly
|
||||
float x = sf::Mouse::getPosition(window).x * 200.f / window.getSize().x - 100.f;
|
||||
float y = -sf::Mouse::getPosition(window).y * 200.f / window.getSize().y + 100.f;
|
||||
|
||||
// Apply some transformations
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glTranslatef(x, y, -100.f);
|
||||
glRotatef(clock.getElapsedTime().asSeconds() * 50.f, 1.f, 0.f, 0.f);
|
||||
glRotatef(clock.getElapsedTime().asSeconds() * 30.f, 0.f, 1.f, 0.f);
|
||||
glRotatef(clock.getElapsedTime().asSeconds() * 90.f, 0.f, 0.f, 1.f);
|
||||
|
||||
// Draw the cube
|
||||
glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||
|
||||
// Draw some text on top of our OpenGL object
|
||||
window.pushGLStates();
|
||||
window.draw(text);
|
||||
window.popGLStates();
|
||||
|
||||
// Finally, display the rendered frame on screen
|
||||
window.display();
|
||||
}
|
||||
|
||||
// Don't forget to destroy our texture
|
||||
glDeleteTextures(1, &texture);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include <SFML/OpenGL.hpp>
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Entry point of application
|
||||
///
|
||||
/// \return Application exit code
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
int main()
|
||||
{
|
||||
// Request a 32-bits depth buffer when creating the window
|
||||
sf::ContextSettings contextSettings;
|
||||
contextSettings.depthBits = 32;
|
||||
|
||||
// Create the main window
|
||||
sf::RenderWindow window(sf::VideoMode(800, 600), "SFML graphics with OpenGL", sf::Style::Default, contextSettings);
|
||||
window.setVerticalSyncEnabled(true);
|
||||
|
||||
// Create a sprite for the background
|
||||
sf::Texture backgroundTexture;
|
||||
if (!backgroundTexture.loadFromFile("resources/background.jpg"))
|
||||
return EXIT_FAILURE;
|
||||
sf::Sprite background(backgroundTexture);
|
||||
|
||||
// Create some text to draw on top of our OpenGL object
|
||||
sf::Font font;
|
||||
if (!font.loadFromFile("resources/sansation.ttf"))
|
||||
return EXIT_FAILURE;
|
||||
sf::Text text("SFML / OpenGL demo", font);
|
||||
text.setColor(sf::Color(255, 255, 255, 170));
|
||||
text.setPosition(250.f, 450.f);
|
||||
|
||||
// Make the window the active target for OpenGL calls
|
||||
// Note: If using sf::Texture or sf::Shader with OpenGL,
|
||||
// be sure to call sf::Texture::getMaximumSize() and/or
|
||||
// sf::Shader::isAvailable() at least once before calling
|
||||
// setActive(), as those functions will cause a context switch
|
||||
window.setActive();
|
||||
|
||||
// Load an OpenGL texture.
|
||||
// We could directly use a sf::Texture as an OpenGL texture (with its Bind() member function),
|
||||
// but here we want more control on it (generate mipmaps, ...) so we create a new one from an image
|
||||
GLuint texture = 0;
|
||||
{
|
||||
sf::Image image;
|
||||
if (!image.loadFromFile("resources/texture.jpg"))
|
||||
return EXIT_FAILURE;
|
||||
glGenTextures(1, &texture);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, image.getSize().x, image.getSize().y, GL_RGBA, GL_UNSIGNED_BYTE, image.getPixelsPtr());
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
}
|
||||
|
||||
// Enable Z-buffer read and write
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_TRUE);
|
||||
glClearDepth(1.f);
|
||||
|
||||
// Disable lighting
|
||||
glDisable(GL_LIGHTING);
|
||||
|
||||
// Configure the viewport (the same size as the window)
|
||||
glViewport(0, 0, window.getSize().x, window.getSize().y);
|
||||
|
||||
// Setup a perspective projection
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
GLfloat ratio = static_cast<float>(window.getSize().x) / window.getSize().y;
|
||||
glFrustum(-ratio, ratio, -1.f, 1.f, 1.f, 500.f);
|
||||
|
||||
// Bind the texture
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
|
||||
// Define a 3D cube (6 faces made of 2 triangles composed by 3 vertices)
|
||||
GLfloat cube[] =
|
||||
{
|
||||
// positions // texture coordinates
|
||||
-20, -20, -20, 0, 0,
|
||||
-20, 20, -20, 1, 0,
|
||||
-20, -20, 20, 0, 1,
|
||||
-20, -20, 20, 0, 1,
|
||||
-20, 20, -20, 1, 0,
|
||||
-20, 20, 20, 1, 1,
|
||||
|
||||
20, -20, -20, 0, 0,
|
||||
20, 20, -20, 1, 0,
|
||||
20, -20, 20, 0, 1,
|
||||
20, -20, 20, 0, 1,
|
||||
20, 20, -20, 1, 0,
|
||||
20, 20, 20, 1, 1,
|
||||
|
||||
-20, -20, -20, 0, 0,
|
||||
20, -20, -20, 1, 0,
|
||||
-20, -20, 20, 0, 1,
|
||||
-20, -20, 20, 0, 1,
|
||||
20, -20, -20, 1, 0,
|
||||
20, -20, 20, 1, 1,
|
||||
|
||||
-20, 20, -20, 0, 0,
|
||||
20, 20, -20, 1, 0,
|
||||
-20, 20, 20, 0, 1,
|
||||
-20, 20, 20, 0, 1,
|
||||
20, 20, -20, 1, 0,
|
||||
20, 20, 20, 1, 1,
|
||||
|
||||
-20, -20, -20, 0, 0,
|
||||
20, -20, -20, 1, 0,
|
||||
-20, 20, -20, 0, 1,
|
||||
-20, 20, -20, 0, 1,
|
||||
20, -20, -20, 1, 0,
|
||||
20, 20, -20, 1, 1,
|
||||
|
||||
-20, -20, 20, 0, 0,
|
||||
20, -20, 20, 1, 0,
|
||||
-20, 20, 20, 0, 1,
|
||||
-20, 20, 20, 0, 1,
|
||||
20, -20, 20, 1, 0,
|
||||
20, 20, 20, 1, 1
|
||||
};
|
||||
|
||||
// Enable position and texture coordinates vertex components
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glVertexPointer(3, GL_FLOAT, 5 * sizeof(GLfloat), cube);
|
||||
glTexCoordPointer(2, GL_FLOAT, 5 * sizeof(GLfloat), cube + 3);
|
||||
|
||||
// Disable normal and color vertex components
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
|
||||
// Create a clock for measuring the time elapsed
|
||||
sf::Clock clock;
|
||||
|
||||
// Start game loop
|
||||
while (window.isOpen())
|
||||
{
|
||||
// Process events
|
||||
sf::Event event;
|
||||
while (window.pollEvent(event))
|
||||
{
|
||||
// Close window: exit
|
||||
if (event.type == sf::Event::Closed)
|
||||
window.close();
|
||||
|
||||
// Escape key: exit
|
||||
if ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Escape))
|
||||
window.close();
|
||||
|
||||
// Adjust the viewport when the window is resized
|
||||
if (event.type == sf::Event::Resized)
|
||||
glViewport(0, 0, event.size.width, event.size.height);
|
||||
}
|
||||
|
||||
// Draw the background
|
||||
window.pushGLStates();
|
||||
window.draw(background);
|
||||
window.popGLStates();
|
||||
|
||||
// Clear the depth buffer
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// We get the position of the mouse cursor, so that we can move the box accordingly
|
||||
float x = sf::Mouse::getPosition(window).x * 200.f / window.getSize().x - 100.f;
|
||||
float y = -sf::Mouse::getPosition(window).y * 200.f / window.getSize().y + 100.f;
|
||||
|
||||
// Apply some transformations
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glTranslatef(x, y, -100.f);
|
||||
glRotatef(clock.getElapsedTime().asSeconds() * 50.f, 1.f, 0.f, 0.f);
|
||||
glRotatef(clock.getElapsedTime().asSeconds() * 30.f, 0.f, 1.f, 0.f);
|
||||
glRotatef(clock.getElapsedTime().asSeconds() * 90.f, 0.f, 0.f, 1.f);
|
||||
|
||||
// Draw the cube
|
||||
glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||
|
||||
// Draw some text on top of our OpenGL object
|
||||
window.pushGLStates();
|
||||
window.draw(text);
|
||||
window.popGLStates();
|
||||
|
||||
// Finally, display the rendered frame on screen
|
||||
window.display();
|
||||
}
|
||||
|
||||
// Don't forget to destroy our texture
|
||||
glDeleteTextures(1, &texture);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
|
||||
set(SRCROOT ${PROJECT_SOURCE_DIR}/examples/pong)
|
||||
|
||||
# all source files
|
||||
set(SRC ${SRCROOT}/Pong.cpp)
|
||||
|
||||
# define the pong target
|
||||
sfml_add_example(pong GUI_APP
|
||||
SOURCES ${SRC}
|
||||
DEPENDS sfml-audio sfml-graphics sfml-window sfml-system)
|
||||
|
||||
set(SRCROOT ${PROJECT_SOURCE_DIR}/examples/pong)
|
||||
|
||||
# all source files
|
||||
set(SRC ${SRCROOT}/Pong.cpp)
|
||||
|
||||
# define the pong target
|
||||
sfml_add_example(pong GUI_APP
|
||||
SOURCES ${SRC}
|
||||
DEPENDS sfml-audio sfml-graphics sfml-window sfml-system)
|
||||
|
|
|
@ -1,241 +1,241 @@
|
|||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include <SFML/Audio.hpp>
|
||||
#include <cmath>
|
||||
#include <ctime>
|
||||
#include <cstdlib>
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Entry point of application
|
||||
///
|
||||
/// \return Application exit code
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
int main()
|
||||
{
|
||||
std::srand(static_cast<unsigned int>(std::time(NULL)));
|
||||
|
||||
// Define some constants
|
||||
const float pi = 3.14159f;
|
||||
const int gameWidth = 800;
|
||||
const int gameHeight = 600;
|
||||
sf::Vector2f paddleSize(25, 100);
|
||||
float ballRadius = 10.f;
|
||||
|
||||
// Create the window of the application
|
||||
sf::RenderWindow window(sf::VideoMode(gameWidth, gameHeight, 32), "SFML Pong");
|
||||
window.setVerticalSyncEnabled(true);
|
||||
|
||||
// Load the sounds used in the game
|
||||
sf::SoundBuffer ballSoundBuffer;
|
||||
if (!ballSoundBuffer.loadFromFile("resources/ball.wav"))
|
||||
return EXIT_FAILURE;
|
||||
sf::Sound ballSound(ballSoundBuffer);
|
||||
|
||||
// Create the left paddle
|
||||
sf::RectangleShape leftPaddle;
|
||||
leftPaddle.setSize(paddleSize - sf::Vector2f(3, 3));
|
||||
leftPaddle.setOutlineThickness(3);
|
||||
leftPaddle.setOutlineColor(sf::Color::Black);
|
||||
leftPaddle.setFillColor(sf::Color(100, 100, 200));
|
||||
leftPaddle.setOrigin(paddleSize / 2.f);
|
||||
|
||||
// Create the right paddle
|
||||
sf::RectangleShape rightPaddle;
|
||||
rightPaddle.setSize(paddleSize - sf::Vector2f(3, 3));
|
||||
rightPaddle.setOutlineThickness(3);
|
||||
rightPaddle.setOutlineColor(sf::Color::Black);
|
||||
rightPaddle.setFillColor(sf::Color(200, 100, 100));
|
||||
rightPaddle.setOrigin(paddleSize / 2.f);
|
||||
|
||||
// Create the ball
|
||||
sf::CircleShape ball;
|
||||
ball.setRadius(ballRadius - 3);
|
||||
ball.setOutlineThickness(3);
|
||||
ball.setOutlineColor(sf::Color::Black);
|
||||
ball.setFillColor(sf::Color::White);
|
||||
ball.setOrigin(ballRadius / 2, ballRadius / 2);
|
||||
|
||||
// Load the text font
|
||||
sf::Font font;
|
||||
if (!font.loadFromFile("resources/sansation.ttf"))
|
||||
return EXIT_FAILURE;
|
||||
|
||||
// Initialize the pause message
|
||||
sf::Text pauseMessage;
|
||||
pauseMessage.setFont(font);
|
||||
pauseMessage.setCharacterSize(40);
|
||||
pauseMessage.setPosition(170.f, 150.f);
|
||||
pauseMessage.setColor(sf::Color::White);
|
||||
pauseMessage.setString("Welcome to SFML pong!\nPress space to start the game");
|
||||
|
||||
// Define the paddles properties
|
||||
sf::Clock AITimer;
|
||||
const sf::Time AITime = sf::seconds(0.1f);
|
||||
const float paddleSpeed = 400.f;
|
||||
float rightPaddleSpeed = 0.f;
|
||||
const float ballSpeed = 400.f;
|
||||
float ballAngle = 0.f; // to be changed later
|
||||
|
||||
sf::Clock clock;
|
||||
bool isPlaying = false;
|
||||
while (window.isOpen())
|
||||
{
|
||||
// Handle events
|
||||
sf::Event event;
|
||||
while (window.pollEvent(event))
|
||||
{
|
||||
// Window closed or escape key pressed: exit
|
||||
if ((event.type == sf::Event::Closed) ||
|
||||
((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Escape)))
|
||||
{
|
||||
window.close();
|
||||
break;
|
||||
}
|
||||
|
||||
// Space key pressed: play
|
||||
if ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Space))
|
||||
{
|
||||
if (!isPlaying)
|
||||
{
|
||||
// (re)start the game
|
||||
isPlaying = true;
|
||||
clock.restart();
|
||||
|
||||
// Reset the position of the paddles and ball
|
||||
leftPaddle.setPosition(10 + paddleSize.x / 2, gameHeight / 2);
|
||||
rightPaddle.setPosition(gameWidth - 10 - paddleSize.x / 2, gameHeight / 2);
|
||||
ball.setPosition(gameWidth / 2, gameHeight / 2);
|
||||
|
||||
// Reset the ball angle
|
||||
do
|
||||
{
|
||||
// Make sure the ball initial angle is not too much vertical
|
||||
ballAngle = (std::rand() % 360) * 2 * pi / 360;
|
||||
}
|
||||
while (std::abs(std::cos(ballAngle)) < 0.7f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isPlaying)
|
||||
{
|
||||
float deltaTime = clock.restart().asSeconds();
|
||||
|
||||
// Move the player's paddle
|
||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up) &&
|
||||
(leftPaddle.getPosition().y - paddleSize.y / 2 > 5.f))
|
||||
{
|
||||
leftPaddle.move(0.f, -paddleSpeed * deltaTime);
|
||||
}
|
||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down) &&
|
||||
(leftPaddle.getPosition().y + paddleSize.y / 2 < gameHeight - 5.f))
|
||||
{
|
||||
leftPaddle.move(0.f, paddleSpeed * deltaTime);
|
||||
}
|
||||
|
||||
// Move the computer's paddle
|
||||
if (((rightPaddleSpeed < 0.f) && (rightPaddle.getPosition().y - paddleSize.y / 2 > 5.f)) ||
|
||||
((rightPaddleSpeed > 0.f) && (rightPaddle.getPosition().y + paddleSize.y / 2 < gameHeight - 5.f)))
|
||||
{
|
||||
rightPaddle.move(0.f, rightPaddleSpeed * deltaTime);
|
||||
}
|
||||
|
||||
// Update the computer's paddle direction according to the ball position
|
||||
if (AITimer.getElapsedTime() > AITime)
|
||||
{
|
||||
AITimer.restart();
|
||||
if (ball.getPosition().y + ballRadius > rightPaddle.getPosition().y + paddleSize.y / 2)
|
||||
rightPaddleSpeed = paddleSpeed;
|
||||
else if (ball.getPosition().y - ballRadius < rightPaddle.getPosition().y - paddleSize.y / 2)
|
||||
rightPaddleSpeed = -paddleSpeed;
|
||||
else
|
||||
rightPaddleSpeed = 0.f;
|
||||
}
|
||||
|
||||
// Move the ball
|
||||
float factor = ballSpeed * deltaTime;
|
||||
ball.move(std::cos(ballAngle) * factor, std::sin(ballAngle) * factor);
|
||||
|
||||
// Check collisions between the ball and the screen
|
||||
if (ball.getPosition().x - ballRadius < 0.f)
|
||||
{
|
||||
isPlaying = false;
|
||||
pauseMessage.setString("You lost!\nPress space to restart or\nescape to exit");
|
||||
}
|
||||
if (ball.getPosition().x + ballRadius > gameWidth)
|
||||
{
|
||||
isPlaying = false;
|
||||
pauseMessage.setString("You won!\nPress space to restart or\nescape to exit");
|
||||
}
|
||||
if (ball.getPosition().y - ballRadius < 0.f)
|
||||
{
|
||||
ballSound.play();
|
||||
ballAngle = -ballAngle;
|
||||
ball.setPosition(ball.getPosition().x, ballRadius + 0.1f);
|
||||
}
|
||||
if (ball.getPosition().y + ballRadius > gameHeight)
|
||||
{
|
||||
ballSound.play();
|
||||
ballAngle = -ballAngle;
|
||||
ball.setPosition(ball.getPosition().x, gameHeight - ballRadius - 0.1f);
|
||||
}
|
||||
|
||||
// Check the collisions between the ball and the paddles
|
||||
// Left Paddle
|
||||
if (ball.getPosition().x - ballRadius < leftPaddle.getPosition().x + paddleSize.x / 2 &&
|
||||
ball.getPosition().x - ballRadius > leftPaddle.getPosition().x &&
|
||||
ball.getPosition().y + ballRadius >= leftPaddle.getPosition().y - paddleSize.y / 2 &&
|
||||
ball.getPosition().y - ballRadius <= leftPaddle.getPosition().y + paddleSize.y / 2)
|
||||
{
|
||||
if (ball.getPosition().y > leftPaddle.getPosition().y)
|
||||
ballAngle = pi - ballAngle + (std::rand() % 20) * pi / 180;
|
||||
else
|
||||
ballAngle = pi - ballAngle - (std::rand() % 20) * pi / 180;
|
||||
|
||||
ballSound.play();
|
||||
ball.setPosition(leftPaddle.getPosition().x + ballRadius + paddleSize.x / 2 + 0.1f, ball.getPosition().y);
|
||||
}
|
||||
|
||||
// Right Paddle
|
||||
if (ball.getPosition().x + ballRadius > rightPaddle.getPosition().x - paddleSize.x / 2 &&
|
||||
ball.getPosition().x + ballRadius < rightPaddle.getPosition().x &&
|
||||
ball.getPosition().y + ballRadius >= rightPaddle.getPosition().y - paddleSize.y / 2 &&
|
||||
ball.getPosition().y - ballRadius <= rightPaddle.getPosition().y + paddleSize.y / 2)
|
||||
{
|
||||
if (ball.getPosition().y > rightPaddle.getPosition().y)
|
||||
ballAngle = pi - ballAngle + (std::rand() % 20) * pi / 180;
|
||||
else
|
||||
ballAngle = pi - ballAngle - (std::rand() % 20) * pi / 180;
|
||||
|
||||
ballSound.play();
|
||||
ball.setPosition(rightPaddle.getPosition().x - ballRadius - paddleSize.x / 2 - 0.1f, ball.getPosition().y);
|
||||
}
|
||||
}
|
||||
|
||||
// Clear the window
|
||||
window.clear(sf::Color(50, 200, 50));
|
||||
|
||||
if (isPlaying)
|
||||
{
|
||||
// Draw the paddles and the ball
|
||||
window.draw(leftPaddle);
|
||||
window.draw(rightPaddle);
|
||||
window.draw(ball);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Draw the pause message
|
||||
window.draw(pauseMessage);
|
||||
}
|
||||
|
||||
// Display things on screen
|
||||
window.display();
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include <SFML/Audio.hpp>
|
||||
#include <cmath>
|
||||
#include <ctime>
|
||||
#include <cstdlib>
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Entry point of application
|
||||
///
|
||||
/// \return Application exit code
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
int main()
|
||||
{
|
||||
std::srand(static_cast<unsigned int>(std::time(NULL)));
|
||||
|
||||
// Define some constants
|
||||
const float pi = 3.14159f;
|
||||
const int gameWidth = 800;
|
||||
const int gameHeight = 600;
|
||||
sf::Vector2f paddleSize(25, 100);
|
||||
float ballRadius = 10.f;
|
||||
|
||||
// Create the window of the application
|
||||
sf::RenderWindow window(sf::VideoMode(gameWidth, gameHeight, 32), "SFML Pong");
|
||||
window.setVerticalSyncEnabled(true);
|
||||
|
||||
// Load the sounds used in the game
|
||||
sf::SoundBuffer ballSoundBuffer;
|
||||
if (!ballSoundBuffer.loadFromFile("resources/ball.wav"))
|
||||
return EXIT_FAILURE;
|
||||
sf::Sound ballSound(ballSoundBuffer);
|
||||
|
||||
// Create the left paddle
|
||||
sf::RectangleShape leftPaddle;
|
||||
leftPaddle.setSize(paddleSize - sf::Vector2f(3, 3));
|
||||
leftPaddle.setOutlineThickness(3);
|
||||
leftPaddle.setOutlineColor(sf::Color::Black);
|
||||
leftPaddle.setFillColor(sf::Color(100, 100, 200));
|
||||
leftPaddle.setOrigin(paddleSize / 2.f);
|
||||
|
||||
// Create the right paddle
|
||||
sf::RectangleShape rightPaddle;
|
||||
rightPaddle.setSize(paddleSize - sf::Vector2f(3, 3));
|
||||
rightPaddle.setOutlineThickness(3);
|
||||
rightPaddle.setOutlineColor(sf::Color::Black);
|
||||
rightPaddle.setFillColor(sf::Color(200, 100, 100));
|
||||
rightPaddle.setOrigin(paddleSize / 2.f);
|
||||
|
||||
// Create the ball
|
||||
sf::CircleShape ball;
|
||||
ball.setRadius(ballRadius - 3);
|
||||
ball.setOutlineThickness(3);
|
||||
ball.setOutlineColor(sf::Color::Black);
|
||||
ball.setFillColor(sf::Color::White);
|
||||
ball.setOrigin(ballRadius / 2, ballRadius / 2);
|
||||
|
||||
// Load the text font
|
||||
sf::Font font;
|
||||
if (!font.loadFromFile("resources/sansation.ttf"))
|
||||
return EXIT_FAILURE;
|
||||
|
||||
// Initialize the pause message
|
||||
sf::Text pauseMessage;
|
||||
pauseMessage.setFont(font);
|
||||
pauseMessage.setCharacterSize(40);
|
||||
pauseMessage.setPosition(170.f, 150.f);
|
||||
pauseMessage.setColor(sf::Color::White);
|
||||
pauseMessage.setString("Welcome to SFML pong!\nPress space to start the game");
|
||||
|
||||
// Define the paddles properties
|
||||
sf::Clock AITimer;
|
||||
const sf::Time AITime = sf::seconds(0.1f);
|
||||
const float paddleSpeed = 400.f;
|
||||
float rightPaddleSpeed = 0.f;
|
||||
const float ballSpeed = 400.f;
|
||||
float ballAngle = 0.f; // to be changed later
|
||||
|
||||
sf::Clock clock;
|
||||
bool isPlaying = false;
|
||||
while (window.isOpen())
|
||||
{
|
||||
// Handle events
|
||||
sf::Event event;
|
||||
while (window.pollEvent(event))
|
||||
{
|
||||
// Window closed or escape key pressed: exit
|
||||
if ((event.type == sf::Event::Closed) ||
|
||||
((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Escape)))
|
||||
{
|
||||
window.close();
|
||||
break;
|
||||
}
|
||||
|
||||
// Space key pressed: play
|
||||
if ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Space))
|
||||
{
|
||||
if (!isPlaying)
|
||||
{
|
||||
// (re)start the game
|
||||
isPlaying = true;
|
||||
clock.restart();
|
||||
|
||||
// Reset the position of the paddles and ball
|
||||
leftPaddle.setPosition(10 + paddleSize.x / 2, gameHeight / 2);
|
||||
rightPaddle.setPosition(gameWidth - 10 - paddleSize.x / 2, gameHeight / 2);
|
||||
ball.setPosition(gameWidth / 2, gameHeight / 2);
|
||||
|
||||
// Reset the ball angle
|
||||
do
|
||||
{
|
||||
// Make sure the ball initial angle is not too much vertical
|
||||
ballAngle = (std::rand() % 360) * 2 * pi / 360;
|
||||
}
|
||||
while (std::abs(std::cos(ballAngle)) < 0.7f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isPlaying)
|
||||
{
|
||||
float deltaTime = clock.restart().asSeconds();
|
||||
|
||||
// Move the player's paddle
|
||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up) &&
|
||||
(leftPaddle.getPosition().y - paddleSize.y / 2 > 5.f))
|
||||
{
|
||||
leftPaddle.move(0.f, -paddleSpeed * deltaTime);
|
||||
}
|
||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down) &&
|
||||
(leftPaddle.getPosition().y + paddleSize.y / 2 < gameHeight - 5.f))
|
||||
{
|
||||
leftPaddle.move(0.f, paddleSpeed * deltaTime);
|
||||
}
|
||||
|
||||
// Move the computer's paddle
|
||||
if (((rightPaddleSpeed < 0.f) && (rightPaddle.getPosition().y - paddleSize.y / 2 > 5.f)) ||
|
||||
((rightPaddleSpeed > 0.f) && (rightPaddle.getPosition().y + paddleSize.y / 2 < gameHeight - 5.f)))
|
||||
{
|
||||
rightPaddle.move(0.f, rightPaddleSpeed * deltaTime);
|
||||
}
|
||||
|
||||
// Update the computer's paddle direction according to the ball position
|
||||
if (AITimer.getElapsedTime() > AITime)
|
||||
{
|
||||
AITimer.restart();
|
||||
if (ball.getPosition().y + ballRadius > rightPaddle.getPosition().y + paddleSize.y / 2)
|
||||
rightPaddleSpeed = paddleSpeed;
|
||||
else if (ball.getPosition().y - ballRadius < rightPaddle.getPosition().y - paddleSize.y / 2)
|
||||
rightPaddleSpeed = -paddleSpeed;
|
||||
else
|
||||
rightPaddleSpeed = 0.f;
|
||||
}
|
||||
|
||||
// Move the ball
|
||||
float factor = ballSpeed * deltaTime;
|
||||
ball.move(std::cos(ballAngle) * factor, std::sin(ballAngle) * factor);
|
||||
|
||||
// Check collisions between the ball and the screen
|
||||
if (ball.getPosition().x - ballRadius < 0.f)
|
||||
{
|
||||
isPlaying = false;
|
||||
pauseMessage.setString("You lost!\nPress space to restart or\nescape to exit");
|
||||
}
|
||||
if (ball.getPosition().x + ballRadius > gameWidth)
|
||||
{
|
||||
isPlaying = false;
|
||||
pauseMessage.setString("You won!\nPress space to restart or\nescape to exit");
|
||||
}
|
||||
if (ball.getPosition().y - ballRadius < 0.f)
|
||||
{
|
||||
ballSound.play();
|
||||
ballAngle = -ballAngle;
|
||||
ball.setPosition(ball.getPosition().x, ballRadius + 0.1f);
|
||||
}
|
||||
if (ball.getPosition().y + ballRadius > gameHeight)
|
||||
{
|
||||
ballSound.play();
|
||||
ballAngle = -ballAngle;
|
||||
ball.setPosition(ball.getPosition().x, gameHeight - ballRadius - 0.1f);
|
||||
}
|
||||
|
||||
// Check the collisions between the ball and the paddles
|
||||
// Left Paddle
|
||||
if (ball.getPosition().x - ballRadius < leftPaddle.getPosition().x + paddleSize.x / 2 &&
|
||||
ball.getPosition().x - ballRadius > leftPaddle.getPosition().x &&
|
||||
ball.getPosition().y + ballRadius >= leftPaddle.getPosition().y - paddleSize.y / 2 &&
|
||||
ball.getPosition().y - ballRadius <= leftPaddle.getPosition().y + paddleSize.y / 2)
|
||||
{
|
||||
if (ball.getPosition().y > leftPaddle.getPosition().y)
|
||||
ballAngle = pi - ballAngle + (std::rand() % 20) * pi / 180;
|
||||
else
|
||||
ballAngle = pi - ballAngle - (std::rand() % 20) * pi / 180;
|
||||
|
||||
ballSound.play();
|
||||
ball.setPosition(leftPaddle.getPosition().x + ballRadius + paddleSize.x / 2 + 0.1f, ball.getPosition().y);
|
||||
}
|
||||
|
||||
// Right Paddle
|
||||
if (ball.getPosition().x + ballRadius > rightPaddle.getPosition().x - paddleSize.x / 2 &&
|
||||
ball.getPosition().x + ballRadius < rightPaddle.getPosition().x &&
|
||||
ball.getPosition().y + ballRadius >= rightPaddle.getPosition().y - paddleSize.y / 2 &&
|
||||
ball.getPosition().y - ballRadius <= rightPaddle.getPosition().y + paddleSize.y / 2)
|
||||
{
|
||||
if (ball.getPosition().y > rightPaddle.getPosition().y)
|
||||
ballAngle = pi - ballAngle + (std::rand() % 20) * pi / 180;
|
||||
else
|
||||
ballAngle = pi - ballAngle - (std::rand() % 20) * pi / 180;
|
||||
|
||||
ballSound.play();
|
||||
ball.setPosition(rightPaddle.getPosition().x - ballRadius - paddleSize.x / 2 - 0.1f, ball.getPosition().y);
|
||||
}
|
||||
}
|
||||
|
||||
// Clear the window
|
||||
window.clear(sf::Color(50, 200, 50));
|
||||
|
||||
if (isPlaying)
|
||||
{
|
||||
// Draw the paddles and the ball
|
||||
window.draw(leftPaddle);
|
||||
window.draw(rightPaddle);
|
||||
window.draw(ball);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Draw the pause message
|
||||
window.draw(pauseMessage);
|
||||
}
|
||||
|
||||
// Display things on screen
|
||||
window.display();
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
|
||||
set(SRCROOT ${PROJECT_SOURCE_DIR}/examples/shader)
|
||||
|
||||
# all source files
|
||||
set(SRC
|
||||
${SRCROOT}/Effect.hpp
|
||||
${SRCROOT}/Shader.cpp)
|
||||
|
||||
# define the shader target
|
||||
sfml_add_example(shader GUI_APP
|
||||
SOURCES ${SRC}
|
||||
DEPENDS sfml-graphics sfml-window sfml-system)
|
||||
|
||||
set(SRCROOT ${PROJECT_SOURCE_DIR}/examples/shader)
|
||||
|
||||
# all source files
|
||||
set(SRC
|
||||
${SRCROOT}/Effect.hpp
|
||||
${SRCROOT}/Shader.cpp)
|
||||
|
||||
# define the shader target
|
||||
sfml_add_example(shader GUI_APP
|
||||
SOURCES ${SRC}
|
||||
DEPENDS sfml-graphics sfml-window sfml-system)
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
////////////////////////////////////////////////////////////
|
||||
class Effect : public sf::Drawable
|
||||
{
|
||||
public :
|
||||
public:
|
||||
|
||||
virtual ~Effect()
|
||||
{
|
||||
|
@ -56,7 +56,7 @@ public :
|
|||
}
|
||||
}
|
||||
|
||||
protected :
|
||||
protected:
|
||||
|
||||
Effect(const std::string& name) :
|
||||
m_name(name),
|
||||
|
@ -70,14 +70,14 @@ protected :
|
|||
return *s_font;
|
||||
}
|
||||
|
||||
private :
|
||||
private:
|
||||
|
||||
// Virtual functions to be implemented in derived effects
|
||||
virtual bool onLoad() = 0;
|
||||
virtual void onUpdate(float time, float x, float y) = 0;
|
||||
virtual void onDraw(sf::RenderTarget& target, sf::RenderStates states) const = 0;
|
||||
|
||||
private :
|
||||
private:
|
||||
|
||||
std::string m_name;
|
||||
bool m_isLoaded;
|
||||
|
|
|
@ -1,379 +1,379 @@
|
|||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include "Effect.hpp"
|
||||
#include <vector>
|
||||
#include <cmath>
|
||||
|
||||
|
||||
const sf::Font* Effect::s_font = NULL;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// "Pixelate" fragment shader
|
||||
////////////////////////////////////////////////////////////
|
||||
class Pixelate : public Effect
|
||||
{
|
||||
public :
|
||||
|
||||
Pixelate() :
|
||||
Effect("pixelate")
|
||||
{
|
||||
}
|
||||
|
||||
bool onLoad()
|
||||
{
|
||||
// Load the texture and initialize the sprite
|
||||
if (!m_texture.loadFromFile("resources/background.jpg"))
|
||||
return false;
|
||||
m_sprite.setTexture(m_texture);
|
||||
|
||||
// Load the shader
|
||||
if (!m_shader.loadFromFile("resources/pixelate.frag", sf::Shader::Fragment))
|
||||
return false;
|
||||
m_shader.setParameter("texture", sf::Shader::CurrentTexture);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void onUpdate(float, float x, float y)
|
||||
{
|
||||
m_shader.setParameter("pixel_threshold", (x + y) / 30);
|
||||
}
|
||||
|
||||
void onDraw(sf::RenderTarget& target, sf::RenderStates states) const
|
||||
{
|
||||
states.shader = &m_shader;
|
||||
target.draw(m_sprite, states);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
sf::Texture m_texture;
|
||||
sf::Sprite m_sprite;
|
||||
sf::Shader m_shader;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// "Wave" vertex shader + "blur" fragment shader
|
||||
////////////////////////////////////////////////////////////
|
||||
class WaveBlur : public Effect
|
||||
{
|
||||
public :
|
||||
|
||||
WaveBlur() :
|
||||
Effect("wave + blur")
|
||||
{
|
||||
}
|
||||
|
||||
bool onLoad()
|
||||
{
|
||||
// Create the text
|
||||
m_text.setString("Praesent suscipit augue in velit pulvinar hendrerit varius purus aliquam.\n"
|
||||
"Mauris mi odio, bibendum quis fringilla a, laoreet vel orci. Proin vitae vulputate tortor.\n"
|
||||
"Praesent cursus ultrices justo, ut feugiat ante vehicula quis.\n"
|
||||
"Donec fringilla scelerisque mauris et viverra.\n"
|
||||
"Maecenas adipiscing ornare scelerisque. Nullam at libero elit.\n"
|
||||
"Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.\n"
|
||||
"Nullam leo urna, tincidunt id semper eget, ultricies sed mi.\n"
|
||||
"Morbi mauris massa, commodo id dignissim vel, lobortis et elit.\n"
|
||||
"Fusce vel libero sed neque scelerisque venenatis.\n"
|
||||
"Integer mattis tincidunt quam vitae iaculis.\n"
|
||||
"Vivamus fringilla sem non velit venenatis fermentum.\n"
|
||||
"Vivamus varius tincidunt nisi id vehicula.\n"
|
||||
"Integer ullamcorper, enim vitae euismod rutrum, massa nisl semper ipsum,\n"
|
||||
"vestibulum sodales sem ante in massa.\n"
|
||||
"Vestibulum in augue non felis convallis viverra.\n"
|
||||
"Mauris ultricies dolor sed massa convallis sed aliquet augue fringilla.\n"
|
||||
"Duis erat eros, porta in accumsan in, blandit quis sem.\n"
|
||||
"In hac habitasse platea dictumst. Etiam fringilla est id odio dapibus sit amet semper dui laoreet.\n");
|
||||
m_text.setFont(getFont());
|
||||
m_text.setCharacterSize(22);
|
||||
m_text.setPosition(30, 20);
|
||||
|
||||
// Load the shader
|
||||
if (!m_shader.loadFromFile("resources/wave.vert", "resources/blur.frag"))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void onUpdate(float time, float x, float y)
|
||||
{
|
||||
m_shader.setParameter("wave_phase", time);
|
||||
m_shader.setParameter("wave_amplitude", x * 40, y * 40);
|
||||
m_shader.setParameter("blur_radius", (x + y) * 0.008f);
|
||||
}
|
||||
|
||||
void onDraw(sf::RenderTarget& target, sf::RenderStates states) const
|
||||
{
|
||||
states.shader = &m_shader;
|
||||
target.draw(m_text, states);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
sf::Text m_text;
|
||||
sf::Shader m_shader;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// "Storm" vertex shader + "blink" fragment shader
|
||||
////////////////////////////////////////////////////////////
|
||||
class StormBlink : public Effect
|
||||
{
|
||||
public :
|
||||
|
||||
StormBlink() :
|
||||
Effect("storm + blink")
|
||||
{
|
||||
}
|
||||
|
||||
bool onLoad()
|
||||
{
|
||||
// Create the points
|
||||
m_points.setPrimitiveType(sf::Points);
|
||||
for (int i = 0; i < 40000; ++i)
|
||||
{
|
||||
float x = static_cast<float>(std::rand() % 800);
|
||||
float y = static_cast<float>(std::rand() % 600);
|
||||
sf::Uint8 r = std::rand() % 255;
|
||||
sf::Uint8 g = std::rand() % 255;
|
||||
sf::Uint8 b = std::rand() % 255;
|
||||
m_points.append(sf::Vertex(sf::Vector2f(x, y), sf::Color(r, g, b)));
|
||||
}
|
||||
|
||||
// Load the shader
|
||||
if (!m_shader.loadFromFile("resources/storm.vert", "resources/blink.frag"))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void onUpdate(float time, float x, float y)
|
||||
{
|
||||
float radius = 200 + std::cos(time) * 150;
|
||||
m_shader.setParameter("storm_position", x * 800, y * 600);
|
||||
m_shader.setParameter("storm_inner_radius", radius / 3);
|
||||
m_shader.setParameter("storm_total_radius", radius);
|
||||
m_shader.setParameter("blink_alpha", 0.5f + std::cos(time * 3) * 0.25f);
|
||||
}
|
||||
|
||||
void onDraw(sf::RenderTarget& target, sf::RenderStates states) const
|
||||
{
|
||||
states.shader = &m_shader;
|
||||
target.draw(m_points, states);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
sf::VertexArray m_points;
|
||||
sf::Shader m_shader;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// "Edge" post-effect fragment shader
|
||||
////////////////////////////////////////////////////////////
|
||||
class Edge : public Effect
|
||||
{
|
||||
public :
|
||||
|
||||
Edge() :
|
||||
Effect("edge post-effect")
|
||||
{
|
||||
}
|
||||
|
||||
bool onLoad()
|
||||
{
|
||||
// Create the off-screen surface
|
||||
if (!m_surface.create(800, 600))
|
||||
return false;
|
||||
m_surface.setSmooth(true);
|
||||
|
||||
// Load the textures
|
||||
if (!m_backgroundTexture.loadFromFile("resources/sfml.png"))
|
||||
return false;
|
||||
m_backgroundTexture.setSmooth(true);
|
||||
if (!m_entityTexture.loadFromFile("resources/devices.png"))
|
||||
return false;
|
||||
m_entityTexture.setSmooth(true);
|
||||
|
||||
// Initialize the background sprite
|
||||
m_backgroundSprite.setTexture(m_backgroundTexture);
|
||||
m_backgroundSprite.setPosition(135, 100);
|
||||
|
||||
// Load the moving entities
|
||||
for (int i = 0; i < 6; ++i)
|
||||
{
|
||||
sf::Sprite entity(m_entityTexture, sf::IntRect(96 * i, 0, 96, 96));
|
||||
m_entities.push_back(entity);
|
||||
}
|
||||
|
||||
// Load the shader
|
||||
if (!m_shader.loadFromFile("resources/edge.frag", sf::Shader::Fragment))
|
||||
return false;
|
||||
m_shader.setParameter("texture", sf::Shader::CurrentTexture);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void onUpdate(float time, float x, float y)
|
||||
{
|
||||
m_shader.setParameter("edge_threshold", 1 - (x + y) / 2);
|
||||
|
||||
// Update the position of the moving entities
|
||||
for (std::size_t i = 0; i < m_entities.size(); ++i)
|
||||
{
|
||||
sf::Vector2f position;
|
||||
position.x = std::cos(0.25f * (time * i + (m_entities.size() - i))) * 300 + 350;
|
||||
position.y = std::sin(0.25f * (time * (m_entities.size() - i) + i)) * 200 + 250;
|
||||
m_entities[i].setPosition(position);
|
||||
}
|
||||
|
||||
// Render the updated scene to the off-screen surface
|
||||
m_surface.clear(sf::Color::White);
|
||||
m_surface.draw(m_backgroundSprite);
|
||||
for (std::size_t i = 0; i < m_entities.size(); ++i)
|
||||
m_surface.draw(m_entities[i]);
|
||||
m_surface.display();
|
||||
}
|
||||
|
||||
void onDraw(sf::RenderTarget& target, sf::RenderStates states) const
|
||||
{
|
||||
states.shader = &m_shader;
|
||||
target.draw(sf::Sprite(m_surface.getTexture()), states);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
sf::RenderTexture m_surface;
|
||||
sf::Texture m_backgroundTexture;
|
||||
sf::Texture m_entityTexture;
|
||||
sf::Sprite m_backgroundSprite;
|
||||
std::vector<sf::Sprite> m_entities;
|
||||
sf::Shader m_shader;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Entry point of application
|
||||
///
|
||||
/// \return Application exit code
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
int main()
|
||||
{
|
||||
// Create the main window
|
||||
sf::RenderWindow window(sf::VideoMode(800, 600), "SFML Shader");
|
||||
window.setVerticalSyncEnabled(true);
|
||||
|
||||
// Load the application font and pass it to the Effect class
|
||||
sf::Font font;
|
||||
if (!font.loadFromFile("resources/sansation.ttf"))
|
||||
return EXIT_FAILURE;
|
||||
Effect::setFont(font);
|
||||
|
||||
// Create the effects
|
||||
std::vector<Effect*> effects;
|
||||
effects.push_back(new Pixelate);
|
||||
effects.push_back(new WaveBlur);
|
||||
effects.push_back(new StormBlink);
|
||||
effects.push_back(new Edge);
|
||||
std::size_t current = 0;
|
||||
|
||||
// Initialize them
|
||||
for (std::size_t i = 0; i < effects.size(); ++i)
|
||||
effects[i]->load();
|
||||
|
||||
// Create the messages background
|
||||
sf::Texture textBackgroundTexture;
|
||||
if (!textBackgroundTexture.loadFromFile("resources/text-background.png"))
|
||||
return EXIT_FAILURE;
|
||||
sf::Sprite textBackground(textBackgroundTexture);
|
||||
textBackground.setPosition(0, 520);
|
||||
textBackground.setColor(sf::Color(255, 255, 255, 200));
|
||||
|
||||
// Create the description text
|
||||
sf::Text description("Current effect: " + effects[current]->getName(), font, 20);
|
||||
description.setPosition(10, 530);
|
||||
description.setColor(sf::Color(80, 80, 80));
|
||||
|
||||
// Create the instructions text
|
||||
sf::Text instructions("Press left and right arrows to change the current shader", font, 20);
|
||||
instructions.setPosition(280, 555);
|
||||
instructions.setColor(sf::Color(80, 80, 80));
|
||||
|
||||
// Start the game loop
|
||||
sf::Clock clock;
|
||||
while (window.isOpen())
|
||||
{
|
||||
// Process events
|
||||
sf::Event event;
|
||||
while (window.pollEvent(event))
|
||||
{
|
||||
// Close window: exit
|
||||
if (event.type == sf::Event::Closed)
|
||||
window.close();
|
||||
|
||||
if (event.type == sf::Event::KeyPressed)
|
||||
{
|
||||
switch (event.key.code)
|
||||
{
|
||||
// Escape key: exit
|
||||
case sf::Keyboard::Escape:
|
||||
window.close();
|
||||
break;
|
||||
|
||||
// Left arrow key: previous shader
|
||||
case sf::Keyboard::Left:
|
||||
if (current == 0)
|
||||
current = effects.size() - 1;
|
||||
else
|
||||
current--;
|
||||
description.setString("Current effect: " + effects[current]->getName());
|
||||
break;
|
||||
|
||||
// Right arrow key: next shader
|
||||
case sf::Keyboard::Right:
|
||||
if (current == effects.size() - 1)
|
||||
current = 0;
|
||||
else
|
||||
current++;
|
||||
description.setString("Current effect: " + effects[current]->getName());
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update the current example
|
||||
float x = static_cast<float>(sf::Mouse::getPosition(window).x) / window.getSize().x;
|
||||
float y = static_cast<float>(sf::Mouse::getPosition(window).y) / window.getSize().y;
|
||||
effects[current]->update(clock.getElapsedTime().asSeconds(), x, y);
|
||||
|
||||
// Clear the window
|
||||
window.clear(sf::Color(255, 128, 0));
|
||||
|
||||
// Draw the current example
|
||||
window.draw(*effects[current]);
|
||||
|
||||
// Draw the text
|
||||
window.draw(textBackground);
|
||||
window.draw(instructions);
|
||||
window.draw(description);
|
||||
|
||||
// Finally, display the rendered frame on screen
|
||||
window.display();
|
||||
}
|
||||
|
||||
// delete the effects
|
||||
for (std::size_t i = 0; i < effects.size(); ++i)
|
||||
delete effects[i];
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include "Effect.hpp"
|
||||
#include <vector>
|
||||
#include <cmath>
|
||||
|
||||
|
||||
const sf::Font* Effect::s_font = NULL;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// "Pixelate" fragment shader
|
||||
////////////////////////////////////////////////////////////
|
||||
class Pixelate : public Effect
|
||||
{
|
||||
public:
|
||||
|
||||
Pixelate() :
|
||||
Effect("pixelate")
|
||||
{
|
||||
}
|
||||
|
||||
bool onLoad()
|
||||
{
|
||||
// Load the texture and initialize the sprite
|
||||
if (!m_texture.loadFromFile("resources/background.jpg"))
|
||||
return false;
|
||||
m_sprite.setTexture(m_texture);
|
||||
|
||||
// Load the shader
|
||||
if (!m_shader.loadFromFile("resources/pixelate.frag", sf::Shader::Fragment))
|
||||
return false;
|
||||
m_shader.setParameter("texture", sf::Shader::CurrentTexture);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void onUpdate(float, float x, float y)
|
||||
{
|
||||
m_shader.setParameter("pixel_threshold", (x + y) / 30);
|
||||
}
|
||||
|
||||
void onDraw(sf::RenderTarget& target, sf::RenderStates states) const
|
||||
{
|
||||
states.shader = &m_shader;
|
||||
target.draw(m_sprite, states);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
sf::Texture m_texture;
|
||||
sf::Sprite m_sprite;
|
||||
sf::Shader m_shader;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// "Wave" vertex shader + "blur" fragment shader
|
||||
////////////////////////////////////////////////////////////
|
||||
class WaveBlur : public Effect
|
||||
{
|
||||
public:
|
||||
|
||||
WaveBlur() :
|
||||
Effect("wave + blur")
|
||||
{
|
||||
}
|
||||
|
||||
bool onLoad()
|
||||
{
|
||||
// Create the text
|
||||
m_text.setString("Praesent suscipit augue in velit pulvinar hendrerit varius purus aliquam.\n"
|
||||
"Mauris mi odio, bibendum quis fringilla a, laoreet vel orci. Proin vitae vulputate tortor.\n"
|
||||
"Praesent cursus ultrices justo, ut feugiat ante vehicula quis.\n"
|
||||
"Donec fringilla scelerisque mauris et viverra.\n"
|
||||
"Maecenas adipiscing ornare scelerisque. Nullam at libero elit.\n"
|
||||
"Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.\n"
|
||||
"Nullam leo urna, tincidunt id semper eget, ultricies sed mi.\n"
|
||||
"Morbi mauris massa, commodo id dignissim vel, lobortis et elit.\n"
|
||||
"Fusce vel libero sed neque scelerisque venenatis.\n"
|
||||
"Integer mattis tincidunt quam vitae iaculis.\n"
|
||||
"Vivamus fringilla sem non velit venenatis fermentum.\n"
|
||||
"Vivamus varius tincidunt nisi id vehicula.\n"
|
||||
"Integer ullamcorper, enim vitae euismod rutrum, massa nisl semper ipsum,\n"
|
||||
"vestibulum sodales sem ante in massa.\n"
|
||||
"Vestibulum in augue non felis convallis viverra.\n"
|
||||
"Mauris ultricies dolor sed massa convallis sed aliquet augue fringilla.\n"
|
||||
"Duis erat eros, porta in accumsan in, blandit quis sem.\n"
|
||||
"In hac habitasse platea dictumst. Etiam fringilla est id odio dapibus sit amet semper dui laoreet.\n");
|
||||
m_text.setFont(getFont());
|
||||
m_text.setCharacterSize(22);
|
||||
m_text.setPosition(30, 20);
|
||||
|
||||
// Load the shader
|
||||
if (!m_shader.loadFromFile("resources/wave.vert", "resources/blur.frag"))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void onUpdate(float time, float x, float y)
|
||||
{
|
||||
m_shader.setParameter("wave_phase", time);
|
||||
m_shader.setParameter("wave_amplitude", x * 40, y * 40);
|
||||
m_shader.setParameter("blur_radius", (x + y) * 0.008f);
|
||||
}
|
||||
|
||||
void onDraw(sf::RenderTarget& target, sf::RenderStates states) const
|
||||
{
|
||||
states.shader = &m_shader;
|
||||
target.draw(m_text, states);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
sf::Text m_text;
|
||||
sf::Shader m_shader;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// "Storm" vertex shader + "blink" fragment shader
|
||||
////////////////////////////////////////////////////////////
|
||||
class StormBlink : public Effect
|
||||
{
|
||||
public:
|
||||
|
||||
StormBlink() :
|
||||
Effect("storm + blink")
|
||||
{
|
||||
}
|
||||
|
||||
bool onLoad()
|
||||
{
|
||||
// Create the points
|
||||
m_points.setPrimitiveType(sf::Points);
|
||||
for (int i = 0; i < 40000; ++i)
|
||||
{
|
||||
float x = static_cast<float>(std::rand() % 800);
|
||||
float y = static_cast<float>(std::rand() % 600);
|
||||
sf::Uint8 r = std::rand() % 255;
|
||||
sf::Uint8 g = std::rand() % 255;
|
||||
sf::Uint8 b = std::rand() % 255;
|
||||
m_points.append(sf::Vertex(sf::Vector2f(x, y), sf::Color(r, g, b)));
|
||||
}
|
||||
|
||||
// Load the shader
|
||||
if (!m_shader.loadFromFile("resources/storm.vert", "resources/blink.frag"))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void onUpdate(float time, float x, float y)
|
||||
{
|
||||
float radius = 200 + std::cos(time) * 150;
|
||||
m_shader.setParameter("storm_position", x * 800, y * 600);
|
||||
m_shader.setParameter("storm_inner_radius", radius / 3);
|
||||
m_shader.setParameter("storm_total_radius", radius);
|
||||
m_shader.setParameter("blink_alpha", 0.5f + std::cos(time * 3) * 0.25f);
|
||||
}
|
||||
|
||||
void onDraw(sf::RenderTarget& target, sf::RenderStates states) const
|
||||
{
|
||||
states.shader = &m_shader;
|
||||
target.draw(m_points, states);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
sf::VertexArray m_points;
|
||||
sf::Shader m_shader;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// "Edge" post-effect fragment shader
|
||||
////////////////////////////////////////////////////////////
|
||||
class Edge : public Effect
|
||||
{
|
||||
public:
|
||||
|
||||
Edge() :
|
||||
Effect("edge post-effect")
|
||||
{
|
||||
}
|
||||
|
||||
bool onLoad()
|
||||
{
|
||||
// Create the off-screen surface
|
||||
if (!m_surface.create(800, 600))
|
||||
return false;
|
||||
m_surface.setSmooth(true);
|
||||
|
||||
// Load the textures
|
||||
if (!m_backgroundTexture.loadFromFile("resources/sfml.png"))
|
||||
return false;
|
||||
m_backgroundTexture.setSmooth(true);
|
||||
if (!m_entityTexture.loadFromFile("resources/devices.png"))
|
||||
return false;
|
||||
m_entityTexture.setSmooth(true);
|
||||
|
||||
// Initialize the background sprite
|
||||
m_backgroundSprite.setTexture(m_backgroundTexture);
|
||||
m_backgroundSprite.setPosition(135, 100);
|
||||
|
||||
// Load the moving entities
|
||||
for (int i = 0; i < 6; ++i)
|
||||
{
|
||||
sf::Sprite entity(m_entityTexture, sf::IntRect(96 * i, 0, 96, 96));
|
||||
m_entities.push_back(entity);
|
||||
}
|
||||
|
||||
// Load the shader
|
||||
if (!m_shader.loadFromFile("resources/edge.frag", sf::Shader::Fragment))
|
||||
return false;
|
||||
m_shader.setParameter("texture", sf::Shader::CurrentTexture);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void onUpdate(float time, float x, float y)
|
||||
{
|
||||
m_shader.setParameter("edge_threshold", 1 - (x + y) / 2);
|
||||
|
||||
// Update the position of the moving entities
|
||||
for (std::size_t i = 0; i < m_entities.size(); ++i)
|
||||
{
|
||||
sf::Vector2f position;
|
||||
position.x = std::cos(0.25f * (time * i + (m_entities.size() - i))) * 300 + 350;
|
||||
position.y = std::sin(0.25f * (time * (m_entities.size() - i) + i)) * 200 + 250;
|
||||
m_entities[i].setPosition(position);
|
||||
}
|
||||
|
||||
// Render the updated scene to the off-screen surface
|
||||
m_surface.clear(sf::Color::White);
|
||||
m_surface.draw(m_backgroundSprite);
|
||||
for (std::size_t i = 0; i < m_entities.size(); ++i)
|
||||
m_surface.draw(m_entities[i]);
|
||||
m_surface.display();
|
||||
}
|
||||
|
||||
void onDraw(sf::RenderTarget& target, sf::RenderStates states) const
|
||||
{
|
||||
states.shader = &m_shader;
|
||||
target.draw(sf::Sprite(m_surface.getTexture()), states);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
sf::RenderTexture m_surface;
|
||||
sf::Texture m_backgroundTexture;
|
||||
sf::Texture m_entityTexture;
|
||||
sf::Sprite m_backgroundSprite;
|
||||
std::vector<sf::Sprite> m_entities;
|
||||
sf::Shader m_shader;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Entry point of application
|
||||
///
|
||||
/// \return Application exit code
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
int main()
|
||||
{
|
||||
// Create the main window
|
||||
sf::RenderWindow window(sf::VideoMode(800, 600), "SFML Shader");
|
||||
window.setVerticalSyncEnabled(true);
|
||||
|
||||
// Load the application font and pass it to the Effect class
|
||||
sf::Font font;
|
||||
if (!font.loadFromFile("resources/sansation.ttf"))
|
||||
return EXIT_FAILURE;
|
||||
Effect::setFont(font);
|
||||
|
||||
// Create the effects
|
||||
std::vector<Effect*> effects;
|
||||
effects.push_back(new Pixelate);
|
||||
effects.push_back(new WaveBlur);
|
||||
effects.push_back(new StormBlink);
|
||||
effects.push_back(new Edge);
|
||||
std::size_t current = 0;
|
||||
|
||||
// Initialize them
|
||||
for (std::size_t i = 0; i < effects.size(); ++i)
|
||||
effects[i]->load();
|
||||
|
||||
// Create the messages background
|
||||
sf::Texture textBackgroundTexture;
|
||||
if (!textBackgroundTexture.loadFromFile("resources/text-background.png"))
|
||||
return EXIT_FAILURE;
|
||||
sf::Sprite textBackground(textBackgroundTexture);
|
||||
textBackground.setPosition(0, 520);
|
||||
textBackground.setColor(sf::Color(255, 255, 255, 200));
|
||||
|
||||
// Create the description text
|
||||
sf::Text description("Current effect: " + effects[current]->getName(), font, 20);
|
||||
description.setPosition(10, 530);
|
||||
description.setColor(sf::Color(80, 80, 80));
|
||||
|
||||
// Create the instructions text
|
||||
sf::Text instructions("Press left and right arrows to change the current shader", font, 20);
|
||||
instructions.setPosition(280, 555);
|
||||
instructions.setColor(sf::Color(80, 80, 80));
|
||||
|
||||
// Start the game loop
|
||||
sf::Clock clock;
|
||||
while (window.isOpen())
|
||||
{
|
||||
// Process events
|
||||
sf::Event event;
|
||||
while (window.pollEvent(event))
|
||||
{
|
||||
// Close window: exit
|
||||
if (event.type == sf::Event::Closed)
|
||||
window.close();
|
||||
|
||||
if (event.type == sf::Event::KeyPressed)
|
||||
{
|
||||
switch (event.key.code)
|
||||
{
|
||||
// Escape key: exit
|
||||
case sf::Keyboard::Escape:
|
||||
window.close();
|
||||
break;
|
||||
|
||||
// Left arrow key: previous shader
|
||||
case sf::Keyboard::Left:
|
||||
if (current == 0)
|
||||
current = effects.size() - 1;
|
||||
else
|
||||
current--;
|
||||
description.setString("Current effect: " + effects[current]->getName());
|
||||
break;
|
||||
|
||||
// Right arrow key: next shader
|
||||
case sf::Keyboard::Right:
|
||||
if (current == effects.size() - 1)
|
||||
current = 0;
|
||||
else
|
||||
current++;
|
||||
description.setString("Current effect: " + effects[current]->getName());
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update the current example
|
||||
float x = static_cast<float>(sf::Mouse::getPosition(window).x) / window.getSize().x;
|
||||
float y = static_cast<float>(sf::Mouse::getPosition(window).y) / window.getSize().y;
|
||||
effects[current]->update(clock.getElapsedTime().asSeconds(), x, y);
|
||||
|
||||
// Clear the window
|
||||
window.clear(sf::Color(255, 128, 0));
|
||||
|
||||
// Draw the current example
|
||||
window.draw(*effects[current]);
|
||||
|
||||
// Draw the text
|
||||
window.draw(textBackground);
|
||||
window.draw(instructions);
|
||||
window.draw(description);
|
||||
|
||||
// Finally, display the rendered frame on screen
|
||||
window.display();
|
||||
}
|
||||
|
||||
// delete the effects
|
||||
for (std::size_t i = 0; i < effects.size(); ++i)
|
||||
delete effects[i];
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
uniform sampler2D texture;
|
||||
uniform float blur_radius;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 offx = vec2(blur_radius, 0.0);
|
||||
vec2 offy = vec2(0.0, blur_radius);
|
||||
|
||||
vec4 pixel = texture2D(texture, gl_TexCoord[0].xy) * 4.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy - offx) * 2.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy + offx) * 2.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy - offy) * 2.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy + offy) * 2.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy - offx - offy) * 1.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy - offx + offy) * 1.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy + offx - offy) * 1.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy + offx + offy) * 1.0;
|
||||
|
||||
gl_FragColor = gl_Color * (pixel / 16.0);
|
||||
}
|
||||
uniform sampler2D texture;
|
||||
uniform float blur_radius;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 offx = vec2(blur_radius, 0.0);
|
||||
vec2 offy = vec2(0.0, blur_radius);
|
||||
|
||||
vec4 pixel = texture2D(texture, gl_TexCoord[0].xy) * 4.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy - offx) * 2.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy + offx) * 2.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy - offy) * 2.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy + offy) * 2.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy - offx - offy) * 1.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy - offx + offy) * 1.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy + offx - offy) * 1.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy + offx + offy) * 1.0;
|
||||
|
||||
gl_FragColor = gl_Color * (pixel / 16.0);
|
||||
}
|
||||
|
|
|
@ -1,32 +1,32 @@
|
|||
uniform sampler2D texture;
|
||||
uniform float edge_threshold;
|
||||
|
||||
void main()
|
||||
{
|
||||
const float offset = 1.0 / 512.0;
|
||||
vec2 offx = vec2(offset, 0.0);
|
||||
vec2 offy = vec2(0.0, offset);
|
||||
|
||||
vec4 hEdge = texture2D(texture, gl_TexCoord[0].xy - offy) * -2.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy + offy) * 2.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy - offx - offy) * -1.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy - offx + offy) * 1.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy + offx - offy) * -1.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy + offx + offy) * 1.0;
|
||||
|
||||
vec4 vEdge = texture2D(texture, gl_TexCoord[0].xy - offx) * 2.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy + offx) * -2.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy - offx - offy) * 1.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy - offx + offy) * -1.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy + offx - offy) * 1.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy + offx + offy) * -1.0;
|
||||
|
||||
vec3 result = sqrt(hEdge.rgb * hEdge.rgb + vEdge.rgb * vEdge.rgb);
|
||||
float edge = length(result);
|
||||
vec4 pixel = gl_Color * texture2D(texture, gl_TexCoord[0].xy);
|
||||
if (edge > (edge_threshold * 8.0))
|
||||
pixel.rgb = vec3(0.0, 0.0, 0.0);
|
||||
else
|
||||
pixel.a = edge_threshold;
|
||||
gl_FragColor = pixel;
|
||||
}
|
||||
uniform sampler2D texture;
|
||||
uniform float edge_threshold;
|
||||
|
||||
void main()
|
||||
{
|
||||
const float offset = 1.0 / 512.0;
|
||||
vec2 offx = vec2(offset, 0.0);
|
||||
vec2 offy = vec2(0.0, offset);
|
||||
|
||||
vec4 hEdge = texture2D(texture, gl_TexCoord[0].xy - offy) * -2.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy + offy) * 2.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy - offx - offy) * -1.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy - offx + offy) * 1.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy + offx - offy) * -1.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy + offx + offy) * 1.0;
|
||||
|
||||
vec4 vEdge = texture2D(texture, gl_TexCoord[0].xy - offx) * 2.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy + offx) * -2.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy - offx - offy) * 1.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy - offx + offy) * -1.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy + offx - offy) * 1.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy + offx + offy) * -1.0;
|
||||
|
||||
vec3 result = sqrt(hEdge.rgb * hEdge.rgb + vEdge.rgb * vEdge.rgb);
|
||||
float edge = length(result);
|
||||
vec4 pixel = gl_Color * texture2D(texture, gl_TexCoord[0].xy);
|
||||
if (edge > (edge_threshold * 8.0))
|
||||
pixel.rgb = vec3(0.0, 0.0, 0.0);
|
||||
else
|
||||
pixel.a = edge_threshold;
|
||||
gl_FragColor = pixel;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
uniform sampler2D texture;
|
||||
uniform float pixel_threshold;
|
||||
|
||||
void main()
|
||||
{
|
||||
float factor = 1.0 / (pixel_threshold + 0.001);
|
||||
vec2 pos = floor(gl_TexCoord[0].xy * factor + 0.5) / factor;
|
||||
gl_FragColor = texture2D(texture, pos) * gl_Color;
|
||||
}
|
||||
uniform sampler2D texture;
|
||||
uniform float pixel_threshold;
|
||||
|
||||
void main()
|
||||
{
|
||||
float factor = 1.0 / (pixel_threshold + 0.001);
|
||||
vec2 pos = floor(gl_TexCoord[0].xy * factor + 0.5) / factor;
|
||||
gl_FragColor = texture2D(texture, pos) * gl_Color;
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
|
||||
set(SRCROOT ${PROJECT_SOURCE_DIR}/examples/sockets)
|
||||
|
||||
# all source files
|
||||
set(SRC ${SRCROOT}/Sockets.cpp
|
||||
${SRCROOT}/TCP.cpp
|
||||
${SRCROOT}/UDP.cpp)
|
||||
|
||||
# define the sockets target
|
||||
sfml_add_example(sockets
|
||||
SOURCES ${SRC}
|
||||
DEPENDS sfml-network sfml-system)
|
||||
|
||||
set(SRCROOT ${PROJECT_SOURCE_DIR}/examples/sockets)
|
||||
|
||||
# all source files
|
||||
set(SRC ${SRCROOT}/Sockets.cpp
|
||||
${SRCROOT}/TCP.cpp
|
||||
${SRCROOT}/UDP.cpp)
|
||||
|
||||
# define the sockets target
|
||||
sfml_add_example(sockets
|
||||
SOURCES ${SRC}
|
||||
DEPENDS sfml-network sfml-system)
|
||||
|
|
|
@ -1,59 +1,59 @@
|
|||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
|
||||
|
||||
void runTcpServer(unsigned short port);
|
||||
void runTcpClient(unsigned short port);
|
||||
void runUdpServer(unsigned short port);
|
||||
void runUdpClient(unsigned short port);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Entry point of application
|
||||
///
|
||||
/// \return Application exit code
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
int main()
|
||||
{
|
||||
// Choose an arbitrary port for opening sockets
|
||||
const unsigned short port = 50001;
|
||||
|
||||
// TCP, UDP or connected UDP ?
|
||||
char protocol;
|
||||
std::cout << "Do you want to use TCP (t) or UDP (u) ? ";
|
||||
std::cin >> protocol;
|
||||
|
||||
// Client or server ?
|
||||
char who;
|
||||
std::cout << "Do you want to be a server (s) or a client (c) ? ";
|
||||
std::cin >> who;
|
||||
|
||||
if (protocol == 't')
|
||||
{
|
||||
// Test the TCP protocol
|
||||
if (who == 's')
|
||||
runTcpServer(port);
|
||||
else
|
||||
runTcpClient(port);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Test the unconnected UDP protocol
|
||||
if (who == 's')
|
||||
runUdpServer(port);
|
||||
else
|
||||
runUdpClient(port);
|
||||
}
|
||||
|
||||
// Wait until the user presses 'enter' key
|
||||
std::cout << "Press enter to exit..." << std::endl;
|
||||
std::cin.ignore(10000, '\n');
|
||||
std::cin.ignore(10000, '\n');
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
|
||||
|
||||
void runTcpServer(unsigned short port);
|
||||
void runTcpClient(unsigned short port);
|
||||
void runUdpServer(unsigned short port);
|
||||
void runUdpClient(unsigned short port);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Entry point of application
|
||||
///
|
||||
/// \return Application exit code
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
int main()
|
||||
{
|
||||
// Choose an arbitrary port for opening sockets
|
||||
const unsigned short port = 50001;
|
||||
|
||||
// TCP, UDP or connected UDP ?
|
||||
char protocol;
|
||||
std::cout << "Do you want to use TCP (t) or UDP (u) ? ";
|
||||
std::cin >> protocol;
|
||||
|
||||
// Client or server ?
|
||||
char who;
|
||||
std::cout << "Do you want to be a server (s) or a client (c) ? ";
|
||||
std::cin >> who;
|
||||
|
||||
if (protocol == 't')
|
||||
{
|
||||
// Test the TCP protocol
|
||||
if (who == 's')
|
||||
runTcpServer(port);
|
||||
else
|
||||
runTcpClient(port);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Test the unconnected UDP protocol
|
||||
if (who == 's')
|
||||
runUdpServer(port);
|
||||
else
|
||||
runUdpClient(port);
|
||||
}
|
||||
|
||||
// Wait until the user presses 'enter' key
|
||||
std::cout << "Press enter to exit..." << std::endl;
|
||||
std::cin.ignore(10000, '\n');
|
||||
std::cin.ignore(10000, '\n');
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -1,81 +1,81 @@
|
|||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Network.hpp>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Launch a server, wait for an incoming connection,
|
||||
/// send a message and wait for the answer.
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void runTcpServer(unsigned short port)
|
||||
{
|
||||
// Create a server socket to accept new connections
|
||||
sf::TcpListener listener;
|
||||
|
||||
// Listen to the given port for incoming connections
|
||||
if (listener.listen(port) != sf::Socket::Done)
|
||||
return;
|
||||
std::cout << "Server is listening to port " << port << ", waiting for connections... " << std::endl;
|
||||
|
||||
// Wait for a connection
|
||||
sf::TcpSocket socket;
|
||||
if (listener.accept(socket) != sf::Socket::Done)
|
||||
return;
|
||||
std::cout << "Client connected: " << socket.getRemoteAddress() << std::endl;
|
||||
|
||||
// Send a message to the connected client
|
||||
const char out[] = "Hi, I'm the server";
|
||||
if (socket.send(out, sizeof(out)) != sf::Socket::Done)
|
||||
return;
|
||||
std::cout << "Message sent to the client: \"" << out << "\"" << std::endl;
|
||||
|
||||
// Receive a message back from the client
|
||||
char in[128];
|
||||
std::size_t received;
|
||||
if (socket.receive(in, sizeof(in), received) != sf::Socket::Done)
|
||||
return;
|
||||
std::cout << "Answer received from the client: \"" << in << "\"" << std::endl;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Create a client, connect it to a server, display the
|
||||
/// welcome message and send an answer.
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void runTcpClient(unsigned short port)
|
||||
{
|
||||
// Ask for the server address
|
||||
sf::IpAddress server;
|
||||
do
|
||||
{
|
||||
std::cout << "Type the address or name of the server to connect to: ";
|
||||
std::cin >> server;
|
||||
}
|
||||
while (server == sf::IpAddress::None);
|
||||
|
||||
// Create a socket for communicating with the server
|
||||
sf::TcpSocket socket;
|
||||
|
||||
// Connect to the server
|
||||
if (socket.connect(server, port) != sf::Socket::Done)
|
||||
return;
|
||||
std::cout << "Connected to server " << server << std::endl;
|
||||
|
||||
// Receive a message from the server
|
||||
char in[128];
|
||||
std::size_t received;
|
||||
if (socket.receive(in, sizeof(in), received) != sf::Socket::Done)
|
||||
return;
|
||||
std::cout << "Message received from the server: \"" << in << "\"" << std::endl;
|
||||
|
||||
// Send an answer to the server
|
||||
const char out[] = "Hi, I'm a client";
|
||||
if (socket.send(out, sizeof(out)) != sf::Socket::Done)
|
||||
return;
|
||||
std::cout << "Message sent to the server: \"" << out << "\"" << std::endl;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Network.hpp>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Launch a server, wait for an incoming connection,
|
||||
/// send a message and wait for the answer.
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void runTcpServer(unsigned short port)
|
||||
{
|
||||
// Create a server socket to accept new connections
|
||||
sf::TcpListener listener;
|
||||
|
||||
// Listen to the given port for incoming connections
|
||||
if (listener.listen(port) != sf::Socket::Done)
|
||||
return;
|
||||
std::cout << "Server is listening to port " << port << ", waiting for connections... " << std::endl;
|
||||
|
||||
// Wait for a connection
|
||||
sf::TcpSocket socket;
|
||||
if (listener.accept(socket) != sf::Socket::Done)
|
||||
return;
|
||||
std::cout << "Client connected: " << socket.getRemoteAddress() << std::endl;
|
||||
|
||||
// Send a message to the connected client
|
||||
const char out[] = "Hi, I'm the server";
|
||||
if (socket.send(out, sizeof(out)) != sf::Socket::Done)
|
||||
return;
|
||||
std::cout << "Message sent to the client: \"" << out << "\"" << std::endl;
|
||||
|
||||
// Receive a message back from the client
|
||||
char in[128];
|
||||
std::size_t received;
|
||||
if (socket.receive(in, sizeof(in), received) != sf::Socket::Done)
|
||||
return;
|
||||
std::cout << "Answer received from the client: \"" << in << "\"" << std::endl;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Create a client, connect it to a server, display the
|
||||
/// welcome message and send an answer.
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void runTcpClient(unsigned short port)
|
||||
{
|
||||
// Ask for the server address
|
||||
sf::IpAddress server;
|
||||
do
|
||||
{
|
||||
std::cout << "Type the address or name of the server to connect to: ";
|
||||
std::cin >> server;
|
||||
}
|
||||
while (server == sf::IpAddress::None);
|
||||
|
||||
// Create a socket for communicating with the server
|
||||
sf::TcpSocket socket;
|
||||
|
||||
// Connect to the server
|
||||
if (socket.connect(server, port) != sf::Socket::Done)
|
||||
return;
|
||||
std::cout << "Connected to server " << server << std::endl;
|
||||
|
||||
// Receive a message from the server
|
||||
char in[128];
|
||||
std::size_t received;
|
||||
if (socket.receive(in, sizeof(in), received) != sf::Socket::Done)
|
||||
return;
|
||||
std::cout << "Message received from the server: \"" << in << "\"" << std::endl;
|
||||
|
||||
// Send an answer to the server
|
||||
const char out[] = "Hi, I'm a client";
|
||||
if (socket.send(out, sizeof(out)) != sf::Socket::Done)
|
||||
return;
|
||||
std::cout << "Message sent to the server: \"" << out << "\"" << std::endl;
|
||||
}
|
||||
|
|
|
@ -1,72 +1,72 @@
|
|||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Network.hpp>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Launch a server, wait for a message, send an answer.
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void runUdpServer(unsigned short port)
|
||||
{
|
||||
// Create a socket to receive a message from anyone
|
||||
sf::UdpSocket socket;
|
||||
|
||||
// Listen to messages on the specified port
|
||||
if (socket.bind(port) != sf::Socket::Done)
|
||||
return;
|
||||
std::cout << "Server is listening to port " << port << ", waiting for a message... " << std::endl;
|
||||
|
||||
// Wait for a message
|
||||
char in[128];
|
||||
std::size_t received;
|
||||
sf::IpAddress sender;
|
||||
unsigned short senderPort;
|
||||
if (socket.receive(in, sizeof(in), received, sender, senderPort) != sf::Socket::Done)
|
||||
return;
|
||||
std::cout << "Message received from client " << sender << ": \"" << in << "\"" << std::endl;
|
||||
|
||||
// Send an answer to the client
|
||||
const char out[] = "Hi, I'm the server";
|
||||
if (socket.send(out, sizeof(out), sender, senderPort) != sf::Socket::Done)
|
||||
return;
|
||||
std::cout << "Message sent to the client: \"" << out << "\"" << std::endl;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Send a message to the server, wait for the answer
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void runUdpClient(unsigned short port)
|
||||
{
|
||||
// Ask for the server address
|
||||
sf::IpAddress server;
|
||||
do
|
||||
{
|
||||
std::cout << "Type the address or name of the server to connect to: ";
|
||||
std::cin >> server;
|
||||
}
|
||||
while (server == sf::IpAddress::None);
|
||||
|
||||
// Create a socket for communicating with the server
|
||||
sf::UdpSocket socket;
|
||||
|
||||
// Send a message to the server
|
||||
const char out[] = "Hi, I'm a client";
|
||||
if (socket.send(out, sizeof(out), server, port) != sf::Socket::Done)
|
||||
return;
|
||||
std::cout << "Message sent to the server: \"" << out << "\"" << std::endl;
|
||||
|
||||
// Receive an answer from anyone (but most likely from the server)
|
||||
char in[128];
|
||||
std::size_t received;
|
||||
sf::IpAddress sender;
|
||||
unsigned short senderPort;
|
||||
if (socket.receive(in, sizeof(in), received, sender, senderPort) != sf::Socket::Done)
|
||||
return;
|
||||
std::cout << "Message received from " << sender << ": \"" << in << "\"" << std::endl;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Network.hpp>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Launch a server, wait for a message, send an answer.
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void runUdpServer(unsigned short port)
|
||||
{
|
||||
// Create a socket to receive a message from anyone
|
||||
sf::UdpSocket socket;
|
||||
|
||||
// Listen to messages on the specified port
|
||||
if (socket.bind(port) != sf::Socket::Done)
|
||||
return;
|
||||
std::cout << "Server is listening to port " << port << ", waiting for a message... " << std::endl;
|
||||
|
||||
// Wait for a message
|
||||
char in[128];
|
||||
std::size_t received;
|
||||
sf::IpAddress sender;
|
||||
unsigned short senderPort;
|
||||
if (socket.receive(in, sizeof(in), received, sender, senderPort) != sf::Socket::Done)
|
||||
return;
|
||||
std::cout << "Message received from client " << sender << ": \"" << in << "\"" << std::endl;
|
||||
|
||||
// Send an answer to the client
|
||||
const char out[] = "Hi, I'm the server";
|
||||
if (socket.send(out, sizeof(out), sender, senderPort) != sf::Socket::Done)
|
||||
return;
|
||||
std::cout << "Message sent to the client: \"" << out << "\"" << std::endl;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Send a message to the server, wait for the answer
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void runUdpClient(unsigned short port)
|
||||
{
|
||||
// Ask for the server address
|
||||
sf::IpAddress server;
|
||||
do
|
||||
{
|
||||
std::cout << "Type the address or name of the server to connect to: ";
|
||||
std::cin >> server;
|
||||
}
|
||||
while (server == sf::IpAddress::None);
|
||||
|
||||
// Create a socket for communicating with the server
|
||||
sf::UdpSocket socket;
|
||||
|
||||
// Send a message to the server
|
||||
const char out[] = "Hi, I'm a client";
|
||||
if (socket.send(out, sizeof(out), server, port) != sf::Socket::Done)
|
||||
return;
|
||||
std::cout << "Message sent to the server: \"" << out << "\"" << std::endl;
|
||||
|
||||
// Receive an answer from anyone (but most likely from the server)
|
||||
char in[128];
|
||||
std::size_t received;
|
||||
sf::IpAddress sender;
|
||||
unsigned short senderPort;
|
||||
if (socket.receive(in, sizeof(in), received, sender, senderPort) != sf::Socket::Done)
|
||||
return;
|
||||
std::cout << "Message received from " << sender << ": \"" << in << "\"" << std::endl;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
|
||||
set(SRCROOT ${PROJECT_SOURCE_DIR}/examples/sound)
|
||||
|
||||
# all source files
|
||||
set(SRC ${SRCROOT}/Sound.cpp)
|
||||
|
||||
# define the sound target
|
||||
sfml_add_example(sound
|
||||
SOURCES ${SRC}
|
||||
DEPENDS sfml-audio sfml-system)
|
||||
|
||||
set(SRCROOT ${PROJECT_SOURCE_DIR}/examples/sound)
|
||||
|
||||
# all source files
|
||||
set(SRC ${SRCROOT}/Sound.cpp)
|
||||
|
||||
# define the sound target
|
||||
sfml_add_example(sound
|
||||
SOURCES ${SRC}
|
||||
DEPENDS sfml-audio sfml-system)
|
||||
|
|
|
@ -1,98 +1,98 @@
|
|||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Audio.hpp>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Play a sound
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void playSound()
|
||||
{
|
||||
// Load a sound buffer from a wav file
|
||||
sf::SoundBuffer buffer;
|
||||
if (!buffer.loadFromFile("resources/canary.wav"))
|
||||
return;
|
||||
|
||||
// Display sound informations
|
||||
std::cout << "canary.wav :" << std::endl;
|
||||
std::cout << " " << buffer.getDuration().asSeconds() << " seconds" << std::endl;
|
||||
std::cout << " " << buffer.getSampleRate() << " samples / sec" << std::endl;
|
||||
std::cout << " " << buffer.getChannelCount() << " channels" << std::endl;
|
||||
|
||||
// Create a sound instance and play it
|
||||
sf::Sound sound(buffer);
|
||||
sound.play();
|
||||
|
||||
// Loop while the sound is playing
|
||||
while (sound.getStatus() == sf::Sound::Playing)
|
||||
{
|
||||
// Leave some CPU time for other processes
|
||||
sf::sleep(sf::milliseconds(100));
|
||||
|
||||
// Display the playing position
|
||||
std::cout << "\rPlaying... " << std::fixed << std::setprecision(2) << sound.getPlayingOffset().asSeconds() << " sec ";
|
||||
std::cout << std::flush;
|
||||
}
|
||||
std::cout << std::endl << std::endl;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Play a music
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void playMusic()
|
||||
{
|
||||
// Load an ogg music file
|
||||
sf::Music music;
|
||||
if (!music.openFromFile("resources/orchestral.ogg"))
|
||||
return;
|
||||
|
||||
// Display music informations
|
||||
std::cout << "orchestral.ogg :" << std::endl;
|
||||
std::cout << " " << music.getDuration().asSeconds() << " seconds" << std::endl;
|
||||
std::cout << " " << music.getSampleRate() << " samples / sec" << std::endl;
|
||||
std::cout << " " << music.getChannelCount() << " channels" << std::endl;
|
||||
|
||||
// Play it
|
||||
music.play();
|
||||
|
||||
// Loop while the music is playing
|
||||
while (music.getStatus() == sf::Music::Playing)
|
||||
{
|
||||
// Leave some CPU time for other processes
|
||||
sf::sleep(sf::milliseconds(100));
|
||||
|
||||
// Display the playing position
|
||||
std::cout << "\rPlaying... " << std::fixed << std::setprecision(2) << music.getPlayingOffset().asSeconds() << " sec ";
|
||||
std::cout << std::flush;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Entry point of application
|
||||
///
|
||||
/// \return Application exit code
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
int main()
|
||||
{
|
||||
// Play a sound
|
||||
playSound();
|
||||
|
||||
// Play a music
|
||||
playMusic();
|
||||
|
||||
// Wait until the user presses 'enter' key
|
||||
std::cout << "Press enter to exit..." << std::endl;
|
||||
std::cin.ignore(10000, '\n');
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Audio.hpp>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Play a sound
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void playSound()
|
||||
{
|
||||
// Load a sound buffer from a wav file
|
||||
sf::SoundBuffer buffer;
|
||||
if (!buffer.loadFromFile("resources/canary.wav"))
|
||||
return;
|
||||
|
||||
// Display sound informations
|
||||
std::cout << "canary.wav:" << std::endl;
|
||||
std::cout << " " << buffer.getDuration().asSeconds() << " seconds" << std::endl;
|
||||
std::cout << " " << buffer.getSampleRate() << " samples / sec" << std::endl;
|
||||
std::cout << " " << buffer.getChannelCount() << " channels" << std::endl;
|
||||
|
||||
// Create a sound instance and play it
|
||||
sf::Sound sound(buffer);
|
||||
sound.play();
|
||||
|
||||
// Loop while the sound is playing
|
||||
while (sound.getStatus() == sf::Sound::Playing)
|
||||
{
|
||||
// Leave some CPU time for other processes
|
||||
sf::sleep(sf::milliseconds(100));
|
||||
|
||||
// Display the playing position
|
||||
std::cout << "\rPlaying... " << std::fixed << std::setprecision(2) << sound.getPlayingOffset().asSeconds() << " sec ";
|
||||
std::cout << std::flush;
|
||||
}
|
||||
std::cout << std::endl << std::endl;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Play a music
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void playMusic()
|
||||
{
|
||||
// Load an ogg music file
|
||||
sf::Music music;
|
||||
if (!music.openFromFile("resources/orchestral.ogg"))
|
||||
return;
|
||||
|
||||
// Display music informations
|
||||
std::cout << "orchestral.ogg:" << std::endl;
|
||||
std::cout << " " << music.getDuration().asSeconds() << " seconds" << std::endl;
|
||||
std::cout << " " << music.getSampleRate() << " samples / sec" << std::endl;
|
||||
std::cout << " " << music.getChannelCount() << " channels" << std::endl;
|
||||
|
||||
// Play it
|
||||
music.play();
|
||||
|
||||
// Loop while the music is playing
|
||||
while (music.getStatus() == sf::Music::Playing)
|
||||
{
|
||||
// Leave some CPU time for other processes
|
||||
sf::sleep(sf::milliseconds(100));
|
||||
|
||||
// Display the playing position
|
||||
std::cout << "\rPlaying... " << std::fixed << std::setprecision(2) << music.getPlayingOffset().asSeconds() << " sec ";
|
||||
std::cout << std::flush;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Entry point of application
|
||||
///
|
||||
/// \return Application exit code
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
int main()
|
||||
{
|
||||
// Play a sound
|
||||
playSound();
|
||||
|
||||
// Play a music
|
||||
playMusic();
|
||||
|
||||
// Wait until the user presses 'enter' key
|
||||
std::cout << "Press enter to exit..." << std::endl;
|
||||
std::cin.ignore(10000, '\n');
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
|
||||
set(SRCROOT ${PROJECT_SOURCE_DIR}/examples/sound_capture)
|
||||
|
||||
# all source files
|
||||
set(SRC ${SRCROOT}/SoundCapture.cpp)
|
||||
|
||||
# define the sound-capture target
|
||||
sfml_add_example(sound-capture
|
||||
SOURCES ${SRC}
|
||||
DEPENDS sfml-audio sfml-system)
|
||||
|
||||
set(SRCROOT ${PROJECT_SOURCE_DIR}/examples/sound_capture)
|
||||
|
||||
# all source files
|
||||
set(SRC ${SRCROOT}/SoundCapture.cpp)
|
||||
|
||||
# define the sound-capture target
|
||||
sfml_add_example(sound-capture
|
||||
SOURCES ${SRC}
|
||||
DEPENDS sfml-audio sfml-system)
|
||||
|
|
|
@ -1,95 +1,95 @@
|
|||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Audio.hpp>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Entry point of application
|
||||
///
|
||||
/// \return Application exit code
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
int main()
|
||||
{
|
||||
// Check that the device can capture audio
|
||||
if (sf::SoundRecorder::isAvailable() == false)
|
||||
{
|
||||
std::cout << "Sorry, audio capture is not supported by your system" << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
// Choose the sample rate
|
||||
unsigned int sampleRate;
|
||||
std::cout << "Please choose the sample rate for sound capture (44100 is CD quality) : ";
|
||||
std::cin >> sampleRate;
|
||||
std::cin.ignore(10000, '\n');
|
||||
|
||||
// Wait for user input...
|
||||
std::cout << "Press enter to start recording audio";
|
||||
std::cin.ignore(10000, '\n');
|
||||
|
||||
// Here we'll use an integrated custom recorder, which saves the captured data into a SoundBuffer
|
||||
sf::SoundBufferRecorder recorder;
|
||||
|
||||
// Audio capture is done in a separate thread, so we can block the main thread while it is capturing
|
||||
recorder.start(sampleRate);
|
||||
std::cout << "Recording... press enter to stop";
|
||||
std::cin.ignore(10000, '\n');
|
||||
recorder.stop();
|
||||
|
||||
// Get the buffer containing the captured data
|
||||
const sf::SoundBuffer& buffer = recorder.getBuffer();
|
||||
|
||||
// Display captured sound informations
|
||||
std::cout << "Sound information :" << std::endl;
|
||||
std::cout << " " << buffer.getDuration().asSeconds() << " seconds" << std::endl;
|
||||
std::cout << " " << buffer.getSampleRate() << " samples / seconds" << std::endl;
|
||||
std::cout << " " << buffer.getChannelCount() << " channels" << std::endl;
|
||||
|
||||
// Choose what to do with the recorded sound data
|
||||
char choice;
|
||||
std::cout << "What do you want to do with captured sound (p = play, s = save) ? ";
|
||||
std::cin >> choice;
|
||||
std::cin.ignore(10000, '\n');
|
||||
|
||||
if (choice == 's')
|
||||
{
|
||||
// Choose the filename
|
||||
std::string filename;
|
||||
std::cout << "Choose the file to create : ";
|
||||
std::getline(std::cin, filename);
|
||||
|
||||
// Save the buffer
|
||||
buffer.saveToFile(filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create a sound instance and play it
|
||||
sf::Sound sound(buffer);
|
||||
sound.play();
|
||||
|
||||
// Wait until finished
|
||||
while (sound.getStatus() == sf::Sound::Playing)
|
||||
{
|
||||
// Display the playing position
|
||||
std::cout << "\rPlaying... " << std::fixed << std::setprecision(2) << sound.getPlayingOffset().asSeconds() << " sec";
|
||||
std::cout << std::flush;
|
||||
|
||||
// Leave some CPU time for other threads
|
||||
sf::sleep(sf::milliseconds(100));
|
||||
}
|
||||
}
|
||||
|
||||
// Finished!
|
||||
std::cout << std::endl << "Done!" << std::endl;
|
||||
|
||||
// Wait until the user presses 'enter' key
|
||||
std::cout << "Press enter to exit..." << std::endl;
|
||||
std::cin.ignore(10000, '\n');
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Audio.hpp>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Entry point of application
|
||||
///
|
||||
/// \return Application exit code
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
int main()
|
||||
{
|
||||
// Check that the device can capture audio
|
||||
if (sf::SoundRecorder::isAvailable() == false)
|
||||
{
|
||||
std::cout << "Sorry, audio capture is not supported by your system" << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
// Choose the sample rate
|
||||
unsigned int sampleRate;
|
||||
std::cout << "Please choose the sample rate for sound capture (44100 is CD quality) : ";
|
||||
std::cin >> sampleRate;
|
||||
std::cin.ignore(10000, '\n');
|
||||
|
||||
// Wait for user input...
|
||||
std::cout << "Press enter to start recording audio";
|
||||
std::cin.ignore(10000, '\n');
|
||||
|
||||
// Here we'll use an integrated custom recorder, which saves the captured data into a SoundBuffer
|
||||
sf::SoundBufferRecorder recorder;
|
||||
|
||||
// Audio capture is done in a separate thread, so we can block the main thread while it is capturing
|
||||
recorder.start(sampleRate);
|
||||
std::cout << "Recording... press enter to stop";
|
||||
std::cin.ignore(10000, '\n');
|
||||
recorder.stop();
|
||||
|
||||
// Get the buffer containing the captured data
|
||||
const sf::SoundBuffer& buffer = recorder.getBuffer();
|
||||
|
||||
// Display captured sound informations
|
||||
std::cout << "Sound information:" << std::endl;
|
||||
std::cout << " " << buffer.getDuration().asSeconds() << " seconds" << std::endl;
|
||||
std::cout << " " << buffer.getSampleRate() << " samples / seconds" << std::endl;
|
||||
std::cout << " " << buffer.getChannelCount() << " channels" << std::endl;
|
||||
|
||||
// Choose what to do with the recorded sound data
|
||||
char choice;
|
||||
std::cout << "What do you want to do with captured sound (p = play, s = save) ? ";
|
||||
std::cin >> choice;
|
||||
std::cin.ignore(10000, '\n');
|
||||
|
||||
if (choice == 's')
|
||||
{
|
||||
// Choose the filename
|
||||
std::string filename;
|
||||
std::cout << "Choose the file to create: ";
|
||||
std::getline(std::cin, filename);
|
||||
|
||||
// Save the buffer
|
||||
buffer.saveToFile(filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create a sound instance and play it
|
||||
sf::Sound sound(buffer);
|
||||
sound.play();
|
||||
|
||||
// Wait until finished
|
||||
while (sound.getStatus() == sf::Sound::Playing)
|
||||
{
|
||||
// Display the playing position
|
||||
std::cout << "\rPlaying... " << std::fixed << std::setprecision(2) << sound.getPlayingOffset().asSeconds() << " sec";
|
||||
std::cout << std::flush;
|
||||
|
||||
// Leave some CPU time for other threads
|
||||
sf::sleep(sf::milliseconds(100));
|
||||
}
|
||||
}
|
||||
|
||||
// Finished!
|
||||
std::cout << std::endl << "Done!" << std::endl;
|
||||
|
||||
// Wait until the user presses 'enter' key
|
||||
std::cout << "Press enter to exit..." << std::endl;
|
||||
std::cin.ignore(10000, '\n');
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
|
||||
set(SRCROOT ${PROJECT_SOURCE_DIR}/examples/voip)
|
||||
|
||||
# all source files
|
||||
set(SRC ${SRCROOT}/VoIP.cpp
|
||||
${SRCROOT}/Client.cpp
|
||||
${SRCROOT}/Server.cpp)
|
||||
|
||||
# define the voip target
|
||||
sfml_add_example(voip
|
||||
SOURCES ${SRC}
|
||||
DEPENDS sfml-audio sfml-network sfml-system)
|
||||
|
||||
set(SRCROOT ${PROJECT_SOURCE_DIR}/examples/voip)
|
||||
|
||||
# all source files
|
||||
set(SRC ${SRCROOT}/VoIP.cpp
|
||||
${SRCROOT}/Client.cpp
|
||||
${SRCROOT}/Server.cpp)
|
||||
|
||||
# define the voip target
|
||||
sfml_add_example(voip
|
||||
SOURCES ${SRC}
|
||||
DEPENDS sfml-audio sfml-network sfml-system)
|
||||
|
|
|
@ -1,129 +1,129 @@
|
|||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Audio.hpp>
|
||||
#include <SFML/Network.hpp>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
const sf::Uint8 audioData = 1;
|
||||
const sf::Uint8 endOfStream = 2;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Specialization of audio recorder for sending recorded audio
|
||||
/// data through the network
|
||||
////////////////////////////////////////////////////////////
|
||||
class NetworkRecorder : public sf::SoundRecorder
|
||||
{
|
||||
public :
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Constructor
|
||||
///
|
||||
/// \param host Remote host to which send the recording data
|
||||
/// \param port Port of the remote host
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
NetworkRecorder(const sf::IpAddress& host, unsigned short port) :
|
||||
m_host(host),
|
||||
m_port(port)
|
||||
{
|
||||
}
|
||||
|
||||
private :
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// /see SoundRecorder::OnStart
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual bool onStart()
|
||||
{
|
||||
if (m_socket.connect(m_host, m_port) == sf::Socket::Done)
|
||||
{
|
||||
std::cout << "Connected to server " << m_host << std::endl;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// /see SoundRecorder::ProcessSamples
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual bool onProcessSamples(const sf::Int16* samples, std::size_t sampleCount)
|
||||
{
|
||||
// Pack the audio samples into a network packet
|
||||
sf::Packet packet;
|
||||
packet << audioData;
|
||||
packet.append(samples, sampleCount * sizeof(sf::Int16));
|
||||
|
||||
// Send the audio packet to the server
|
||||
return m_socket.send(packet) == sf::Socket::Done;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// /see SoundRecorder::OnStop
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual void onStop()
|
||||
{
|
||||
// Send a "end-of-stream" packet
|
||||
sf::Packet packet;
|
||||
packet << endOfStream;
|
||||
m_socket.send(packet);
|
||||
|
||||
// Close the socket
|
||||
m_socket.disconnect();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Member data
|
||||
////////////////////////////////////////////////////////////
|
||||
sf::IpAddress m_host; ///< Address of the remote host
|
||||
unsigned short m_port; ///< Remote port
|
||||
sf::TcpSocket m_socket; ///< Socket used to communicate with the server
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Create a client, connect it to a running server and
|
||||
/// start sending him audio data
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void doClient(unsigned short port)
|
||||
{
|
||||
// Check that the device can capture audio
|
||||
if (sf::SoundRecorder::isAvailable() == false)
|
||||
{
|
||||
std::cout << "Sorry, audio capture is not supported by your system" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// Ask for server address
|
||||
sf::IpAddress server;
|
||||
do
|
||||
{
|
||||
std::cout << "Type address or name of the server to connect to : ";
|
||||
std::cin >> server;
|
||||
}
|
||||
while (server == sf::IpAddress::None);
|
||||
|
||||
// Create an instance of our custom recorder
|
||||
NetworkRecorder recorder(server, port);
|
||||
|
||||
// Wait for user input...
|
||||
std::cin.ignore(10000, '\n');
|
||||
std::cout << "Press enter to start recording audio";
|
||||
std::cin.ignore(10000, '\n');
|
||||
|
||||
// Start capturing audio data
|
||||
recorder.start(44100);
|
||||
std::cout << "Recording... press enter to stop";
|
||||
std::cin.ignore(10000, '\n');
|
||||
recorder.stop();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Audio.hpp>
|
||||
#include <SFML/Network.hpp>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
const sf::Uint8 audioData = 1;
|
||||
const sf::Uint8 endOfStream = 2;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Specialization of audio recorder for sending recorded audio
|
||||
/// data through the network
|
||||
////////////////////////////////////////////////////////////
|
||||
class NetworkRecorder : public sf::SoundRecorder
|
||||
{
|
||||
public:
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Constructor
|
||||
///
|
||||
/// \param host Remote host to which send the recording data
|
||||
/// \param port Port of the remote host
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
NetworkRecorder(const sf::IpAddress& host, unsigned short port) :
|
||||
m_host(host),
|
||||
m_port(port)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// /see SoundRecorder::OnStart
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual bool onStart()
|
||||
{
|
||||
if (m_socket.connect(m_host, m_port) == sf::Socket::Done)
|
||||
{
|
||||
std::cout << "Connected to server " << m_host << std::endl;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// /see SoundRecorder::ProcessSamples
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual bool onProcessSamples(const sf::Int16* samples, std::size_t sampleCount)
|
||||
{
|
||||
// Pack the audio samples into a network packet
|
||||
sf::Packet packet;
|
||||
packet << audioData;
|
||||
packet.append(samples, sampleCount * sizeof(sf::Int16));
|
||||
|
||||
// Send the audio packet to the server
|
||||
return m_socket.send(packet) == sf::Socket::Done;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// /see SoundRecorder::OnStop
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual void onStop()
|
||||
{
|
||||
// Send a "end-of-stream" packet
|
||||
sf::Packet packet;
|
||||
packet << endOfStream;
|
||||
m_socket.send(packet);
|
||||
|
||||
// Close the socket
|
||||
m_socket.disconnect();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Member data
|
||||
////////////////////////////////////////////////////////////
|
||||
sf::IpAddress m_host; ///< Address of the remote host
|
||||
unsigned short m_port; ///< Remote port
|
||||
sf::TcpSocket m_socket; ///< Socket used to communicate with the server
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Create a client, connect it to a running server and
|
||||
/// start sending him audio data
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void doClient(unsigned short port)
|
||||
{
|
||||
// Check that the device can capture audio
|
||||
if (sf::SoundRecorder::isAvailable() == false)
|
||||
{
|
||||
std::cout << "Sorry, audio capture is not supported by your system" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// Ask for server address
|
||||
sf::IpAddress server;
|
||||
do
|
||||
{
|
||||
std::cout << "Type address or name of the server to connect to: ";
|
||||
std::cin >> server;
|
||||
}
|
||||
while (server == sf::IpAddress::None);
|
||||
|
||||
// Create an instance of our custom recorder
|
||||
NetworkRecorder recorder(server, port);
|
||||
|
||||
// Wait for user input...
|
||||
std::cin.ignore(10000, '\n');
|
||||
std::cout << "Press enter to start recording audio";
|
||||
std::cin.ignore(10000, '\n');
|
||||
|
||||
// Start capturing audio data
|
||||
recorder.start(44100);
|
||||
std::cout << "Recording... press enter to stop";
|
||||
std::cin.ignore(10000, '\n');
|
||||
recorder.stop();
|
||||
}
|
||||
|
|
|
@ -1,200 +1,200 @@
|
|||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Audio.hpp>
|
||||
#include <SFML/Network.hpp>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
|
||||
|
||||
const sf::Uint8 audioData = 1;
|
||||
const sf::Uint8 endOfStream = 2;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Customized sound stream for acquiring audio data
|
||||
/// from the network
|
||||
////////////////////////////////////////////////////////////
|
||||
class NetworkAudioStream : public sf::SoundStream
|
||||
{
|
||||
public :
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Default constructor
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
NetworkAudioStream() :
|
||||
m_offset (0),
|
||||
m_hasFinished(false)
|
||||
{
|
||||
// Set the sound parameters
|
||||
initialize(1, 44100);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Run the server, stream audio data from the client
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void start(unsigned short port)
|
||||
{
|
||||
if (!m_hasFinished)
|
||||
{
|
||||
// Listen to the given port for incoming connections
|
||||
if (m_listener.listen(port) != sf::Socket::Done)
|
||||
return;
|
||||
std::cout << "Server is listening to port " << port << ", waiting for connections... " << std::endl;
|
||||
|
||||
// Wait for a connection
|
||||
if (m_listener.accept(m_client) != sf::Socket::Done)
|
||||
return;
|
||||
std::cout << "Client connected: " << m_client.getRemoteAddress() << std::endl;
|
||||
|
||||
// Start playback
|
||||
play();
|
||||
|
||||
// Start receiving audio data
|
||||
receiveLoop();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Start playback
|
||||
play();
|
||||
}
|
||||
}
|
||||
|
||||
private :
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// /see SoundStream::OnGetData
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual bool onGetData(sf::SoundStream::Chunk& data)
|
||||
{
|
||||
// We have reached the end of the buffer and all audio data have been played : we can stop playback
|
||||
if ((m_offset >= m_samples.size()) && m_hasFinished)
|
||||
return false;
|
||||
|
||||
// No new data has arrived since last update : wait until we get some
|
||||
while ((m_offset >= m_samples.size()) && !m_hasFinished)
|
||||
sf::sleep(sf::milliseconds(10));
|
||||
|
||||
// Copy samples into a local buffer to avoid synchronization problems
|
||||
// (don't forget that we run in two separate threads)
|
||||
{
|
||||
sf::Lock lock(m_mutex);
|
||||
m_tempBuffer.assign(m_samples.begin() + m_offset, m_samples.end());
|
||||
}
|
||||
|
||||
// Fill audio data to pass to the stream
|
||||
data.samples = &m_tempBuffer[0];
|
||||
data.sampleCount = m_tempBuffer.size();
|
||||
|
||||
// Update the playing offset
|
||||
m_offset += m_tempBuffer.size();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// /see SoundStream::OnSeek
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual void onSeek(sf::Time timeOffset)
|
||||
{
|
||||
m_offset = timeOffset.asMilliseconds() * getSampleRate() * getChannelCount() / 1000;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Get audio data from the client until playback is stopped
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void receiveLoop()
|
||||
{
|
||||
while (!m_hasFinished)
|
||||
{
|
||||
// Get waiting audio data from the network
|
||||
sf::Packet packet;
|
||||
if (m_client.receive(packet) != sf::Socket::Done)
|
||||
break;
|
||||
|
||||
// Extract the message ID
|
||||
sf::Uint8 id;
|
||||
packet >> id;
|
||||
|
||||
if (id == audioData)
|
||||
{
|
||||
// Extract audio samples from the packet, and append it to our samples buffer
|
||||
const sf::Int16* samples = reinterpret_cast<const sf::Int16*>(static_cast<const char*>(packet.getData()) + 1);
|
||||
std::size_t sampleCount = (packet.getDataSize() - 1) / sizeof(sf::Int16);
|
||||
|
||||
// Don't forget that the other thread can access the sample array at any time
|
||||
// (so we protect any operation on it with the mutex)
|
||||
{
|
||||
sf::Lock lock(m_mutex);
|
||||
std::copy(samples, samples + sampleCount, std::back_inserter(m_samples));
|
||||
}
|
||||
}
|
||||
else if (id == endOfStream)
|
||||
{
|
||||
// End of stream reached : we stop receiving audio data
|
||||
std::cout << "Audio data has been 100% received!" << std::endl;
|
||||
m_hasFinished = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Something's wrong...
|
||||
std::cout << "Invalid packet received..." << std::endl;
|
||||
m_hasFinished = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Member data
|
||||
////////////////////////////////////////////////////////////
|
||||
sf::TcpListener m_listener;
|
||||
sf::TcpSocket m_client;
|
||||
sf::Mutex m_mutex;
|
||||
std::vector<sf::Int16> m_samples;
|
||||
std::vector<sf::Int16> m_tempBuffer;
|
||||
std::size_t m_offset;
|
||||
bool m_hasFinished;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Launch a server and wait for incoming audio data from
|
||||
/// a connected client
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void doServer(unsigned short port)
|
||||
{
|
||||
// Build an audio stream to play sound data as it is received through the network
|
||||
NetworkAudioStream audioStream;
|
||||
audioStream.start(port);
|
||||
|
||||
// Loop until the sound playback is finished
|
||||
while (audioStream.getStatus() != sf::SoundStream::Stopped)
|
||||
{
|
||||
// Leave some CPU time for other threads
|
||||
sf::sleep(sf::milliseconds(100));
|
||||
}
|
||||
|
||||
std::cin.ignore(10000, '\n');
|
||||
|
||||
// Wait until the user presses 'enter' key
|
||||
std::cout << "Press enter to replay the sound..." << std::endl;
|
||||
std::cin.ignore(10000, '\n');
|
||||
|
||||
// Replay the sound (just to make sure replaying the received data is OK)
|
||||
audioStream.play();
|
||||
|
||||
// Loop until the sound playback is finished
|
||||
while (audioStream.getStatus() != sf::SoundStream::Stopped)
|
||||
{
|
||||
// Leave some CPU time for other threads
|
||||
sf::sleep(sf::milliseconds(100));
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Audio.hpp>
|
||||
#include <SFML/Network.hpp>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
|
||||
|
||||
const sf::Uint8 audioData = 1;
|
||||
const sf::Uint8 endOfStream = 2;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Customized sound stream for acquiring audio data
|
||||
/// from the network
|
||||
////////////////////////////////////////////////////////////
|
||||
class NetworkAudioStream : public sf::SoundStream
|
||||
{
|
||||
public:
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Default constructor
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
NetworkAudioStream() :
|
||||
m_offset (0),
|
||||
m_hasFinished(false)
|
||||
{
|
||||
// Set the sound parameters
|
||||
initialize(1, 44100);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Run the server, stream audio data from the client
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void start(unsigned short port)
|
||||
{
|
||||
if (!m_hasFinished)
|
||||
{
|
||||
// Listen to the given port for incoming connections
|
||||
if (m_listener.listen(port) != sf::Socket::Done)
|
||||
return;
|
||||
std::cout << "Server is listening to port " << port << ", waiting for connections... " << std::endl;
|
||||
|
||||
// Wait for a connection
|
||||
if (m_listener.accept(m_client) != sf::Socket::Done)
|
||||
return;
|
||||
std::cout << "Client connected: " << m_client.getRemoteAddress() << std::endl;
|
||||
|
||||
// Start playback
|
||||
play();
|
||||
|
||||
// Start receiving audio data
|
||||
receiveLoop();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Start playback
|
||||
play();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// /see SoundStream::OnGetData
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual bool onGetData(sf::SoundStream::Chunk& data)
|
||||
{
|
||||
// We have reached the end of the buffer and all audio data have been played: we can stop playback
|
||||
if ((m_offset >= m_samples.size()) && m_hasFinished)
|
||||
return false;
|
||||
|
||||
// No new data has arrived since last update: wait until we get some
|
||||
while ((m_offset >= m_samples.size()) && !m_hasFinished)
|
||||
sf::sleep(sf::milliseconds(10));
|
||||
|
||||
// Copy samples into a local buffer to avoid synchronization problems
|
||||
// (don't forget that we run in two separate threads)
|
||||
{
|
||||
sf::Lock lock(m_mutex);
|
||||
m_tempBuffer.assign(m_samples.begin() + m_offset, m_samples.end());
|
||||
}
|
||||
|
||||
// Fill audio data to pass to the stream
|
||||
data.samples = &m_tempBuffer[0];
|
||||
data.sampleCount = m_tempBuffer.size();
|
||||
|
||||
// Update the playing offset
|
||||
m_offset += m_tempBuffer.size();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// /see SoundStream::OnSeek
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual void onSeek(sf::Time timeOffset)
|
||||
{
|
||||
m_offset = timeOffset.asMilliseconds() * getSampleRate() * getChannelCount() / 1000;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Get audio data from the client until playback is stopped
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void receiveLoop()
|
||||
{
|
||||
while (!m_hasFinished)
|
||||
{
|
||||
// Get waiting audio data from the network
|
||||
sf::Packet packet;
|
||||
if (m_client.receive(packet) != sf::Socket::Done)
|
||||
break;
|
||||
|
||||
// Extract the message ID
|
||||
sf::Uint8 id;
|
||||
packet >> id;
|
||||
|
||||
if (id == audioData)
|
||||
{
|
||||
// Extract audio samples from the packet, and append it to our samples buffer
|
||||
const sf::Int16* samples = reinterpret_cast<const sf::Int16*>(static_cast<const char*>(packet.getData()) + 1);
|
||||
std::size_t sampleCount = (packet.getDataSize() - 1) / sizeof(sf::Int16);
|
||||
|
||||
// Don't forget that the other thread can access the sample array at any time
|
||||
// (so we protect any operation on it with the mutex)
|
||||
{
|
||||
sf::Lock lock(m_mutex);
|
||||
std::copy(samples, samples + sampleCount, std::back_inserter(m_samples));
|
||||
}
|
||||
}
|
||||
else if (id == endOfStream)
|
||||
{
|
||||
// End of stream reached: we stop receiving audio data
|
||||
std::cout << "Audio data has been 100% received!" << std::endl;
|
||||
m_hasFinished = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Something's wrong...
|
||||
std::cout << "Invalid packet received..." << std::endl;
|
||||
m_hasFinished = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Member data
|
||||
////////////////////////////////////////////////////////////
|
||||
sf::TcpListener m_listener;
|
||||
sf::TcpSocket m_client;
|
||||
sf::Mutex m_mutex;
|
||||
std::vector<sf::Int16> m_samples;
|
||||
std::vector<sf::Int16> m_tempBuffer;
|
||||
std::size_t m_offset;
|
||||
bool m_hasFinished;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Launch a server and wait for incoming audio data from
|
||||
/// a connected client
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void doServer(unsigned short port)
|
||||
{
|
||||
// Build an audio stream to play sound data as it is received through the network
|
||||
NetworkAudioStream audioStream;
|
||||
audioStream.start(port);
|
||||
|
||||
// Loop until the sound playback is finished
|
||||
while (audioStream.getStatus() != sf::SoundStream::Stopped)
|
||||
{
|
||||
// Leave some CPU time for other threads
|
||||
sf::sleep(sf::milliseconds(100));
|
||||
}
|
||||
|
||||
std::cin.ignore(10000, '\n');
|
||||
|
||||
// Wait until the user presses 'enter' key
|
||||
std::cout << "Press enter to replay the sound..." << std::endl;
|
||||
std::cin.ignore(10000, '\n');
|
||||
|
||||
// Replay the sound (just to make sure replaying the received data is OK)
|
||||
audioStream.play();
|
||||
|
||||
// Loop until the sound playback is finished
|
||||
while (audioStream.getStatus() != sf::SoundStream::Stopped)
|
||||
{
|
||||
// Leave some CPU time for other threads
|
||||
sf::sleep(sf::milliseconds(100));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,50 +1,50 @@
|
|||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Function prototypes
|
||||
// (I'm too lazy to put them into separate headers...)
|
||||
////////////////////////////////////////////////////////////
|
||||
void doClient(unsigned short port);
|
||||
void doServer(unsigned short port);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Entry point of application
|
||||
///
|
||||
/// \return Application exit code
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
int main()
|
||||
{
|
||||
// Choose a random port for opening sockets (ports < 1024 are reserved)
|
||||
const unsigned short port = 2435;
|
||||
|
||||
// Client or server ?
|
||||
char who;
|
||||
std::cout << "Do you want to be a server ('s') or a client ('c') ? ";
|
||||
std::cin >> who;
|
||||
|
||||
if (who == 's')
|
||||
{
|
||||
// Run as a server
|
||||
doServer(port);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Run as a client
|
||||
doClient(port);
|
||||
}
|
||||
|
||||
// Wait until the user presses 'enter' key
|
||||
std::cout << "Press enter to exit..." << std::endl;
|
||||
std::cin.ignore(10000, '\n');
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Function prototypes
|
||||
// (I'm too lazy to put them into separate headers...)
|
||||
////////////////////////////////////////////////////////////
|
||||
void doClient(unsigned short port);
|
||||
void doServer(unsigned short port);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Entry point of application
|
||||
///
|
||||
/// \return Application exit code
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
int main()
|
||||
{
|
||||
// Choose a random port for opening sockets (ports < 1024 are reserved)
|
||||
const unsigned short port = 2435;
|
||||
|
||||
// Client or server ?
|
||||
char who;
|
||||
std::cout << "Do you want to be a server ('s') or a client ('c') ? ";
|
||||
std::cin >> who;
|
||||
|
||||
if (who == 's')
|
||||
{
|
||||
// Run as a server
|
||||
doServer(port);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Run as a client
|
||||
doClient(port);
|
||||
}
|
||||
|
||||
// Wait until the user presses 'enter' key
|
||||
std::cout << "Press enter to exit..." << std::endl;
|
||||
std::cin.ignore(10000, '\n');
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
|
||||
set(SRCROOT ${PROJECT_SOURCE_DIR}/examples/win32)
|
||||
|
||||
# all source files
|
||||
set(SRC ${SRCROOT}/Win32.cpp)
|
||||
|
||||
# define the win32 target
|
||||
sfml_add_example(win32 GUI_APP
|
||||
SOURCES ${SRC}
|
||||
DEPENDS sfml-graphics sfml-window sfml-system)
|
||||
|
||||
set(SRCROOT ${PROJECT_SOURCE_DIR}/examples/win32)
|
||||
|
||||
# all source files
|
||||
set(SRC ${SRCROOT}/Win32.cpp)
|
||||
|
||||
# define the win32 target
|
||||
sfml_add_example(win32 GUI_APP
|
||||
SOURCES ${SRC}
|
||||
DEPENDS sfml-graphics sfml-window sfml-system)
|
||||
|
|
|
@ -1,130 +1,130 @@
|
|||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include <windows.h>
|
||||
#include <cmath>
|
||||
|
||||
HWND button;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Function called whenever one of our windows receives a message
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
LRESULT CALLBACK onEvent(HWND handle, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (message)
|
||||
{
|
||||
// Quit when we close the main window
|
||||
case WM_CLOSE :
|
||||
{
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Quit when we click the "quit" button
|
||||
case WM_COMMAND :
|
||||
{
|
||||
if (reinterpret_cast<HWND>(lParam) == button)
|
||||
{
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return DefWindowProc(handle, message, wParam, lParam);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Entry point of application
|
||||
///
|
||||
/// \param Instance : Instance of the application
|
||||
///
|
||||
/// \return Error code
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
INT WINAPI WinMain(HINSTANCE instance, HINSTANCE, LPSTR, INT)
|
||||
{
|
||||
// Define a class for our main window
|
||||
WNDCLASS windowClass;
|
||||
windowClass.style = 0;
|
||||
windowClass.lpfnWndProc = &onEvent;
|
||||
windowClass.cbClsExtra = 0;
|
||||
windowClass.cbWndExtra = 0;
|
||||
windowClass.hInstance = instance;
|
||||
windowClass.hIcon = NULL;
|
||||
windowClass.hCursor = 0;
|
||||
windowClass.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_BACKGROUND);
|
||||
windowClass.lpszMenuName = NULL;
|
||||
windowClass.lpszClassName = TEXT("SFML App");
|
||||
RegisterClass(&windowClass);
|
||||
|
||||
// Let's create the main window
|
||||
HWND window = CreateWindow(TEXT("SFML App"), TEXT("SFML Win32"), WS_SYSMENU | WS_VISIBLE, 200, 200, 660, 520, NULL, NULL, instance, NULL);
|
||||
|
||||
// Add a button for exiting
|
||||
button = CreateWindow(TEXT("BUTTON"), TEXT("Quit"), WS_CHILD | WS_VISIBLE, 560, 440, 80, 40, window, NULL, instance, NULL);
|
||||
|
||||
// Let's create two SFML views
|
||||
HWND view1 = CreateWindow(TEXT("STATIC"), NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS, 20, 20, 300, 400, window, NULL, instance, NULL);
|
||||
HWND view2 = CreateWindow(TEXT("STATIC"), NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS, 340, 20, 300, 400, window, NULL, instance, NULL);
|
||||
sf::RenderWindow SFMLView1(view1);
|
||||
sf::RenderWindow SFMLView2(view2);
|
||||
|
||||
// Load some textures to display
|
||||
sf::Texture texture1, texture2;
|
||||
if (!texture1.loadFromFile("resources/image1.jpg") || !texture2.loadFromFile("resources/image2.jpg"))
|
||||
return EXIT_FAILURE;
|
||||
sf::Sprite sprite1(texture1);
|
||||
sf::Sprite sprite2(texture2);
|
||||
sprite1.setOrigin(sf::Vector2f(texture1.getSize()) / 2.f);
|
||||
sprite1.setPosition(sprite1.getOrigin());
|
||||
|
||||
// Create a clock for measuring elapsed time
|
||||
sf::Clock clock;
|
||||
|
||||
// Loop until a WM_QUIT message is received
|
||||
MSG message;
|
||||
message.message = static_cast<UINT>(~WM_QUIT);
|
||||
while (message.message != WM_QUIT)
|
||||
{
|
||||
if (PeekMessage(&message, NULL, 0, 0, PM_REMOVE))
|
||||
{
|
||||
// If a message was waiting in the message queue, process it
|
||||
TranslateMessage(&message);
|
||||
DispatchMessage(&message);
|
||||
}
|
||||
else
|
||||
{
|
||||
float time = clock.getElapsedTime().asSeconds();
|
||||
|
||||
// Clear views
|
||||
SFMLView1.clear();
|
||||
SFMLView2.clear();
|
||||
|
||||
// Draw sprite 1 on view 1
|
||||
sprite1.setRotation(time * 100);
|
||||
SFMLView1.draw(sprite1);
|
||||
|
||||
// Draw sprite 2 on view 2
|
||||
sprite2.setPosition(std::cos(time) * 100.f, 0.f);
|
||||
SFMLView2.draw(sprite2);
|
||||
|
||||
// Display each view on screen
|
||||
SFMLView1.display();
|
||||
SFMLView2.display();
|
||||
}
|
||||
}
|
||||
|
||||
// Destroy the main window (all its child controls will be destroyed)
|
||||
DestroyWindow(window);
|
||||
|
||||
// Don't forget to unregister the window class
|
||||
UnregisterClass(TEXT("SFML App"), instance);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include <windows.h>
|
||||
#include <cmath>
|
||||
|
||||
HWND button;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Function called whenever one of our windows receives a message
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
LRESULT CALLBACK onEvent(HWND handle, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (message)
|
||||
{
|
||||
// Quit when we close the main window
|
||||
case WM_CLOSE:
|
||||
{
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Quit when we click the "quit" button
|
||||
case WM_COMMAND:
|
||||
{
|
||||
if (reinterpret_cast<HWND>(lParam) == button)
|
||||
{
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return DefWindowProc(handle, message, wParam, lParam);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Entry point of application
|
||||
///
|
||||
/// \param Instance: Instance of the application
|
||||
///
|
||||
/// \return Error code
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
INT WINAPI WinMain(HINSTANCE instance, HINSTANCE, LPSTR, INT)
|
||||
{
|
||||
// Define a class for our main window
|
||||
WNDCLASS windowClass;
|
||||
windowClass.style = 0;
|
||||
windowClass.lpfnWndProc = &onEvent;
|
||||
windowClass.cbClsExtra = 0;
|
||||
windowClass.cbWndExtra = 0;
|
||||
windowClass.hInstance = instance;
|
||||
windowClass.hIcon = NULL;
|
||||
windowClass.hCursor = 0;
|
||||
windowClass.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_BACKGROUND);
|
||||
windowClass.lpszMenuName = NULL;
|
||||
windowClass.lpszClassName = TEXT("SFML App");
|
||||
RegisterClass(&windowClass);
|
||||
|
||||
// Let's create the main window
|
||||
HWND window = CreateWindow(TEXT("SFML App"), TEXT("SFML Win32"), WS_SYSMENU | WS_VISIBLE, 200, 200, 660, 520, NULL, NULL, instance, NULL);
|
||||
|
||||
// Add a button for exiting
|
||||
button = CreateWindow(TEXT("BUTTON"), TEXT("Quit"), WS_CHILD | WS_VISIBLE, 560, 440, 80, 40, window, NULL, instance, NULL);
|
||||
|
||||
// Let's create two SFML views
|
||||
HWND view1 = CreateWindow(TEXT("STATIC"), NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS, 20, 20, 300, 400, window, NULL, instance, NULL);
|
||||
HWND view2 = CreateWindow(TEXT("STATIC"), NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS, 340, 20, 300, 400, window, NULL, instance, NULL);
|
||||
sf::RenderWindow SFMLView1(view1);
|
||||
sf::RenderWindow SFMLView2(view2);
|
||||
|
||||
// Load some textures to display
|
||||
sf::Texture texture1, texture2;
|
||||
if (!texture1.loadFromFile("resources/image1.jpg") || !texture2.loadFromFile("resources/image2.jpg"))
|
||||
return EXIT_FAILURE;
|
||||
sf::Sprite sprite1(texture1);
|
||||
sf::Sprite sprite2(texture2);
|
||||
sprite1.setOrigin(sf::Vector2f(texture1.getSize()) / 2.f);
|
||||
sprite1.setPosition(sprite1.getOrigin());
|
||||
|
||||
// Create a clock for measuring elapsed time
|
||||
sf::Clock clock;
|
||||
|
||||
// Loop until a WM_QUIT message is received
|
||||
MSG message;
|
||||
message.message = static_cast<UINT>(~WM_QUIT);
|
||||
while (message.message != WM_QUIT)
|
||||
{
|
||||
if (PeekMessage(&message, NULL, 0, 0, PM_REMOVE))
|
||||
{
|
||||
// If a message was waiting in the message queue, process it
|
||||
TranslateMessage(&message);
|
||||
DispatchMessage(&message);
|
||||
}
|
||||
else
|
||||
{
|
||||
float time = clock.getElapsedTime().asSeconds();
|
||||
|
||||
// Clear views
|
||||
SFMLView1.clear();
|
||||
SFMLView2.clear();
|
||||
|
||||
// Draw sprite 1 on view 1
|
||||
sprite1.setRotation(time * 100);
|
||||
SFMLView1.draw(sprite1);
|
||||
|
||||
// Draw sprite 2 on view 2
|
||||
sprite2.setPosition(std::cos(time) * 100.f, 0.f);
|
||||
SFMLView2.draw(sprite2);
|
||||
|
||||
// Display each view on screen
|
||||
SFMLView1.display();
|
||||
SFMLView2.display();
|
||||
}
|
||||
}
|
||||
|
||||
// Destroy the main window (all its child controls will be destroyed)
|
||||
DestroyWindow(window);
|
||||
|
||||
// Don't forget to unregister the window class
|
||||
UnregisterClass(TEXT("SFML App"), instance);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
|
||||
set(SRCROOT ${PROJECT_SOURCE_DIR}/examples/window)
|
||||
|
||||
# all source files
|
||||
set(SRC ${SRCROOT}/Window.cpp)
|
||||
|
||||
# find OpenGL and GLU
|
||||
find_package(OpenGL REQUIRED)
|
||||
include_directories(${OPENGL_INCLUDE_DIR})
|
||||
set(ADDITIONAL_LIBRARIES ${OPENGL_LIBRARIES})
|
||||
|
||||
# define the window target
|
||||
sfml_add_example(window GUI_APP
|
||||
SOURCES ${SRC}
|
||||
DEPENDS sfml-window sfml-system ${ADDITIONAL_LIBRARIES})
|
||||
|
||||
set(SRCROOT ${PROJECT_SOURCE_DIR}/examples/window)
|
||||
|
||||
# all source files
|
||||
set(SRC ${SRCROOT}/Window.cpp)
|
||||
|
||||
# find OpenGL and GLU
|
||||
find_package(OpenGL REQUIRED)
|
||||
include_directories(${OPENGL_INCLUDE_DIR})
|
||||
set(ADDITIONAL_LIBRARIES ${OPENGL_LIBRARIES})
|
||||
|
||||
# define the window target
|
||||
sfml_add_example(window GUI_APP
|
||||
SOURCES ${SRC}
|
||||
DEPENDS sfml-window sfml-system ${ADDITIONAL_LIBRARIES})
|
||||
|
|
|
@ -1,146 +1,146 @@
|
|||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Window.hpp>
|
||||
#include <SFML/OpenGL.hpp>
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Entry point of application
|
||||
///
|
||||
/// \return Application exit code
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
int main()
|
||||
{
|
||||
// Request a 32-bits depth buffer when creating the window
|
||||
sf::ContextSettings contextSettings;
|
||||
contextSettings.depthBits = 32;
|
||||
|
||||
// Create the main window
|
||||
sf::Window window(sf::VideoMode(640, 480), "SFML window with OpenGL", sf::Style::Default, contextSettings);
|
||||
|
||||
// Make it the active window for OpenGL calls
|
||||
window.setActive();
|
||||
|
||||
// Set the color and depth clear values
|
||||
glClearDepth(1.f);
|
||||
glClearColor(0.f, 0.f, 0.f, 1.f);
|
||||
|
||||
// Enable Z-buffer read and write
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_TRUE);
|
||||
|
||||
// Disable lighting and texturing
|
||||
glDisable(GL_LIGHTING);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
// Configure the viewport (the same size as the window)
|
||||
glViewport(0, 0, window.getSize().x, window.getSize().y);
|
||||
|
||||
// Setup a perspective projection
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
GLfloat ratio = static_cast<float>(window.getSize().x) / window.getSize().y;
|
||||
glFrustum(-ratio, ratio, -1.f, 1.f, 1.f, 500.f);
|
||||
|
||||
// Define a 3D cube (6 faces made of 2 triangles composed by 3 vertices)
|
||||
GLfloat cube[] =
|
||||
{
|
||||
// positions // colors (r, g, b, a)
|
||||
-50, -50, -50, 0, 0, 1, 1,
|
||||
-50, 50, -50, 0, 0, 1, 1,
|
||||
-50, -50, 50, 0, 0, 1, 1,
|
||||
-50, -50, 50, 0, 0, 1, 1,
|
||||
-50, 50, -50, 0, 0, 1, 1,
|
||||
-50, 50, 50, 0, 0, 1, 1,
|
||||
|
||||
50, -50, -50, 0, 1, 0, 1,
|
||||
50, 50, -50, 0, 1, 0, 1,
|
||||
50, -50, 50, 0, 1, 0, 1,
|
||||
50, -50, 50, 0, 1, 0, 1,
|
||||
50, 50, -50, 0, 1, 0, 1,
|
||||
50, 50, 50, 0, 1, 0, 1,
|
||||
|
||||
-50, -50, -50, 1, 0, 0, 1,
|
||||
50, -50, -50, 1, 0, 0, 1,
|
||||
-50, -50, 50, 1, 0, 0, 1,
|
||||
-50, -50, 50, 1, 0, 0, 1,
|
||||
50, -50, -50, 1, 0, 0, 1,
|
||||
50, -50, 50, 1, 0, 0, 1,
|
||||
|
||||
-50, 50, -50, 0, 1, 1, 1,
|
||||
50, 50, -50, 0, 1, 1, 1,
|
||||
-50, 50, 50, 0, 1, 1, 1,
|
||||
-50, 50, 50, 0, 1, 1, 1,
|
||||
50, 50, -50, 0, 1, 1, 1,
|
||||
50, 50, 50, 0, 1, 1, 1,
|
||||
|
||||
-50, -50, -50, 1, 0, 1, 1,
|
||||
50, -50, -50, 1, 0, 1, 1,
|
||||
-50, 50, -50, 1, 0, 1, 1,
|
||||
-50, 50, -50, 1, 0, 1, 1,
|
||||
50, -50, -50, 1, 0, 1, 1,
|
||||
50, 50, -50, 1, 0, 1, 1,
|
||||
|
||||
-50, -50, 50, 1, 1, 0, 1,
|
||||
50, -50, 50, 1, 1, 0, 1,
|
||||
-50, 50, 50, 1, 1, 0, 1,
|
||||
-50, 50, 50, 1, 1, 0, 1,
|
||||
50, -50, 50, 1, 1, 0, 1,
|
||||
50, 50, 50, 1, 1, 0, 1,
|
||||
};
|
||||
|
||||
// Enable position and color vertex components
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
glVertexPointer(3, GL_FLOAT, 7 * sizeof(GLfloat), cube);
|
||||
glColorPointer(4, GL_FLOAT, 7 * sizeof(GLfloat), cube + 3);
|
||||
|
||||
// Disable normal and texture coordinates vertex components
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
// Create a clock for measuring the time elapsed
|
||||
sf::Clock clock;
|
||||
|
||||
// Start the game loop
|
||||
while (window.isOpen())
|
||||
{
|
||||
// Process events
|
||||
sf::Event event;
|
||||
while (window.pollEvent(event))
|
||||
{
|
||||
// Close window: exit
|
||||
if (event.type == sf::Event::Closed)
|
||||
window.close();
|
||||
|
||||
// Escape key: exit
|
||||
if ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Escape))
|
||||
window.close();
|
||||
|
||||
// Resize event: adjust the viewport
|
||||
if (event.type == sf::Event::Resized)
|
||||
glViewport(0, 0, event.size.width, event.size.height);
|
||||
}
|
||||
|
||||
// Clear the color and depth buffers
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// Apply some transformations to rotate the cube
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glTranslatef(0.f, 0.f, -200.f);
|
||||
glRotatef(clock.getElapsedTime().asSeconds() * 50, 1.f, 0.f, 0.f);
|
||||
glRotatef(clock.getElapsedTime().asSeconds() * 30, 0.f, 1.f, 0.f);
|
||||
glRotatef(clock.getElapsedTime().asSeconds() * 90, 0.f, 0.f, 1.f);
|
||||
|
||||
// Draw the cube
|
||||
glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||
|
||||
// Finally, display the rendered frame on screen
|
||||
window.display();
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Window.hpp>
|
||||
#include <SFML/OpenGL.hpp>
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Entry point of application
|
||||
///
|
||||
/// \return Application exit code
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
int main()
|
||||
{
|
||||
// Request a 32-bits depth buffer when creating the window
|
||||
sf::ContextSettings contextSettings;
|
||||
contextSettings.depthBits = 32;
|
||||
|
||||
// Create the main window
|
||||
sf::Window window(sf::VideoMode(640, 480), "SFML window with OpenGL", sf::Style::Default, contextSettings);
|
||||
|
||||
// Make it the active window for OpenGL calls
|
||||
window.setActive();
|
||||
|
||||
// Set the color and depth clear values
|
||||
glClearDepth(1.f);
|
||||
glClearColor(0.f, 0.f, 0.f, 1.f);
|
||||
|
||||
// Enable Z-buffer read and write
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_TRUE);
|
||||
|
||||
// Disable lighting and texturing
|
||||
glDisable(GL_LIGHTING);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
// Configure the viewport (the same size as the window)
|
||||
glViewport(0, 0, window.getSize().x, window.getSize().y);
|
||||
|
||||
// Setup a perspective projection
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
GLfloat ratio = static_cast<float>(window.getSize().x) / window.getSize().y;
|
||||
glFrustum(-ratio, ratio, -1.f, 1.f, 1.f, 500.f);
|
||||
|
||||
// Define a 3D cube (6 faces made of 2 triangles composed by 3 vertices)
|
||||
GLfloat cube[] =
|
||||
{
|
||||
// positions // colors (r, g, b, a)
|
||||
-50, -50, -50, 0, 0, 1, 1,
|
||||
-50, 50, -50, 0, 0, 1, 1,
|
||||
-50, -50, 50, 0, 0, 1, 1,
|
||||
-50, -50, 50, 0, 0, 1, 1,
|
||||
-50, 50, -50, 0, 0, 1, 1,
|
||||
-50, 50, 50, 0, 0, 1, 1,
|
||||
|
||||
50, -50, -50, 0, 1, 0, 1,
|
||||
50, 50, -50, 0, 1, 0, 1,
|
||||
50, -50, 50, 0, 1, 0, 1,
|
||||
50, -50, 50, 0, 1, 0, 1,
|
||||
50, 50, -50, 0, 1, 0, 1,
|
||||
50, 50, 50, 0, 1, 0, 1,
|
||||
|
||||
-50, -50, -50, 1, 0, 0, 1,
|
||||
50, -50, -50, 1, 0, 0, 1,
|
||||
-50, -50, 50, 1, 0, 0, 1,
|
||||
-50, -50, 50, 1, 0, 0, 1,
|
||||
50, -50, -50, 1, 0, 0, 1,
|
||||
50, -50, 50, 1, 0, 0, 1,
|
||||
|
||||
-50, 50, -50, 0, 1, 1, 1,
|
||||
50, 50, -50, 0, 1, 1, 1,
|
||||
-50, 50, 50, 0, 1, 1, 1,
|
||||
-50, 50, 50, 0, 1, 1, 1,
|
||||
50, 50, -50, 0, 1, 1, 1,
|
||||
50, 50, 50, 0, 1, 1, 1,
|
||||
|
||||
-50, -50, -50, 1, 0, 1, 1,
|
||||
50, -50, -50, 1, 0, 1, 1,
|
||||
-50, 50, -50, 1, 0, 1, 1,
|
||||
-50, 50, -50, 1, 0, 1, 1,
|
||||
50, -50, -50, 1, 0, 1, 1,
|
||||
50, 50, -50, 1, 0, 1, 1,
|
||||
|
||||
-50, -50, 50, 1, 1, 0, 1,
|
||||
50, -50, 50, 1, 1, 0, 1,
|
||||
-50, 50, 50, 1, 1, 0, 1,
|
||||
-50, 50, 50, 1, 1, 0, 1,
|
||||
50, -50, 50, 1, 1, 0, 1,
|
||||
50, 50, 50, 1, 1, 0, 1,
|
||||
};
|
||||
|
||||
// Enable position and color vertex components
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
glVertexPointer(3, GL_FLOAT, 7 * sizeof(GLfloat), cube);
|
||||
glColorPointer(4, GL_FLOAT, 7 * sizeof(GLfloat), cube + 3);
|
||||
|
||||
// Disable normal and texture coordinates vertex components
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
// Create a clock for measuring the time elapsed
|
||||
sf::Clock clock;
|
||||
|
||||
// Start the game loop
|
||||
while (window.isOpen())
|
||||
{
|
||||
// Process events
|
||||
sf::Event event;
|
||||
while (window.pollEvent(event))
|
||||
{
|
||||
// Close window: exit
|
||||
if (event.type == sf::Event::Closed)
|
||||
window.close();
|
||||
|
||||
// Escape key: exit
|
||||
if ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Escape))
|
||||
window.close();
|
||||
|
||||
// Resize event: adjust the viewport
|
||||
if (event.type == sf::Event::Resized)
|
||||
glViewport(0, 0, event.size.width, event.size.height);
|
||||
}
|
||||
|
||||
// Clear the color and depth buffers
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// Apply some transformations to rotate the cube
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glTranslatef(0.f, 0.f, -200.f);
|
||||
glRotatef(clock.getElapsedTime().asSeconds() * 50, 1.f, 0.f, 0.f);
|
||||
glRotatef(clock.getElapsedTime().asSeconds() * 30, 0.f, 1.f, 0.f);
|
||||
glRotatef(clock.getElapsedTime().asSeconds() * 90, 0.f, 0.f, 1.f);
|
||||
|
||||
// Draw the cube
|
||||
glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||
|
||||
// Finally, display the rendered frame on screen
|
||||
window.display();
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue