これ単体で動くようにしてありますので、
$ 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