From: Paul Brannan Date: 2001-11-08T05:30:18+09:00 Subject: [ruby-talk:24590] Re: OpenGL (rbogl) bindings to Tk? On Thu, 8 Nov 2001, Phlip wrote: > Rubies: > > I have wrapped my Mandrake 7.2 around Yoshi's Ruby OpenGl binding > (rbogl-0.32a.tgz), and have a couple very pedestrian comfort zone > issues with it... > > - how to put it in a Tk widget instead of a free floating window? For this I think you need to get a Tk OpenGL widget and wrap it. I generally use Gtk, which has a gtkglarea. I'm not sure which Tk widget provides something like this, but a search on google for seems to bring up some entries. > - how to click on it and get the viewed object to rotate You need to grab mouse down and mouse motion events, and coordinates of the mouse in 2D space when these events occur. You can then use quaternions or spaceballs or whatever other mechanisms you wish to calculate the rotation matrix for the object, then pass that to GL.Rotate. You can find some (C/C++) tutorials on this at nehe.gamedev.net and www.gamasutra.com. > You can see I'm spoiled by bigger ready-made front-end solutions such > as Blender, Visualization Toolkit, Coin3d, the VRML viewers, CernRoot, > CrystalSpace, SciLab, PyOpenGl, OpenDX, GnuPlot, QuesaLibrary, etc. > > Will roll my own if someone reveals I have to... You may have to do that, though I'm sure someone has already written a library to do basic rotations and translations. Perhaps a wrapper for CrystalSpace would be in order... Here's a simple example of how to do basic rotations with the mouse using GLUT (based on cube.rb that comes with the opengl extension): require 'opengl' require 'glut' class Cube FACES = [[0,1,2,3],[3,2,6,7],[7,6,5,4],[4,5,1,0],[5,6,2,1],[7,4,0,3]] VERTS = [[-1,-1,1],[-1,-1,-1],[-1,1,-1],[-1,1,1],[1,-1,1],[1,-1,-1],[1,1,-1],[1,1,1]] def display GL.Clear(GL::COLOR_BUFFER_BIT) GL.Begin(GL::QUADS) FACES.each do |face| face.each do |vert| GL.Vertex(VERTS[vert]) end end GL.End() GLUT.SwapBuffers end def mouse(button, state, x, y) @x0 = x; @y0 = y @state = state end def motion(x, y) if @state == GLUT::DOWN then GL.Rotate(@x0 - x, 0.0, 1.0, 0.0) GL.Rotate(@y0 - y, 1.0, 0.0, 0.0) @x0 = x; @y0 = y GLUT.PostRedisplay end end def initialize GLUT.Init GLUT.InitDisplayMode(GLUT::DOUBLE | GLUT::RGB) GLUT.CreateWindow("cube") GLUT.DisplayFunc(method(:display).to_proc) GLUT.MouseFunc(method(:mouse).to_proc) GLUT.MotionFunc(method(:motion).to_proc) GL.MatrixMode(GL::PROJECTION) GLU.Perspective(40.0, 1.0, 1.0, 10.0) GL.MatrixMode(GL::MODELVIEW) GL.PolygonMode(GL::FRONT_AND_BACK, GL::LINE) GLU.LookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0) @state = nil end def go GLUT.MainLoop() end end Cube.new.go -- Paul