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