Created
August 6, 2008 17:41
-
-
Save takuma104/4241 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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