Ruby+Ruby/SDL+ruby-openglよたび
というわけで、悪戦苦闘の後を恥ずかしながら公開いたします。
これは、文字(の画像)を、色々エフェクトさせています。
左右が逆転していますがキニシナーイ!
描画は書いた順でいいので、デプスバッファは取ってません(ムダになるけどね)。
require 'sdl' require 'gl' require 'glu' include Gl include Glu SCREEN_WIDTH = 640 SCREEN_HEIGHT = 480 @pos = 0.0 @st = 0 @size = 20 @amt = -1 @x = 0 @y = 0 @ox = 0.0 @oy = 0.0 @w = 256.0 @h = 256.0 @ow = 128.0 @oh = 128.0 @r = 0.0 @wx = 16 @hy = 16 @ww = 4 @hh = 4 def init_screen SDL.init(SDL::INIT_VIDEO|SDL::INIT_AUDIO) SDL::GL.set_attr(SDL::GL::RED_SIZE, 8) SDL::GL.set_attr(SDL::GL::GREEN_SIZE, 8) SDL::GL.set_attr(SDL::GL::BLUE_SIZE, 8) SDL::GL.set_attr(SDL::GL::ALPHA_SIZE, 8) SDL::GL.set_attr(SDL::GL::DOUBLEBUFFER, 1) SDL::Screen.open(SCREEN_WIDTH, SCREEN_HEIGHT, 32, SDL::HWSURFACE | SDL::OPENGL) end def init_sprite(file_name) # 本当は、displayformatしなきゃいけないけど…。 SDL::Surface.load(file_name) end def init_gl(w, h) glClearColor(0.0, 0.0, 0.0, 0.0) glPixelStorei(GL_UNPACK_ALIGNMENT, 4) resize(w, h) end def init_textures(sprites) textures = glGenTextures(sprites.length) sprites.each_with_index{|sprite, i| bitmap = sprite.pixels glBindTexture(GL_TEXTURE_2D, textures[i]) glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR) glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, sprite.w, sprite.h, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, bitmap) } textures end def resize(w, h, theta=30.0,top=[0.0,1.0,0.0]) # 0 < theta < 90.0 w2 = w / 2 h2 = h / 2 gluPerspective(theta, w/h, -1.0, 1.0) # radian=2*PI*((theta/2)/360) # z = h * (cos(radian)/sin(radian)) = h * (1/tan(radian)) gluLookAt(w2,h2,-(h2 / Math.tan(Math::PI * theta / 360.0)),w2,h2,0.0,*top) end def draw(screen, textures, w, h) glClear(GL_COLOR_BUFFER_BIT) l = @ox t = @oy r = (@ox+@ow) b = (@oy+@oh) lv = l / @ow tv = t / @oh rv = r / @ow bv = b / @oh ll = @x tt = @y rr = (@x+@ow) bb = (@y+@oh) llv = ll / @ow ttv = tt / @oh rrv = rr / @ow bbv = bb / @oh 0.step(h, @hy){|y| 0.step(w, @wx){|x| glPushMatrix glBegin(GL_QUADS) glColor3d(1,0,0) glVertex3d(x ,y , 0) glVertex3d(x+@ww,y , 0) glVertex3d(x+@ww,y+@hh, 0) glVertex3d(x ,y+@hh, 0) glColor3d(1,1,1) glEnd glPopMatrix } } glPushMatrix glEnable(GL_TEXTURE_2D) glEnable(GL_BLEND) glBindTexture(GL_TEXTURE_2D, textures[0]) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) glTranslated(@ow/2,@oh/2,0.0) glRotated(@r, 1.0, 0.0, 1.0) glTranslated(-@ow/2,-@oh/2,0.0) glBegin(GL_QUADS) glTexCoord2d(lv, bv) glVertex3d(ll,tt,0.0) glTexCoord2d(rv, bv) glVertex3d(rr,tt,0.0) glTexCoord2d(rv, tv) glVertex3d(rr,bb,0.0) glTexCoord2d(lv, tv) glVertex3d(ll,bb,0.0) glEnd glDisable(GL_BLEND) glDisable(GL_TEXTURE_2D) glPopMatrix glPushMatrix glEnable(GL_TEXTURE_2D) glEnable(GL_BLEND) glBindTexture(GL_TEXTURE_2D, textures[1]) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) glBegin(GL_QUADS) glTexCoord2i(0, @size) glVertex3i(120,120,0) glTexCoord2i(@size, @size) glVertex3i(375,120,0) glTexCoord2i(@size, 0) glVertex3i(375,375,0) glTexCoord2i(0, 0) glVertex3i(120,375,0) glEnd glDisable(GL_BLEND) glDisable(GL_TEXTURE_2D) glPopMatrix glPushMatrix glEnable(GL_TEXTURE_2D) glEnable(GL_BLEND) glBindTexture(GL_TEXTURE_2D, textures[2]) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) glBegin(GL_QUADS) glTexCoord2d(0.0, 1.0) glVertex3f(@pos,0,0) glTexCoord2d(1.0, 1.0) glVertex3f(@pos+255.0,0,0) glTexCoord2d(1.0, 0.0) glVertex3f(@pos+255.0,255.0,0) glTexCoord2d(0.0, 0.0) glVertex3f(@pos,255,0) glEnd glDisable(GL_BLEND) glDisable(GL_TEXTURE_2D) glPopMatrix SDL::GL.swap_buffers @pos += 8.0 if @pos >= 480.0 if @st == 0 @st = SDL.get_ticks else ed = SDL.get_ticks @st = ed end @pos = 0.0 end @size += @amt if @size == 0 @size = 1 @amt = 1 elsif @size == 20 @size = 19 @amt = -1 end @r = @r + 15.0 @r = 0.0 if @x >= 360.0 end def main_loop(screen, textures, w, h) flag = true while flag while event = SDL::Event.poll case event when SDL::Event::KeyDown case event.sym when SDL::Key::Q when SDL::Key::ESCAPE flag = false end end end draw(screen, textures, w, h) end end w = SCREEN_WIDTH.to_f h = SCREEN_HEIGHT.to_f screen = init_screen exit if glGetString(GL_VERSION) < "2.0" init_gl(w, h) textures = init_textures( [1,2,3].map{|n| init_sprite("a#{n}.png")} ) main_loop(screen, textures, w, h)
使用する画像は以下の3つ。
a1.png
(文字色が白なので、たんなる透明な画像に見えてしまいますが…(^^;
a2.png
a3.png
画像を直接保存して使ってみてください(32bit、アルファチャネル付き画像です)