#!/usr/bin/env ruby -rubygems # Name: nehe_lesson02.rb # Purpose: An implementation of NeHe's OpenGL Lesson #02 # using ruby-opengl (http://nehe.gamedev.net/) # require "sdl" require "opengl" require "mathn" require "find" # Add GL and GLUT namespaces in to make porting easier include Gl include Glu include Glut # Placeholder for the window object window = "" @objectsToDraw = Array.new class PictureCollection attr_accessor :current_picture def initialize @pictures = Array.new @current_picture = -1 end def select_next_picture @current_picture += 1 if (@current_picture + 1) != @pictures.size end def select_previous_picture @current_picture -= 1 if (@current_picture - 1) >= 0 end def num_prepictures if @current_picture > -1 @current_picture else 0 end end def num_postpictures @pictures.size - @current_picture - 1 end def get_picture(pos) @pictures[pos] if pos > -1 end def add_picture(pic) @pictures.push pic @current_picture = 0 if(@current_picture == -1) end def each @pictures.each do |pic| yield pic end end def length @pictures.length end end class Picture def initialize(filename, number) surface = SDL::Surface.load(filename) texture = glGenTextures(1) glBindTexture(GL_TEXTURE_2D, texture[0]) glTexImage2D(GL_TEXTURE_2D, 0, 3, surface.w, surface.h, 0, GL_RGB, GL_UNSIGNED_BYTE, surface.pixels) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) surface = nil #hopefully this gets garbage collected @textureId = texture[0] # Store the Texture ID end def draw glBindTexture(GL_TEXTURE_2D, @textureId) glMatrixMode(GL_TEXTURE) glLoadIdentity glRotatef(180,0,0,1) glScalef(-1,1,1) glMatrixMode(GL_MODELVIEW) # Draw a rectangle glBegin(GL_QUADS) glTexCoord2f(0,0) glVertex3f(-1.0, -1.0, 0.0) # Bottom Left glTexCoord2f(1,0) glVertex3f( 1.0, -1.0, 0.0) # Bottom Right glTexCoord2f(1,1) glVertex3f( 1.0, 1.0, 0.0) # Top Right glTexCoord2f(0,1) glVertex3f(-1.0, 1.0, 0.0) # Top Left glEnd end end def init_gl_window(width = 640, height = 480) glViewport(0,0, width, height) # Background color to black glClearColor(0.0, 0.0, 0.0, 0) # Enables clearing of depth buffer glClearDepth(1.0) # Set type of depth test glDepthFunc(GL_LEQUAL) # Enable Textures glEnable(GL_TEXTURE_2D) # Enable depth testing glEnable(GL_DEPTH_TEST) # Enable smooth color shading glShadeModel(GL_SMOOTH) glMatrixMode(GL_PROJECTION) glLoadIdentity # Calculate aspect ratio of the window gluPerspective(60.0, width / height, 0.1, 100.0) glMatrixMode(GL_MODELVIEW) end #draw_gl_scene = Proc.new do def draw_gl_scene # Clear the screen and depth buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) # Reset the view glMatrixMode(GL_MODELVIEW) glLoadIdentity # Draw main picture glTranslatef(0,0,-4) @objectsToDraw.get_picture(@objectsToDraw.current_picture).draw glLoadIdentity # Draw pre pictures if(@objectsToDraw.num_prepictures > 0) pos = @objectsToDraw.current_picture - 1 glTranslatef(-3.0,0,-6.0) # Starting position glRotatef(45.0,0,1,0) while pos >= 0 @objectsToDraw.get_picture(pos).draw pos -= 1 glTranslatef(-0.3,0,-1); end end glLoadIdentity # Draw post pictures if(@objectsToDraw.num_postpictures > 0) pos = @objectsToDraw.current_picture + 1 glTranslatef(3.0,0,-6.0) # Starting position glRotatef(-45.0,0,1,0) while pos < @objectsToDraw.length @objectsToDraw.get_picture(pos).draw pos += 1 glTranslatef(0.3,0,-1); end end # Swap buffers for display SDL.GLSwapBuffers end SDL.init(SDL::INIT_VIDEO) SDL.setGLAttr(SDL::GL_DOUBLEBUFFER,1) SDL.setVideoMode(1280, 800, 0, SDL::FULLSCREEN|SDL::OPENGL|SDL::HWSURFACE) init_gl_window(1280, 800) @objectsToDraw = PictureCollection.new pos = 0 Find.find(".") do |path| if FileTest.directory?(path) && path != "." Find.prune elsif File.extname(path) == ".jpg" puts path @objectsToDraw.add_picture Picture.new(path, pos) pos += 1 end end # Main Loop loop do event = SDL::Event2.poll if !event.nil? break if event.is_a?(SDL::Event2::Quit) if event.is_a?(SDL::Event2::KeyDown) # This means it's some kind of key press @objectsToDraw.select_next_picture if event.sym == SDL::Key::RIGHT @objectsToDraw.select_previous_picture if event.sym == SDL::Key::LEFT exit if event.sym == SDL::Key::ESCAPE end end draw_gl_scene end