···
---------------------------------------------------------
#
# Togl wrapper for tcl3d Tk extension.
#
TkPackage.require('tcl3d')
class Tk::Togl < TkWindow
# By default, the constracter of a widget class (subclass of
TkWindow)
# uses TkCommandNames[0] as a command to create a widget object.
TkCommandNames = ['togl'.freeze].freeze
# The following definitions are used to create a widget object
# from a widget path string.
WidgetClassName = 'Togl'.freeze
WidgetClassNames[WidgetClassName] = self
def postredisplay
tk_send_without_enc('postredisplay')
self
end
def render
tk_send_without_enc('render')
self
end
def swapbuffers
tk_send_without_enc('swapbuffers')
self
end
def make_current
tk_send_without_enc('makecurrent')
self
end
end
# f = TkFrame.new
# togl_obj1 = Tk::Togl.new(f, :width=>200, :height=>200,
:ident=>'Single',
# :rgba=>true, :double=>false,
:depth=>true).pack
# togl_obj2 = Tk::Togl.new(f, :width=>200, :height=>200,
:ident=>'Double',
# :sharelist=>'Single',
# :rgba=>true, :double=>true,
:depth=>true).pack
# togl_obj1.bind('B1-Motion', proc{....})
---------------------------------------------------------
Now I'm trying to get the standard gears.rb OpenGL application running
within the tk managed window. This is where I'm really getting lost. I
posted below the application as it looks now, but it isn't working and
the window just comes up blank. I assume I'm missing something
fundamental here. I'm hoping someone could either provide a working
example of a Tk/OpenGL application using togl or help steer me in where
my code is failing below.
Thanks,
Mike Thompson
---------------------------------------------------------
# 2005-05-01 Ruby version by Arto Bendiken based on gears.c rev 1.8.
# 2005-01-09 Original C version (gears.c) by Brian Paul et al.
# http://cvs.freedesktop.org/mesa/Mesa/progs/demos/gears.c?rev=1.8
require 'opengl_c'
require 'glut_c'
require 'tk'
require 'tkextlib/tkHTML'
require 'togl'
include OpenGL
include Glut
class Gears
POS = [5.0, 5.0, 10.0, 0.0]
RED = [0.8, 0.1, 0.0, 1.0]
GREEN = [0.0, 0.8, 0.2, 1.0]
BLUE = [0.2, 0.2, 1.0, 1.0]
include Math
# Draw a gear wheel. You'll probably want to call this function when
# building a display list since we do a lot of trig here.
#
# Input: inner_radius - radius of hole at center
# outer_radius - radius at center of teeth
# width - width of gear
# teeth - number of teeth
# tooth_depth - depth of tooth
def gear(inner_radius, outer_radius, width, teeth, tooth_depth)
r0 = inner_radius
r1 = outer_radius - tooth_depth / 2.0
r2 = outer_radius + tooth_depth / 2.0
da = 2.0 * PI / teeth / 4.0
glShadeModel(GL_FLAT)
glNormal(0.0, 0.0, 1.0)
# Draw front face
glBegin(GL_QUAD_STRIP)
for i in 0..teeth
angle = i * 2.0 * PI / teeth
glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5)
glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5)
if i < teeth
glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5)
glVertex3f(r1 * cos(angle + 3 * da),
r1 * sin(angle + 3 * da), width * 0.5)
end
end
glEnd()
# Draw front sides of teeth
glBegin(GL_QUADS)
for i in 0...teeth
angle = i * 2.0 * PI / teeth
glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5)
glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width *
0.5)
glVertex3f(r2 * cos(angle + 2 * da),
r2 * sin(angle + 2 * da), width * 0.5)
glVertex3f(r1 * cos(angle + 3 * da),
r1 * sin(angle + 3 * da), width * 0.5)
end
glEnd()
glNormal(0.0, 0.0, -1.0)
# Draw back face
glBegin(GL_QUAD_STRIP)
for i in 0..teeth
angle = i * 2.0 * PI / teeth
glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5)
glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5)
if i < teeth
glVertex3f(r1 * cos(angle + 3 * da),
r1 * sin(angle + 3 * da), -width * 0.5)
glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5)
end
end
glEnd()
# Draw back sides of teeth
glBegin(GL_QUADS)
for i in 0...teeth
angle = i * 2.0 * PI / teeth
glVertex3f(r1 * cos(angle + 3 * da),
r1 * sin(angle + 3 * da), -width * 0.5)
glVertex3f(r2 * cos(angle + 2 * da),
r2 * sin(angle + 2 * da), -width * 0.5)
glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width *
0.5)
glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5)
end
glEnd()
# Draw outward faces of teeth
glBegin(GL_QUAD_STRIP)
for i in 0...teeth
angle = i * 2.0 * PI / teeth
glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5)
glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5)
u = r2 * cos(angle + da) - r1 * cos(angle)
v = r2 * sin(angle + da) - r1 * sin(angle)
len = sqrt(u * u + v * v)
u /= len
v /= len
glNormal(v, -u, 0.0)
glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width *
0.5)
glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width *
0.5)
glNormal(cos(angle), sin(angle), 0.0)
glVertex3f(r2 * cos(angle + 2 * da),
r2 * sin(angle + 2 * da), width * 0.5)
glVertex3f(r2 * cos(angle + 2 * da),
r2 * sin(angle + 2 * da), -width * 0.5)
u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da)
v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da)
glNormal(v, -u, 0.0)
glVertex3f(r1 * cos(angle + 3 * da),
r1 * sin(angle + 3 * da), width * 0.5)
glVertex3f(r1 * cos(angle + 3 * da),
r1 * sin(angle + 3 * da), -width * 0.5)
glNormal(cos(angle), sin(angle), 0.0)
end
glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5)
glVertex3f(r1 * cos(0), r1 * sin(0), -width * 0.5)
glEnd()
glShadeModel(GL_SMOOTH)
# Draw inside radius cylinder
glBegin(GL_QUAD_STRIP)
for i in 0..teeth
angle = i * 2.0 * PI / teeth
glNormal(-cos(angle), -sin(angle), 0.0)
glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5)
glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5)
end
glEnd()
end
def draw
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix()
glRotate(@view_rotx, 1.0, 0.0, 0.0)
glRotate(@view_roty, 0.0, 1.0, 0.0)
glRotate(@view_rotz, 0.0, 0.0, 1.0)
glPushMatrix()
glTranslate(-3.0, -2.0, 0.0)
glRotate(@angle, 0.0, 0.0, 1.0)
glCallList(@gear1)
glPopMatrix()
glPushMatrix()
glTranslate(3.1, -2.0, 0.0)
glRotate(-2.0 * @angle - 9.0, 0.0, 0.0, 1.0)
glCallList(@gear2)
glPopMatrix()
glPushMatrix()
glTranslate(-3.1, 4.2, 0.0)
glRotate(-2.0 * @angle - 25.0, 0.0, 0.0, 1.0)
glCallList(@gear3)
glPopMatrix()
glPopMatrix()
@glwin.swapbuffers
end
def idle
#t = glutGet(GLUT_ELAPSED_TIME) / 1000.0
#@t0_idle = t if !defined? @t0_idle
# 90 degrees per second
#@angle += 70.0 * (t - @t0_idle)
#@t0_idle = t
#@glwin.postredisplay
end
# Change view angle, exit upon ESC
def key(k, x, y)
case k
when ?z
@view_rotz += 5.0
when ?Z
@view_rotz -= 5.0
when 27 # Escape
exit
end
@glwin.postredisplay
end
# Change view angle
def special(k, x, y)
case k
when GLUT_KEY_UP
@view_rotx += 5.0
when GLUT_KEY_DOWN
@view_rotx -= 5.0
when GLUT_KEY_LEFT
@view_roty += 5.0
when GLUT_KEY_RIGHT
@view_roty -= 5.0
end
@glwin.postredisplay
end
# New window size or exposure
def reshape(width, height)
h = height.to_f / width.to_f
glViewport(0, 0, width, height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
glTranslate(0.0, 0.0, -40.0)
end
def init
@angle = 0.0
@view_rotx, @view_roty, @view_rotz = 20.0, 30.0, 0.0
glLightfv(GL_LIGHT0, GL_POSITION, POS)
glEnable(GL_CULL_FACE)
glEnable(GL_LIGHTING)
glEnable(GL_LIGHT0)
glEnable(GL_DEPTH_TEST)
# Make the gears
@gear1 = glGenLists(1)
glNewList(@gear1, GL_COMPILE)
glMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, RED)
gear(1.0, 4.0, 1.0, 20, 0.7)
glEndList()
@gear2 = glGenLists(1)
glNewList(@gear2, GL_COMPILE)
glMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, GREEN)
gear(0.5, 2.0, 2.0, 10, 0.7)
glEndList()
@gear3 = glGenLists(1)
glNewList(@gear3, GL_COMPILE)
glMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, BLUE)
gear(1.3, 2.0, 0.5, 10, 0.7)
glEndList()
glEnable(GL_NORMALIZE)
ARGV.each do |arg|
case arg
when '-info'
printf("GL_RENDERER = %s\n", glGetString(GL_RENDERER))
printf("GL_VERSION = %s\n", glGetString(GL_VERSION))
printf("GL_VENDOR = %s\n", glGetString(GL_VENDOR))
printf("GL_EXTENSIONS = %s\n", glGetString(GL_EXTENSIONS))
when '-exit'
@autoexit = 30
printf("Auto Exit after %i seconds.\n", @autoexit);
end
end
end
def visible(vis)
#glutIdleFunc((vis == GLUT_VISIBLE ? method(:idle).to_proc : nil))
end
def mouse(button, state, x, y)
@mouse = state
@x0, @y0 = x, y
end
def motion(x, y)
if @mouse == GLUT_DOWN then
@view_roty += @x0 - x
@view_rotx += @y0 - y
end
@x0, @y0 = x, y
end
def initialize
@root = TkRoot.new
@frame = TkFrame.new(@root)
@glwin = Tk::Togl.new(@frame, :width=>300, :height=>300,
:ident=>'Single',
:rgba=>true, :depth=>true,
:double=>false).pack('fill'=>'both')
init()
end
def start
Tk.mainloop
end
end
Gears.new.start
---------------------------------------------------------