Skip to content

Instantly share code, notes, and snippets.

@takuma104
Created August 6, 2008 17:41
Show Gist options
  • Save takuma104/4241 to your computer and use it in GitHub Desktop.
Save takuma104/4241 to your computer and use it in GitHub Desktop.
require 'rubygems'
require "opengl"
require "glut"
require 'RMagick'
module Panorama
WINDOW_WIDTH = 800
WINDOW_HEIGHT = 600
class PanoramaView
Coordinates = Struct.new(:x, :y)
def initialize(filename)
init_glut("Panorama View: #{filename}")
init_gl
load_texture(filename)
@viewpos = Coordinates.new(0, 90)
@viewpos_saved = @viewpos.dup
@drag_start_pos = Coordinates.new(0, 0)
@wireframe = false
end
def run
run_glut
end
private
def init_glut(title)
GLUT.Init
GLUT.InitDisplayMode(GLUT::DOUBLE | GLUT::RGB)
GLUT.InitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT)
GLUT.CreateWindow(title)
end
def init_gl
GL.Viewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT)
GL.MatrixMode(GL::PROJECTION)
GL.LoadIdentity
GLU.Perspective(80.0, WINDOW_WIDTH/WINDOW_HEIGHT, 0.1, 100.0)
GL.MatrixMode(GL::MODELVIEW)
GL.LoadIdentity
GL.Enable(GL::TEXTURE_2D)
GL.ClearColor(0.2, 0.2, 0.2, 1.0)
@qo = GLU.NewQuadric
GLU.QuadricNormals(@qo, GLU::SMOOTH)
GLU.QuadricTexture(@qo, GL::TRUE)
end
def load_texture_rawdata(filename)
img = Magick::Image.read(filename.to_s).first
[img.to_blob { |e| e.format = "RGBA"; e.depth = 8 } + "",
img.columns,
img.rows]
end
def load_texture(filename)
raw, width, height = load_texture_rawdata(filename)
texture = GL.GenTextures(1)
GL.BindTexture(GL::TEXTURE_2D, texture[0])
GL.TexImage2D(GL::TEXTURE_2D, 0, 3, width, height,
0, GL::RGBA, GL::UNSIGNED_BYTE, raw)
GL.TexParameteri(GL::TEXTURE_2D, GL::TEXTURE_MIN_FILTER, GL::LINEAR)
GL.TexParameteri(GL::TEXTURE_2D, GL::TEXTURE_MAG_FILTER, GL::LINEAR)
GL.BindTexture(GL::TEXTURE_2D, texture[0])
end
def method_to_proc(func)
self.method(func).to_proc
end
def run_glut
GLUT.DisplayFunc(method_to_proc(:display))
GLUT.KeyboardFunc(method_to_proc(:keyboard))
GLUT.MouseFunc(method_to_proc(:mouse))
GLUT.MotionFunc(method_to_proc(:motion))
GLUT.MainLoop()
end
def display
GL.Clear(GL::COLOR_BUFFER_BIT|GL::DEPTH_BUFFER_BIT)
GL.PushMatrix
GL.LoadIdentity
GL.Rotate(@viewpos.y, 1.0, 0.0, 0.0)
GL.Rotate(@viewpos.x, 0.0, 0.0, 1.0)
ds = if @wireframe then GLU::LINE else GLU::FILL end
GLU.QuadricDrawStyle(@qo, ds)
GLU.Sphere(@qo, 1.3, 48, 48) # draw sphere
GL.PopMatrix
GL.Flush
GLUT.SwapBuffers
end
# mouse down/up event
def mouse(button, state, x, y)
if (state == 0)
@drag_start_pos.x = x
@drag_start_pos.y = y
@viewpos_saved = @viewpos.dup
end
end
# mouse move event
def motion(x, y)
fac = 0.2
@viewpos.x = @viewpos_saved.x + ((x - @drag_start_pos.x) * fac) % 360
@viewpos.y = @viewpos_saved.y + ((@drag_start_pos.y - y) * fac) % 360
GLUT.PostRedisplay() # to redraw
end
# keyboard down event
def keyboard(key , x , y)
case (key)
when ?q
GLU.DeleteQuadric(@qo)
exit(1)
when ?w
@wireframe = ! @wireframe
GLUT.PostRedisplay() # to redraw
end
end
end
end
if $0 == __FILE__
panorama = Panorama::PanoramaView.new(ARGV.shift)
panorama.run
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment