Exemple #1
0
/* Audio_Thread::play: start playing */
void Audio_Thread::play(const char *alias, const char *file)
{
   /* check */
   if(isRunning() == false)
      return;
   if(MMDAgent_strlen(alias) <= 0 || MMDAgent_strlen(file) <= 0)
      return;

   /* wait buffer mutex */
   glfwLockMutex(m_mutex);

   /* save character name, speaking style, and text */
   if(m_alias) free(m_alias);
   if(m_file) free(m_file);
   m_alias = MMDAgent_strdup(alias);
   m_file = MMDAgent_strdup(file);
   m_count++;

   /* start playing thread */
   if(m_count <= 1)
      glfwSignalCond(m_cond);

   /* release buffer mutex */
   glfwUnlockMutex(m_mutex);
}
Exemple #2
0
/* Audio_Thread::clear: free thread */
void Audio_Thread::clear()
{
   stop();
   m_kill = true;

   /* wait */
   if(m_cond != NULL)
      glfwSignalCond(m_cond);

   if(m_mutex != NULL || m_cond != NULL || m_thread >= 0) {
      if(m_thread >= 0) {
         glfwWaitThread(m_thread, GLFW_WAIT);
         glfwDestroyThread(m_thread);
      }
      if(m_cond != NULL)
         glfwDestroyCond(m_cond);
      if(m_mutex != NULL)
         glfwDestroyMutex(m_mutex);
      glfwTerminate();
   }

   if(m_alias) free(m_alias);
   if(m_file) free(m_file);

   initialize();
}
/* Audio_Manager::clear: clear */
void Audio_Manager::clear()
{
   Audio_Link *tmp1, *tmp2;

   m_kill = true;

   /* stop and release all thread */
   for(tmp1 = m_list; tmp1; tmp1 = tmp2) {
      tmp2 = tmp1->next;
      tmp1->audio_thread.stopAndRelease();
      delete tmp1;
   }

   /* wait */
   if(m_cond != NULL)
      glfwSignalCond(m_cond);

   if(m_mutex != NULL || m_cond != NULL || m_thread >= 0) {
      if(m_thread >= 0) {
         glfwWaitThread(m_thread, GLFW_WAIT);
         glfwDestroyThread(m_thread);
      }
      if(m_cond != NULL)
         glfwDestroyCond(m_cond);
      if(m_mutex != NULL)
         glfwDestroyMutex(m_mutex);
      glfwTerminate();
   }

   Audio_EventQueue_clear(&m_bufferQueue);

   initialize();
}
Exemple #4
0
void GLFWCALL PhysicsThreadFun( void *arg )
{
    while( running )
    {
        // Lock mutex
        glfwLockMutex( 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 );
        }

        // No longer running?
        if( !running )
        {
            break;
        }

        // Update particles
        ParticleEngine( thread_sync.t, thread_sync.dt );

        // Update frame counter
        thread_sync.p_frame ++;

        // Unlock mutex and signal drawing thread
        glfwUnlockMutex( thread_sync.particles_lock );
        glfwSignalCond( thread_sync.p_done );
    }
}
/* Open_JTalk_Manager::synthesis: start synthesis */
void Open_JTalk_Manager::synthesis(const char *str)
{
   /* check */
   if(isRunning() == false || MMDAgent_strlen(str) <= 0)
      return;

   /* wait buffer mutex */
   glfwLockMutex(m_mutex);

   /* enqueue character name, speaking style, and text */
   Open_JTalk_EventQueue_enqueue(&m_bufferQueue, str);
   m_count++;

   /* start synthesis event */
   if(m_count <= 1)
      glfwSignalCond(m_cond);

   /* release buffer mutex */
   glfwUnlockMutex(m_mutex);
}
/* Audio_Manager::play: start playing */
void Audio_Manager::play(const char *str)
{
   /* check */
   if(isRunning() == false)
      return;
   if(MMDAgent_strlen(str) <= 0)
      return;

   /* wait buffer mutex */
   glfwLockMutex(m_mutex);

   /* enqueue alias and file name */
   Audio_EventQueue_enqueue(&m_bufferQueue, str);
   m_count++;

   /* start playing event */
   if(m_count <= 1)
      glfwSignalCond(m_cond);

   /* release buffer mutex */
   glfwUnlockMutex(m_mutex);
}
Exemple #7
0
void DrawParticles( double t, float dt )
{
    int       i, particle_count;
    VERTEX    vertex_array[ BATCH_PARTICLES * PARTICLE_VERTS ], *vptr;
    float     alpha;
    GLuint    rgba;
    VEC       quad_lower_left, quad_lower_right;
    GLfloat   mat[ 16 ];
    PARTICLE  *pptr;

    // Here comes the real trick with flat single primitive objects (s.c.
    // "billboards"): We must rotate the textured primitive so that it
    // always faces the viewer (is coplanar with the view-plane).
    // We:
    //   1) Create the primitive around origo (0,0,0)
    //   2) Rotate it so that it is coplanar with the view plane
    //   3) Translate it according to the particle position
    // Note that 1) and 2) is the same for all particles (done only once).

    // Get modelview matrix. We will only use the upper left 3x3 part of
    // the matrix, which represents the rotation.
    glGetFloatv( GL_MODELVIEW_MATRIX, mat );

    // 1) & 2) We do it in one swift step:
    // Although not obvious, the following six lines represent two matrix/
    // vector multiplications. The matrix is the inverse 3x3 rotation
    // matrix (i.e. the transpose of the same matrix), and the two vectors
    // represent the lower left corner of the quad, PARTICLE_SIZE/2 *
    // (-1,-1,0), and the lower right corner, PARTICLE_SIZE/2 * (1,-1,0).
    // The upper left/right corners of the quad is always the negative of
    // the opposite corners (regardless of rotation).
    quad_lower_left.x = (-PARTICLE_SIZE/2) * (mat[0] + mat[1]);
    quad_lower_left.y = (-PARTICLE_SIZE/2) * (mat[4] + mat[5]);
    quad_lower_left.z = (-PARTICLE_SIZE/2) * (mat[8] + mat[9]);
    quad_lower_right.x = (PARTICLE_SIZE/2) * (mat[0] - mat[1]);
    quad_lower_right.y = (PARTICLE_SIZE/2) * (mat[4] - mat[5]);
    quad_lower_right.z = (PARTICLE_SIZE/2) * (mat[8] - mat[9]);

    // Don't update z-buffer, since all particles are transparent!
    glDepthMask( GL_FALSE );

    // Enable blending
    glEnable( GL_BLEND );
    glBlendFunc( GL_SRC_ALPHA, GL_ONE );

    // Select particle texture
    if( !wireframe )
    {
        glEnable( GL_TEXTURE_2D );
        glBindTexture( GL_TEXTURE_2D, particle_tex_id );
    }

    // Set up vertex arrays. We use interleaved arrays, which is easier to
    // handle (in most situations) and it gives a linear memeory access
    // access pattern (which may give better performance in some
    // situations). GL_T2F_C4UB_V3F means: 2 floats for texture coords,
    // 4 ubytes for color and 3 floats for vertex coord (in that order).
    // Most OpenGL cards / drivers are optimized for this format.
    glInterleavedArrays( GL_T2F_C4UB_V3F, 0, vertex_array );

    // Is particle physics carried out in a separate thread?
    if( multithreading )
    {
        // Wait for particle physics thread to be done
        glfwLockMutex( 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 );
        }

        // Store the frame time and delta time for the physics thread
        thread_sync.t  = t;
        thread_sync.dt = dt;

        // Update frame counter
        thread_sync.d_frame ++;
    }
    else
    {
        // Perform particle physics in this thread
        ParticleEngine( t, dt );
    }

    // Loop through all particles and build vertex arrays.
    particle_count = 0;
    vptr = vertex_array;
    pptr = particles;
    for( i = 0; i < MAX_PARTICLES; i ++ )
    {
        if( pptr->active )
        {
            // Calculate particle intensity (we set it to max during 75%
            // of its life, then it fades out)
            alpha =  4.0f * pptr->life;
            if( alpha > 1.0f )
            {
                alpha = 1.0f;
            }

            // Convert color from float to 8-bit (store it in a 32-bit
            // integer using endian independent type casting)
            ((GLubyte *)&rgba)[0] = (GLubyte)(pptr->r * 255.0f);
            ((GLubyte *)&rgba)[1] = (GLubyte)(pptr->g * 255.0f);
            ((GLubyte *)&rgba)[2] = (GLubyte)(pptr->b * 255.0f);
            ((GLubyte *)&rgba)[3] = (GLubyte)(alpha * 255.0f);

            // 3) Translate the quad to the correct position in modelview
            // space and store its parameters in vertex arrays (we also
            // store texture coord and color information for each vertex).

            // Lower left corner
            vptr->s    = 0.0f;
            vptr->t    = 0.0f;
            vptr->rgba = rgba;
            vptr->x    = pptr->x + quad_lower_left.x;
            vptr->y    = pptr->y + quad_lower_left.y;
            vptr->z    = pptr->z + quad_lower_left.z;
            vptr ++;

            // Lower right corner
            vptr->s    = 1.0f;
            vptr->t    = 0.0f;
            vptr->rgba = rgba;
            vptr->x    = pptr->x + quad_lower_right.x;
            vptr->y    = pptr->y + quad_lower_right.y;
            vptr->z    = pptr->z + quad_lower_right.z;
            vptr ++;

            // Upper right corner
            vptr->s    = 1.0f;
            vptr->t    = 1.0f;
            vptr->rgba = rgba;
            vptr->x    = pptr->x - quad_lower_left.x;
            vptr->y    = pptr->y - quad_lower_left.y;
            vptr->z    = pptr->z - quad_lower_left.z;
            vptr ++;

            // Upper left corner
            vptr->s    = 0.0f;
            vptr->t    = 1.0f;
            vptr->rgba = rgba;
            vptr->x    = pptr->x - quad_lower_right.x;
            vptr->y    = pptr->y - quad_lower_right.y;
            vptr->z    = pptr->z - quad_lower_right.z;
            vptr ++;

            // Increase count of drawable particles
            particle_count ++;
        }

        // If we have filled up one batch of particles, draw it as a set
        // of quads using glDrawArrays.
        if( particle_count >= BATCH_PARTICLES )
        {
            // The first argument tells which primitive type we use (QUAD)
            // The second argument tells the index of the first vertex (0)
            // The last argument is the vertex count
            glDrawArrays( GL_QUADS, 0, PARTICLE_VERTS * particle_count );
            particle_count = 0;
            vptr = vertex_array;
        }

        // Next particle
        pptr ++;
    }

    // We are done with the particle data: Unlock mutex and signal physics
    // thread
    if( multithreading )
    {
        glfwUnlockMutex( thread_sync.particles_lock );
        glfwSignalCond( thread_sync.d_done );
    }

    // Draw final batch of particles (if any)
    glDrawArrays( GL_QUADS, 0, PARTICLE_VERTS * particle_count );

    // Disable vertex arrays (Note: glInterleavedArrays implicitly called
    // glEnableClientState for vertex, texture coord and color arrays)
    glDisableClientState( GL_VERTEX_ARRAY );
    glDisableClientState( GL_TEXTURE_COORD_ARRAY );
    glDisableClientState( GL_COLOR_ARRAY );

    // Disable texturing and blending
    glDisable( GL_TEXTURE_2D );
    glDisable( GL_BLEND );

    // Allow Z-buffer updates again
    glDepthMask( GL_TRUE );
}