bounty将在6天后过期。回答此问题可获得+400声望奖励。Tom Wenseleers正在寻找标准答案:我们诚邀SDL和OpenGL领域的任何Maven尝试回答这个问题,这对R社区非常有用...
对于一个实时交互式Mandelbrot查看器,我在R中制作,我正在寻找一种高性能的方式来显示1920 x1080原始十六进制颜色矩阵作为光栅图像,希望能够达到约5-10 fps(calculating the Mandelbrot images themselves now achieves ca. 20-30 fps at moderate zooms,当然滚动应该很快)(当然,在R中可能存在许多访问 swift2 D图形的应用程序)。使用image()
和选项useRaster=TRUE
,plot.raster
或甚至grid.raster()
都不能解决这个问题,因为显示光栅图像比实际计算要慢得多(最好的情况下大约1/4秒),所以我在寻找一个性能更高的选项,最好使用OpenGL加速。
我注意到应该可以使用rdyncall
包从R中调用SDL、SDL_image和GL/OpenGL函数,这应该有更好的性能。
虽然此软件包存档在CRAN上,但它仍然具有完整的功能。请参阅白皮书here和Mercurial资源库here。
要安装存档版本,请执行以下操作:
library(devtools)
install_version("rdyncall",
version="0.7.5",
repos="http://cran.us.r-project.org")
SDL
、SDL_image
和SDL_mixer
DLL(版本1.2)(在Windows上)必须首先从https://libsdl.org/release/、https://www.libsdl.org/projects/SDL_image/release/和https://www.libsdl.org/projects/SDL_mixer/release/安装)(the 64 bit DLLs are to be put under
R-4.2.1/bin/x64“)。在Ubuntu上,它们可以使用
sudo apt-get install libsdl1.2-dev libsdl-image1.2-dev libsdl-mixer1.2
有关如何调用SDL和OpenGL的一些演示可在https://dyncall.org/demos/soulsalicious/index.html(20世纪80年代计算机游戏风格的starfield,包括音乐)上获得。
我说这个软件包应该可以使用SDL
和opengl
加速来显示2D图像光栅,对吗?如果是,有人有什么想法吗?(我这么问是因为我没有使用SDL或OpenGL的经验)
要打开一个1920 x 1080的SDL窗口,我想我必须使用(来自https://dyncall.org/demos/soulsalicious/soulsalicious.tar.gz中的windowed.R
脚本,全屏也是可能的,请参见fullscreen.R
)
init <- function()
{
require(rdyncall)
dynport(SDL)
SDL_Init(SDL_INIT_VIDEO)
dynport(GL)
dynport(GLU)
dynport(SDL_image)
SDL_GL_SetAttribute(SDL_GL_RED_SIZE,8)
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,8)
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE,8)
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1)
s <<- SDL_SetVideoMode(1920,1080,32,SDL_HWSURFACE+SDL_OPENGL+SDL_DOUBLEBUF)
SDL_WM_SetCaption("SDL window",NULL)
}
init()
再次关闭该窗口是SDL_Quit()
我想我应该能够传递一个原始十六进制颜色矩阵,并将其作为OpenGL 2D纹理绑定到这个SDL表面。在windowed.R
演示中,它有一个loadTexture
函数,看起来接近我所需要的,尽管它加载了一个PNG图像,而我想传递一个原始十六进制颜色矩阵。有人知道如何完成吗?
非OpenGL选项的某些计时对我的应用程序来说太慢:
# some example data & desired colour mapping of [0-1] ranged data matrix
library(RColorBrewer)
ncol=1080
cols=colorRampPalette(RColorBrewer::brewer.pal(11, "RdYlBu"))(ncol)
colfun=colorRamp(RColorBrewer::brewer.pal(11, "RdYlBu"))
col = rgb(colfun(seq(0,1, length.out = ncol)), max = 255)
mat=matrix(seq(1:1080)/1080,nrow=1920,ncol=1080,byrow=TRUE)
mat2rast = function(mat, col) {
idx = findInterval(mat, seq(0, 1, length.out = length(col)))
colors = col[idx]
rastmat = t(matrix(colors, ncol = ncol(mat), nrow = nrow(mat), byrow = TRUE))
class(rastmat) = "raster"
return(rastmat)
}
system.time(mat2rast(mat, col)) # 0.24s
# plot.raster method - one of the best?
par(mar=c(0, 0, 0, 0))
system.time(plot(mat2rast(mat, col), asp=NA)) # 0.26s
# grid graphics - tie with plot.raster?
library(grid)
system.time(grid.raster(mat2rast(mat, col),interpolate=FALSE)) # 0.28s
# base R image()
par(mar=c(0, 0, 0, 0))
system.time(image(mat,axes=FALSE,useRaster=TRUE,col=cols)) # 0.74s # note Y is flipped to compared to 2 options above - but not so important as I can fill matrix the way I want
# ggplot2 - just for the record...
df=expand.grid(y=1:1080,x=1:1920)
df$z=seq(1,1080)/1080
library(ggplot2)
system.time({q <- qplot(data=df,x=x,y=y,fill=z,geom="raster") +
scale_x_continuous(expand = c(0,0)) +
scale_y_continuous(expand = c(0,0)) +
scale_fill_gradientn(colours = cols) +
theme_void() + theme(legend.position="none"); print(q)}) # 11s
1条答案
按热度按时间kupeojn61#
根据RGL package introduction,它是:
R的可视化设备系统,使用OpenGL作为渲染后端。其核心的rgl设备是用C++编写的实时3D引擎。它提供交互式视点导航工具(鼠标+滚轮支持)和R编程接口。
由于RGL是一个真实的的3D引擎,我希望使用RGL的2D将给予你一个快速的显示。
您可以查看this paper,并看到一些结果图像in this gallery