Mercurial > pub > dyncall > bindings
diff R/rdyncall/demo/randomfield2.R @ 0:0cfcc391201f
initial from svn dyncall-1745
author | Daniel Adler |
---|---|
date | Thu, 19 Mar 2015 22:26:28 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/R/rdyncall/demo/randomfield2.R Thu Mar 19 22:26:28 2015 +0100 @@ -0,0 +1,228 @@ +# Package: rdyncall +# File: demo/randomfield.R +# Description: Scientific Computations using OpenGL: Rendering 512x512 random field by blending 5000 point sprites (dynport demo) +require(rdyncall) +library(lattice) +dynport(SDL) +dynport(GL) + +# ---------------------------------------------------------------------------- +# Parameters: + +# Framebuffer size +fb.size <- 512 + +# Texture size +tex.size <- 512 + +# Blending color +colorunit <- 0.02 + +# ---------------------------------------------------------------------------- +# texture setup + +genTex.circle <- function(n) +{ + m <- matrix(data=FALSE,nr=n,nc=n) + r <- n/2 + for(i in 1:n) + { + for(j in 1:n) + { + m[[i,j]] <- ifelse((i-r)^2+(j-r)^2 > r^2,0L,255L) + } + } + return(m) +} + +genTex.bnorm <- function(n) +{ + x <- seq(-3,3,len=n) + y <- dnorm(x) + return( outer(y,y) ) +} + +# ---------------------------------------------------------------------------- +# draw circle using OpenGL Vertex Arrays + +drawTexCirclesVertexArray <- function(x,y,r) +{ + n <- max( length(x), length(y), length(r) ) + x1 <- x-r + x2 <- x+r + y1 <- y-r + y2 <- y+r + + vertexArray <- as.vector(rbind(x1,y1,x2, y1, x2, y2, x1, y2)) + texCoordArray <- rep( as.double(c(0,0,1,0,1,1,0,1)), n ) + + glEnableClientState(GL_VERTEX_ARRAY) + glEnableClientState(GL_TEXTURE_COORD_ARRAY) + glVertexPointer(2,GL_DOUBLE,0,vertexArray) + glTexCoordPointer(2,GL_DOUBLE,0,texCoordArray) + + glDrawArrays(GL_QUADS, 0, n*4) + + glDisableClientState(GL_VERTEX_ARRAY) + glDisableClientState(GL_TEXTURE_COORD_ARRAY) +} + +#drawPointSprite <- function() +#{ +# glEnable(GL_POINT_SPRITE) +# glTexEnvi(GL_POINT_SPRITE,GL_COORD_REPLACE,GL_TRUE) +# glPointParameter(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT) +# glPointSize +#} + +# ---------------------------------------------------------------------------- +# initialize SDL, OpenGL + +max.tex.size <- integer(1) +max.tex.units <- integer(1) +tex.ids <- integer(1) + +init <- function() +{ + # initialize SDL + + SDL_Init(SDL_INIT_VIDEO) + surface <<- SDL_SetVideoMode(fb.size,fb.size,32,SDL_OPENGL+SDL_DOUBLEBUF) + + # initialize OpenGL + + glGetIntegerv(GL_MAX_TEXTURE_SIZE, max.tex.size) + glGetIntegerv(GL_MAX_TEXTURE_UNITS, max.tex.units) + + glClearColor(0,0,0,0) + glColor4f(0.1,0.1,0.1,0) + + # img <- genTex.circle(tex.size) + # texdata <- as.raw(img) + + img <- genTex.bnorm(tex.size) + m <- max(img) + texdata <- as.raw( ( img/m ) * 255 ) + + + glGenTextures( length(tex.ids),tex.ids) + glBindTexture(GL_TEXTURE_2D, tex.ids[[1]]) + glPixelStorei(GL_UNPACK_ALIGNMENT, 1) + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, tex.size, tex.size, 0, GL_ALPHA, GL_UNSIGNED_BYTE, texdata) + # glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, tex.size, tex.size, 0, GL_ALPHA, GL_DOUBLE, as.vector(img)) + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_CLAMP_TO_BORDER) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_CLAMP_TO_BORDER) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE) + glEnable(GL_TEXTURE_2D) + + # blending setup + + glBlendFunc(GL_SRC_ALPHA, GL_ONE) + glEnable(GL_BLEND) + + glColor3d( colorunit,colorunit,colorunit ) + +} + +cleanup <- function() +{ + glDeleteTextures( length(tex.ids), tex.ids) + SDL_Quit() +} + +sim <- function(N = 5000) + return(list( + x = runif(N,-1.1,+1.1), + y = runif(N,-1.1,+1.1), + r = runif(N, 0.1, 0.2) + )) + +render <- function(o) { + glClear(GL_COLOR_BUFFER_BIT) + drawTexCirclesVertexArray(o$x,o$y,o$r) + glFinish() + SDL_GL_SwapBuffers() +} + +event <- new.struct("SDL_Event") +quit <- FALSE +pollEvents <- function() { + while( SDL_PollEvent(event) != 0 ) + { + type <- event$type + if (type == SDL_MOUSEBUTTONDOWN) { + cat("Read pixels via OpenGL into an R integer matrix..") + pixels <<- readpixels() + cat("done.\nPlot image results with R plotting device. This may take a while - please be patient..") + image(pixels) + cat("done.\nContinue..\n") + } else if (type == SDL_QUIT) { + cat("Read pixels via OpenGL into an R integer matrix 'pixels'..") + pixels <<- readpixels() + cat("done.\nRe-run by 'run()'\n") + quit <<- TRUE + } + } +} + +# --- Read Pixels ------------------------------------------------------------ + +readpixels <- function() +{ + array <- matrix(NA_integer_,fb.size,fb.size) + glPixelStorei(GL_PACK_ALIGNMENT,1) + glReadPixels(0,0,fb.size,fb.size, GL_LUMINANCE, GL_INT, array) + return(array) +} + + +# --- FPS Counter ------------------------------------------------------------ + +fpsInit <- function() + return(list( + tbase = SDL_GetTicks(), + frames = 0 + )) + +fpsUpdate <- function(o) { + tnow <- SDL_GetTicks() + if ((tnow - o$tbase) > 1000) + { + o$tbase <- tnow + SDL_WM_SetCaption(paste("FPS:", o$frames),NULL) + o$frames <- 0 + } else { + o$frames <- o$frames + 1 + } + return(o) +} + +# --- Main Loop -------------------------------------------------------------- + +main <- function() +{ + init() + # disable interactive plot device. + oldpars <- par(ask=FALSE,mfrow=c(1,1)) + # user notice + cat("Click on window to import current random field and plot in R.\nClose window to quit mainloop.\n") + + fps <- fpsInit() + quit <<- FALSE + while(!quit) + { + sim <- sim(5000) + render(sim) + pollEvents() + fps <- fpsUpdate(fps) + } + + par(oldpars) +} + +main() +