在R中,似乎目前没有任何可用的选项(例如
我注意到可以使用
尽管这个包在CRAN上已经归档,但是在这里有一个更新版本可用(我们正在努力将其重新放回CRAN)。
首先,必须从https://libsdl.org/release/、https://www.libsdl.org/projects/SDL_image/release/和https://www.libsdl.org/projects/SDL_mixer/release/下载并安装(在Windows上)
在Ubuntu上,它们可以通过以下方式进行安装。
一些演示如何进行SDL和OpenGL调用的示例可在https://dyncall.org/demos/soulsalicious/index.html(1980年代电脑游戏风格的星空场景,包含音乐)中找到。
我是否正确理解,使用这个软件包可以使用SDL和OpenGL加速来显示2D图像栅格?如果是这样,有人有任何关于如何做到这一点的想法吗(我问这个问题是因为我没有使用SDL或OpenGL的经验)?
要打开一个1920 x 1080的SDL窗口,我认为我需要使用(从一些OpenGL示例和https://dyncall.org/demos/soulsalicious/soulsalicious.tar.gz中的
然后使用另一个`pixels <- glPixelMapfv`调用为像素数据创建缓冲区,并使用`glDrawPixels`将像素数据绘制到屏幕上,然后使用`SDL_GL_SwapBuffers(win)`交换前后缓冲区以显示图像,接着等待用户关闭窗口,然后使用`SDL_Quit()`进行清理等操作。问题是我没有OpenGL或SDL的经验,所以有人知道如何执行这些最后几个步骤吗?(我在这里使用的是SDL版本1.2)
一些非OpenGL选项的时间安排对于我的应用程序来说太慢了。
image
)允许快速实时显示2D栅格图形。我对实时交互式曼德勃罗浏览器很感兴趣,希望能够以每秒大约5-10帧的速度显示1920x1080的原始十六进制颜色矩阵作为栅格图像(现在计算曼德勃罗图像本身在适度缩放下可以达到每秒20-30帧)。或者更好的是,我希望能够将强度像素映射传递给图形卡,并使用OpenGL加速进行颜色映射。使用image()
选项useRaster=TRUE
,plot.raster
甚至grid.raster()
都无法满足要求,因为显示栅格图像需要大约1/4秒的时间(比实际计算帧的时间还长),所以我正在寻找更高效的选项,最好使用SDL或OpenGL加速。我注意到可以使用
rdyncall
外部函数接口包从R中调用SDL、SDL_image和GL/OpenGL函数,这样应该能获得更好的性能。尽管这个包在CRAN上已经归档,但是在这里有一个更新版本可用(我们正在努力将其重新放回CRAN)。
library(remotes)
remotes::install_github("hongyuanjia/rdyncall")
library(rdyncall)
首先,必须从https://libsdl.org/release/、https://www.libsdl.org/projects/SDL_image/release/和https://www.libsdl.org/projects/SDL_mixer/release/下载并安装(在Windows上)
SDL
、SDL_image
和SDL_mixer
DLLs(版本1.2)。将64位DLL文件放置在`R-4.2.1/bin/x64`目录下或使用其他方法安装。source("https://raw.githubusercontent.com/Jean-Romain/lidRviewer/master/sdl.R")
在Ubuntu上,它们可以通过以下方式进行安装。
sudo apt-get install libsdl1.2-dev libsdl-image1.2-dev libsdl-mixer1.2
一些演示如何进行SDL和OpenGL调用的示例可在https://dyncall.org/demos/soulsalicious/index.html(1980年代电脑游戏风格的星空场景,包含音乐)中找到。
我是否正确理解,使用这个软件包可以使用SDL和OpenGL加速来显示2D图像栅格?如果是这样,有人有任何关于如何做到这一点的想法吗(我问这个问题是因为我没有使用SDL或OpenGL的经验)?
要打开一个1920 x 1080的SDL窗口,我认为我需要使用(从一些OpenGL示例和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)
x_res <- 1920
y_res <- 1080
win <- SDL_SetVideoMode(x_res, y_res, 32,
SDL_HWSURFACE + SDL_OPENGL + SDL_DOUBLEBUF)
SDL_WM_SetCaption("SDL surface",NULL)
glEnable(GL_TEXTURE_2D)
# Set the projection matrix for the image
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
x_min=1
x_max=x_res
y_min=1
y_max=y_res
glOrtho(x_min, x_max, y_min, y_max, -1, 1)
# Set the modelview matrix for the image
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
}
init()
我认为我应该使用类似的方法设置一些像素传输映射
glPixelMapfv(GL_PIXEL_MAP_I_TO_R, nb_colors, map_colors)
glPixelMapfv(GL_PIXEL_MAP_I_TO_G, nb_colors, map_colors)
glPixelMapfv(GL_PIXEL_MAP_I_TO_B, nb_colors, map_colors)
然后使用另一个`pixels <- glPixelMapfv`调用为像素数据创建缓冲区,并使用`glDrawPixels`将像素数据绘制到屏幕上,然后使用`SDL_GL_SwapBuffers(win)`交换前后缓冲区以显示图像,接着等待用户关闭窗口,然后使用`SDL_Quit()`进行清理等操作。问题是我没有OpenGL或SDL的经验,所以有人知道如何执行这些最后几个步骤吗?(我在这里使用的是SDL版本1.2)
一些非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