mirror of
				https://github.com/glfw/glfw.git
				synced 2025-11-03 22:04:15 +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