mirror of
https://github.com/glfw/glfw.git
synced 2024-11-25 22:14:34 +00:00
Plain port of particles example to GLFW 3.
This commit is contained in:
parent
e38740d6ef
commit
d9f53c78a0
@ -18,17 +18,21 @@ endif()
|
|||||||
|
|
||||||
set(GETOPT ${GLFW_SOURCE_DIR}/deps/getopt.h
|
set(GETOPT ${GLFW_SOURCE_DIR}/deps/getopt.h
|
||||||
${GLFW_SOURCE_DIR}/deps/getopt.c)
|
${GLFW_SOURCE_DIR}/deps/getopt.c)
|
||||||
|
set(TINYCTHREAD ${GLFW_SOURCE_DIR}/deps/tinycthread.h
|
||||||
|
${GLFW_SOURCE_DIR}/deps/tinycthread.c)
|
||||||
|
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
# Set fancy names for bundles
|
# Set fancy names for bundles
|
||||||
add_executable(Boing MACOSX_BUNDLE boing.c)
|
add_executable(Boing MACOSX_BUNDLE boing.c)
|
||||||
add_executable(Gears MACOSX_BUNDLE gears.c)
|
add_executable(Gears MACOSX_BUNDLE gears.c)
|
||||||
|
add_executable(Particles MACOSX_BUNDLE particles.c ${TINYCTHREAD})
|
||||||
add_executable(Simple MACOSX_BUNDLE simple.c)
|
add_executable(Simple MACOSX_BUNDLE simple.c)
|
||||||
add_executable("Split View" MACOSX_BUNDLE splitview.c)
|
add_executable("Split View" MACOSX_BUNDLE splitview.c)
|
||||||
add_executable(Wave MACOSX_BUNDLE wave.c)
|
add_executable(Wave MACOSX_BUNDLE wave.c)
|
||||||
|
|
||||||
set_target_properties(Boing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Boing")
|
set_target_properties(Boing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Boing")
|
||||||
set_target_properties(Gears PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Gears")
|
set_target_properties(Gears PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Gears")
|
||||||
|
set_target_properties(Particles PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Particles")
|
||||||
set_target_properties(Simple PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Simple")
|
set_target_properties(Simple PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Simple")
|
||||||
set_target_properties("Split View" PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Split View")
|
set_target_properties("Split View" PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Split View")
|
||||||
set_target_properties(Wave PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Wave")
|
set_target_properties(Wave PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Wave")
|
||||||
@ -37,13 +41,14 @@ else()
|
|||||||
add_executable(boing WIN32 boing.c)
|
add_executable(boing WIN32 boing.c)
|
||||||
add_executable(gears WIN32 gears.c)
|
add_executable(gears WIN32 gears.c)
|
||||||
add_executable(heightmap WIN32 heightmap.c ${GETOPT})
|
add_executable(heightmap WIN32 heightmap.c ${GETOPT})
|
||||||
|
add_executable(particles WIN32 particles.c ${TINYCTHREAD})
|
||||||
add_executable(simple WIN32 simple.c)
|
add_executable(simple WIN32 simple.c)
|
||||||
add_executable(splitview WIN32 splitview.c)
|
add_executable(splitview WIN32 splitview.c)
|
||||||
add_executable(wave WIN32 wave.c)
|
add_executable(wave WIN32 wave.c)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
set(WINDOWS_BINARIES boing gears heightmap simple splitview wave)
|
set(WINDOWS_BINARIES boing gears heightmap particles simple splitview wave)
|
||||||
|
|
||||||
# Tell MSVC to use main instead of WinMain for Windows subsystem executables
|
# Tell MSVC to use main instead of WinMain for Windows subsystem executables
|
||||||
set_target_properties(${WINDOWS_BINARIES} PROPERTIES
|
set_target_properties(${WINDOWS_BINARIES} PROPERTIES
|
||||||
@ -51,7 +56,7 @@ if (MSVC)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
set(BUNDLE_BINARIES Boing Gears Simple "Split View" Wave)
|
set(BUNDLE_BINARIES Boing Gears Particles Simple "Split View" Wave)
|
||||||
|
|
||||||
set_target_properties(${BUNDLE_BINARIES} PROPERTIES
|
set_target_properties(${BUNDLE_BINARIES} PROPERTIES
|
||||||
MACOSX_BUNDLE_SHORT_VERSION_STRING ${GLFW_VERSION}
|
MACOSX_BUNDLE_SHORT_VERSION_STRING ${GLFW_VERSION}
|
||||||
|
@ -41,7 +41,11 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <GL/glfw.h>
|
|
||||||
|
#define GLFW_INCLUDE_GLU
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
#include <tinycthread.h>
|
||||||
|
|
||||||
// Define tokens for GL_EXT_separate_specular_color if not already defined
|
// Define tokens for GL_EXT_separate_specular_color if not already defined
|
||||||
#ifndef GL_EXT_separate_specular_color
|
#ifndef GL_EXT_separate_specular_color
|
||||||
@ -100,9 +104,9 @@ struct {
|
|||||||
float dt; // Time since last frame (s)
|
float dt; // Time since last frame (s)
|
||||||
int p_frame; // Particle physics frame number
|
int p_frame; // Particle physics frame number
|
||||||
int d_frame; // Particle draw frame number
|
int d_frame; // Particle draw frame number
|
||||||
GLFWcond p_done; // Condition: particle physics done
|
cnd_t p_done; // Condition: particle physics done
|
||||||
GLFWcond d_done; // Condition: particle draw done
|
cnd_t d_done; // Condition: particle draw done
|
||||||
GLFWmutex particles_lock; // Particles data sharing mutex
|
mtx_t particles_lock; // Particles data sharing mutex
|
||||||
} thread_sync;
|
} thread_sync;
|
||||||
|
|
||||||
|
|
||||||
@ -456,11 +460,12 @@ void DrawParticles( double t, float dt )
|
|||||||
if( multithreading )
|
if( multithreading )
|
||||||
{
|
{
|
||||||
// Wait for particle physics thread to be done
|
// Wait for particle physics thread to be done
|
||||||
glfwLockMutex( thread_sync.particles_lock );
|
mtx_lock( &thread_sync.particles_lock );
|
||||||
while( running && thread_sync.p_frame <= thread_sync.d_frame )
|
while( running && thread_sync.p_frame <= thread_sync.d_frame )
|
||||||
{
|
{
|
||||||
glfwWaitCond( thread_sync.p_done, thread_sync.particles_lock,
|
struct timespec ts = { 0, 100000000 };
|
||||||
0.1 );
|
cnd_timedwait( &thread_sync.p_done, &thread_sync.particles_lock,
|
||||||
|
&ts );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store the frame time and delta time for the physics thread
|
// Store the frame time and delta time for the physics thread
|
||||||
@ -563,8 +568,8 @@ void DrawParticles( double t, float dt )
|
|||||||
// thread
|
// thread
|
||||||
if( multithreading )
|
if( multithreading )
|
||||||
{
|
{
|
||||||
glfwUnlockMutex( thread_sync.particles_lock );
|
mtx_unlock( &thread_sync.particles_lock );
|
||||||
glfwSignalCond( thread_sync.d_done );
|
cnd_signal( &thread_sync.d_done );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw final batch of particles (if any)
|
// Draw final batch of particles (if any)
|
||||||
@ -897,7 +902,7 @@ void Draw( double t )
|
|||||||
// Resize() - GLFW window resize callback function
|
// Resize() - GLFW window resize callback function
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
void GLFWCALL Resize( int x, int y )
|
void Resize( GLFWwindow* window, int x, int y )
|
||||||
{
|
{
|
||||||
width = x;
|
width = x;
|
||||||
height = y > 0 ? y : 1; // Prevent division by zero in aspect calc.
|
height = y > 0 ? y : 1; // Prevent division by zero in aspect calc.
|
||||||
@ -908,16 +913,16 @@ void GLFWCALL Resize( int x, int y )
|
|||||||
// Input callback functions
|
// Input callback functions
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
void GLFWCALL KeyFun( int key, int action )
|
void KeyFun( GLFWwindow* window, int key, int scancode, int action, int mods )
|
||||||
{
|
{
|
||||||
if( action == GLFW_PRESS )
|
if( action == GLFW_PRESS )
|
||||||
{
|
{
|
||||||
switch( key )
|
switch( key )
|
||||||
{
|
{
|
||||||
case GLFW_KEY_ESC:
|
case GLFW_KEY_ESCAPE:
|
||||||
running = 0;
|
running = 0;
|
||||||
break;
|
break;
|
||||||
case 'W':
|
case GLFW_KEY_W:
|
||||||
wireframe = !wireframe;
|
wireframe = !wireframe;
|
||||||
glPolygonMode( GL_FRONT_AND_BACK,
|
glPolygonMode( GL_FRONT_AND_BACK,
|
||||||
wireframe ? GL_LINE : GL_FILL );
|
wireframe ? GL_LINE : GL_FILL );
|
||||||
@ -933,18 +938,19 @@ void GLFWCALL KeyFun( int key, int action )
|
|||||||
// PhysicsThreadFun() - Thread for updating particle physics
|
// PhysicsThreadFun() - Thread for updating particle physics
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
void GLFWCALL PhysicsThreadFun( void *arg )
|
int PhysicsThreadFun( void *arg )
|
||||||
{
|
{
|
||||||
while( running )
|
while( running )
|
||||||
{
|
{
|
||||||
// Lock mutex
|
// Lock mutex
|
||||||
glfwLockMutex( thread_sync.particles_lock );
|
mtx_lock( &thread_sync.particles_lock );
|
||||||
|
|
||||||
// Wait for particle drawing to be done
|
// Wait for particle drawing to be done
|
||||||
while( running && thread_sync.p_frame > thread_sync.d_frame )
|
while( running && thread_sync.p_frame > thread_sync.d_frame )
|
||||||
{
|
{
|
||||||
glfwWaitCond( thread_sync.d_done, thread_sync.particles_lock,
|
struct timespec ts = { 0, 100000000 };
|
||||||
0.1 );
|
cnd_timedwait( &thread_sync.d_done, &thread_sync.particles_lock,
|
||||||
|
&ts );
|
||||||
}
|
}
|
||||||
|
|
||||||
// No longer running?
|
// No longer running?
|
||||||
@ -960,9 +966,11 @@ void GLFWCALL PhysicsThreadFun( void *arg )
|
|||||||
thread_sync.p_frame ++;
|
thread_sync.p_frame ++;
|
||||||
|
|
||||||
// Unlock mutex and signal drawing thread
|
// Unlock mutex and signal drawing thread
|
||||||
glfwUnlockMutex( thread_sync.particles_lock );
|
mtx_unlock( &thread_sync.particles_lock );
|
||||||
glfwSignalCond( thread_sync.p_done );
|
cnd_signal( &thread_sync.p_done );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -974,7 +982,8 @@ int main( int argc, char **argv )
|
|||||||
{
|
{
|
||||||
int i, frames, benchmark;
|
int i, frames, benchmark;
|
||||||
double t0, t;
|
double t0, t;
|
||||||
GLFWthread physics_thread = 0;
|
thrd_t physics_thread = 0;
|
||||||
|
GLFWwindow* window;
|
||||||
|
|
||||||
// Use multithreading by default, but don't benchmark
|
// Use multithreading by default, but don't benchmark
|
||||||
multithreading = 1;
|
multithreading = 1;
|
||||||
@ -1028,24 +1037,25 @@ int main( int argc, char **argv )
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Open OpenGL fullscreen window
|
// Open OpenGL fullscreen window
|
||||||
if( !glfwOpenWindow( WIDTH, HEIGHT, 0,0,0,0, 16,0, GLFW_FULLSCREEN ) )
|
window = glfwCreateWindow( WIDTH, HEIGHT, "Particle Engine",
|
||||||
|
glfwGetPrimaryMonitor(), NULL);
|
||||||
|
if( !window )
|
||||||
{
|
{
|
||||||
fprintf( stderr, "Failed to open GLFW window\n" );
|
fprintf( stderr, "Failed to open GLFW window\n" );
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
exit( EXIT_FAILURE );
|
exit( EXIT_FAILURE );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set window title
|
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||||
glfwSetWindowTitle( "Particle engine" );
|
|
||||||
|
|
||||||
// Disable VSync (we want to get as high FPS as possible!)
|
glfwMakeContextCurrent(window);
|
||||||
glfwSwapInterval( 0 );
|
glfwSwapInterval( 0 );
|
||||||
|
|
||||||
// Window resize callback function
|
// Window resize callback function
|
||||||
glfwSetWindowSizeCallback( Resize );
|
glfwSetWindowSizeCallback( window, Resize );
|
||||||
|
|
||||||
// Set keyboard input callback function
|
// Set keyboard input callback function
|
||||||
glfwSetKeyCallback( KeyFun );
|
glfwSetKeyCallback( window, KeyFun );
|
||||||
|
|
||||||
// Upload particle texture
|
// Upload particle texture
|
||||||
glGenTextures( 1, &particle_tex_id );
|
glGenTextures( 1, &particle_tex_id );
|
||||||
@ -1099,10 +1109,15 @@ int main( int argc, char **argv )
|
|||||||
{
|
{
|
||||||
thread_sync.p_frame = 0;
|
thread_sync.p_frame = 0;
|
||||||
thread_sync.d_frame = 0;
|
thread_sync.d_frame = 0;
|
||||||
thread_sync.particles_lock = glfwCreateMutex();
|
mtx_init(&thread_sync.particles_lock, mtx_timed);
|
||||||
thread_sync.p_done = glfwCreateCond();
|
cnd_init(&thread_sync.p_done);
|
||||||
thread_sync.d_done = glfwCreateCond();
|
cnd_init(&thread_sync.d_done);
|
||||||
physics_thread = glfwCreateThread( PhysicsThreadFun, NULL );
|
|
||||||
|
if (thrd_create( &physics_thread, PhysicsThreadFun, NULL ) != thrd_success)
|
||||||
|
{
|
||||||
|
glfwTerminate();
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Main loop
|
// Main loop
|
||||||
@ -1117,10 +1132,11 @@ int main( int argc, char **argv )
|
|||||||
Draw( t );
|
Draw( t );
|
||||||
|
|
||||||
// Swap buffers
|
// Swap buffers
|
||||||
glfwSwapBuffers();
|
glfwSwapBuffers(window);
|
||||||
|
glfwPollEvents();
|
||||||
|
|
||||||
// Check if window was closed
|
// Check if window was closed
|
||||||
running = running && glfwGetWindowParam( GLFW_OPENED );
|
running = running && !glfwWindowShouldClose( window );
|
||||||
|
|
||||||
// Increase frame count
|
// Increase frame count
|
||||||
frames ++;
|
frames ++;
|
||||||
@ -1136,7 +1152,7 @@ int main( int argc, char **argv )
|
|||||||
// Wait for particle physics thread to die
|
// Wait for particle physics thread to die
|
||||||
if( multithreading )
|
if( multithreading )
|
||||||
{
|
{
|
||||||
glfwWaitThread( physics_thread, GLFW_WAIT );
|
thrd_join( physics_thread, NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display profiling information
|
// Display profiling information
|
||||||
@ -1144,6 +1160,8 @@ int main( int argc, char **argv )
|
|||||||
(double)frames / t );
|
(double)frames / t );
|
||||||
printf( " (multithreading %s)\n", multithreading ? "on" : "off" );
|
printf( " (multithreading %s)\n", multithreading ? "on" : "off" );
|
||||||
|
|
||||||
|
glfwDestroyWindow(window);
|
||||||
|
|
||||||
// Terminate OpenGL
|
// Terminate OpenGL
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user