2014/01/15(水) [n年前の日記]
#1 [cg_tools] GeoGebraのインストールでハマったり
説明画像を作ろうとして、作図ツールを探したり。
幾何のアレコレをを描いて、動かして、その変更結果を見た目で確認できる、 _GeoGebra をインストールしてみようかなと。昔インストールした記憶もあるのだけど、今のPCには入れてなかったみたいで。
しかし、公式サイトから GeoGebra-Windows-Installer-4-4-7-0.exe をDLして実行しても、インストーラが、ライセンス確認画面の次に行こうとするところで不正終了してしまう。環境は Windows7 x64。
ググってみたら、同じ症状も見かけたのだけど。掲示板その他で質問しても、回答者は「ウチでは問題なくインストールできたよ?」みたいな話ばかり。てことは、自分の環境に何か原因があるのだろうか…。
さては常駐ソフトが悪さをしてるのだろうか。あらゆる常駐ソフトを終了させて試してみたけど、結果は変わらず。うーん。
_Index of /installers から辿って、GeoGebra-Windows-Installer-4-4-7-0.msi を入手してみた。.exe じゃなくて .msi版。こちらなら、インストーラは英語だけど、インストールができた。
まあ、GeoGebra-Windows-Portable-4-4-7-0.zip をDL・解凍すれば、バイナリ一式が入っているので、最悪の場合、ソレを使うのでもよさそうだけど。
幾何のアレコレをを描いて、動かして、その変更結果を見た目で確認できる、 _GeoGebra をインストールしてみようかなと。昔インストールした記憶もあるのだけど、今のPCには入れてなかったみたいで。
しかし、公式サイトから GeoGebra-Windows-Installer-4-4-7-0.exe をDLして実行しても、インストーラが、ライセンス確認画面の次に行こうとするところで不正終了してしまう。環境は Windows7 x64。
ググってみたら、同じ症状も見かけたのだけど。掲示板その他で質問しても、回答者は「ウチでは問題なくインストールできたよ?」みたいな話ばかり。てことは、自分の環境に何か原因があるのだろうか…。
さては常駐ソフトが悪さをしてるのだろうか。あらゆる常駐ソフトを終了させて試してみたけど、結果は変わらず。うーん。
_Index of /installers から辿って、GeoGebra-Windows-Installer-4-4-7-0.msi を入手してみた。.exe じゃなくて .msi版。こちらなら、インストーラは英語だけど、インストールができた。
まあ、GeoGebra-Windows-Portable-4-4-7-0.zip をDL・解凍すれば、バイナリ一式が入っているので、最悪の場合、ソレを使うのでもよさそうだけど。
[ ツッコむ ]
#2 [dxruby] DXRuby+Shaderで床ラスタースクロールっぽいことができたような気がする
Shader利用サンプルの sample_spehari.rb を弄って、望んだ感じの床ラスタースクロール、っぽいことができたような気がする。たぶん。
sample_spehari.rb を眺めていて、気づいた点を列挙。
こんな感じに。
STGサンプルに組み込んでみたら、こんな感じ。 どう見ても、 _「お願い、私の星を助けて…」 ですな。アレも、こんな感じのことをしてたのかしら。
長いけど、一応ソースも貼っときます。
_floorrasterscroll.rb
今回も、単体で実行しても動くけど、他のファイルから呼んでも使えるようにしておきました。本体ファイル?と同じフォルダに floorrasterscroll.rb を入れといて、以下のような記述で使えるかなと…。
サンプルを弄って作っただけなので、これもサンプル同様、Public Domain にしておきます。それと、画像は以下からDLして使ってみてください。
_cloud.png (320x320 dot)
もやもやした模様ではよく分からないでしょうから、あの有名な、 _lena様画像 も置いときますね…。
_lena.png (160x160 dot)
使うと、以下のような感じになります。
やっぱり、lena様のような画像で実験すると、なんだかやる気がでてくるなあ。
sample_spehari.rb を眺めていて、気づいた点を列挙。
- Shaderは、スクロール処理をしていない。あくまで、渡された画像を透視変換して描画することのみに専念してる。
- するとスクロール処理はどうやってるかというと…。縦横スクロールさせた後の画像を、Shader に渡すことでやっていた。
- 縦横スクロールは、元画像と、RenderTarget#drawTile() を使って行う。RenderTarget に描いた画像を Shader に渡す感じ。
こんな感じに。
STGサンプルに組み込んでみたら、こんな感じ。 どう見ても、 _「お願い、私の星を助けて…」 ですな。アレも、こんな感じのことをしてたのかしら。
長いけど、一応ソースも貼っときます。
_floorrasterscroll.rb
require 'dxruby'
#
# Shaderを使って床ラスタースクロールっぽい処理をするクラス
#
class FloorRasterScroll
@@hlsl = <<EOS
float floor_distance;
float screen_distance;
float x_diff;
float y_diff;
float alpha;
texture tex0;
sampler Samp0 = sampler_state
{
Texture =<tex0>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
AddressU = WRAP;
AddressV = WRAP;
};
float4 PS(float2 input : TEXCOORD0) : COLOR0
{
float4 output;
input.y = screen_distance * floor_distance / -(input.y + y_diff);
input.x = (input.x - x_diff) * -input.y / screen_distance;
output = tex2D( Samp0, input );
output.a = alpha;
return output;
}
technique FloorRasterScroll
{
pass P0
{
PixelShader = compile ps_2_0 PS();
}
}
EOS
attr_accessor :core, :shader, :image
attr_accessor :w, :h
attr_accessor :tilew, :tileh
attr_accessor :rt_w, :rt_h, :rt_scaley
attr_accessor :rt
attr_accessor :floor_dist, :scr_dist, :x_diff, :y_diff, :alpha
#
# 初期化処理
#
# @param [Image] image 使用する画像
# @param [float] floor_dist 床までの距離。1.0前後が目安
# @param [float] scr_dist 画面までの距離。1.0以下が目安
# @param [float] y_diff 視線方向を上下にずらす量。0.0から1.0の範囲
# @param [float] alpha 透明度。0.0で透明。1.0で不透明
# @param [int] w 描画横幅。nil ならウインドウ横幅
# @param [int] h 描画縦幅。nil ならウインドウ縦幅
#
def initialize(image, floor_dist=0.3, scr_dist=0.3, y_diff=0.1, alpha=1.0,
w=nil, h=nil)
self.core = Shader::Core.new(@@hlsl,{
:floor_distance=>:float,
:screen_distance=>:float,
:x_diff=>:float,
:y_diff=>:float,
:alpha=>:float
})
self.shader = Shader.new(self.core, "FloorRasterScroll")
self.image = image
self.w = (w == nil)? Window.width : w
self.h = (h == nil)? Window.height : h
self.floor_dist = floor_dist
self.scr_dist = scr_dist
self.y_diff = y_diff
self.alpha = alpha
# 画面を覆い隠すタイル数を求める
self.tilew = self.w.quo(self.image.width).ceil
self.tileh = self.h.quo(self.image.height).ceil
# RenderTarget の必要サイズを求める
self.rt_w = self.image.width * self.tilew
self.rt_h = self.image.height * self.tileh
# y方向で拡大縮小して描画縦横幅に合わせる
self.rt_scaley = self.h.quo(2).quo(rt_h)
# Rendertarget生成
self.rt = RenderTarget.new(rt_w, rt_h)
# 画面の真ん中に消失点?を持ってくるための補正値を算出
self.shader.x_diff = 0.5 * self.w.quo(self.rt_w)
end
#
# 描画処理
#
# @param [int] x 描画x座標
# @param [int] y 描画y座標
# @param [float] scrl_x 横方向スクロール位置
# @param [float] scrl_z 奥行方向スクロール位置
# @param [Hash] opts オプション
# @option opts [float] floor_dist 床との距離。1.0前後が目安
# @option opts [float] scr_dist 画面との距離。1.0以下が目安
# @option opts [float] y_dist 視線方向を上下にずらす量。0.0 - 1.0 の範囲
# @option opts [int] z 描画奥行情報
# @option opts [float] alpha 透明度。0.0で透明。1.0で不透明
# @option opts [Boolean] vflip trueなら上下判定。falseなら反転しない
#
def draw(x, y, scrl_x, scrl_z, opts={})
self.floor_dist = opts[:floor_dist] if opts.has_key?(:floor_dist)
self.scr_dist = opts[:scr_dist] if opts.has_key?(:scr_dist)
self.y_diff = opts[:y_diff] if opts.has_key?(:y_diff)
self.alpha = opts[:alpha] if opts.has_key?(:alpha)
self.shader.floor_distance = self.floor_dist
self.shader.screen_distance = self.scr_dist
self.shader.y_diff = self.y_diff
self.shader.alpha = self.alpha
vflip = 1
vflip *= -1 if opts.has_key?(:vflip) and opts[:vflip] == true
z = 0
z = opts[:z] if opts.has_key?(:z)
# Shader が参照する画像を RenderTarget に作成
self.rt.draw_tile(0, 0, [[0]], [self.image],
scrl_x, scrl_z, self.tilew, self.tileh).update
# Shader を使って透視変換しつつ描画
Window.drawEx(x, y, self.rt, :shader=>self.shader,
:scaley=>self.rt_scaley * vflip, :centery=>0, :z=>z)
end
#
# 動作確認用。グリッド画像を生成して返す
#
# @param [int] w 画像横幅
# @param [int] h 画像縦幅
# @return [Image] 生成した画像
#
def self.get_grid_image(w, h)
image = Image.new(w, h, [0, 255, 0])
image.box_fill(0, 0, w / 2 - 1, h / 2 - 1, [150,250,150])
image.box_fill(w / 2, 0, w - 1, h / 2 - 1, [100,250,100])
image.box_fill(0, h / 2, w / 2 - 1, h - 1, [200,250,200])
image.box_fill(w / 2, h / 2, w - 1, h - 1, [0,220,0])
return image
end
end
# ----------------------------------------
if $0 == __FILE__
# 動作テスト
# 画像を読み込む
# imgfilename = "lena.png"
imgfilename = "cloud.png"
if File.file?(imgfilename)
image = Image.load(imgfilename)
else
# 画像ファイルが見つからなければ、タイル画像を作成
image = FloorRasterScroll.get_grid_image(160, 160)
end
test_mode = 1
case test_mode
when 0
# ----------------------------------------
# シンプルな使い方の例
bg = FloorRasterScroll.new(image)
x = 0
z = 0
Window.loop do
break if Input.keyPush?(K_ESCAPE)
x += 8
z += 5
bg.draw(0, 240, x, z)
end
when 1
# ----------------------------------------
# 動作テスト。各パラメータを細かく変更しながら描画してみる
bg = FloorRasterScroll.new(image) # 床用
bg2 = FloorRasterScroll.new(image) # 天井用
x = 0
z = 0
x_spd = 8
z_spd = 5
floor_dist = 0.3
scr_dist = 0.3
y_diff = 0.1
font = Font.new(16)
fade_enable = false
count = 0
Window.loop do
break if Input.keyPush?(K_ESCAPE)
# 速度リセット
if Input.keyDown?(K_C)
x_spd = 0
z_spd = 0
end
# 横方向スクロール速度を変更
x_spd += 0.1 * Input.x
# 奥行方向スクロール速度を変更
z_spd -= 0.1 * Input.y
# 床との距離を変更
floor_dist += 0.01 if Input.keyDown?(K_W)
floor_dist -= 0.01 if Input.keyDown?(K_S)
# 画面までの距離を変更
scr_dist += 0.005 if Input.keyDown?(K_D)
scr_dist -= 0.005 if Input.keyDown?(K_A)
scr_dist = 0.05 if scr_dist < 0.05
# 視線を上下にずらす値を変更
y_diff += 0.005 if Input.keyDown?(K_R)
y_diff -= 0.005 if Input.keyDown?(K_F)
# 透明度を変更
fade_enable = !fade_enable if Input.keyPush?(K_Q)
alpha = (fade_enable)? Math.sin(3 * count * Math::PI / 180.0).abs : 1.0
# スクロール位置変更
x += x_spd
z += z_spd
# 描画
bg.draw(0, 240, x, z,
:vflip=>false,
:floor_dist=>floor_dist,
:scr_dist=>scr_dist,
:y_diff=>y_diff,
:z=>-255, :alpha=>alpha)
bg2.draw(0, 240, x, -z,
:vflip=>true,
:floor_dist=>floor_dist,
:scr_dist=>scr_dist,
:y_diff=>y_diff,
:z=>-255, :alpha=>alpha)
# 説明文を描画
tx = 4
h = 20
Window.drawFont(tx, h * 0, "RIGHT , LEFT : x speed = #{x_spd}", font)
Window.drawFont(tx, h * 1, "UP , DOWN : z speed = #{z_spd}", font)
Window.drawFont(tx, h * 2, "W , S : floor dist = #{floor_dist}", font)
Window.drawFont(tx, h * 3, "D , A : screen dist = #{scr_dist}", font)
Window.drawFont(tx, h * 4, "R , F : y_diff = #{y_diff}", font)
Window.drawFont(tx, h * 5, "Q : Fade in/out", font)
Window.drawFont(tx, h * 6, "C : Speed clear", font)
count += 1
end
end
end
動作テスト部分のほうが、長いという…。今回も、単体で実行しても動くけど、他のファイルから呼んでも使えるようにしておきました。本体ファイル?と同じフォルダに floorrasterscroll.rb を入れといて、以下のような記述で使えるかなと…。
# 床ラスター処理のテスト
require 'dxruby'
require_relative 'floorrasterscroll'
image = Image.load("lena.png")
bg = FloorRasterScroll.new(image)
x = 0
z = 0
Window.loop do
break if Input.keyPush?(K_ESCAPE)
x += 8
z += 4
bg.draw(0, 240, x, z)
end
サンプルを弄って作っただけなので、これもサンプル同様、Public Domain にしておきます。それと、画像は以下からDLして使ってみてください。
_cloud.png (320x320 dot)

