2-4 minutes

An audio visualization program that plays audio files or listens to an input device and generates visualizations using the signal data.

The project was restarted once because the original codebase was all crammed into a single file, and a royal mess.

The first iteration of Punch was one of my first forays into programming post process effects using OpenGL.

It relies on an off-screen framebuffer that is used for feedback effects which are modulated by the overall/average loudness of the sound.

It looked pretty awesome, but the program was pretty unstable. Eventually the effects kind of broke down as GPU generations moved on, and I never properly looked into fixing it.

Here's some code from the original program.

glVertex3f(0.0f+(i * 0.5 * direction * cos( glfwGetTime() * 0.05)*sinVex( newcalc )*( 2.0f/maxdraw ))* 1.5, 0.1f + cosVex(newcalc), 0.0f);

Looks "great", right?

The second iteration of the program was kind of the opposite, it didn't rely on post process effects at all. Instead everything you see on screen relied mostly on additive blending.

I still like to run this second iteration, it has more features that make it easier to queue tracks and the likes. Of course, I also like to run this one because the first one doesn't work anymore.

Here's a snippet of code from the second iteration as well.

GLuint ProgressBarVBO;
std::vector<glm::vec3> ProgressBarVertices;
void CPunchApplication::InitializeProgressBar()
    glGenBuffers( 1, &ProgressBarVBO );

void CPunchApplication::UpdateProgressBar()

    const float ProgressBarLength = MusicModuleInstance->IsPlaying() ? static_cast<float>( MusicModuleInstance->MusicGetPosition() / MusicModuleInstance->MusicGetLength() ) : 0.0f;
    const float ProgressBarVertexLocation = ProgressBarLength * 2.0f - 1.0f;

    const float ProgressBarHeight = CConfigurationManager::GetInstance().IsValidKey( "progress_bar_height" ) ? static_cast<float>( CConfigurationManager::GetInstance().GetDouble( "progress_bar_height" ) ) : 0.05f;
    const float ProgressBarVertexHeight = 1.0f - ProgressBarHeight;

    ProgressBarVertices.push_back( glm::vec3( -1.0f, 1.0f, 0.0f ) );
    ProgressBarVertices.push_back( glm::vec3( ProgressBarVertexLocation, 1.0f, 0.0f ) );
    ProgressBarVertices.push_back( glm::vec3( -1.0f, ProgressBarVertexHeight, 0.0f ) );

    ProgressBarVertices.push_back( glm::vec3( -1.0f, ProgressBarVertexHeight, 0.0f ) );
    ProgressBarVertices.push_back( glm::vec3( ProgressBarVertexLocation, 1.0f, 0.0f ) );
    ProgressBarVertices.push_back( glm::vec3( ProgressBarVertexLocation, ProgressBarVertexHeight, 0.0f ) );

    glBindBuffer( GL_ARRAY_BUFFER, ProgressBarVBO );
    glBufferData( GL_ARRAY_BUFFER, ProgressBarVertices.size() * sizeof( glm::vec3 ), &ProgressBarVertices[0], GL_DYNAMIC_DRAW );

void CPunchApplication::DrawProgressBar()
    glColor4f( 0.25f, 0.25f, 0.25f, 0.5f );
    glEnableVertexAttribArray( 0 );
    glBindBuffer( GL_ARRAY_BUFFER, ProgressBarVBO );
    glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 0, 0 );
    glDrawArrays( GL_TRIANGLES, 0, ProgressBarVertices.size() );
    glDisableVertexAttribArray( 0 );

It was a lot more readable, if you ask me.

Some of the code of Punch 2, as I called it, formed the basis of the Shatter Engine. Mainly its configuration manager, although it has lost its manager monicker.

Loopin' II (the track that played in the last video)