これ単体で動くようにしてありますので、
$ ruby -rubygems glwidget.rb
…とすれば起動します。
動作に必要なものは以下の通りです:
- ruby 1.8.6 [i386-mswin32]
- qtruby4-1.4.9-mswin32.gem
- ruby-opengl-0.60.0-i386-mswin32.gem
コード:
require 'qt'
require 'opengl'
class GLWidget < Qt::GLWidget
signals 'xRotationChanged(int)'
signals 'yRotationChanged(int)'
signals 'zRotationChanged(int)'
slots 'setXRotation(int)'
slots 'setYRotation(int)'
slots 'setZRotation(int)'
def initialize
super
@object = 0
@xRot = 0
@yRot = 0
@zRot = 0
@lastPos = Qt::Point.new
@trolltechGreen = Qt::Color::fromCmykF( 0.40, 0.0, 1.0, 0.0 )
@trolltechPurple = Qt::Color::fromCmykF( 0.39, 0.39, 0.0, 0.0 )
end
def destroy
makeCurrent()
glDeleteLists( @object, 1 )
end
def minimumSizeHint
return Qt::Size.new( 50, 50 )
end
def sizeHint
return Qt::Size.new( 400, 400 )
end
def setXRotation( angle )
normalizeAngle( angle )
if ( angle != @xRot )
@xRot = angle
emit xRotationChanged( angle )
updateGL()
end
end
def setYRotation( angle )
normalizeAngle( angle )
if ( angle != @yRot )
@yRot = angle
emit yRotationChanged( angle )
updateGL()
end
end
def setZRotation( angle )
normalizeAngle( angle )
if ( angle != @zRot )
@zRot = angle
emit zRotationChanged( angle )
updateGL()
end
end
def initializeGL
qglClearColor( @trolltechPurple.dark() )
@object = makeObject()
glShadeModel( GL_FLAT )
glEnable( GL_DEPTH_TEST )
glEnable( GL_CULL_FACE )
end
def paintGL
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT )
glLoadIdentity()
glTranslated( 0.0, 0.0, -10.0)
glRotated( @xRot / 16.0, 1.0, 0.0, 0.0 )
glRotated( @yRot / 16.0, 0.0, 1.0, 0.0 )
glRotated( @zRot / 16.0, 0.0, 0.0, 1.0 )
glCallList( @object )
end
def resizeGL( width, height )
# [NOTE] +qMin+ in the original code is a C++ Template Function.
# Ref.: $(QTDIR)/src/corelib/global/qglobal.h
# template
# inline const T &qMin(const T &a, const T &b) { if (a < b) return a; return b; }
side = [width, height].min
glViewport( (width - side) / 2, (height - side) / 2, side, side )
glMatrixMode( GL_PROJECTION )
glLoadIdentity()
glOrtho( -0.5, +0.5, +0.5, -0.5, 4.0, 15.0 )
glMatrixMode( GL_MODELVIEW )
end
def mousePressEvent( event ) # event : Qt::MouseEvent
@lastPos = event.pos
end
def mouseMoveEvent( event ) # event : Qt::MouseEvent
dx = event.x - @lastPos.x
dy = event.y - @lastPos.y
if ( event.buttons() & Qt::LeftButton.to_i )
setXRotation( @xRot + 8 * dy )
setYRotation( @yRot + 8 * dx )
elsif ( event.buttons() & Qt::RightButton.to_i )
setXRotation( @xRot + 8 * dy )
setZRotation( @zRot + 8 * dx )
end
@lastPos = event.pos
end
def makeObject
list = glGenLists( 1 )
glNewList( list, GL_COMPILE )
glBegin( GL_QUADS )
x1 = +0.06
y1 = -0.14
x2 = +0.14
y2 = -0.06
x3 = +0.08
y3 = +0.00
x4 = +0.30
y4 = +0.22
quad( x1, y1, x2, y2, y2, x2, y1, x1 )
quad( x3, y3, x4, y4, y4, x4, y3, x3 )
extrude( x1, y1, x2, y2 )
extrude( x2, y2, y2, x2 )
extrude( y2, x2, y1, x1 )
extrude( y1, x1, x1, y1 )
extrude( x3, y3, x4, y4 )
extrude( x4, y4, y4, x4 )
extrude( y4, x4, y3, x3 )
num_sectors = 200
for i in 0...num_sectors do
angle1 = (i * 2 * Math::PI) / num_sectors
x5 = 0.30 * Math::sin( angle1 )
y5 = 0.30 * Math::cos( angle1 )
x6 = 0.20 * Math::sin( angle1 )
y6 = 0.20 * Math::cos( angle1 )
angle2 = ((i + 1) * 2 * Math::PI) / num_sectors
x7 = 0.20 * Math::sin( angle2 )
y7 = 0.20 * Math::cos( angle2 )
x8 = 0.30 * Math::sin( angle2 )
y8 = 0.30 * Math::cos( angle2 )
quad( x5, y5, x6, y6, x7, y7, x8, y8 )
extrude( x6, y6, x7, y7 )
extrude( x8, y8, x5, y5 )
end
glEnd()
glEndList()
return list
end
def quad( x1, y1, x2, y2, x3, y3, x4, y4 )
qglColor( @trolltechGreen )
glVertex3d( x1, y1, -0.05 )
glVertex3d( x2, y2, -0.05 )
glVertex3d( x3, y3, -0.05 )
glVertex3d( x4, y4, -0.05 )
glVertex3d( x4, y4, +0.05 )
glVertex3d( x3, y3, +0.05 )
glVertex3d( x2, y2, +0.05 )
glVertex3d( x1, y1, +0.05 )
end
def extrude( x1, y1, x2, y2 )
qglColor( @trolltechGreen.dark(250 + (100 * x1).to_i) )
glVertex3d( x1, y1, +0.05 )
glVertex3d( x2, y2, +0.05 )
glVertex3d( x2, y2, -0.05 )
glVertex3d( x1, y1, -0.05 )
end
def normalizeAngle( angle )
while ( angle < 0 ) do
angle += 360 * 16
end
while ( angle > 360 * 16 ) do
angle -= 360 * 16
end
end
end
#
# Application starts here.
#
begin
a = Qt::Application.new(ARGV)
w = GLWidget.new
w.show
a.exec
ensure
w.destroy
end