RGSS2を知る(3)

互換ライブラリを作っていて気になってたことを片っ端から試す。
すぐにネタ切れになるので続くことは期待してはいけない。
作っていればまた疑問も沸くだろうが。


Viewportとは何か、という話。
画面の描画範囲を指定するオブジェクトだが、Spriteオブジェクトなどから参照がある。
単純に範囲指定オブジェクトであれば、Spriteを描画する際にDirectXのsetViewportを毎回呼んでるのかな、とか思うのだが、Viewportにz指定があるところに不思議な感じがするのだ。
つまり、関連付けされたViewportにzがあり、Spriteオブジェクトにもzがあり、関連付けされていないSpriteオブジェクトもある。
関連付けされたものとされてないもので、zの効果はどう変わるのか。
まずはこちら。
Viewportを指定しないでzを3段階に指定した。

bitmap1 = Bitmap.new(100,100)
bitmap1.fill_rect(bitmap1.rect, Color.new(0,0,255,255))
bitmap2 = Bitmap.new(100,100)
bitmap2.fill_rect(bitmap2.rect, Color.new(0,255,0,255))
bitmap3 = Bitmap.new(100,100)
bitmap3.fill_rect(bitmap3.rect, Color.new(255,0,0,255))

s1 = Sprite.new
s1.bitmap = bitmap1
s1.z = 50

s2 = Sprite.new
s2.bitmap = bitmap2
s2.x = 50
s2.z = 60

s3 = Sprite.new
s3.bitmap = bitmap3
s3.x = 25
s3.y = 50
s3.z = 70

loop do
  Graphics.update
end


そのままだ。
次にViewportを指定して、Viewportより奥の関連付けなし、Viewportより手前の関連付けなし、そして、Viewportに関連付けしたもの。

bitmap1 = Bitmap.new(100,100)
bitmap1.fill_rect(bitmap1.rect, Color.new(0,0,255,255))
bitmap2 = Bitmap.new(100,100)
bitmap2.fill_rect(bitmap2.rect, Color.new(0,255,0,255))
bitmap3 = Bitmap.new(100,100)
bitmap3.fill_rect(bitmap3.rect, Color.new(255,0,0,255))

viewport = Viewport.new(0,0,640,480)
viewport.z = 100

s1 = Sprite.new(viewport)
s1.bitmap = bitmap1
s1.z = 50

s2 = Sprite.new
s2.bitmap = bitmap2
s2.x = 50
s2.z = 60

s3 = Sprite.new
s3.bitmap = bitmap3
s3.x = 25
s3.y = 50
s3.z = 120

loop do
  Graphics.update
end


Viewportに関連付けた青Spriteのzは50だが、Viewportが100のために60の緑より手前になっている。100+50で150になるわけではないのは、zが120の赤Spriteがさらに手前に来ていることからわかる。


つまり、関連付けていないSpriteとViewportは同列でソートされ、関連付けられたSpriteは同じViewport内でソートされると想像できる。
ここから推察できることは、関連付けされていないSpriteオブジェクトはRGSSが管理するメモリで保持され、関連付けされたSpriteオブジェクトはViewportが管理するメモリで保持されているのではないか、ということだ。
関連付けされていないSpriteとViewportを同じように扱ってソートし、Spriteの描画はそのまま、Viewportの描画はViewportが持つSpriteをソートして描画、という感じか。この動作を俺が作るならそう作る。
そしてこの結果はある妄想に繋がる。


Viewportって実はDirectXのsetViewportしてるんじゃなくて、サーフェイスを作ってそこに描画してるんでない?


だってSpriteとViewportにそれぞれcolor、toneプロパティ、flashメソッドがあるんだもの。
SpriteオブジェクトとViewportの補正をSprite描画一発で処理するのはあまりにも複雑になりそうで、サーフェイスへの描画→サーフェイスからバックスクリーンへの描画として、それぞれに補正をかけたほうがどう見ても簡単。
つまり、Viewportは動的にレンダリングされるSpriteなのではないか、ということだ。
マニュアルを眺めながらクラス構造とメソッド群を調べていてなんだか腑に落ちなかったのだが、俺が作るならViewportはこう作る、と想像していた結果と一致した。
デフォルトViewportも無かったから、たぶんそういう感じなのではなかろうかと思う。
違う可能性も大いにあるけど。