mieki256's diary



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・解凍すれば、バイナリ一式が入っているので、最悪の場合、ソレを使うのでもよさそうだけど。

#2 [dxruby] DXRuby+Shaderで床ラスタースクロールっぽいことができたような気がする

Shader利用サンプルの sample_spehari.rb を弄って、望んだ感じの床ラスタースクロール、っぽいことができたような気がする。たぶん。

sample_spehari.rb を眺めていて、気づいた点を列挙。 そのあたりを意識しながら弄ってみたり。

こんな感じに。
床ラスタースクロール

STGサンプルに組み込んでみたら、こんな感じ。
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)
cloud.png


もやもやした模様ではよく分からないでしょうから、あの有名な、 _lena様画像 も置いときますね…。

_lena.png (160x160 dot)

使うと、以下のような感じになります。
lena様で試した結果

やっぱり、lena様のような画像で実験すると、なんだかやる気がでてくるなあ。

透視変換で頭が混乱してきたのでメモ。 :

透視変換をするShader ―― 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値。これが分からない。
ということで。pz を求めればいい。

(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 [pc] Javaのアップデート時にMcAfeeのソレも入れてよと言ってくるのが困る

コレ、親父さんや、親父さんの友人知人は、うっかり入れちゃいそうだな…。そして、ウイルス対策ソフトが、1つのPC上で2つも3つも同時に動いてて、何をするにしても遅い、なんだか最近PCの調子がおかしい、てな話になりそうな予感。

と思ったけどググってみたら、そもそもウイルス対策ソフトじゃないっぽい。

_McAfee Security Scan Plus削除アンインストール方法 【宣伝広告ソフト】
_ロイドベンチャーシステム雑記<ロイドの日記>: McAfee Security Scan Plus がいつの間にかインストールされている
_【スタッフ日記】McAfee Security Scan Plusってなんだ?「アンインストール手順」|パソコン修理設定・データ復旧・救出のコムサス~栃木県小山市


しかし、Windows起動時にファイルを走査?したりはするらしくて。となると、最近OSの起動がやたらと遅い、みたいな話が出てきそうだな…。

以上、1 日分です。

過去ログ表示

Prev - 2014/01 - Next
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project