もやもやした模様ではよく分からないでしょうから、あの有名な、 _lena様画像 も置いときますね…。
_lena.png (160x160 dot)
使うと、以下のような感じになります。
やっぱり、lena様のような画像で実験すると、なんだかやる気がでてくるなあ。
◎ 透視変換で頭が混乱してきたのでメモ。 :
透視変換をするShader ―― HLSLを書くあたりで、ちょっとハマった。なんだかややこしいので、一応図解してメモ。
まず、画面座標は、縦横 0.0 〜 1.0 の範囲になってる、と考える。また、元画像は、床に、つまり平面に、ずらりと並んでると考える。z値として得た値は、uv値のvとして使う、とでも言えばいいのか…。 もしかしたら v の方向は逆かもしれないけど。上が1.0なのか、下が1.0なのか、よく分かってません…。
真横から見た状態を考える。 作図ツールの関係で、上方向が +y になってるけど、プログラム上では、下方向が +y なので、ちと注意。
値が分かってるものと、値が分かってないものを、分類してみる。
(sz, sy) が作る三角形と (pz, py) が作る三角形は相似なので、以下が成り立つ。
さらに、真上から見た状態を考える。
これも、値が分かってるものと、分かってないものを、分類してみる。
で、注意点が。
sx は input.x から求まるのだけど、input.x の範囲は、画面左から右に向かって 0.0〜1.0 なので、真ん中は 0.5。なので、sx = input.x - 0.5 として、ずらしてやらないといけない。
sy は…。今回は、床を表示したいなーと思ってるので、画面の下半分だけ考えればいいよなと。だったら、sy = input.y でいいかなと。画面の上半分も含めて何かしたいなら、sy = input.y - 0.5 になるのだろうけど。
そんな感じで、HLSL内では、以下のようなソレを書けば良さそう。
まず、画面座標は、縦横 0.0 〜 1.0 の範囲になってる、と考える。また、元画像は、床に、つまり平面に、ずらりと並んでると考える。z値として得た値は、uv値のvとして使う、とでも言えばいいのか…。 もしかしたら v の方向は逆かもしれないけど。上が1.0なのか、下が1.0なのか、よく分かってません…。
真横から見た状態を考える。 作図ツールの関係で、上方向が +y になってるけど、プログラム上では、下方向が +y なので、ちと注意。
値が分かってるものと、値が分かってないものを、分類してみる。
- sy は、画面上の座標。HLSL 内の input.y が、そのものズバリなので、これは値が分かってる。
- sz は、画面までの距離。これはテキトーに決めるので、値が分かってる。画面の縦横が 0.0 〜 1.0 なので、sz も 0.n みたいな値になりそう。
- py は、床までの距離。これもテキトーに決めるので、値が分かってる。おそらくこれも、値が 0.n ぐらいになりそう。
- pz は、参照する画像の、v値。これが分からない。
(sz, sy) が作る三角形と (pz, py) が作る三角形は相似なので、以下が成り立つ。
sz : sy = pz : py sz * py = sy * pz pz = (sz * py) / syこれで、参照する画像の v 値は得られるので、HLSL内の input.y に代入してやればいい。はず。
さらに、真上から見た状態を考える。
これも、値が分かってるものと、分かってないものを、分類してみる。
- sx は、画面上の座標。HLSL内の input.x から得られる。これは値が分かってる。
- sz は、画面までの距離。これはテキトーに決めるので、値が分かってる。
- pz は、参照する画像の v値。これはさっき求めたから、値が分かってる。
- px は、参照する画像の u値。これが分からない。コイツを求めたい。
sz : sx = pz : px sz * px = sx * pz px = sx * pz / sz
で、注意点が。
sx は input.x から求まるのだけど、input.x の範囲は、画面左から右に向かって 0.0〜1.0 なので、真ん中は 0.5。なので、sx = input.x - 0.5 として、ずらしてやらないといけない。
sy は…。今回は、床を表示したいなーと思ってるので、画面の下半分だけ考えればいいよなと。だったら、sy = input.y でいいかなと。画面の上半分も含めて何かしたいなら、sy = input.y - 0.5 になるのだろうけど。
そんな感じで、HLSL内では、以下のようなソレを書けば良さそう。
sz = 画面までの距離 py = 床までの距離 input.y = sz * py / input.y input.x = (input.x - 0.5) * input.y / szと思ったけど、試してみたら上下が逆になった。やっぱり v値は、上が1.0なのかもしれない…? そんなわけで、ちょっと修正。
input.y = sz * py / -input.y input.x = (input.x - 0.5) * -input.y / sz見た目はそれらしくなったから、これでいいか…。
◎ 天井はどうしてるかというと。 :
天井は、床を上下反転して描画してるだけです。Window.drawEx() で描画する際に、:scaley => -n を渡してるだけ。
[ ツッコむ ]
#3 [dxruby] DXRubyで四角形の自由変形をする際に遠近感をつけるとかえってマズイのかもしれない
DXRuby の Window.drawMorph() を使えば、四角形の自由変形ができるので、もしかすると疑似3Dっぽい見せ方ができるかな、と夢想してたけど。変形する際に、というか分割する際に、遠近感をつけて分割したら、なんだかマズイような気がしてきたわけで。
たとえば、ゼビウスのバキュラみたいなソレに、テクスチャを貼ったら…回転軸上のテクスチャは、表示する際、位置がずれないだろうなと。
だけど、変形した四角形の4点から、対角線の交点を求めて分割を、とかやったりすると、位置がずれるよなと。4点の位置が変わるたびに中心部分があっちこっちにうねうね動いちゃうのってどうなんだろう、かえって不自然にならないかと思えてきたり。
ん? もしかして、回転軸が、本来なら対角線の交点上になってるのが正しいのかな? なんだかよく分からなくなってきた…。

