Hello
I was trying the example program provided in the CSFML 1.6 doc and everything went as expected.
But when I tried to use separate threads (one for rendering, another for handling events) the window freezes, and all I get is a black display
the only way to close the program is through the task manager.
Here is my code:
#ifdef __linux__ #include <unistd.h>#elif _WIN32 #include <windows.h>#endif#include <stdio.h>#include <stdlib.h>#include <time.h>// CSFML headers#include <SFML/Graphics.h>#include <SFML/Window.h>// csfmlsfWindowSettings windowSettings
= {24, 8, 0};sfVideoMode videoMode
= {800, 600, 32};sfRenderWindow
* mainWindow
;sfImage
* image
;sfSprite
* sprite
;sfFont
* font
;sfString
* text
;sfEvent event
;int gui_init
();void gui_cleanup
();void rendering_thread_handler
(void* arg
);void event_handler_thread_handler
(void* arg
);long mx_get_uptime
();void mx_msleep
();void mx_sync_loop
(long* t1
, long fps
);int main
(int argc
, char* argv
[]){ if (gui_init
() != EXIT_SUCCESS
) return EXIT_FAILURE
; sfThread
* rendering_thread
= sfThread_Create
(rendering_thread_handler
, NULL
); sfThread
* event_handling_thread
= sfThread_Create
(event_handler_thread_handler
, NULL
); sfThread_Launch
(rendering_thread
); sfThread_Launch
(event_handling_thread
); sfThread_Wait
(event_handling_thread
); sfThread_Wait
(rendering_thread
); gui_cleanup
(); return EXIT_SUCCESS
;}int gui_init
(){ /* Create the main window */ mainWindow
= sfRenderWindow_Create
(videoMode
, "SFML window", sfResize
| sfClose
, windowSettings
); if (!mainWindow
) return EXIT_FAILURE
; /* Load a sprite to display */ image
= sfImage_CreateFromFile
("metal-hull.png"); if (!image
) return EXIT_FAILURE
; sprite
= sfSprite_Create
(); sfSprite_SetImage
(sprite
, image
); /* Create a graphical string to display */ font
= sfFont_CreateFromFile
("UbuntuMono-R.ttf", 64, NULL
); if (!font
) return EXIT_FAILURE
; text
= sfString_Create
(); sfString_SetText
(text
, "Hello CSFML"); sfString_SetFont
(text
, font
); sfString_SetSize
(text
, 32); return EXIT_SUCCESS
;}void gui_cleanup
(){ /* Cleanup resources */ sfString_Destroy
(text
); sfFont_Destroy
(font
); sfSprite_Destroy
(sprite
); sfImage_Destroy
(image
); sfRenderWindow_Destroy
(mainWindow
);}void rendering_thread_handler
(void* arg
){ sfContext
* p_context
= sfContext_Create
(); sfContext_SetActive
(p_context
, sfTrue
); long t1
= mx_get_uptime
(); while (sfRenderWindow_IsOpened
(mainWindow
)) { /* Clear the screen */ sfRenderWindow_Clear
(mainWindow
, sfBlack
); /* Draw the sprite */ sfRenderWindow_DrawSprite
(mainWindow
, sprite
); /* Draw the string */ sfRenderWindow_DrawString
(mainWindow
, text
); /* Update the window */ sfRenderWindow_Display
(mainWindow
); mx_sync_loop
(&t1
, 30); } sfContext_Destroy
(p_context
);}void event_handler_thread_handler
(void* arg
){ sfContext
* p_context
= sfContext_Create
(); sfContext_SetActive
(p_context
, sfTrue
); /* Process events */ long t1
= mx_get_uptime
(); while (sfRenderWindow_GetEvent
(mainWindow
, &event
)) { /* Close window : exit */ if (event.
Type == sfEvtClosed
) { sfRenderWindow_Close
(mainWindow
); break; } mx_sync_loop
(&t1
, 30); } sfContext_Destroy
(p_context
);}/** \brief Returns the amount of micro-seconds since the program was started.
* \return The time (in milli-seconds) since the program was started.
*
*/long mx_get_uptime
(){ return (long) ((double) clock() / (CLOCKS_PER_SEC
/ 1000.0)); // ... until I think of a better implementation...}/** \brief Causes the program to wait for ms_time milliseconds.
*
*/void mx_msleep
(long ms_time
){#ifdef __linux__ usleep
(ms_time
* 1000);#elif _WIN32 Sleep
(ms_time
);#endif}/** \brief Synchronizes a loop to be executed at certain rate.
* \param t1 a pointer to the last syncing time in milliseconds. Must be initialized before entering the loop.
* \param fps the frame rate to maintain
*
*/void mx_sync_loop
(long* t1
, long fps
){ long t2
= mx_get_uptime
(); if ((t2
-*t1
) > (1000/fps
)) { *t1
= t2
; } else { mx_msleep
((1000/fps
) - (t2
-*t1
)); *t1
= mx_get_uptime
(); }} Can someone help me, please ?
I'm using Code::Blocks 12.11, MinGW with gcc 4.7.2 and my OS is a 64-bit Windows 7.
PS: I don't know why, but when I run the Debug build, the program prints a lot of
An internal OpenGL call failed in SOURCE_FILE.cpp (LINE_NUMBER) : GL_INVALID_OPERATION, the specified operation is not allowed in the current state
messages to the console (where SOURCE_FILE.cpp (LINE_NUMBER) are various, for example Image.cpp (482)).
Also, I tried with and without the
sfContext* p_context = sfContext_Create();
sfContext_SetActive(p_context , sfTrue);
...
sfContext_Destroy(p_context);
lines, but the problem is the same.