我正在开发某种音频应用程序,我需要在其中显示一些图表。想一想:高帧率的实时 Oscillope 类图像。
我所需要的只是以高帧率显示一些图形缓冲区。最好 >60fps 而无需花费太多时间。我现在实现它的方式太慢了。我只能以 800x800 像素的分辨率获得 10fps。绘图不是问题,Xorg 正在占用所有时间。
我现在使用的方法是创建一个cairo_image_surface
,然后在需要改变的像素处操作cairo_images_surface
中的数据(速度相当快)
因为我正在为示波器之类的东西编程,所以我不需要一直重绘所有像素。所以画东西不是很慢。
我认为最慢的部分是我需要调用 cairo_set_source_surface()
来实际显示一些东西。
代码最重要部分的摘要。 on_plot_event
每当有新的音频样本准备好显示时调用。
static gboolean on_plot_event(GtkWidget *widget,cairo_t *cr,gpointer user_data){
cairo_set_source_surface(cr,crsurfplot,0,0);
cairo_paint(cr);
return FALSE;
}
int doplot(jack_default_audio_sample_t *in,jack_nframes_t nframes){
cairo_surface_flush(crsurfplot);
char *p;
unsigned char *pixstart;
pixstart = plotdata;
//drawing stuff, manipulate pixels at pixstart
cairo_surface_mark_dirty(crsurfplot);
if(drawcount%10 ==0){
gdk_threads_enter();
gtk_widget_queue_draw(window);
gdk_threads_leave();
}
}
int main(int argc,char *argv[]){
gdk_threads_init();
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
window2 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
plotstride = cairo_format_stride_for_width (CAIRO_FORMAT_RGB24,plotwidth);
plotdata = malloc (16000000);
crsurfplot = cairo_image_surface_create_for_data (plotdata,CAIRO_FORMAT_RGB24,plotwidth,plotheight,plotstride);
plotdata = cairo_image_surface_get_data(crsurfplot);
plot = gtk_drawing_area_new();
gtk_container_add(GTK_CONTAINER(window),plot);
g_signal_connect(G_OBJECT(plot),"draw",G_CALLBACK(on_plot_event),NULL);
g_signal_connect(G_OBJECT(plot),"configure-event",G_CALLBACK(on_confev),NULL);
gtk_widget_show_all (window);
gtk_widget_show (window2);
printf("test\n");
crplot=gdk_cairo_create(gtk_widget_get_window(plot));
cairo_set_source_surface(crplot,crsurfplot,0,0);
gtk_main ();
jack_client_close(client);
return 0;
}
用 Cairo 创造我想要的东西是不可能的吗?我应该改用 openGL 或类似的东西吗?还是我只是做错了什么?
编辑:到目前为止添加了指向我的丑陋程序的链接。 http://ubuntuone.com/4dphKneXOgQPTR8fZydKpo
最佳答案
The method I use now is that I create a cairo_image_surface and then manipulate the data in the cairo_images_surface at the pixels that need to change (which is quite fast)
Because I'm programming something like an oscilloscope I don't need to redraw all the pixels all the time. So drawing things isn't very slow.
在我遇到的 99.9% 的图形应用程序(更大的显示器和帧速率)中,我不同意在背景中使用所有复杂的 Sprite 、条等重新绘制图片比一次翻转它更快。尽管这听起来有悖常理,但我还是建议您尝试一下
开罗应该能够处理你想要的。
关于c - 如何快速重绘图像缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15773965/