void _kl_particle_render_geom_shdr_advance_time(float dt, void* context) { kl_particle_render_geom_shdr_t renderer = (kl_particle_render_geom_shdr_t)context; int next_buffer_idx = !renderer->buffer_idx; int last_used_idx = renderer->last_used_idx; kl_particle_system_t system = renderer->system; if(system != NULL && last_used_idx != next_buffer_idx) { uint32_t num_particles = system->num_particles; const float* px_stream = system->px_stream; const float* py_stream = system->py_stream; const float* pz_stream = system->pz_stream; const float* vx_stream = system->vx_stream; const float* vy_stream = system->vy_stream; const float* vz_stream = system->vz_stream; const float* lifespan_stream = system->lifespan_stream; const float* time_stream = system->time_stream; KL_UNUSED(vx_stream); KL_UNUSED(vy_stream); KL_UNUSED(vz_stream); KL_UNUSED(lifespan_stream); KL_UNUSED(time_stream); CGLSetCurrentContext(renderer->context->resourceCGLContext); CGLLockContext(renderer->context->resourceCGLContext); glBindBuffer(GL_ARRAY_BUFFER, renderer->vertX_buffer[next_buffer_idx]); glBufferData(GL_ARRAY_BUFFER, num_particles * sizeof(float), px_stream, GL_STREAM_DRAW); glBindBuffer(GL_ARRAY_BUFFER, renderer->vertY_buffer[next_buffer_idx]); glBufferData(GL_ARRAY_BUFFER, num_particles * sizeof(float), py_stream, GL_STREAM_DRAW); glBindBuffer(GL_ARRAY_BUFFER, renderer->vertZ_buffer[next_buffer_idx]); glBufferData(GL_ARRAY_BUFFER, num_particles * sizeof(float), pz_stream, GL_STREAM_DRAW); CGLUnlockContext(renderer->context->resourceCGLContext); renderer->vert_buffer_elements[next_buffer_idx] = num_particles; renderer->buffer_idx = next_buffer_idx; } }
void DarwinGlContext::unbind() const { if ( iContext ) { GreResourceAutolock ; if ( iGetCurrentBindedContext() == iContext ) { iContextStack.pop(); CGLUnlockContext( iContext ) ; if ( CGLSetCurrentContext(iContextStack.top()) != kCGLNoError ) { GreDebugPretty() << "Can't unbind CGLContext '" << getName() << "'." << std::endl; } else { iIsBinded = false; } } } }
void kl_particle_render_geom_shdr_assign_effect(kl_particle_render_geom_shdr_t renderer, const char* effect) { char effect_key[512]; kl_shader_t vert_shader, geom_shader, pix_shader; GLuint program; CGLSetCurrentContext(renderer->context->resourceCGLContext); CGLLockContext(renderer->context->resourceCGLContext); sprintf(effect_key, "%s.Vertex.%s", effect, "GL2"); if(kl_shader_manager_get_vertex_shader(renderer->context, effect_key, &vert_shader) == KL_SUCCESS) { sprintf(effect_key, "%s.Geometry.%s", effect, "GL2"); if(kl_shader_manager_get_geometry_shader(renderer->context, effect_key, &geom_shader) == KL_SUCCESS) { sprintf(effect_key, "%s.Fragment.%s", effect, "GL2"); if(kl_shader_manager_get_pixel_shader(renderer->context, effect_key, &pix_shader) == KL_SUCCESS) { program = glCreateProgram(); glAttachShader(program, vert_shader->shader); glAttachShader(program, geom_shader->shader); glAttachShader(program, pix_shader->shader); glBindAttribLocation(program, 0, "in_X"); glBindAttribLocation(program, 1, "in_Y"); glBindAttribLocation(program, 2, "in_Z"); glLinkProgram(program); /* TODO: Check link status */ if(1) { GLuint old_program = renderer->program; kl_shader_t old_shader; renderer->program = program; program = old_program; old_shader = renderer->vert_shader; renderer->vert_shader = vert_shader; vert_shader = old_shader; old_shader = renderer->geom_shader; renderer->geom_shader = geom_shader; geom_shader = old_shader; old_shader = renderer->pix_shader; renderer->pix_shader = pix_shader; pix_shader = old_shader; } if(vert_shader != NULL) glDetachShader(program, vert_shader->shader); if(geom_shader != NULL) glDetachShader(program, geom_shader->shader); if(pix_shader != NULL) glDetachShader(program, pix_shader->shader); glDeleteProgram(program); kl_shader_manager_destroy_shader(renderer->context, &vert_shader); kl_shader_manager_destroy_shader(renderer->context, &pix_shader); kl_shader_manager_destroy_shader(renderer->context, &geom_shader); } else { kl_shader_manager_destroy_shader(renderer->context, &vert_shader); kl_shader_manager_destroy_shader(renderer->context, &geom_shader); } } else { kl_shader_manager_destroy_shader(renderer->context, &vert_shader); } } CGLUnlockContext(renderer->context->resourceCGLContext); }
ITunesPixelFormat ivis_render( ITunesVis* plugin, short audio_data[][512], float freq_data[][512], void* buffer, long buffer_size, bool idle ) { ITunesPixelFormat format = ITunesPixelFormatUnknown; /* make sure we have a plugin and a visual handler */ if ( !plugin || !plugin->imports.visual_handler ) return format; int i=0, w=0; RenderVisualData visual_data; DSPSplitComplex splitComplex[2]; float *data[2]; /* perform FFT if we're not idling */ if ( ! idle ) { /* allocate some complex vars */ for ( i = 0 ; i < 2 ; i++ ) { splitComplex[i].realp = calloc( 512, sizeof(float) ); splitComplex[i].imagp = calloc( 512, sizeof(float) ); data[i] = calloc( 512, sizeof(float) ); } /* 2 channels for spectrum and waveform data */ visual_data.numWaveformChannels = 2; visual_data.numSpectrumChannels = 2; /* copy spectrum audio data to visual data strucure */ for ( w = 0 ; w < 512 ; w++ ) { /* iTunes visualizers expect waveform data from 0 - 255, with level 0 at 128 */ visual_data.waveformData[0][w] = (UInt8)( (long)(audio_data[0][w]) / 128 + 128 ); visual_data.waveformData[1][w] = (UInt8)( (long)(audio_data[1][w]) / 128 + 128 ); /* scale to -1, +1 */ *( data[0] + w ) = (float)(( audio_data[0][w]) / (2.0 * 8192.0) ); *( data[1] + w ) = (float)(( audio_data[1][w]) / (2.0 * 8192.0) ); } /* FFT scaler */ float scale = ( 1.0 / 1024.0 ) ; /* scale by length of input * 2 (due to how vDSP does FFTs) */ float nyq=0, dc=0, freq=0; for ( i = 0 ; i < 2 ; i++ ) { /* pack data into format fft_zrip expects it */ vDSP_ctoz( (COMPLEX*)( data[i] ), 2, &( splitComplex[i] ), 1, 256 ); /* perform FFT on normalized audio data */ fft_zrip( plugin->fft_setup, &( splitComplex[i] ), 1, 9, FFT_FORWARD ); /* scale the values */ vDSP_vsmul( splitComplex[i].realp, 1, &scale, splitComplex[i].realp, 1, 256 ); vDSP_vsmul( splitComplex[i].imagp, 1, &scale, splitComplex[i].imagp, 1, 256 ); /* unpack data */ vDSP_ztoc( &splitComplex[i], 1, (COMPLEX*)( data[i] ), 2, 256 ); /* ignore phase */ dc = *(data[i]) = fabs( *(data[i]) ); nyq = fabs( *(data[i] + 1) ); for ( w = 1 ; w < 256 ; w++ ) { /* don't use vDSP for this since there's some overflow */ freq = hypot( *(data[i] + w * 2), *(data[i] + w * 2 + 1) ) * 256 * 16; freq = MAX( 0, freq ); freq = MIN( 255, freq ); visual_data.spectrumData[i][ w - 1 ] = (UInt8)( freq ); } visual_data.spectrumData[i][256] = nyq; } /* deallocate complex vars */ for ( i = 0 ; i < 2 ; i++ ) { free( splitComplex[i].realp ); free( splitComplex[i].imagp ); free( data[i] ); } /* update the render message with the new visual data and timestamp */ plugin->visual_message.u.renderMessage.renderData = &visual_data; plugin->visual_message.u.renderMessage.timeStampID++; } /* update time */ plugin->visual_message.u.renderMessage.currentPositionInMS = ivis_current_time() - plugin->start_time; // FIXME: real time /* save our GL context and send the vis a render message */ CGLContextObj currentContext = CGLGetCurrentContext(); if ( plugin->gl_context ) aglSetCurrentContext( (AGLContext)(plugin->gl_context ) ); /* call the plugin's render method */ if ( idle ) { /* idle message */ if ( plugin->wants_idle ) plugin->imports.visual_handler( kVisualPluginIdleMessage, &( plugin->visual_message ), plugin->vis_ref ); } else { /* render message */ plugin->imports.visual_handler( kVisualPluginRenderMessage, &( plugin->visual_message ), plugin->vis_ref ); /* set position message */ plugin->visual_message.u.setPositionMessage.positionTimeInMS = plugin->visual_message.u.renderMessage.currentPositionInMS; plugin->imports.visual_handler( kVisualPluginSetPositionMessage, &( plugin->visual_message ), plugin->vis_ref ); } /* update message */ plugin->imports.visual_handler( kVisualPluginUpdateMessage, NULL, plugin->vis_ref ); /* read pixels and restore our GL context */ CGLLockContext( CGLGetCurrentContext() ); switch ( get_pixels( buffer, buffer_size, CGLGetCurrentContext() != currentContext ) ) { case 3: format = ITunesPixelFormatRGB24; break; case 4: format = ITunesPixelFormatRGBA32; break; default: break; } CGLUnlockContext ( CGLGetCurrentContext() ); /* restore our GL context */ CGLSetCurrentContext( currentContext ); return format; }