図にしてみたけど、やっぱりよく分からない…。どれが自然な見た目になるんだろう。動かしてみないとわからんかな…。
たとえば、ゼビウスのバキュラみたいなソレに、テクスチャを貼ったら…回転軸上のテクスチャは、表示する際、位置がずれないだろうなと。
だけど、変形した四角形の4点から、対角線の交点を求めて分割を、とかやったりすると、位置がずれるよなと。4点の位置が変わるたびに中心部分があっちこっちにうねうね動いちゃうのってどうなんだろう、かえって不自然にならないかと思えてきたり。
ん? もしかして、回転軸が、本来なら対角線の交点上になってるのが正しいのかな? なんだかよく分からなくなってきた…。

図にしてみたけど、やっぱりよく分からない…。どれが自然な見た目になるんだろう。動かしてみないとわからんかな…。
[ ツッコむ ]
#4 [pc] Javaのアップデート時にMcAfeeのソレも入れてよと言ってくるのが困る
コレ、親父さんや、親父さんの友人知人は、うっかり入れちゃいそうだな…。そして、ウイルス対策ソフトが、1つのPC上で2つも3つも同時に動いてて、何をするにしても遅い、なんだか最近PCの調子がおかしい、てな話になりそうな予感。
と思ったけどググってみたら、そもそもウイルス対策ソフトじゃないっぽい。
_McAfee Security Scan Plus削除アンインストール方法 【宣伝広告ソフト】
_ロイドベンチャーシステム雑記<ロイドの日記>: McAfee Security Scan Plus がいつの間にかインストールされている
_【スタッフ日記】McAfee Security Scan Plusってなんだ?「アンインストール手順」|パソコン修理設定・データ復旧・救出のコムサス~栃木県小山市
しかし、Windows起動時にファイルを走査?したりはするらしくて。となると、最近OSの起動がやたらと遅い、みたいな話が出てきそうだな…。
と思ったけどググってみたら、そもそもウイルス対策ソフトじゃないっぽい。
_McAfee Security Scan Plus削除アンインストール方法 【宣伝広告ソフト】
_ロイドベンチャーシステム雑記<ロイドの日記>: McAfee Security Scan Plus がいつの間にかインストールされている
_【スタッフ日記】McAfee Security Scan Plusってなんだ?「アンインストール手順」|パソコン修理設定・データ復旧・救出のコムサス~栃木県小山市
しかし、Windows起動時にファイルを走査?したりはするらしくて。となると、最近OSの起動がやたらと遅い、みたいな話が出てきそうだな…。
[ ツッコむ ]
以上、1 日分です。





