ブレンドの実装

ざっとこんな感じ。

左から順に、通常半透明、加算半透明1、加算半透明2、減算合成。
上からα255、α100、α1.


左上が通常の描画で、これに各種ブレンド処理を施した描画がそれ以外となる。
加算半透明1はソースのαを変動させる方式で、2のほうは背景のαを変動させる。
αを0にすると加算半透明2も消えてしまうが、これはドライバ側がα0の描画を省略しているからだろう。
1と2は効果が違うから、使いどころが変わってきそうで、とりあえず両方入れておくことにする。
Window.drawExのオプションにblendキーを追加した。
従来のaddキーも互換性のために残してあるが、将来的には消す予定。

# DXRuby1.0.3予定機能サンプル
require "dxruby"

image = Image.load("bg.png")
image2 = Image.new(103,103)
51.downto(1) do |i|
  image2.circleFill(51, 51, i, [255,255 - i*5,255 - i*5, 255 - i*5])
end
font = Font.new(16)

Window.loop do
  Window.draw(0,0,image)

  Window.drawFont(110, 70, "通常半透明", font)
  Window.drawFont(210, 70, "加算半透明1", font)
  Window.drawFont(310, 70, "加算半透明2", font)
  Window.drawFont(410, 70, "減算半透明", font)
  Window.drawFont(20,   144, "Alpha 255", font)
  Window.drawFont(20,   244, "Alpha 100", font)
  Window.drawFont(20,   344, "Alpha 1", font)

  # 通常
  Window.draw(100,100,image2)
  # 半透明
  Window.drawAlpha(100,200,image2, 100)
  # 完全な透明
  Window.drawAlpha(100,300,image2, 1)

  # 加算合成
  Window.drawAdd(200,100,image2)
  # 加算半透明1
  Window.drawEx(200,200,image2, :blend=>:add, :alpha=>100)
  # 完全に透明な加算半透明1
  Window.drawEx(200,300,image2, :blend=>:add, :alpha=>1)

  # 加算合成2
  Window.drawEx(300,100,image2, :blend=>:add2)
  # 加算半透明2
  Window.drawEx(300,200,image2, :blend=>:add2, :alpha=>100)
  # 完全に透明な加算半透明2
  Window.drawEx(300,300,image2, :blend=>:add2, :alpha=>1)

  # 減算合成
  Window.drawSub(400,100,image2)
  # 減算半透明
  Window.drawEx(400,200,image2, :blend=>:sub, :alpha=>100)
  # 完全に透明な減算半透明
  Window.drawEx(400,300,image2, :blend=>:sub, :alpha=>1)

  break if Input.keyPush?(K_ESCAPE)
end

ちなみに、circleFillのところを真っ白でαを変動させるとこんな感じになる。

  image2.circleFill(51, 51, i, [255 - i*5, 255, 255, 255])


加算半透明2はソースのα値を無視するから、真っ白だ。
一番下が小さいのは、α1に対して更にαを変動させて、結果が0になったら描画されないからだろう。
正直、ネットで検索して出てくる2の方式は使いにくいような気がするのだが、青い背景に赤い爆風を重ねたら紫になる現象を軽減するにはこれを使うしかない。
軽減も何も光の意味を考えたら当たり前な気もするんだけど。