Shaderその後

ShaderをHLSLの複数パスと複数Techniqueに対応。
それに伴ってTechnique名の指定はShader::Core.newの引数からShader.newの引数に移動した。移動しただけでは意味がないが、Shader#technique=で後から変更できる。
あと、Shader::Core.newのパラメータの型を簡素化した。float2とかfloat3とかの指定は結局あんまり意味が無いから、配列に数字を突っ込んで指定したらその数だけ引き渡されるようにした。HLSLをパースして型を取得しない限り、どのみち使う側の責任でどうにでもなってしまう。

サンプルソースも修正。上のほうは同じなので割愛。
トランジションアルゴリズムも俺流に変更。やっぱりRGSSのトランジションの動きは気に入らない。引数の指定と計算方法は所詮サポートクラスだしインターフェイス含めて自由に作り変えてもらえばよい。
とりあえずこの形で動作するようにして、簡単な説明を添付してDXRuby1.2.2devを公開しよう。週末ぐらいが目標。

  @@core = Shader::Core.new(
    hlsl,
    {
      :g_min => :float,
      :g_max => :float,
      :scale => :float, # HLSL側がfloat2の場合は:floatを指定して[Float, Flaot]という形で渡す
      :tex1 => :texture,
    }
  )

  # durationは遷移にかけるフレーム数、imageはImageオブジェクト(省略でクロスフェード)、vagueは曖昧さ
  def initialize(duration, image=nil, vague=nil)
    super(@@core, "TShader")
    if image
      @image = image
      @vague = vague == nil ? 40 : vague
    else
      @image = Image.new(1, 1, [255,255,255])
      @vague = 256
    end
    @duration = duration
    @count = 0
    self.g_min = -@vague.fdiv(@duration)
    self.g_max = 0.0
    self.tex1   = @image
    self.scale  = [Window.width.fdiv(@image.width), Window.height.fdiv(@image.height)]
  end

  def start
    @count = 0
    self.g_min = -@vague.fdiv(@duration)
    self.g_max = 0.0
  end

  def next
    @count += 1
    self.g_min = (((@vague+@duration).fdiv(@duration)) * @count - @vague).fdiv(@duration)
    self.g_max = (((@vague+@duration).fdiv(@duration)) * @count).fdiv(@duration)
  end

  # 描画対象を指定する。RenderTargetオブジェクトか、Windowを渡す。省略時はWindow。
  def target=(t)
    self.scale = [t.width.fdiv(@image.width), t.height.fdiv(@image.height)]
  end
end

shader = TransitionShader.new(60, Image.load("右渦巻き.png"),50)

rt = RenderTarget.new(640, 480)
image = Image.loadToArray("image/maptile.png", 9, 10)

Window.loop do
  rt.drawTile(0, 0, map, image, 0, 0, 12, 14)
  rt.drawTile(300, 200, map, image, 0, 0, 12, 14)
  rt.update

  shader.start if Input.keyPush?(K_Z)
  shader.next

  # drawShaderに渡すのはShaderオブジェクト
  Window.drawShader(0, 0, rt, shader)

  break if Input.keyPush?(K_ESCAPE)
end