domingo, 14 de marzo de 2010

Usar OpenGL desde ruby

Es interesante poder crear demos o escenarios en 3D desde un lenguaje dinámico como ruby (cuando el rendimiento no sea un problema).

Hay unos bindings para opengl llamados ruby-opengl que nos permiten acceder directamente a la API de OpenGL desde ruby.

Os dejo un ejemplo (inspirado en los tutoriales de NeHe) para que os hagáis una idea de la sintaxis.

require 'rubygems'
require 'opengl'

require "gl"
require "glu"
require "glut"
require "mathn"

include Gl, Glu, Glut

window = ""

def init_gl_window(width = 640, height = 480)
glClearColor(0.0, 0.0, 0.0, 0)
glClearDepth(1.0)
glDepthFunc(GL_LEQUAL)
glEnable(GL_DEPTH_TEST)
glShadeModel(GL_SMOOTH)

glMatrixMode(GL_PROJECTION)
glLoadIdentity
gluPerspective(45.0, width / height, 0.1, 100.0)

glMatrixMode(GL_MODELVIEW)

draw_gl_scene
end

def reshape(width, height)
height = 1 if height == 0

glViewport(0, 0, width, height)

glMatrixMode(GL_PROJECTION)
glLoadIdentity

gluPerspective(45.0, width / height, 0.1, 100.0)
end

$color1_intensity = 0
$color2_intensity = 0
$color3_intensity = 0

$rotation = 0

def draw_gl_scene
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

glMatrixMode(GL_MODELVIEW)
glLoadIdentity
glTranslatef(0, 0, -6)

# Draw a triangle
glBegin(GL_POLYGON)
glColor3f($color1_intensity, $color2_intensity, $color3_intensity)
glVertex3f( 0.0, 1.0, 0.0)
glColor3f($color3_intensity, $color1_intensity, $color2_intensity)
glVertex3f( 1.0, -1.0, 0.0)
glColor3f($color2_intensity, $color3_intensity, $colo1r_intensity)
glVertex3f(-1.0, -1.0, 0.0)
glEnd

$color1_intensity += 0.0005 if($color1_intensity %gt; 0.5)
$color2_intensity += 0.0005 if($color2_intensity %gt; 0.5)
$color3_intensity += 0.0010 if($color3_intensity %gt; 1)

glutSwapBuffers
end

def idle
glutPostRedisplay
end

# Keyboard handler to exit when ESC is typed
keyboard = lambda do |key, x, y|
if(key == 27) then
GLUT.DestroyWindow($window)
exit(0)
end
end


glutInit
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH)
glutInitWindowSize(640, 480)
glutInitWindowPosition(0, 0)
window = glutCreateWindow("Example")
glutDisplayFunc(method(:draw_gl_scene).to_proc)
glutReshapeFunc(method(:reshape).to_proc)
glutIdleFunc(method(:idle).to_proc)
glutKeyboardFunc(keyboard)
init_gl_window(640, 480)
glutMainLoop()

Quizá sería interesante aportar un grado más de abstracción para hacer aún más sencillo la elaboración de gráficos desde este tipo de lenguajes.

0 comentarios: