mieki256's diary



2023/09/06(水) [n年前の日記]

#1 [hsp] 疑似3D道路その3

_昨日 の続き。HSP 3.6 を使って、疑似3D道路が作れないか試しているところ。

道路のデータをセグメントで持つあたりは実装できたので、カーブ処理を追加してみた。

参考ページ :

_PICO-8 を使った、以下のチュートリアル記事がとても参考になった。ありがたや。

_Creating a pseudo 3D racer
_Creating a pseudo 3D racer - part 2
_Creating a pseudo 3D racer - part 3

雛形を一つ一つ作って、そこで起きる不具合を実際に目にして、その問題を少しずつ解決していくあたりが非常に分かりやすいなと…。また、PICO-8用に書かれた各サンプルの下にある「Code」をクリックすればソースコードが全部見れるので、英文が分からなくてもソースコードを眺めていけばなんとかなりそう。

余談。PICO-8 については以下が参考になるかなと…。

_PICO-8って何? - PICO-8ゲーム開発入門(1) - AUTOMATON
_PICO-8 ゲーム開発のススメ
_PICO-8で遊ぼう!【PICO-8入門】 | INWAN'S LABO

動作画面 :

書いたサンプルの動作画面は以下。それらしくカーブが表示されている、ような気がする。




  • カーソルキーの上下で、速度を上げたり下げたりできる。
  • カーソルキーの左右は動作確認用。遠景の横方向スクロールのテスト。

ソースコード :

以下のようなソースコードになった。

_road03.hsp
    ; 疑似3D道路を描画する / Drawing pseudo 3D roads
    ; セグメントで道路を管理してカーブを実装

    #include "hspmath.as"

    #define BG0_FILE    "bg_bg0.png"
    #define BG1_FILE    "bg_bg1.png"
    #define SCR_W       640
    #define SCR_H       360
    
   ; セグメントの区切りを色分け. 0 or 1
    #define SEG_DELIMITER   0

    ; 同梱ファイル / bundled files
    #pack   BG0_FILE
    #pack   BG1_FILE
    
    #packopt name "road03"      ; exe filename
    #packopt type 0             ; generate ".exe"
    #packopt xsize SCR_W
    #packopt ysize SCR_H
    
    ; onkey goto *jobend
    
    ; get windows size
    screen 0, SCR_W, SCR_H, 0
    gsel 0
    ; width SCR_W, SCR_H
    dispw = ginfo_winx
    disph = ginfo_winy
    cls 4

    ; load bg image
    bgimgid0 = 4
    buffer bgimgid0, 1280, 720
    picload BG0_FILE
    bg0w = ginfo_winx
    bg0h = ginfo_winy
    
    bgimgid1 = 5
    buffer bgimgid1, 1280, 720
    picload BG1_FILE
    bg1w = ginfo_winx
    bg1h = ginfo_winy
    
    ; セグメント作成用データ初期化用マクロ
    #define set_array(%1, %2, %3, %4, %5) \
        %1(%2, 0) = %3 :\
        %1(%2, 1) = %4 :\
        %1(%2, 2) = %5 :

    ; セグメント作成用データ
    dim segm, 12, 3
    ; set_array 配列変数名, index, count, curve, pitch
    ; curve と pitch は100倍した値。
    ; HSPは int と double を配列内で混在できないらしいので…
    set_array segm, 0, 20, 0, 0
    set_array segm, 1, 10, 50, 0
    set_array segm, 2, 60, 200, 0
    set_array segm, 3, 10, 50, 0
    set_array segm, 4, 50, 0, 100
    set_array segm, 5, 10, -100, 0
    set_array segm, 6, 30, -400, 0
    set_array segm, 7, 10, -100, 0
    set_array segm, 8, 20, 0, -100
    set_array segm, 9, 50, -100, 0
    set_array segm, 10, 25, 200, 0
    set_array segm, 11, 20, 0, 0

    ; セグメント総数を取得
    seg_max = 0
    repeat length(segm)
        seg_max += segm(cnt, 0)
    loop
    
    ; セグメントのz幅を指定
    seg_length = 20
    seg_total_length = seg_length * seg_max

    ; 参照されるセグメントデータとして展開
    dim seg, seg_max, 3
    z = 0
    i = 0
    repeat length(segm)
        lp = segm(cnt, 0)
        curve = segm(cnt, 1)
        pitch = segm(cnt, 2)
        repeat lp
            seg(i, 0) = z
            seg(i, 1) = curve
            seg(i, 2) = pitch
            z += seg_length
            i++
        loop
    loop
    
    dist = 200.0    ; 画面までの距離 / distance to screen
    
    camera_z = 0.0
    
    spd = 0.0
    spda = 0.1
    spd_max = 16.0

    xd = 0.0
    yd = 0.0
    zd = double(seg_length)
    
    bgx = 0.0
    tgt_bgx = 0.0

*mainloop

    ; ESC key to exit
    stick k, 255
    if k & 128 : goto *jobend
    
    ; check cursor key
    if k & 2 {
        ; Up key
        spd += spda
        if spd >= spd_max : spd = spd_max
    }
    if k & 8 {
        ; Down key
        spd -= (spda * 3)
        if spd <= 0.0 : spd = 0.0
    }
    if k & 1 {
        ; Left key
        bg_x -= 16
    }
    if k & 4 {
        ; Right key
        bg_x += 16
    }

    road_y = 100        ; 道路のy位置
    road_x = 300        ; 道路の幅(片側の幅)
    
    base_y = int(double(disph) * 0.5)
    h = disph - base_y

    ; 最初のセグメント番号を取得
    if camera_z = 0 {
        seg_index = 0
    } else {
        ; "\"はHSPの剰余記号。一般的なプログラミング言語なら "%" に相当
        seg_index = (int(camera_z) / seg_length) \ seg_max
    }
    
    ; カメラが居るセグメントのカーブ量を求める
    curve = double(seg(seg_index, 1)) * 0.01
    
    ; カメラがセグメント内のどの位置に居るか割合を求める
    z0 = seg(seg_index, 0)
    z1 = z0 + seg_length
    ccz = camera_z \ seg_total_length
    camz = double(ccz - z0) / double(z1 - z0)

    ; セグメント内のカメラ位置に応じて事前に横方向にある程度ずらしておく
    xd = (-camz * curve)
    yd = 0.0
    zd = double(seg_length)
    
    cx = -(xd * camz)
    ; cx = 0.0
    cy = double(road_y) + (yd * camz)
    cz = 0.0
    
    bg_x += curve * (spd * 0.5)

    redraw 0    ; 描画開始 / draw start
    gsel 0
    
    ; 背景(遠景)を描画 / draw BG
    bgw = bg1w
    bgh = bg1h
    bgx = int(double(bg_x) * 0.4) \ bgw
    bgy = bgh / 2 - base_y
    bgid = bgimgid1
    gmode 0
    gosub *draw_bg

    bgw = bg0w
    bgh = bg0h
    bgx = int(double(bg_x) * 0.5) \ bgw
    bgy = bgh / 2 - base_y
    bgid = bgimgid0
    gmode 2
    gosub *draw_bg
    
    gmode 0

    ; 道路を描画 / draw road
    
    seg_z_max = 0
    seg_distance = 96
    repeat seg_distance
        ; セグメントのz値、カーブ量、ピッチ量を取得
        idx = (seg_index + cnt) \ seg_max
        z0 = seg(idx, 0)
        curve = double(seg(idx, 1)) * 0.01
        pitch = double(seg(idx, 2)) + 0.01
        
        ; 最後のセグメントを超えて最初にループする場合、z値を調整する
        if z0 > seg_z_max : seg_z_max = z0
        if z0 < seg_z_max : z0 += seg_total_length
        
        cam_z = int(camera_z) \ seg_total_length
        z0 -= cam_z
        z1 = z0 + seg_length
        if z1 <  (dist / 4) : goto *seg_cancel
        
        if z0 = 0 : z0 = 1      ; 0で除算しないように微調整
        
        ; 画面上で描画すべきy座標位置を取得
        y0 = int(road_y * dist / z0)
        y1 = int(road_y * dist / z1)
        
        ; 画面上で描画すべき道路の幅(片側の幅)を取得
        x0 = double(road_x) * double(dist) / double(z0)
        x1 = double(road_x) * double(dist) / double(z1)

        ; 画面上でずらすべき中心線の位置を取得
        cx0 = double(cx) * double(dist) / double(z0)
        cx1 = (double(cx) + double(xd)) * double(dist) / double(z1)
        
        h = abs(y1 - y0)
        dsy = sgn(y1 - y0)
        if dsy = 0 : dsy = 1
        repeat h
            sy = y0 + (dsy * cnt)
            draw_y = sy + base_y
            
            ; 画面縦幅を超えたy座標なら描画しない
            if draw_y < 0 | draw_sy > disph : continue
            
            ; 2次元的な計算で割合を求める
            if y0 == y1 {
                p = 0.0
            } else {
                p = double(sy - y0) / double(y1 - y0)
            }
            z = (double(z1) - double(z0)) * p + double(z0)
            x = (double(x1) - double(x0)) * p + double(x0)
            center_x = (cx1 - cx0) * p + cx0
            addv = ((int(z) + int(camera_z)) / 40) & $1
            
            ; 1ラスター分を描画 / draw 1 raster
            road_w = x * 2
            draw_x = -x + (dispw / 2) + center_x
            
            kind = addv
            if SEG_DELIMITER = 1 {
                ; セグメントの区切りを色分けしたい場合
                if sy = y0 : kind = 2
            }
            gosub *draw_raster_road
        loop
        
*seg_cancel
        cx += xd
        cy += yd
        cz += zd
        
        xd += curve
        ; yd += pitch
    loop

    ; draw text
    font "Arial", 18, 1
    color 1, 1, 1
    pos 8, 4
    mes "Press cursor key"
    pos 8, disph - 32
    mes "seg_index : " + seg_index

    redraw 1    ; 描画終了 / draw end
    
    camera_z += spd
    
    await (1000 / 60)
    goto *mainloop

*draw_raster_road
    ; 道路を1ラスター分描画 / draw road 1 raster
    ; draw_x, draw_y : draw x, y
    ; road_w : road width
    ; kind : 0 or 1 or 2
    ; dispw : screen width

    ; draw ground
    if kind = 0 {
        ; color R, G, B
        color 114, 185, 66
    } else {
        color 22, 174, 63
    }
    ; boxf x0, y0, x1, y1
    boxf 0, draw_y, dispw, draw_y

    ; draw road base
    switch kind
    case 0
        color 133, 149, 158
        swbreak
    case 1
        color 149, 168, 179
        swbreak
    case 2
        color 255, 0, 0
        swbreak
    swend
    boxf draw_x, draw_y, draw_x + road_w, draw_y

    ; draw white line
    lw = double(road_w) * 48.0 / 2048.0     ; white line width

    switch kind
    case 0
        color 255, 255, 255
        
        lx = double(draw_x)
        boxf lx, draw_y, lx + lw, draw_y
        
        lx = lx + road_w - lw
        boxf lx, draw_y, lx + lw, draw_y
        
        lx = double(draw_x) + (double(road_w) * 0.5) - (lw * 0.5)
        boxf lx, draw_y, lx + lw, draw_y
        
        lx = double(draw_x) + double(road_w) * 0.25 - (lw * 0.5)
        boxf lx, draw_y, lx + lw, draw_y
        
        lx = double(draw_x) + double(road_w) * 0.75 - (lw * 0.5)
        boxf lx, draw_y, lx + lw, draw_y
        swbreak
    case 1
        color 228, 236, 252
        
        lx = double(draw_x) + lw
        boxf lx, draw_y, lx + lw, draw_y
        
        lx = double(draw_x) + road_w - (lw * 2)
        boxf lx, draw_y, lx + lw, draw_y
        swbreak
    swend
    
    return

*draw_bg
    ; BGを1枚描画 / draw BG. 1 layer
    ; bgid : bg image buffer id
    ; bgx, bgy : bg position
    ; bgw, bgh : bg image width, height
    ; dispw, disph : screen width, height
    if bgx >= 0 & bgx < (bgw - dispw) {
        pos 0,0
        gcopy bgid, bgx, bgy, dispw, disph
    } else {
        if bgx < 0 {
            w = -bgx
            pos 0, 0
            gcopy bgid, bgw - w, bgy, w, disph
            pos w, 0
            gcopy bgid, 0, bgy, dispw - w, disph
        } else {
            w = bgw - bgx
            pos 0, 0
            gcopy bgid, bgx, bgy, w, disph
            pos (bgw - bgx), 0
            gcopy bgid, 0, bgy, dispw - w, disph
        }
    }
    return

*jobend
    end

使用画像は以下。road03.hsp と同じフォルダ階層に置く。

bg_bg0.png
_bg_bg0.png

bg_bg1.png
_bg_bg1.png

考え方 :

考え方は、前述の参考ページが分かりやすいかなと…。

_Creating a pseudo 3D racer

実のところ、カーブを表現する処理について、まだ今一つ仕組みが分かってないけど…。

とりあえず、道路データは、セグメントと呼ばれるソレで管理する。以下の画像の赤い線がセグメントの区切り部分。

ss_road03_ss02.png

セグメントが横方向に少しずつずれていくことで、カーブが表現できるということらしい。


参考ページのセグメントデータは、そのセグメントが並ぶ個数(ct)、カーブ量(tu)、の2つを並べていくけれど。
road={
 {ct=10,tu=0},
 {ct=6,tu=-1},
 {ct=8,tu=0},
 {ct=4,tu=1.5},
 {ct=10,tu=0.2},
 {ct=4,tu=0},
 {ct=5,tu=-1},
}

今回はそれに近い元データを一旦展開(?)して、ベタなセグメントの並びを作ってから処理するようにしてみた。

about_segment_ss01.png

こうしておけば、z値とどのセグメントが対応してるか計算しやすくなるかなと…。メモリは多少食うけれど。


さて。各セグメントはz値を持っている。もしくは、セグメントのインデックス番号に、1セグメント当たりのz幅をかけてやれば、そのセグメントのz値を求めることができる。そして、道路の幅は今回一定としているので…。各セグメントのz値と道路幅を透視変換してやれば、各セグメントの区切りに相当する線が画面上のどのあたりに位置するかを求めることができる。

ss_road03_ss03.png


セグメント[n] と、セグメント[n+1]、二本の水平線の、画面上での位置を得ることができれば…。その二本の線で作られる台形を塗り潰すように描画してやることで、1セグメント分の道路を描画できる。

about_segment_ss02.png

台形の塗り潰しは、HSP の場合、line で線を引いても、boxf で矩形塗り潰しをしても、どちらでもOK。横一直線 ―― 1ラスター分の塗り潰しが可能なら、それを台形の縦幅分繰り返すことで、台形の塗り潰しはできる。

これを、画面に出ているセグメント個数分繰り返せば、道路が描画できる。

また、セグメント[n」に対して、セグメント[n+1]が、横方向にある程度ずれていれば、そこの部分だけ道路が傾いているように見える。昔のレースゲームの道路は横方向のラスタースクロールをすることでそれらしく見せることができていた、というのはそういう話だろうなと。

疑問点その1 :

ここでちょっと気になった。本当にセグメント単位で台形の形を求めて、そこを塗り潰すだけでいいのだろうか…? そんな処理をしたら、カーブにさしかかった時、道路がカクカクした形に見えたりしないだろうか。細かい直線で道路が作られているように見えてしまって、なんだかイマイチだったりしないか…。

しかし実際に試してみたら、パッと見た感じ、それほど気にならなかったので、まあいいか、と。

考えてみたら、現実世界の道路だって、道路の端にある縁石の一つ一つ、側溝の蓋の一つ一つなどは、カーブに沿って曲線を描く形になっていない。縁石も、側溝も、直線で構成されているなと…。だけど道路を走っていて、カーブではちゃんと道路が曲がっているように見えているわけだから、道路のカーブが細かい直線の並びで作られていたとしても案外気にならないのかもしれない。

疑問点その2 :

もう一点気になった。台形の形を求めた後、台形内のラスター単位でz値を求めて、そのz値に応じて道路の白線を描いたり描かなかったりするようにしてみたのだけど。その処理は、3Dで計算してるわけじゃなくて、2Dで計算してるわけで…。そのことで見た目がおかしくなったりしないのだろうか?

これも、実際に試してみたら全然気にならなかったので、まあいいか、と。

考えてみたら、プレステ1やセガサターンの頃だって、各ポリゴン内に描かれるテクスチャは単に2D的な変形で塗り潰していたけれど、それほど気にならなかったよなと…。いやまあ、そのポリゴンが画面に大きく表示された時は「ギャーッ」って感じではあったけど、面積が小さければほとんど気にならなかったし。

先ほどの直線云々の話もそうだけど、面積だの幅だのがそれなりに小さければ、このあたりは案外気にならないのだろう。たぶん。

カーブに入った時のガクガク感 :

カーブに入ると道路が急に曲がったような感じがする。本来なら、少しずつ曲がっていって、本来の曲がり具合になってから、また徐々に曲がりが少なくなっていくように感じられるほうがいいだろうなと…。

そのあたりは、セグメントデータを展開するあたりで手を加えれば多少は改善できるかもしれない。カーブ量を持っているセグメントにさしかかったら、イージングを使って少しずつ本来の角度(ずれ具合)に近づくようにセグメントを並べていけば滑らかさを付加できるのではないかと…。

たしか、現実世界の道路も、カーブに入ったら急に曲がるようにはなってないはず。カーブに入るところ、出るところで、少しずつ曲がり具合が増減するようになっていた記憶がある。そういう設計になってないダメダメな道路は、車が曲がり切れずに事故が起きる確率が高いのだとか。

遠景もスクロールさせてみた :

試しに、カーブに差し掛かったら遠景も横スクロールするようにしてみた。セグメントのカーブ量を遠景BGの横スクロール量に加算してみたけど、これでいいのだろうか…。もっと違う処理のほうがらしく見えないか…。

せっかく疑似3Dでやっていることだし、遠景を2つにわけて、雲の部分と山の部分のスクロール量を変えて、多重スクロールを ―― パララックス(parallax、視差)スクロールを試みたのだけど。なんだかあまり効果が感じられないというか、不自然さが増してしまった気もするなと…。

既存のレースゲームの動画を眺めて遠景スクロールはどうしているのか確認してみたけれど、一枚絵をスクロールさせてる事例、パララックススクロールにしてる事例、どちらもあるのだよな…。

余談。デフォルメ派とリアル派 :

ここからは余談だけど。本来、リアルに考えたら、遠景なんだから別々にスクロールするはずはないのだよな…。めちゃくちゃ遠くにある風景なのだから視差を感じられる動きになるわけがない。ただ、遠景がスクロールしてますよ感を誇張、というかデフォルメするために、ここはあえて嘘をついて別々にスクロールさせるのもアリと言えばアリ、とも思っていて…。このあたり、大昔に関わった某ゲームの一シーンを思い出したりもする。担当プログラマーさんは、リアルに考えたら遠景は一枚絵でスクロールするはず、と主張してた気がするのだけど、カーブのスピード感を増すために、別々に、かつ、リアルではない速度で動かしたほうが、と自分が主張してしまって…。当時の自分の主張は正しかったのかどうか、間違っていたのではないかと、実は未だに、ふとした拍子に悩み始めてしまったりする。

せっかくの疑似3Dだし、しかもゲームなんだから、いっそ思い切って誇張したほうが、という考えもアリじゃないのかと思うのだけど、たとえ疑似であってもできる範囲でリアルに見えるように、というのもアリだよなとも思えるし。

ゲームに限らず、漫画やアニメ等もそうだろうけど。娯楽商品関係には、色々な答えがあるけれどどれも正解と言えば正解、という場面があって…。そんなとき何を判断基準にしてアリナシを決めていくか、というのがちょっと悩ましいよなと。まあ、最終的には「お客さんが一番楽しめそうなのはどれか」で考えるのが理想だろうけど。それもまた、「デフォルメしたほうが楽しめるよ」派と「リアルにしたほうが楽しめるよ」派が…。

もっとも、ゲームに限って言えば、今の時代は疑似3Dなんてやらなくても3Dでゲーム画面が作れるわけで、なのにあえて疑似3Dを選ぶということは、それはもう最初からデフォルメして見せる気満々だから、ということだよなと。リアルにしたいなら、まずは疑似3Dを選ばないのが妥当だろう…。

2022/09/06(火) [n年前の日記]

#1 [prog][windows] GDIでダブルバッファ描画

Windows10 x64 21H2上で、C/C++ (MinGW) と Windows API を使ってウインドウ描画ができるか実験中。

_昨日、GDI+を使ってpng画像を描画できるのか、 実験していたわけだけど。GDI+ は描画が遅いという話を見かけたので、GDI+ ではなく GDI だけを使って描画ができるならそのほうがいいのかなと…。そんなわけで、GDI でダブルバッファ描画をする方法を試してみた。まあ、png画像の使用を諦めて、bmp画像(bitmap画像)だけを利用することになってしまうけど…。

環境は、Windows10 x64 21H2 + MinGW (gcc 9.2.0)。MSYS2 + MinGW-w64 ではなくて、MinGW (+ MSYS) で実験してる。

以下を参考にさせてもらいました。

_ビットマップのマルチバッファリング【Windowsプログラミング研究所】

今回書いたサンプルの実行結果は以下。ちょっと解像度が荒いけど、雰囲気は伝わるかと…。ダブルバッファで描画しているので、ちらつきは感じられない。

リソースファイル。 :

リソースファイルは以下。このファイルは、windres を使って .o に変換する。

_res.rc
BALL_IMG        BITMAP  "ball.bmp"
BALL_MSK        BITMAP  "ball_mask.bmp"
BG_IMG          BITMAP  "bg2.bmp"
  • 3つのbmp画像ファイルを含めるように指定している。
  • 先頭に書かれている「BALL_IMG」「BALL_MSK」「BG_IMG」が、C言語のソース内で指定する識別名。

使用画像。 :

使用画像は以下。

_images.zip
  • ball.bmp : 赤いボール画像。透明にしたい部分は黒(#000000)にしておく。
  • ball_mask.bmp : ボール画像のマスク画像。不透明部分は黒(#000000)、透明部分は白(#ffffff)。アルファチャンネルを反転した感じの画像。
  • bg2.bmp : 背景用画像。タイル状に描画することを前提にしている。

一応、png画像も載せておきます。

ball.png

ball_mask.png

bg2.png

C言語のソースファイル。 :

C言語のソースファイルは以下。今回は GDI+ を使ってないので、C++ ではなく C言語で書くことができる。

_01_dblbuf.c
/* GDI Double buffer sample */

#include <windows.h>

#define SCRW        1280
#define SCRH        720

#define FPS         60

#define TM_COUNT1   101

#define LPCLASSNAME     TEXT("DoubleBufferSample")
#define WINDOW_TITLE    TEXT("Double Buffer Sample")


LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
  static HBITMAP hBitmap;
  static HBITMAP hBitmap_mask;
  static HBITMAP hBitmap_bg;
  static HBITMAP offScrnBitmap;
  static int wdw_w, wdw_h;
  static int imgw, imgh;
  static int bgw, bgh;
  static int bgx, bgy;
  static float x, y;
  static float dx, dy;

  switch (msg)
    {
    case WM_CREATE:
      // get window size
      {
        RECT rc;
        GetClientRect(hwnd, &rc);
        wdw_w = rc.right - rc.left;
        wdw_h = rc.bottom - rc.top;
      }

      // create off screen bitmap
      {
        HDC hdc;
        hdc = GetDC(hwnd);
        offScrnBitmap = CreateCompatibleBitmap(hdc, wdw_w, wdw_h);
        ReleaseDC(hwnd, hdc);    // GetDC() -> ReleaseDC()
      }

      // load bitmaps from resource
      hBitmap = LoadBitmap(((LPCREATESTRUCT)lp)->hInstance, TEXT("BALL_IMG"));
      hBitmap_mask = LoadBitmap(((LPCREATESTRUCT)lp)->hInstance, TEXT("BALL_MSK"));
      hBitmap_bg = LoadBitmap(((LPCREATESTRUCT)lp)->hInstance, TEXT("BG_IMG"));

      // get images size
      {
        BITMAP bp;

        // get ball image size
        GetObject(hBitmap, sizeof(BITMAP), &bp);
        imgw = bp.bmWidth;
        imgh = bp.bmHeight;

        // get bg image size
        GetObject(hBitmap_bg, sizeof(BITMAP), &bp);
        bgw = bp.bmWidth;
        bgh = bp.bmHeight;
      }

      // init work
      x = wdw_w / 2;
      y = wdw_h / 2;
      dx = (float)wdw_w / (float)FPS;
      dy = dx * 0.2;
      bgx = 0;
      bgy = 0;

      SetTimer(hwnd, TM_COUNT1, (int)(1000 / FPS), NULL);
      return 0;

    case WM_TIMER:
      // main loop
      x += dx;
      y += dy;

      if (x <= 0 || (x + imgw) >= wdw_w) dx *= -1;

      if (y <= 0 || (y + imgh) >= wdw_h) dy *= -1;

      bgx -= 1;
      bgy -= 1;

      if (bgx <= -(bgw)) bgx += bgw;

      if (bgy <= -(bgh)) bgy += bgh;

      if (0)
        {
          // clear background
          InvalidateRect(hwnd, NULL, TRUE);
        }
      else
        {
          // not clear background
          InvalidateRect(hwnd, NULL, FALSE);
        }

      break;

    case WM_PAINT:
      // draw window
      {
        HDC hdc, hBmpDC, hMemDC;
        PAINTSTRUCT ps;

        hdc = BeginPaint(hwnd, &ps);
        // hdc = GetDC(hwnd);

        // set off-screen bitmap
        hMemDC = CreateCompatibleDC(hdc);
        SelectObject(hMemDC, offScrnBitmap);

        // draw bg to off-screen
        hBmpDC = CreateCompatibleDC(hdc);
        SelectObject(hBmpDC, hBitmap_bg);
        {
          int by = bgy;

          while (by <= wdw_h)
            {
              int bx = bgx;

              while (bx <= wdw_w)
                {
                  BitBlt(hMemDC, bx, by, bgw, bgh, hBmpDC, 0, 0, SRCCOPY);
                  bx += bgw;
                }

              by += bgh;
            }
        }
        DeleteDC(hBmpDC);

        // draw mask to off-screen
        hBmpDC = CreateCompatibleDC(hdc);
        SelectObject(hBmpDC, hBitmap_mask);
        BitBlt(hMemDC, (int)x, (int)y, imgw, imgh, hBmpDC, 0, 0, SRCAND);
        DeleteDC(hBmpDC);

        // draw source image to off-screen
        hBmpDC = CreateCompatibleDC(hdc);
        SelectObject(hBmpDC, hBitmap);
        BitBlt(hMemDC, (int)x, (int)y, imgw, imgh, hBmpDC, 0, 0, SRCPAINT);
        DeleteDC(hBmpDC);

        // drawing to off-screen is finished

        // draw off-screen bitmap to window
        BitBlt(hdc, 0, 0, wdw_w, wdw_h, hMemDC, 0, 0, SRCCOPY);

        DeleteDC(hMemDC);     // Create*() -> DeleteDC()

        EndPaint(hwnd, &ps);
      }

      return 0;

    case WM_DESTROY:
      KillTimer(hwnd, TM_COUNT1);  // kill timer

      DeleteObject(offScrnBitmap);
      DeleteObject(hBitmap);
      DeleteObject(hBitmap_mask);
      DeleteObject(hBitmap_bg);
      PostQuitMessage(0);
      return 0;
    }

  return DefWindowProc(hwnd, msg, wp, lp);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   PSTR lpCmdLine, int nCmdShow)
{
  HWND hwnd;
  MSG msg;
  WNDCLASS winc;

  winc.style            = CS_HREDRAW | CS_VREDRAW;
  winc.lpfnWndProc      = WndProc;
  winc.cbClsExtra       = winc.cbWndExtra   = 0;
  winc.hInstance        = hInstance;
  winc.hIcon            = LoadIcon(NULL, IDI_APPLICATION);
  winc.hCursor          = LoadCursor(NULL, IDC_ARROW);
  winc.hbrBackground    = (HBRUSH)GetStockObject(WHITE_BRUSH);
  winc.lpszMenuName     = NULL;
  winc.lpszClassName    = LPCLASSNAME;

  if (!RegisterClass(&winc)) return -1;

  hwnd = CreateWindow(
    LPCLASSNAME, WINDOW_TITLE,
    WS_OVERLAPPEDWINDOW | WS_VISIBLE,
    CW_USEDEFAULT, CW_USEDEFAULT,
    SCRW, SCRH,
    NULL, NULL,
    hInstance, NULL
    );

  if (hwnd == NULL) return -1;

  while (GetMessage(&msg, NULL, 0, 0))
    {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    }

  return msg.wParam;
}

  • SetTimer() で指定したミリ秒が経過すると、その都度、WM_TIMER というメッセージが Windows から送られてくる。
  • WM_TIMER が来た時に、ボールやBG画像の表示位置を更新することで、アニメーションをさせている。
  • InvalidateRect() を呼べば、ウインドウの再描画を要求できる。(WM_PAINTメッセージが送られてくる。)
  • InvalidateRect(hwnd, NULL, TRUE); なら、背景を消去しつつ、ウインドウを再描画(するように要求)。
  • InvalidateRect(hwnd, NULL, FALSE); なら、背景を消去せずに、ウインドウを再描画(するように要求)。ダブルバッファ描画をする時はこちらを指定する。
  • WM_PAINT が来た時に、描画処理を行う。
  • WM_DESTROY が来たら、終了処理を行う。タイマーを殺して、bitmap を全部削除しておく。

Makefile。 :

Makefile は以下。.c や .rc から .o を生成後、.o群をリンクして .exe を生成する。

_Makefile
01_dblbuf.exe: 01_dblbuf.o res.o
        gcc 01_dblbuf.o res.o -o 01_dblbuf.exe -mwindows

01_dblbuf.o: 01_dblbuf.c
        gcc -c 01_dblbuf.c

res.o: res.rc ball.bmp ball_mask.bmp bg2.bmp
        windres res.rc res.o

.PHONY: clean
clean:
        rm -f *.exe
        rm -f *.o

コンパイル/ビルド。 :

全部で以下のファイルになる。
  • 01_dblbuf.c
  • ball.bmp
  • ball_mask.bmp
  • bg2.bmp
  • Makefile
  • res.rc
これを任意のディレクトリに置いて make と打てば、コンパイル/ビルドがされて、01_dblbuf.exe が生成される。

ちなみに、make clean と打てば、*.o や *.exe を削除してくれる。

余談。 :

DeleteDC() と ReleaseDC() の使い分けが分からなくて悩んだけれど、以下のページを眺めたら分かってきた。

_API 関数解説
  • GetDC() を使って取得したデバイスコンテキストは、ReleaseDC() を使って解放する。
  • Create*() を使って取得したデバイスコンテキストは、DeleteDC() を使って解放する。

余談その2。 :

今回のソースは、中括弧(?)を利用して、変数のスコープを極力狭めつつ書いてみた。

_変数のスコープ(C言語) - 超初心者向けプログラミング入門
_C/C++ 中括弧でローカルスコープを作る - 【はてな】ガットポンポコ

#2 [prog][windows] ビットマップ画像を描画するスクリーンセーバを書いてみた

せっかく C/C++ と GDI を使って、bitmap画像を描画、ダブルバッファ描画、アニメーションができたので…。以前、MinGW を使ってビルドが通ることを確認できた、Windows用スクリーンセーバのサンプルソースにも処理を反映させてみたい。

_スクリーンセーバのビルドの実験中
_Windows10にmingwをインストールし直した

環境は、Windows10 x64 21H2 + MinGW (gcc 9.2.0)。

ちなみに、MSYS2 + MinGW-w64 (gcc 12.2.0) では、Windows用スクリーンセーバはビルドできない。
_msys2 + mingw-w64でスクリーンセーバをビルドしようとしてハマった

さておき。今回書いたサンプルの実行結果は以下。解像度が荒くてアレだけど、雰囲気は伝わるかと…。

リソースファイル。 :

リソースファイルは以下。以前のサンプルの最初のほうに、bitmap画像群を追記した。このファイルは、windres を使って、.rc から .o に変換することになる。

_resource.rc
/* resource.rc */

#include <windows.h>
#include <scrnsave.h>

#define IDC_STATIC_ICON     2300
#define IDC_STATIC_TEXT     2301

/* bitmap */
IDI_BALL        BITMAP  "ball.bmp"
IDI_BALL_MSK    BITMAP  "ball_mask.bmp"
IDI_BG          BITMAP  "bg2.bmp"
IDI_PREVIEW     BITMAP  "scrsav_preview.bmp"

/* Config dialog */
DLG_SCRNSAVECONFIGURE DIALOG DISCARDABLE  0, 0, 220, 50
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Setting Sample Screensaver"
 FONT 9, "Segoe UI"
BEGIN
  DEFPUSHBUTTON "OK", IDOK, 85, 30, 50, 14
  ICON          IDI_WARNING, IDC_STATIC_ICON, 6, 5, 20, 20
  LTEXT         "This is the template for the configuration dialog.", 
                IDC_STATIC_TEXT, 35, 12, 230, 12
END
※ このWeb日記システムの関係で、FONT指定行がおかしな状態で表示されてます。先頭の空白は削除してもらえればと…。


ヘッダーファイルは以下。でも、今回コレは使ってない気がする…。

_resource.h
#ifndef RESOURCE_H_
#define RESOURCE_H_

#define IDC_STATIC_ICON     2300
#define IDC_STATIC_TEXT     2301

#define IDI_BALL            2401
#define IDI_BALL_MSK        2402
#define IDI_BG              2403

#endif

使用画像。 :

使用画像は以下。4つのbmp画像を使っている。

_images.zip
  • ball.bmp : 赤いボール画像。透明部分は黒(#000000)にしておく。
  • ball_mask.bmp : ボールのマスク画像。不透明部分は黒(#000000)、透明部分は白(#ffffff)。
  • bg2.bmp : bg画像(背景画像)。タイル状に描画することを前提にしている。
  • scrsav_preview.bmp : プレビュー画像。スクリーンセーバの設定画面で表示されてる小さい窓の中に表示するための画像。サイズは 152 x 112 ドット。

一応、png画像も載せておきます。

ball.png

ball_mask.png

bg2.png

scrsav_preview.png

C言語のソースファイル。 :

_mgscrsv2.c
/* mingwscr.c */

#include <windows.h>
#include <tchar.h>
#include <scrnsave.h>
#include <time.h>
#include <stdlib.h>

#define FPS        60

#define ID_TIMER   101


/* screensaver main processing */
LRESULT WINAPI ScreenSaverProc(HWND hWnd, UINT msg,
                               WPARAM wParam, LPARAM lParam)
{
  static HBITMAP hBitmap;
  static HBITMAP hBitmap_mask;
  static HBITMAP hBitmap_bg;
  static HBITMAP hBitmap_preview;
  static HBITMAP offScrnBitmap;

  static int wdw_w, wdw_h;
  static int imgw, imgh;
  static int bgw, bgh;
  static int pvw, pvh;
  static float x, y, dx, dy, bgx, bgy;
  int bx, by;

  switch (msg)
    {
    case WM_CREATE:
      /* initialize */

      // get window size
      {
        RECT rc;

        GetClientRect(hWnd, &rc);
        wdw_w = rc.right - rc.left;
        wdw_h = rc.bottom - rc.top;
      }

      // create off-screen bitmap
      {
        HDC hdc;

        hdc = GetDC(hWnd);
        offScrnBitmap = CreateCompatibleBitmap(hdc, wdw_w, wdw_h);
        ReleaseDC(hWnd, hdc);
      }

      // load bitmaps
      hBitmap = LoadBitmap(((LPCREATESTRUCT)lParam)->hInstance, TEXT("IDI_BALL"));
      hBitmap_mask = LoadBitmap(((LPCREATESTRUCT)lParam)->hInstance, TEXT("IDI_BALL_MSK"));
      hBitmap_bg = LoadBitmap(((LPCREATESTRUCT)lParam)->hInstance, TEXT("IDI_BG"));
      hBitmap_preview = LoadBitmap(((LPCREATESTRUCT)lParam)->hInstance, TEXT("IDI_PREVIEW"));

      // get images size
      {
        BITMAP bp;

        // get ball image size
        GetObject(hBitmap, sizeof(BITMAP), &bp);
        imgw = bp.bmWidth;
        imgh = bp.bmHeight;

        // get bg image size
        GetObject(hBitmap_bg, sizeof(BITMAP), &bp);
        bgw = bp.bmWidth;
        bgh = bp.bmHeight;

        // get preview image size
        GetObject(hBitmap_preview, sizeof(BITMAP), &bp);
        pvw = bp.bmWidth;
        pvh = bp.bmHeight;
      }

      // init work
      x = wdw_w / 2;
      y = wdw_h / 2;
      dx = (float)wdw_w / (float)FPS;
      dy = dx * 0.5;
      bgx = 0;
      bgy = 0;

      // create timer
      SetTimer(hWnd, ID_TIMER, (int)(1000 / FPS), NULL);
      break;

    case WM_TIMER:
      /* main loop */

      // update ball position
      x += dx;
      y += dy;

      if (x <= 0 || x + imgw >= wdw_w) dx *= -1;

      if (y <= 0 || y + imgh >= wdw_h) dy *= -1;

      // update bg position
      bgx -= 2;
      bgy -= 2;

      if (bgx <= -bgw) bgx += bgw;

      if (bgy <= -bgh) bgy += bgh;

      // draw bitmap

      if (wdw_w >= 160)
        {
          // draw fullscreen

          HDC hdc, hBmpDC, hMemDC;

          hdc = GetDC(hWnd);

          // set off-screen bitmap
          hMemDC = CreateCompatibleDC(hdc);
          SelectObject(hMemDC, offScrnBitmap);

          // draw bg to off-screen
          hBmpDC = CreateCompatibleDC(hdc);
          SelectObject(hBmpDC, hBitmap_bg);
          {
            int by = bgy;

            while (by <= wdw_h)
              {
                int bx = bgx;

                while (bx <= wdw_w)
                  {
                    BitBlt(hMemDC, bx, by, bgw, bgh, hBmpDC, 0, 0, SRCCOPY);
                    bx += bgw;
                  }

                by += bgh;
              }
          }
          DeleteDC(hBmpDC);

          // draw ball mask to off-screen
          hBmpDC = CreateCompatibleDC(hdc);
          SelectObject(hBmpDC, hBitmap_mask);
          BitBlt(hMemDC, (int)x, (int)y, imgw, imgh, hBmpDC, 0, 0, SRCAND);
          DeleteDC(hBmpDC);

          // draw ball source to off-screen
          hBmpDC = CreateCompatibleDC(hdc);
          SelectObject(hBmpDC, hBitmap);
          BitBlt(hMemDC, (int)x, (int)y, imgw, imgh, hBmpDC, 0, 0, SRCPAINT);
          DeleteDC(hBmpDC);

          // drawing to off-screen is finished

          // draw off-screen bitmap to window
          BitBlt(hdc, 0, 0, wdw_w, wdw_h, hMemDC, 0, 0, SRCCOPY);

          DeleteDC(hMemDC);      // Create*() -> DeleteDC()
          ReleaseDC(hWnd, hdc);  // GetDC() -> ReleaseDC()
        }
      else
        {
          // draw preview
          HDC hdc, hBmpDC;
          hdc = GetDC(hWnd);
          hBmpDC = CreateCompatibleDC(hdc);
          SelectObject(hBmpDC, hBitmap_preview);
          BitBlt(hdc, 0, 0, pvw, pvh, hBmpDC, 0, 0, SRCCOPY);
          DeleteDC(hBmpDC);      // Create*() -> DeleteDC()
          ReleaseDC(hWnd, hdc);  // GetDC() -> ReleaseDC()
        }

      break;

    case WM_DESTROY:
      KillTimer(hWnd, ID_TIMER);  // kill timer

      // delete bitmap
      DeleteObject(offScrnBitmap);
      DeleteObject(hBitmap);
      DeleteObject(hBitmap_mask);
      DeleteObject(hBitmap_bg);
      DeleteObject(hBitmap_preview);

      PostQuitMessage(0);
      break;

    default:
      break;
    }

  return DefScreenSaverProc(hWnd, msg, wParam, lParam);
}

/* Processing of dialog boxes for configuration */
BOOL WINAPI ScreenSaverConfigureDialog(HWND hDlg, UINT msg,
                                       WPARAM wParam, LPARAM lParam)
{
  switch (msg)
    {
    case WM_INITDIALOG:
      MessageBox(
        hDlg,
        _T("This screen saver has no configuration options."),
        _T("Sample Screensaver by using MinGW"),
        MB_OK | MB_ICONWARNING);
      EndDialog(hDlg, IDOK);
      return TRUE;

    case WM_COMMAND:
      switch (LOWORD(wParam))
        {
        case IDOK:
          EndDialog(hDlg, IDOK);
          return TRUE;

        case IDCANCEL:
          EndDialog(hDlg, IDCANCEL);
          return TRUE;
        }

      return FALSE;
    }

  return FALSE;
}

/* Register non-standard window classes required by dialog boxes for configuration */
BOOL WINAPI RegisterDialogClasses(HANDLE hInst)
{
  return TRUE;
}

Makefile。 :

Makefile は以下。

_Makefile
mgscrsv2.scr: mgscrsv2.o resource.o
        gcc mgscrsv2.o resource.o -o mgscrsv2.scr -mwindows -lscrnsave

mgscrsv2.o: mgscrsv2.c
        gcc -c mgscrsv2.c

resource.o: resource.rc resource.h ball.bmp ball_mask.bmp bg2.bmp scrsav_preview.bmp
        windres resource.rc -o resource.o

.PHONY: clean
clean:
        rm -f *.scr
        rm -f *.o
  • Windows用プログラムなので、-mwindows を渡している。
  • スクリーンセーバを作るので、-lscrnsave を渡して「libscrnsave.a (or libscrnsavw.a) をリンクせよ」と指定している。

コンパイル/ビルド。 :

全部で以下のファイルになる。
  • ball.bmp
  • ball_mask.bmp
  • bg2.bmp
  • Makefile
  • mgscrsv2.c
  • resource.h
  • resource.rc
  • scrsav_preview.bmp
これらを、同じディレクトリに置いて make と打てば、コンパイル/ビルドされて mgscrsv2.scr が生成される。

ちなみに、make clean と打てば、*.o や *.scr を削除できる。

動作確認。 :

エクスプローラ等で mgscrsv2.scr を右クリック。
  • 「Test」を選べば、フルスクリーン表示時の動作確認ができる。
  • 「構成」を選べば、スクリーンセーバの設定画面で「設定」をクリックした時の動作を確認できる。

正しく動作しているようなら、スクリーンセーバを本来置くべき場所に .scr をコピーして、スクリーンセーバとして動作するのか確認する。

  • Windows が 64bit版、スクリーンセーバが32bit版なら、C:\Windows\SysWOW64\ に .scr をコピー。
  • Windows が 64bit版、スクリーンセーバが64bit版なら、C:\Windows\System32\ に .scr をコピー。
  • Windows が 32bit版なら、C:\Windows\System32\ 以下に .scr をコピー。

今回は MinGW を使ってビルドしたので、生成された .scr は32bit版プログラム。

Windows10 64bit + 32bit版プログラムなので ―― C:\Windows\SysWOW64\ に .scr をコピーして動作確認することになる。

試してみたところ、スクリーンセーバとして、それらしく動いてくれた。

ちなみに、作業に使ったメインPCとは別のPC(Windows10 x64 21H2)にコピーして動作確認したけれど、そちらでもちゃんと動いてくれた。

覚書。 :

Windows用のプログラムをC/C++で書く場合、まずはメイン関数が必要になる。

  • コンソールプログラム(DOS窓上で使う感じのプログラム)なら、main() という名前の関数が必要。
  • GUIアプリなら、WinMain() という名前の関数が必要。

GUIアプリの場合、えてして他にも、WndProc() とか WindowProc() という名前の関数も書くことになるらしい。これはウィンドウプロシージャと呼ばれる関数で、Windowsから送られてきたメッセージを処理する関数なのだとか。

そして、スクリーンセーバはGUIアプリに分類される。だから本来は、WinMain() という関数を書かなきゃいけない。

ところが、前述のスクリーンセーバのサンプルソースを眺めても、WinMain関数なんて書いてない。…どうなってるの?

なんでも、「スクリーンセーバの処理って大体似た感じになるよね」「WinMain() や WndProc() ってフツーは同じ処理を書くよね」ということで、そのあたりは scrnsave.lib (または scrnsavw.lib。MinGW の場合は libscrnsave.a or libscrnsavw.a) の中に既に入っているらしい。そして、「そこから呼び出される3つの関数だけ書けばスクリーンセーバを作れますよ」ということになっている模様。

そんなわけで、scrnsave.h と scrnsav*.lib (libscrnsav*.a) を使う場合は、以下の3つの関数の中身だけ書けばスクリーンセーバが作れてしまう。
  • ScreenSaverProc()
  • ScreenSaverConfigureDialog()
  • RegisterDialogClasses()

とは言え、GDI / GDI+ / DirectX / OpenGL等々を使わないと画面の描画はできないので、そのあたりの知識が必要になってしまうあたり、まだハードルが高い感じはする…。もっと簡単に作れるようにできないものか…。

余談。プレビューモードのウインドウサイズ。 :

今回書いたサンプルでは、プレビューモード(スクリーンセーバ設定画面の小窓に描画する処理)をどのように処理するかで悩んでしまった。

これがもし、座標を指定して線を描画する系のスクリーンセーバなら、フルスクリーン表示だろうと、プレビューモードだろうと、ウインドウサイズに合わせて座標値を計算して描画すればいいだけだから対応するのは難しくなさそうだけど…。

しかし、bitmap画像を描画する場合、bitmapは等倍で描画されて拡大縮小してくれないわけで…。フルスクリーン表示に合わせて座標値等を決めてしまうと、プレビューモード時は変な表示になってしまう。

一応、GDIにも、処理速度はさておいて拡大縮小描画する関数があるらしいので…。あらかじめ描画サイズを決めておいて、空のbitmapにアレコレ描いてから、それをディスプレイ一杯に拡大描画、もしくはプレビューモードの小さいウインドウに縮小描画すれば対応できるだろうけど…。

そのあたり面倒臭くなってしまったので、今回は、プレビューモード用のbitmap画像を一枚用意して、おそらくプレビューモードだろうと思われる時は、そのbitmap画像だけ描画してお茶濁しすることにした。

ちなみに、Windows10上で、スクリーンセーバ設定画面の小窓のサイズを測ってみたら、152 x 112 だった。巷のスクリーンショット等を調べた感じでは、Windows95 の頃からそのサイズだった模様。

そんなわけで、ウインドウサイズを取得して、もし横幅が160ドット以下なら「これはプレビューモードで呼び出されているのだろう」と判断して処理をするようにしてみた。こういうやり方が妥当なのかどうかは分からんけど…。

2021/09/06(月) [n年前の日記]

#1 [nitijyou] 自宅サーバ止めてました

雷が鳴ったので、06:45-08:50の間、自宅サーバ止めてました。申し訳ないです。

朝から雷ですよ…。なんだかな…。

#2 [povray] CityGenが生成したビルについて少し調べた

POV-Ray用の都市景観シーンを生成してくれる CityGen 1.5 について、どういうモデルデータを生成しているのか気になったので少し調べてみた。

とりあえず、道路の個数やビルの個数を少なめにして、各記述をコメントアウトしながら確認。

_one_povcity_test.pov

one_povcity_test_ss01.png

ビルの形。 :

まず、ビル1つあたりは、わずか3個の box で作られているようだなと…。
  • ビル本体を担当する box。
  • ビルの屋上部分を削り取るための box。
  • ビルの下に広がってる敷地部分を担当する box。

one_povcity_test_ss02.png

見た目の複雑さはテクスチャでどうにかしているらしい。

L型のビルもあったけど、これは2つの箱を重ねてL型にしていた。

one_povcity_test_ss06.png

one_povcity_test_ss07.png

one_povcity_test_ss08.png

テクスチャの重ね方。 :

テクスチャは3枚ほど重ねてある模様。

1枚目のテクスチャは下地を ―― 窓ガラス部分を担当。reflection を強めに指定して周囲を反射するようにしつつ、窓毎に明るさが変わるように、 _bozo とやらを指定して、ランダムなノイズを元にしながら明度の違いを出していた。

one_povcity_test_ss03.png

2枚目のテクスチャは、窓ガラスを含まないビルの壁面を担当。ただし縦方向の壁面のみ。

one_povcity_test_ss04.png

3枚目のテクスチャも、窓ガラスを含まないビルの壁面を担当。これは横方向の壁面のみ。

one_povcity_test_ss05.png

以上、3枚のテクスチャで、ビルの見た目を実現していたらしい。

上記は WinTxt5 というテクスチャだけど、WinTxt1 も同様に、3枚のテクスチャで構成されてた。

one_povcity_test_ss10.png

one_povcity_test_ss11.png

one_povcity_test_ss09.png

道路について。 :

道路は、3つのboxで構成されてた。
  • box1 : 道路全体。色は黒。
  • box2 : 白線部分。色は黄色。
  • box3 : 白線部分。色は黄色。
これをグリッド上に並べていく感じらしい。

交差点部分は調べてないけど、おそらく似たような感じじゃないのかなと…。

余談。pov内のコマンドラインオプション。 :

.pov を眺めていると、「// +W800 +H600」みたいな記述があって気になっていたのだけど。POV-Ray 3.6 のマニュアルページを眺めてたら謎が解けた。

_POV-Ray: Documentation: 3.5.10.9 Copy "..." to Command-Line

POV-Rayエディタで .pov を開いてから、該当行を右クリックすると、右クリックメニュー内に「Copy 〜 to Command-Line」という項目が出てきて、それを選ぶとツールバー上のコマンドラインオプション入力箇所にコピーされるらしい。それであちこちの .pov に記述があったのだな…。

ただ、POV-Ray 3.7 Windows版 + 自分で書いた .pov で試してみたけど、右クリックメニュー内に該当項目が出てくる時と出てこない時があって…。この機能の発動条件が分からない…。

でもまあ、該当行をコピーして、コマンドラインオプション入力箇所に貼り付けても事足りるので、動かないとめちゃくちゃ困るというわけでもないかなと…。もちろん、ちゃんと動けば便利機能なんだろうけど。

2020/09/06() [n年前の日記]

#1 [nitijyou] 某ゲームを触ってる

せっかく買ったのだから使い方ぐらいは把握したいと某ゲームを触ってるところ。スタジオ機能の操作方法が今一つ分かってないというか…。

キャラメイクに入る際にやたらと待たされるのに閉口して、キャラカードの枚数を少なくしないとダメだなと、使いそうもないカードを別フォルダに移動させた。元々1,500枚ぐらい入ってたのを100枚前後まで減らしてみたら、目に見えて反応が早くなった。それでもまだ多いけど。キャラカードの格納フォルダ内にサブフォルダを作って管理できる系のmodを追加してどんどんサブフォルダに入れていったら、更に軽くなった。このあたり、キャラカードにしろ、シーンデータにしろ、ユーザが任意の設定を増やしていける系のゲームは、サブフォルダをサポートしたほうが良い、ということなのだろう…。

フレームレートが低くてこれはおかしい、以前はもうちょっと高かったはずとmodをオンオフして描画を遅くしてる犯人を捜したり。IBLを追加できる系のmodをオフにしたらかなり改善された。このmodは静止画キャプチャ改善用と思っておいたほうが良さそうだなと…。

2019/09/06(金) [n年前の日記]

#1 [ubuntu][gerbera] Gerberaの設定を見直し中

REGZA 37Z9000 から動画が見れるようにするために設定を見直し中。

色々作業し過ぎてグチャグチャになってきた。明日まとめてメモしよう…。

2018/09/06(木) [n年前の日記]

#1 [cg_tools] 無料で使えるドローソフトの日本語サポート状態を少しだけ確認

Windows上で、無料で使えるドローソフトについて、日本語テキストを入力できるかどうか気になり始めたので少し動作確認。

LibreOffice Draw :

_ホーム | LibreOffice - オフィススイートのルネサンス

lodraw_ss.png

フツーに日本語テキストを入力できた。

Inkscape :

_Draw Freely | Inkscape

inkscape_ss.png

フツーに日本語テキストを入力できた。

輪郭線(ストローク)と、面(フィル)の設定があるので、そこはちょっと注意かも。ストロークは無し、フィルは有りにすると、本来のフォントっぽい見た目になるような気がする。

Gravit Designer :

_Gravit Designer

gravit_designer_ss.png

フォントとして System Fonts を選択して、PC内にインストールされてる日本語フォントを選べば、日本語テキストを入力・表示することができた。

Microsoft Expression Design 4 :

_Download Microsoft Expression Design 4 (Free Version) from Official Microsoft Download Center

_無料で使えるMicrosoftの画像加工ツール - Microsoft Expression Design4のレビュー | ジグソー | レビューメディア

ms_expression_design4_ss.png

開発停止して無料で使える状態になったソフトだけれど、コレもフツーに日本語テキストを入力できた。

ただ、テキストボックス・テキスト枠相当の機能が見当たらなくて、つまりはテキストの自動折り返しが使えない気配が…。1行が長いテキストを打ち込むと、面倒なことになりそう。

sk1 2.0RC3 win64 Portable :

_sK1 2.0 Download Page

sk1_2_0rc3_x64_portable_ss.png

コレも日本語テキストを入力できた。

ただ、テキストボックス・テキスト枠相当が無さそうな気配。

それと、テキスト関係のツールを使おうとすると、最初に結構待たされる。おそらくPC内にインストール済みのフォントを全て検索してリストアップする処理が入るのではないかと。フォントキャッシュを残す設定もあるようだけど、どこにキャッシュが作られるのか、ちと不安。フォントキャッシュを作る Inkscape と競合しそう。

Zoner Draw 5 FREE :

zoner_draw5free_ss.png

これは文字化けしてしまった。英語圏のソフトだし、かなり古いソフトだから公式サイトでもどこから入手できるのかちょっと分からない状態なので、まあ仕方ないのだろう…。

入手方法は、以下でメモしてあった。

_mieki256's diary - Zoner Draw 5 FREEを試用

読み返したら、日本語テキストは入力できないよ、と自分でメモしてあった…。忘れてた…。

Serif DrawPlus Starter Edition :

serif_drawplus_starter_ss.png

色々な部分で機能制限されている版だけど、フツーに日本語テキストを入力できた。

ただ、Serif社は、DrawPlus を Affinity Designer という製品に置き換えたので、もうこのソフトは入手できない…。ググっても、ウイルス入りファイルを公開してる怪しいサイトばかり出てくる…。それに、動作させるためには、Serif社のサイトから申し込んで、メールでシリアル番号を入手しないといけなかったので、その仕組みが無くなった現在、セットアップ用のファイルだけ入手できても使えないという…。

2017/09/06(水) [n年前の日記]

#1 [raspberrypi] Raspberry Pi Zero Wが気になる

Raspberry Pi Zero W がなんだか気になる。どの程度の速度がでるのか、みたいなあたりが。

今現在手元にある Raspberry Pi3 は、CPUが4コア + 1.2GHzだけど、Zero W はCPUが1コア + 1.0GHz なので、確実に遅いはずだけど、話にならないぐらい遅いのか、なんとなくちょっと遅いのか、実際はどんな感じなんだろうと。

それと、Pi3 で使えるBluetoothキーボードについて調べてたら、値段的に Zero W 買えちゃうよな、てな気分もなってきて。一々ワイヤレスキーボードの子機を繋ぐのが面倒だから Bluetooth キーボードを、という考えだったけど、もう一台 Raspberry Piがあれば、ソイツに子機をずっと刺したままそこらへんに置いといて実験できるだろうし。

いっそ、Zero W を買ってしまうか…。

と思ってググり始めたけど、そもそも日本じゃ単品で販売してない模様。どの通販サイトを眺めても、ケースや変換コネクタをセットにした状態でしか売ってない。

それでもまだ、好みの構成で売ってるならなんとかなりそうだけど、個人的には今一つなセット構成で。ケースが気に入らなかったり、電源アダプタは不要なのに同梱されてたり、microSDHC は16GBぐらい欲しいのに8GBだったり。コレだ、てな感じのセットが存在しない。

結局アレコレ揃えていくと、全部で5,000円ぐらいになってしまうあたりも…。どうしたもんか。

2016/09/06(火) [n年前の日記]

#1 [nitijyou] 自宅サーバ止めてました

雷が鳴ったので、18:00-20:00の間、自宅サーバを止めてました。申し訳ないです。

#2 [pc] Windows10にREGZAからアクセス

親父さんからの要望が。Windows10が動いてる親父さんPC、の中に入ってる画像ファイルを、茶の間に置いてある液晶TV、REGZA Z9000 から閲覧したいという話で。

方法をググってみたら、Windows10にインストールされている Windows Media Player 12 で設定をすればREGZAからも見れるらしくて。
  1. Windows Media Player 12 を起動。Cortanaに「media」と打ち込めばリストアップされるので、クリックすれば起動する。
  2. ストリーム → プレーヤーのリモート制御を許可、と、デバイスでのメディア再生を自動的に許可、にチェックを入れる。何を配信するか選べた…ような気がする。
  3. REGZA側で、リモコンのレグザリンクボタンを押す。画像を見る → LAN-S上の機器を選ぶ → 画像フォルダを選ぶ。
これで一応画像のサムネイルが表示されて、カーソルキーで選んで決定ボタンを押せば画像が表示された。

ただ、動画については再生されなくて。Windows10 + Windows Media Player 12 って、トランスコードして配信してくれないのかな…。

#3 [anime][neta] TVアニメの本編を短くできないものか

バカ妄想を、なんとなくメモ。思考メモというか妄想メモ。

先日、某アニメを見ていたら、さすがにちょっと擁護できないぐらいに作画崩壊状態になっていて。まあ、ヤシガニまでは行ってなかったけど…。

見ているうちに、これはもうさすがに限界じゃないのかと思えてきて。やっぱり今のアニメ業界は本数が多過ぎるんじゃないか。だけどアニメ業界って状況を改善していこうという意思が全然見えないよなと。おそらく現場だけが延々と地獄を見てるのだろう。こんな状況をいつまで続けるつもりなんだ。上の連中は何をやってるんだ。いい加減にしろ。みたいなところまで、自分の中で、何かがボワッと…。

てなわけで、何か手はないものかともやもや考え始めてしまったり。まあ、どうせどれもこれも素人考えのくだらない妄想ばかりで実行は無理に決まってますけど。

本編の尺を短くするアレコレ。 :

とりあえず、本編の尺を短くできれば本編スタッフの負荷が多少は減ってくれるのではないかと安易に想像したりもするわけで。でも、どうやって短くしたらいいのか…。

一つ。30分TVアニメのOP・EDは、それぞれ1分半ぐらいの長さがフツーだけど。ちと短過ぎないかと。それぞれ3分ぐらいあってもいいんじゃないかと。製作委員会に入ってることが多いのであろうレコード会社としては、曲を売りたくて売りたくて仕方ないはずで、だったらココはたっぷり時間をとって毎週しっかりと曲を宣伝してやるべきだろうと。OPで3分、EDで3分、合わせて6分ぐらいは確保しないとレコード会社さんに申し訳ないよねと。それに、どうやらOP・EDの映像制作は本編スタッフ以外の別動隊にお願いしちゃう場面も多くなってるとも聞くので、本編制作と並列して作業が進められて本編スタッフの負荷が少しは減ることを期待できないかと。

一つ。最近のアニメは複雑な設定が多いので、本編を見てるだけでは視聴者が設定を正しく理解できてるのか怪しいところがあるなと。なので、本編が終わったら「○○講座」を設けて設定の復習、あるいは予習ができるようにしたほうが望ましいのではあるまいかと。要するに「ワールドトリガー」や「トップをねらえ!」でやってたソレですけど。そしておそらく映像面はFLASHアニメレベルで十分だろうから、ここも別動隊にお任せできるよなと。

一つ。次回予告はえてして数秒しか流さないものだけど、どうせならちょっとした寸劇を入れてお客さんを楽しませるのもアリだよなと。要は、ufotableが作ってる「テイルズ オブ ゼスティリア ザ クロス」のソレですけど。本編では見られない、各キャラの意外な一面を目にすることができて、視聴者にとってはお得感が増すはず。時間にして1〜2分ぐらいあればイイ感じ。これも映像面はFLASHアニメレベルで十分だろうから、別動隊にお任せできるはず。

一つ。最近はアニメの本数が多くなってるので、いざ視聴を始めても「コレ何のアニメだっけ?」「先週どんな話だったっけ?」と視聴者が混乱する場面がよくあるわけで。いやコレホント。twitterの実況を眺めてると結構そういうつぶやきを見かけるし。しかしそんな時、冒頭であらすじが放送されれば「ああ、そうだったそうだった」と思い出せてスムーズに本編視聴へと移行できるわけで。要は「ラブライブ」のソレですけど。本数がそれほど多くなかった大昔ならいざ知らず、現在の、この異常な本数では、あらすじを入れる工夫はもはや必須と思えたり。時間にして…15秒? 30秒? 何にせよ少しは入れておかないと。もちろん、前回放送した映像を使い回せるはず。

ということで、OP・EDで3分、講座コーナーで1分、予告の寸劇で1分、あらすじで30秒、合計5分30秒は本編の尺を削り取れるよなと。今まで本編が20分だったら、15分ぐらいに短くなる。カット数はどのくらい減るだろうか。本編スタッフさんも少しは楽にならないだろうか。

「そんなあからさまなことをしてまで楽になりたくない」「そんなことしたら叩かれる」と言い出す人が居そうな気もするけど、だったらカット数だけほんのちょっと減らすことを前提にして、しかし本編15分の中にギュウギュウに内容を詰め込んで本編の密度を濃くすればいいだろうと。楽をするために本編を短くするんじゃないぞ、密度を高めるために本編を短くするのだ、そのように捉えればよいではないかと。

ていうか自分、録画したアニメを見るときは、えてして早見再生しないとかったるくて見てられないという…。 *1 最初から本編の時間が短くなってたほうがむしろ嬉しいよな、などと思ったりもして。

そもそも30分も見たくない、てなところも。 :

あらゆるメディアがユーザの自由時間を奪い合ってる現在、そもそも30分TVアニメって長過ぎるだろと思ったりもするわけで。毎週30分も要らないよ。15分アニメでいいよ。いや、10分アニメでOKだよ。

例えばスマホゲームなどは、ゲームをプレイする人達が電車に乗って目的の駅に着くまで最短で10分ぐらいかなーと予想して、10分で一区切りつくように作ってたりする、とも聞くわけで。だったらアニメもそのくらいの長さにしといたほうがいいのではないか。本編を20分も作らなくていいッス。10分未満でいいッス。電車に乗ってスマホで視聴して「ああ、今週分も面白かったー」と満足しながら学校や会社に向かう、ぐらいの長さでいいんじゃないかと。

もっともTV局としては、30分単位で放送スケジュール考えてるんだから30分でアニメを作れ、と言ってきたりするのですかね…。だったら、Aパートはアニメ本編、Bパートはアニメに絡んだバラエティコーナーでいいんじゃないか。要は「進撃中学校」「ミルキィホームズ」のソレですけど。

例えばラノベ原作アニメなら、出版社は原作ラノベを売りたいはずで。なら、Bパートのバラエティコーナー内で、原作者や担当編集連れてきて毎回原作本の宣伝をすればいいじゃないかと。原作者の過去作品もついでに紹介して宣伝してみてもいい。原作本の挿絵を描いてくれてるイラストレーターさんの制作風景を、毎週数分ほど流すのもいいかもしれない。NHKの「漫勉」が成立するんだから、イラスト制作風景だって視聴者にはお得な映像、かもしれないし。

レコード会社は、所属ミュージシャンを視聴者に売り込んでいきたいはず。であれば、バラエティコーナー内で毎週ライブ映像でも見せたらいいじゃないかと。せっかくタイアップしてるのだから、ミュージシャンが出してるCDについて、毎週1曲ずつ宣伝して露出を増やせばよろしい。

製作委員会の中で宣伝しておきたいアレコレってきっとたくさんあるだろうから、Bパートでガンガン宣伝すればいいだろうと。そうなればアニメ本編はAパート分だけ作れば済む。本編スタッフが楽になるのではあるまいかと。

「アニメ番組なのに半分がバラエティなんて…」と眉をしかめる人が居そうだけど。TV番組というものは、視聴者を楽しませれば番組として成立するわけで。その楽しませる何かが、必ず絶対にアニメでなければならないと法律で決まってるわけでもないでしょう。本来、何を見せてもいいはずで。TVの前のお客さんが楽しんで見てくれるなら、なんでもええやん。「30分アニメ作らなきゃ」と真っ青な顔して思い込む必要なんて無い。毎週作れそうな長さだけ作ればいい。残りはアニメじゃない何かで埋めればいい。埋めた何かが十分面白ければ、それはそれで許されちゃう。はず。

とにかく、いつまでこんなこと続けてるんだと、一視聴者の立場で見ても心配しちゃうわけで。アニメーターさんが過労死したり、制作進行さんが自殺したり、そうまでして作るもんでもないだろうと。本数を減らせればいいのだろうけど、減らせないならあの手この手で尺を短くする、ぐらいのことをしてもいいんじゃないか。などと思ってしまったりするわけで。

まあ、個人的には、手描きのTVアニメの大半が3DCGアニメに移行すればいいのになと願ってたりもするんですけど。ラノベ原作アニメなんて、どうせ出版社側は「作品」「商品」じゃなくてCM映像ぐらいにしか考えてないのだから、そんな連中のために業界内で何年もかけて育ててきた貴重な手描きアニメーターさんを割いてしまって疲弊させてモチベを無くす状態に追い込まなくていいよと。見た目が不自然だろうと、動きがおかしかろうと、TVに映ってりゃそれでいいんだからCGアニメで十分。ていうか今時のCGアニメはレベルがめっちゃ上がっててさほど不自然じゃないし。「アルペジオ」「シドニア」「ローニャ」「亜人」なんか拝みたくなるぐらいのクオリティだったし。

てな感じのくだらないことをもやもや考えてしまったのでメモ。思考メモというか妄想メモ。

*1: まあ、標準速で見ないと話が分からないぐらいに隙が無くギッチリ作ってあるアニメと、早見再生で見ても十分わかるぐらいに無駄にダラダラしたアニメに分かれるというか…。

2015/09/06() [n年前の日記]

#1 [dxruby] DXRubyを1.4.2に更新

DXRuby 1.4.2が公開されたらしいので、Windows7 x64 + Ruby 2.0.0 上で試しに更新してみたり。手元で書いてるソレは問題なく動いてくれた。ありがたや。

DXRuby 1.4.2は、Ruby 1.9.x はサポート対象外にしたようで。以前作者様が書いてたイージングのソレも Ruby 1.9.x では動かなかったし、そもそも Rubyコミュニティも Ruby 1.9.x は非サポートにしているので、流れとしては妥当、なのかなと…。

ついでに、Ruby 2.1.7、Ruby 2.2.3 も _RubyInstaller for Windows からDLしてインストール。そちらにも DXRuby をインストールしておいた。とメモ。

#2 [ruby] Ruby 2.1.7でNokogiriがインストールできない

Windows7 x64 + Ruby 2.1.7 p400 で gem install nokogiri をしたらエラーが。

_Windows で Nokogiri のビルドエラー解決法 再び|Ruby と iPhone と UI と で解決策が書いてあった。gem? を更新すればインストールできるようになるらしい。
gem update --system
gem install mini_portile
gem install nokogiri
gem -v で、バージョン確認ができる。2.2.5 から、2.4.8 になった。

しかし今度は、pry がインストールできない。gem install pry pry-doc をするとエラーが出てしまう。

_pryをWindows8-64bitに入れる - kenmituoの日記 によると、gem のバージョンを 2.4.4 まで落とさないとエラーが出るらしい。
gem update --system 2.4.4
gem install pry pry-doc
これならインストールできた。

Ruby 2.2.3 p173 でも試してみた。 :

gem のバージョンは以下。
  • Ruby 2.1.7 p400 ... gem 2.2.5
  • Ruby 2.2.3 p173 ... gem 2.4.5.1

Ruby 2.2.3 p173 + gem 2.4.5.1 では、Nokogiri は gem install nokogiri で、スンナリとインストールできた。

しかし pry と pry-doc はインストールできない。gem update --system 2.4.4 をして gemのバージョンを落としてから gem install pry pry-doc をしたらインストールできた。

しかし、ここで gem のバージョンを元に戻そうとして gem update --system 2.4.5.1 と打ってみても、
> gem update --system 2.4.5.1

Updating rubygems-update
ERROR:  Error installing rubygems-update:
        Unable to resolve dependency: user requested 'rubygems-update (= 2.4.5.1)'
ERROR:  While executing gem ... (NoMethodError)
    undefined method `version' for nil:NilClass
元に戻せなくなった…。うーん。

Ruby って、こういうところがアレだなと…。

#3 [cg_tools][dxruby] Spineというスプライトエディタが気になる

Spineという有償のスプライトエディタがあるらしいのだけど。

_Spine: ゲーム用 2D アニメーション ソフトウェア

_Spine: 2D animation for games - YouTube の、1:24あたりからの映像を見て、非常に気になってきたり。静止画のはずなのに、どうしてこんな風に動かせるのか…。「GOD EATER」アニメ版も、一々原動画描いて手塗りしなくてもこういうのを使えばいいんじゃないのか。いや、アレも既にこういうの使ってやってるのかもしれないけど。

この手のスプライトエディタ、というか多関節スプライトエディタは、えてしてパーツ画像一枚に対してポリゴン一枚を割り当てて、そのポリゴンを回転拡大縮小、あるいは矩形ポリゴンの4頂点を自由に移動できますよ、てなタイプがほとんどで。そのせいで、動きが硬いというか、いかにも「ああ、切り絵アニメっぽいですねえ」てな見た目になるわけで。

しかし Spine は、動画を見る限り、パーツ画像一枚を複数のポリゴンで分割してるあたりがゴイスっぽいなと。パーツ画像内に位置する頂点を移動させれば、パーツ画像内のピクセル情報を色んな方向に移動・変形できる。結果、丸みを帯びた動きを見せたりできるから、動きが立体的に見える、てなことなのだろうと。

で、どうやら Professional版じゃないとその機能は使えないようで、となると、お値段が 35,000円ぐらいになるらしい。

こういうのって After Effects のパペットツールとやらでも可能なのだろうけど。…やっぱり有償ソフトじゃないと無理なのかな。

2014/09/06() [n年前の日記]

#1 [anime] 特撮関係の記事を眺めてたり

「巨神兵東京に〜」のメイキングその他が気になったのでググってるうちに何故かレッドマン、ゴッドマン、グリーンマンの記事に辿り着いてそっちを調べて始めてしまったりとかそんな感じで。

レッドマン、ゴッドマン、グリーンマンは、TVで放映できるレベルではないはずのモノが堂々と放映されてしまったあたりに価値があるのだろうか。もしかすると「水曜どうでしょう」もソレに近いのかもしれないと思えてきたり。グダグダな内容・出来栄えでも、ある閾値を超えると娯楽コンテンツに成り得るのかも。

#2 [anime] 同時上映についてなんだか少し考え込んでしまった

「EVAQ」と「巨神兵東京に〜」が同時上映だったことに対して、不満を持った・怒ったお客さんが結構多かったらしいと今頃になって知ったのだけど。

考えてみたら、ナウシカやラピュタの上映時も、名探偵ホームズの宮崎駿担当回が同時上映されたわけで…。それと似たようなもんだと思うのだけど…。

昭和世代にとっては、監督が関わった別タイトル、しかも、見ることがなかなか難しい作品を同時上映してくれるなんて、単純に嬉しい話だったけど。現代においては、そういうことをすると、嫌がられたり怒られたりしてしまうのだなと…。時代は変わってしまったのかもしれんなあ、と思えてきました。

巨神兵ってEVAの元ネタだから、それほど離れてるコンテンツではないと思うのだけど…。そういや、ナウシカとホームズも、設定レベルでは結構似てたっけ。メーヴェやガンシップの祖先はプテラノドンメカかもしれんよな。

でも、ナウシカはシリアス、ホームズはコメディだから…。ナウシカ+ホームズに比べたら、EVAQ+巨神兵なんて、シリアス+シリアスで、マシな組み合わせに思える。…いや、そこは逆なのかな。シリアス+コメディのほうが、スイッチを切り替えられるから、受け入れやすかったりして?

もしかすると、ビデオ、DVD、BD、ネットの普及も関係してるのかな。昔は映像機器が充実してなかったから、「○○を見たい」と思っても容易に見れなくて。故に、見れる機会があるならぜひとも見てみたい、何でもいいから見せてくれ、てな欲求が今より強くて、それで喜ばれたのかもしれないか。今は、ソレを見たいと思った時は自分で探して見ますわ、強制的に見せるなや、とにかく俺の『自由時間』を奪うな、みたいな感覚だったりするのかしらん。どうなんだろ。

でもまあ、EVAQを見に行ったら巨神兵まで見せられた、てのは、映画館で味わった体験の一つになるはずで。「EVAQと一緒に巨神兵も見せられたよな?」「そうそう! アレ、わけわからんかった!」と思い出話ができるわけで。話のネタにはなるから損はしてないはず、と思うのですけど。

それに、100人に一人、1000人に一人でも、「ミニチュア特撮も結構面白いな」と思う人が出てくれば、特撮の普及活動としては成功かもしれないし…。「なんでこんなもん見せられるんだよー」と、ほとんどの観客が文句を言ってる中で、たった一人、目をキラキラさせて見入ってしまってる少年のために、これを同時上映する意味はあるのだよ、みたいな。まあ、目をキラキラさせてるのは、おじさんばかりかもしれないけど。

#3 [anime] 名探偵ホームズのようなアニメって最近見かけない気がする

片渕須直脚本+宮崎駿コンテ・演出の、ホームズの数話分は、今見ても傑作だと思うのだけど。ああいうアニメって最近見てないような気がするなと。膨大な数のアニメが作られてるのに、そもそも企画自体が通りそうにないというか。誰にでも見せられるし、誰でもそこそこ楽しめる作品だと思うのだけど。

まあ、ああいったアニメは、ピクサーやディズニーが作ってくれそうか…。日本で作らない・作れないのはなんだか悲しいけど、市場が無いなら仕方ないよな…。

2013/09/06(金) [n年前の日記]

#1 [cg_tools] MakeHumanが起動しなくてちょっとハマった

人体モデルを生成できるCGソフト、MakeHuman。出力されたモデルデータはCC0扱いされるそうで、素体にする等もできそうな感じなので、試しに導入してみることに。

_Download Alpha 7 | Makehuman から、makehuman-1.0a7-win32.exe をDL・実行・インストール。Python 2.7 も入ってるらしい。

しかし、makehuman.exe を実行してみたところ、以下のようなエラーメッセージが表示されて起動しない。
Trying to load numpy
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "main.py", line 92, in <module>
    import mh2obj, mh2bvh, mh2mhx

(中略)

  File "C:\Python26\Lib\site-packages\numpy\core\__init__.py", line 5, in <module>
    import multiarray
ImportError: Module use of python26.dll conflicts with this version of Python.
Could not run main Python script
自分の環境は Python 2.6 をインストールしてあるから、そのせいかな…。GIMPその他が、Python 2.6 を要求してくるから、仕方なく入れてるのだけど…。

環境変数 PATH の中に Python 2.6 へのパスがあるからマズいのかなと思ったけど、そういうわけではなかったらしい。PYTHONPATH に Python 2.6 のソレが指定されてたことが問題だったようで。
set PYTHONPATH=
cd C:\hoge\fuga\MakeHUman
makehuman.exe
というバッチファイルを書いて実行したら起動してくれた。

PYTHONPATH って何に使ってるんだろう…。とにかく設定しとけとPythonの入門記事に書いてあったからとりあえず設定してる状態で…。

それはともかく、モデルさんみたいなモデルデータができるのかなと期待してたら…。何かこう、「うわぁ…」って感じのモデルデータが出来上がるようで、ちょっとビックリしたり。Poser1〜2 の頃を思い出す…。あの頃も、「どうすんだ、コレ…」って感じだったよなあ…。

アジア人寄りの顔に調整バーを動かしたら、なんだか落ち込んできた。外国人にとっては、アジア人ってこんな風に見えてるのか…。いや、たぶんこれが、平均的なアジア人らしい顔なんだろうけど。TVに映ってる芸能人等は、本来アジア人らしさから随分離れたところにあるモデリングなんだろうな。

Blenderで読み込めず。 :

.mhx で export すれば、Blender で import できるらしいのだけど。(Blender側の Add-on設定で、.mhx importer を有効にしておく必要有。)

makeHuman 1.0 alpha 7 で export した .mhx を、Blender 2.68.2 x64 で import しようとしても、よくわからんエラーが大量に出て、インポートできず。
  • io_import_scene_mhx.py を、MakeHuman インストールフォルダ\tools\ 以下からコピーしてきたり。
  • MakeHuman の Nightly Builds版を導入してみたり。
  • Blender 2.64 x64 で試してみたり。
色々やってみたけど、色んなエラーが出てきて何がなんだか。

結局、色々試して、以下の条件で import できた。
  • 公式版の Blender 2.64a x64 zip版を利用。今まで GraphicAll.org で入手した版を使ってた。
  • MakeHuman 1.0 alpha 7 版を利用。
  • MakeHuman に同梱されている io_import_scene_mhx.py を、Blender インストールフォルダ\2.64\scripts\addons\ にコピー。

MakeHuman の Nightly Builds 版について。 :

動かす際には注意が必要。1.0 alpha 7 をアンインストール、かつ、ホームフォルダ内の makehuman\ フォルダを消去してから Nightly Builds 版を起動しないと、変な動作をする。

ちなみに、Nightly Builds 版は、1.0 alpha 7 に比べると、描画・設定値の変更処理が爆速になってました。

2012/09/06(木) [n年前の日記]

#1 [python] Ulipadなるエディタを導入しようとしてハマる

_ulipad - python editor based on wxPython - Google Project Hosting

Pythonスクリプトを書く際に、PyScripter を使っていたのだけど。どうもエディタとしての機能が弱い気がして、もっとヨサゲなエディタはないものかと。 _PythonEditors - PythonInfo Wiki を眺めてるうちに、Pythonで書かれた Ulipad なるエディタが気になったので導入しようかと。

しかし、Windows7 x64 上でインストールしたものの、起動してもうんともすんとも言わない。ウインドウすら出てこない。zip版をDLしてコマンドラインから実行したところ、comtypes なるライブラリが見つからないというエラーが出る。Python と WxPython Unicode版をインストールしてあれば動くように見えたのだけどなあ…。

とりあえず、WxPython を、2.8.12.1 から 2.9.4.0 にしてみたり。しかし改善せず。

もしかすると、別途ライブラリがあるのかもと検索したら、 _comtypes 0.6.2 : Python Package Index というページに遭遇。しかし、インストーラをDL・実行したものの、今度はインストール時に Runtime エラーが発生。

勘だけど、どうも PyGTK all-in-one installer が怪しい気がする…。Windows上のGTK関係は、アンインストーラが環境変数pathを全削除したり等、怪しい動作をしていた時期もあるし。

試しに、 PyGtk (pygtk-all-in-one-2.24.2.win32-py2.7.msi)をアンインストールしてから、comtypes のインストーラを実行したところ、エラーが出ない。やっぱり PyGtk が怪しい…。でも、コレを入れておかないと、GIMP の Python-fu が動かないし…。ひとまず、色々インストールしてから、最後に PyGtk を再インストール。

それはともかく、comtypes をインストールしても、Ulipad は動作してくれず。

色々検索したら、 _Issue 206 というやり取りに遭遇。どうやら、Windows7 x64 上では動かないっぽい。いや、動くのかもしれないが、何かの条件を満たしている必要があるのかもしれず。

勢い余って他のエディタも試したり。 :

_Komodo Edit も試してみたり。以前、少し触ったような記憶もあるのだけど。…やっぱり、何かが違う。補完が弱いような。

eclipse 4.2 に PyDev をインストールしてみたり。…やっぱり、起動が遅いのがどうにも引っ掛かる。

Python に型宣言があれば、補完機能も活用できるのだろうけど。実行してみるまで何の型か分からないのでは、難しいのだろうな…。

PyDevって有償じゃなかったかな。 :

PyDev は無料だけど、PyDev Extension は有償だった記憶が…。たしか昔はそうだった記憶があるのだけど、今はどうなってるんだろう。

_PyDev Extensions がオープンソースになっていた | Livingdeadの日記 | スラッシュドット・ジャパン

そうだったのか…。

#2 [zatta] 職場と写真

夢の中で、あるシーンを見て、起きてから考え込んでしまった。自分が昔勤めていた職場って、職場内で写真を撮ったことが全く無かったなあ、と。

まあ、そういった写真から、未発表のプロジェクト内容や開発機材の情報が外部に流出する可能性もあるわけで、故にそういった行為は厳禁だったせいもあるだろうし。そもそも当時はデジカメもケータイも無かったから、職場に銀塩カメラを持ち込むという行為だけで怪しさ大爆発、貴様はどこのスパイだ!状態になるから仕方なかったのだろうけど。

でも、せめて、プロジェクトの開始時と終了時に、参加メンバーの記念写真を撮る、なんてイベントがあっても良かったのかもしれないなと。最初の頃は少人数だったのに、終わった時は人数が随分増えてた、みたいなことが、写真で見ればすぐに分かるわけで。そういった記録は、もしかすると、後で価値が生まれたのかもしれないと。

プロジェクトXの事例を思い出したり。 :

職場内の写真と言えば。昔、NHKで放映していたプロジェクトX ―― 企業内の新製品開発エピソードを紹介する番組では、たまに、当時の写真が画面に映ったりしていたような。

今になって考えると、よくまあ写真を撮っておいたものだなあと。多少の精神的余裕がそこにないと、そういうことはできないものだろうし。

スタジオジブリの事例をぼんやり考えたり。 :

宮崎駿監督や、アニメーター大塚康生氏なども、アニメ関連の雑誌や書籍に、東映動画時代の写真が載っていた、そんな記憶もあり。当時のアニメ業界には、まだ、スタジオ内で写真を撮る場面もあった…のかもしれないなと。

そのあたりの方々は、やがて、組合活動が原因で東映動画から追い出されて、日本アニメーションやテレコムに移籍していくわけだけど。ハイジのロケをしていた際の写真は目にした記憶があるものの、その後の写真を、自分は目にした記憶が無く。もしかすると、写真どころではない厳しい制作状態に追い込まれていったのだろうか…。

しかし、鈴木Pが関係を持ち始めるあたりから、また写真が増え始めた印象もあり。鈴木Pは、アニメ雑誌の編集長をしていたぐらいの方だから、写真と言う記録も、商品の素材になり得ることを十分熟知していたのだろうか。そう考えると、今現在のスタジオジブリの広報業務等は、おそらく鈴木Pの経歴があったからこそ、気付くことができた内容なのかもしれないなと思えてきたり。

そしておそらく、後世で、当時のアニメ業界を知ろうとした際は、スタジオジブリの残した多くの写真が、第一級の豊富な資料として使われるのは間違いないのだろうと。…他のスタジオは、写真なんか撮ってる余裕は無さそうだし。

ITベンチャー企業の事例も気にしてみたり。 :

昨今のITベンチャー企業などでも、このへん傾向がありそうな。職場内の写真をほとんど公開しない企業と、ガンガン公開する企業と、ハッキリ分かれている印象が。

職場の写真を公開する際、社員が疲労困憊・暗い顔をしている写真をアップロードしてしまう、そんな企業はないわけで。大体は、笑顔の社員、真剣に仕事に取り組む社員が撮影されている。また、社員の背景には、雑然とした職場の風景も映っていることも多々あるので、かなり現実感のある光景になる。そういう写真が何枚も並んでるわけだから…。企業イメージ向上には有効かもしれないなと。

となると、逆に、職場の写真をほとんど公開しない企業は…職場はどんな状態なのか…。まあ、うっすらと、なんとなく、そういうことなんだろうなと。

飛躍した結論。 :

職場内で撮った写真の枚数と、企業の成長ぶり・社員の幸福度・参加メンバーの仕事に対する充実感・社内の健康性は、比例関係にある。という仮説はどうか。

極端な話、職場内の写真が無い企業は十中八九ブラック。…これは暴論であってほしい。

2011/09/06(火) [n年前の日記]

#1 [comic][anime] うさぎドロップについてメモ

気が付いたことや、妄想をメモ。

うさドロアニメ版5話で感心したところ。 :

原作では、ダイキチが大人用包丁でジャガイモの切り方を実演していたのだけど、アニメ版は子供用包丁で実演していて。りんがこれから作業をするのだから、りんが使う包丁で実演したほうがいいだろう、とダイキチは瞬時に考えたのかもしれない、と読むことができるシーンになってる。ような気がして感心した。

ジャガイモの切り方一つであっても、りんのことを思いやって振舞うダイキチの姿。そう捉えるとなんだか胸が熱くなりませんか。…いや、そこまで意識して改変したわけじゃないのかもしれないけど。このほうが流れが自然だろうと思って変えただけかもしれないけど。結果的には、ダイキチのそういうソレが垣間見えるようなシーンになったので、良かったのではないかと。

うさぎドロップを宮崎駿が演出したらどうなるかと妄想。 :

なんとなく妄想。

りんの母親が「わからない」と言った次の瞬間、
  1. ダイキチの髪の毛が総毛立ち
  2. 大口を開けて何か喋ろうとするが、グッと言葉を飲み込んで
  3. 少しうつむき
  4. こぶしをギュッと握る
みたいなソレになるのかなと妄想。少なくとも髪の毛は絶対に逆立つ!…ような気がする。宮崎キャラは怒りを感じると大体そういう反応をする。…モノローグを使ってキャラの心情を説明しないなら、そういう見せ方を積極的にしていかないといかんような気がする。上のような見せ方をすることで、
  1. 「あ、ダイキチが怒ってる! 怒りゲージ、スゲー上がってる!」
  2. 「おお、堪えた。大人だな、ダイキチ」
  3. 「何か考え込み始めたぞ…」
  4. 「ん? 何か決意した?」
と見てる側に想像させる。みたいな。

でも、こんな見せ方をしていたら、脚本もコンテも作業時間がかかってしょうがない上に、尺が伸びていくような気がする。…それでジブリ作品は、いつもスケジュール的に大変だったり、制作中に尺がどんどん伸びていったりするのか。なるほど。なんだか納得。

一々モノローグで説明するより、髪の毛が逆立つほうが、尺は短くなるような気もする。一瞬で「あ、怒ってる」と伝わるし。それがどういう種類の怒りなのかは伝わらないので、複雑な気持ちを抱えながら怒ってる場合はモノローグを使ったほうが良いのかもしれないけど。

2010/09/06(月) [n年前の日記]

#1 [pc] e-TRENDからマイクが届いた

後になって気付いたのだけど、ちゃんと日曜日に発送を知らせるメールが送られていた。迷惑メールフォルダの中に入ってしまっていて気付かなかった…。今度から注意しないといかん…。>自分。

それはともかく購入したのは、 PC用コンデンサマイク SONY ECM-PC50。代引手数料や送料込みで、3,337円。

めちゃくちゃ小さい。付属のスタンドも小さい。早速IdeaPadに接続して使ってみたが、たしかにノイズが少ないように思えた。感度もヨサゲ。先日購入した、ELECOM MS-STM87SV とは雲泥の差。

とはいうものの。やっぱりノイズが載る場面もあって。もしかすると、IdeaPadのマイク端子がよろしくないのかもしれず。USB接続のオーディオインターフェイスを導入して、そこに接続すれば改善するのだろうか。だが、それもまた相性があるのだろうし…。

関係ないけどIdeaPadの電源を入れたらスピーカがプアーッと鳴り響いて焦った。 :

どうやら、マイクからの入力を、常時スピーカに出すように設定したままOSを終了したのがまずかったらしい。マイクを繋いでない状態だと、マイク端子に本体側のノイズが回り込んで妙な入力が入ってしまうのだけど。その状態でスピーカから、マイク端子から入ってくるノイズを再生→ますますマイク端子に妙なノイズが入る→スピーカから出る音が大きくなる、という状態、つまりはハウリングに近い現象が起きていたのではないかと想像する。今後気をつけないと…。

2009/09/06() [n年前の日記]

#1 [pc][ruby][markdown] _BlueFeather

BlueFeather は、拡張 Markdown 記法で書かれたテキストを html に変換するソフトウェアです。 コマンドラインツールと、Ruby スクリプト内で変換を行うためのライブラリがセットになっています。

BlueFeather より



試しにインストールしてみたり。

#2 [anime] ライダーディケイド最終回を鑑賞

終わってしまった…。いや、どう見ても終わってないけど!

お祭り企画という扱い、かつ、話数が若干少ないらしいとは言え、よくぞこんな企画をTVシリーズとして実現させたものだなと。その一点だけで自分はこの作品の存在を肯定したいのであります。や、面白い作品になったのかどうかは今一つ判断がつかないのですけど。こんな企画が実現したというそれだけでやっぱり凄い、みたいな。

にしても、劇場版で真の最終回って…。非常に複雑な気分。まあ、イデオンやバルディオス、あるいはEVAの例もあるからアレだけど。ただ、それら作品は、スタッフは一応ちゃんとTVシリーズ内でまとめるつもりだったのに諸々の事情で、という状況だったろうし。だからこそ、劇場版が出てきたときに視聴者も喜んだわけで。それに対し、最初からそういうやり方にする気満々で構成しちゃうのって、はたしてどうなんだろうなと。番組視聴を楽しみにしていた子供さんから、「どうしてTVで最終回見れないの?」と質問されたら、自分だったら困ってしまいそう。子供さんも納得する理論武装が思い浮かびません。いや、子供さんが見てるかどうかは知らんのですけど。

何はともあれ、スタッフの方々お疲れ様…って今までのように書けないのだな。これから劇場版を作らないといかんのだろうし。

#3 [anime] ライダーW、1話を鑑賞

田崎監督担当回。三条陸脚本。

ビルの周りを飛ぶヘリコプター。いきなりの「おやっさん」コール。ビル大爆発。…素晴らしい。ハッタリ?全開だなあ。

検索って…マトリックスかよ!とツッコんでもらうこと前提の映像だろうか。

今回の玩具はもしかしてUSBメモリを使ってるのだろうか。それとも形が似てるだけで中身は別物なのだろうか。気になったので検索。端子の形が全然違うのか。当然USBメモリではない、と。USBメモリと同じ端子だったら間違ってPC等にツッコまれて大変なことになるだろうし。玩具だから、あえて全く異なる端子形状にするのだな…。

#4 [anime] 「風が吹くとき」を鑑賞

昔からずっと気になっていたのだけど未見だったのです。先日NHK-BS2で放映されたのを録画してたので鑑賞。

なるほど…。今まで見てなかったことを今更ながら後悔。これは全世界の人間が、せめて一度は目にしておくべき映画かも、とすら思えたり。

まあ、見た結果、核を無くそうと考えるのか、核を持たないとこうなってしまうから持つべきだと考えるのか、そのへんは各人お好きなように、なんだけど。自分達下々の者には運が良くてもこういう展開が待ってるでしょうな、てなあたりを知った上で各自結論を出してくれ、と思うわけで。どこぞのハリウッド映画のように、核爆発をバックにキスシーン、なんてことは現実には出来ませんからね、みたいな。 *1
*1: あのシーンは、判っててやったのか、判らないからやったのか、未だに判らないです。いや、前者なのかなあ。バカの極致、的な画だし…。

2008/09/06() [n年前の日記]

#1 [iappli] ジングルとSEを差し替えたバイナリを送った

サウンドデータに関しては、これで仮で鳴らしてる音はなくなったはず。

#2 [pc] 妹がマウスの内部改造に手を染めた模様

自分も妹も、マウスのホイール問題 ―― 回転が重い・ホイールクリックがやりづらい ―― で悩んでるときが多くて。

以前、妹と、そのあたりの会話をしたときに、
自分「自分が使ってる Microsoft の IntelliMouse Optical は、まだ比較的ホイール回転が軽いほう。このぐらい軽い。」
妹「(試しにホイールを回してみながら)ほほう。こりゃたしかに軽い。これなら許容範囲かもしれぬ」
みたいな話になったのだけど。

しかし。自分の IntelliMouse Optical のサイドボタンが故障し、先日、代替品が届いた際に発覚したわけだけど。昔のロット(?)はともかくとして、今のロットはホイールの回転が「コリコリ」から「ゴキッゴキッ」に改悪されてしまい、Microsoft IntelliMouse Optical も、凡百の製品と同様、ホイール問題を抱えるクズ製品になり下がってしまった。

のだけど。その情報を伝える前に、妹が Microsoft IntelliMouse Optical を買ってきてしまった。あーしまった、早く伝えておけばよかった、と後悔したのが数日前の話。

妹曰く、買ってきたマウスのホイールもやっぱり「ゴキッゴキッ」で、到底常用したいと思えるものではないとのこと。最近のロットは本当にダメダメらしい。

そこで、保証は効かなくなるけれど、中を開けてホイール周りを削ると多少改善するという情報もある、ネット検索していてそういう話を見かけた、と妹に伝えたところ、どうせこの値段だし試してみるわい、との話に。

で、今日、妹から「改造してみた。めちゃくちゃ軽くなった」という報告が。触らせてもらったら、たしかにホイール回転が「カラカラ」になっていた。これは素晴らしい。

ここまで軽くなるなら、自分の個体もバラして改造したい。以前の個体(サイドボタン故障品)は、実はまだMSに送り返してないけど、代替品を改造することを前提にすれば、送り返しちゃっても良さそうかもしれん。いや、その代わり、改造すると5年保証は利かなくなるわけだけど。

どうせ保証が利かないなら、初期のロットを手離さず、自分でバラして修理したほうが幸せになれるのかもしれない。が、代替品が届いてしまった現状では、そういうわけにもいかないだろうし。現在のロットがこんな酷い状態になってると知ってたら、MSに連絡などするのではなかった…。

ラインナップを増やすのって難しいことなのだろうか。 :

ホイール回転の軽い版と、ゴキゴキ版を作って、別々の製品として売り出すわけにはいかんのだろうか。>MS。いや、いっそ、ボタンの重さもそれぞれ変えた商品を出して、「『マウスに体を合わせる』なんて馬鹿げてる!」「『体に合ったマウス』を選ぶ時代ですよ!」などと言って売り出したりしないものか。

個人的には、MS製マウスの、握る部分が斜めになってる製品が気になってるのだけど。チルトホイールだからホイール回転が重い上にホイールクリックがしづらいだろうし、ワイヤレスは電池が切れた時にイライラするから有線がいいし、と言った具合に、構成要素の一部が気に入らない。かようにマウスは、さまざまの要素が組み合わされて一つの製品になっている。人体に絶えず触れる製品でありながら、「1種類の組み合わせ」しか市場に出てこないのは、実に不自由というか、選択の幅があまりに狭すぎる。

形状、ホイール機構、有線無線、ボール・光学・レーザー、そういったものを組み合わせて選べる製品群が、どうして出てこないのだろう。いや、他社製品ならそういうラインナップを揃えてるところもあるのだけど。

組み立てるマウスが出てきてもいいのではないか。 :

PCには「PC自作」という趣味もあるのだから、マウスを自作、と称して組み立てる、そんな商品があってもいいではないか。工場でお姉さんが組み立てる前の部品群を、そのまま箱に詰めて売ってしまえばよろしい。プラモデルだのミニ四駆だのと似た感覚で自分だけのマウスに改造しやすいですよ、てな売り文句にでもして。説明書に、「ココを削るとホイールが軽くなる」等々の説明でもつけて。

2007/09/06(木) [n年前の日記]

#1 [nitijyou] 台風が近づいてる

時々急に激しい雨が。

あめあめ ふれふれ かあさんが :

ジャノメーンでお迎え嬉しいな。の「ジャノメ」って何だろうな。

_蛇の目 - Wikipedia
_「蛇の目」とは何でしょうか? - Yahoo!知恵袋

和傘の種類らしい。

2006/09/06(水) [n年前の日記]

#1 [nitijyou] 免許の更新に行ってきた

郡山免許センターまで。自転車で行こうかとも思ってたけど、雨が降りそうだったのと、親父さんが車で送ってくれるとの話で、お言葉に甘えて送ってもらった。

優良ドライバーなる区分になったらしい。怖くて運転してない = 事故を起こしてないだけなのに。この国は、変な国だ。 *1

更新時、2つほど失敗。 :

一つは、交通安全協会への入会時。冗談? 嫌味? で、受付の人に、「警察の天下り組織になってるという噂もありますねえ…」と口にしたら、「そんなこと絶対にありません!」と、こちらが恐怖を感じてしまうぐらいに物凄い表情で抗議されてしまった。…毎日毎日、ゲンナリするほど多くの人が来訪して、とにかく忙しい状態であろうに、そういうくだらんことを言われたんでは、そりゃ怒るわな。スイマセン。ていうか実務やってる人には関係ない階層での話だし。さておき。「他所の県ではそういう話もありますが、ウチの県は違います!」との返事に、「他所の県ではそうなのかよ!」と思わずツッコミを入れてしまいそうになったりして。

もう一つは、受付で返された免許証を、うっかりポケットの中に戻してしまったこと。視力検査のときに、「手元にない!」「もしかして受付で返されてない?」と勘違いしてパニックに。…受付に突撃する前に、係員の人に状況を話したら、「ポケットの中に入ってないですか?」「うっかり戻してしまう人がよく居る」と言われて。探してみたら見つかってホッとした。自分、頭の上にメガネを置いたままメガネを探す波平さんですか。…まあ、常に体から免許証を離さない癖がついてるのは、考えようによってはいいことなのかもしれん。と自分を慰めたり。

*1: もっとも、運転回数・運転時間等をどうやって測定するかを考えたら、事実に見合った分類など不可能だろうけど。

#2 [pc] 500円のCRTってどうなんだろ

免許更新の帰り、親父さんにお願いして、HARD OFF に寄ってもらった。中古CRTの値段を調べたいなと。

21インチほどのCRTは、商品棚に並んでた。大体3万円ぐらい。しかし、15・17インチのCRTは見当たらない。

15・17インチのCRTは、ジャンク品の棚に並んでた。「画面写りました」なるメモだけが張ってあって、値札には「525円」の記述が。

525円…。それってどういう状態なんだろう。画面がボケてるとか、色が変とか、そういった酷い状態だから、500円台なのだろうか。それとも、15・17インチCRTは、もはや買手がつかないから、投売り状態なだけなのか。しかし、4,900円という17インチCRTも置いてあって、首を捻る。525円のCRTと4,900円のCRT。何が違うのだろう。状態が違うのか。そもそもスペックが違うのか。さっぱり判らない。

店頭で動作確認でもさせてもらえればありがたいのだけど。たぶん、そういうお願いは拒否されるだろうしなぁ。…まあ、CRTは経年劣化するものだから、極力新品を買ったほうがいいわけだけど。

#3 [wiki] Hikiを設置してみたり

動作が高速、というのが売りらしいので、試しに設置。

たしかに、FreeStyleWikiよりはるかに速い。Pukiwiki と同程度の時間で画面が出てくる。かなりいい感じ。

設置した自宅サーバは、mod_ruby を導入してあるのだけど。その効果も期待できる、のであらうか。 *1
*1: Perl で書かれたツールの場合、自宅サーバ上で、mod_perl 非対応の hns を動かしてる関係で、mod_perl を導入できなかったりするわけで。…や、抜け道があるのかもしれないけど、そのへんさっぱり知らない。>自分。とりあえず、ウチのサーバは、ruby で書かれたツールのほうがまだ快適に動かせるのかもしれない。

この記事へのツッコミ

Re: Hikiを設置してみたり by otsune    2006/09/07 12:38
http://www.ku3g.org/negi/diary/?20040509#200405092
hnsをmod_perlで動かす方法は有ると言えば有ります。
「有ると言えば有ります」という書き方に何かを感じました by mieki256    2006/09/09 21:03
> hnsをmod_perlで動かす方法は有ると言えば有ります。

ありがとうございます。早速眺めてみました。

む、難しい…。
diff が書いてないというか、
変更場所のヒントは示してあるものの、
どう書き換えたかが書いてないので、
Perlの知識がある人が自力で修正すべし、という感じなのですな…。
自分にはハードル高過ぎな内容でありました。

mod_perl 非対応版と、対応版を、
一つのソース内で記述するのは難しいのかしら…。

2005/09/06(火) [n年前の日記]

#1 [pc] _マックメムテスター

「Mac専用メモリショップがフリーソフトとして公開してる」という情報を教えてもらったので検索。…たぶんコレかしら。なるほど、MacOS 8.x 〜 9.x 用らしい。

余談。妹が使うMacのメモリは増量済みらしい :

昨日、アップルメニューから辿ったところ、384MBだったとか。CGレタッチ作業をするのに128MBでは少なすぎると思ってたけど。さすがに増量してあったか…。

OS は、やっぱり8.6のままらしい。9.x だったら現行製品のタブレット購入で問題解決したのだろうけど。

#2 [zatta] _@nifty:デイリーポータルZ:でかいタバコの箱

煙草の箱が巨大になることで周囲のあらゆる物体が縮小するという逆転(?)の発想。 _(via たまにっき。)

#3 [vine][linux] 自宅サーバの mod_gzip を無効にしてみてレスポンスの変化を期待してみたり

自宅サーバについて「レスポンスが悪い」という話を聞いたので、試しに mod_gzip を無効に。/etc/httpd/conf/httpd.conf 中の、
mod_gzip_on Yes
を、
mod_gzip_on No
に変更。

これでどうスか? > Y氏。 *1

特に変化がないようであれば、ルータかなぁ…。

「日記ページのレスポンスが悪い」ということなら、cgi の呼び出し、というか起動で時間がかかってるのかもしれず。FastCGI 等を導入したほうがいいのかも。 *2
*1: って台風でそれどころじゃないような予感。TVニュース見てたら広島が凄いことになってる。
*2: たしか hns を mod_perl に対応させるにはなんか色々と弄らなきゃいけなかった記憶もあって…。キャッシュも無効にしなきゃいけないとかなんとか…。いや、それもそれで興味があるのだけど。

この記事へのツッコミ

Re: 自宅サーバの mod_gzip を無効にしてみてレスポンスの変化を期待してみたり by けいと    2005/09/07 19:12
なんとなく効いている様な気がします^^
Re: 自宅サーバの mod_gzip を無効にしてみてレスポンスの変化を期待してみたり by Y    2005/09/07 19:42
少し速くなったような気がします。

読み込むまでの時間が少し改善され、読み込みが始まったら
読み込み終わるまでの時間がかなり速く感じます。

それと・・・
台風の被害はありませんでした。
報告ありがとうです by mieki256    2005/09/09 15:05
報告ありがとうです。レスポンス、ちょっとは良くなってますか。
すると mod_gzip を使えるだけのCPUパワーは残ってないみたいですな…。

> Y氏
台風被害、特にありませんでしたか。良かった…。

#4 [nitijyou] とりあえず相手先にSSL関係の話をメールで送ってみたり

ひとまず、OCNホスティングを使った場合、という前提で内容を。どういう形で知らせたものかと悩んでいたけど、試しにQ&A形式にまとめて送信。

でも、本文が長すぎて、そもそも読まれない可能性大。

この日記ページもそうだけど、話が長いんだよな… >自分。かといって短く端折り過ぎちゃうと、「いや、これは正確じゃない」と思えてきてストレスが。正確な解説でも読まれなかったら意味がないのに。うーむ。

#5 [windows] OpenOffice.org 2.0 beta で Excelファイルを読み込んでみた

ワードアート(フォントワーク)の再現率がかなり高くなってる。よくまあ、ここまで…。これなら少なくとも何が書いてあるかちゃんと読める。イイ感じ。

ということで .xls を読ませて html出力…しようかと思ったのだけど、レイアウトにこりすぎというか、画像を使いすぎで、なんだか今一つの結果に。やっぱり最初から作り直すか。

ところで OpenOffice の場合、html文書は何で作ればいいのやら。Writer を使うのかしら。

せっかくだから、 _Nvu を導入してそちらで作業してみやうかしら。

#6 [mozilla] Nvu 1.0 をインストールしてみた

1.0PRが入ってたので、アンインストールしてから。1.0をインストール。

起動したらエラーが。1.0PRのときの設定が残ってたらしい。 x:\Documents and Settings\USERNAME\Application Data\Nvu を削除。

起動した。 _Nvu用試製JLP をインストール。Tools → Extensions → Install。Nvu を再起動。メニューが日本語化された。ありがたや。

入れては見たものの :

ソースの整形のされかたに納得いかず。ここのところ xyzzy で作ってたから、インデントが消されたりすると、なんだかしっくりこない。

ということで、やっぱり xyzzy で作ることに。

#7 [windows] OpenOffice Draw のエクスポートでビットマップ画像を出力する際にアンチエイリアスはかけられないのだろうか

png で出力するとジャギーが。うーん。

eps で出力してみた。GIMP で読もうとしたらエラー発生。Ghostscript だの GSview だのが必要らしい。でも、導入が面倒だな…。

eps を Photoshop で読んでみた。解析できないと言われて拒否された。うーん。

pdf で出力したものを、Photoshop で読ませてみた。一応読めた・ビットマップに変換できたように見える。

最初から OpenOffice でアンチエイリアス出力してくれれば助かるのだけどなぁ。

_去年も同じところでハマってたらしい :

cygwin + ImageMagick convert で eps → png 変換すればいいのか。

_GIMP for WindowsでPostScriptを扱う方法 :

メモ。

_Windows 用 Ghostscript と GSview のインストール :

_Ghostscript 8.51 + GSview 4.7 の日本語版

せっかくの機会だからインストールしてみた。昔と違って、環境変数 GS_LIB は指定しなくても済むようになったらしい。
SET PATH="%PATH%";c:\gs\gs8.51\bin;c:\gs\gs8.51\lib
といった具合に、path を通すだけでOKだとか。

インストールしたら、GIMPで eps を読めるようになった。のだけど。特定の文字の輪郭だけが太い…。なんだか変だ…。

ImageMagick の convert で eps → png 変換しても似たような結果。なんとなくだけど、oodraw の eps 出力自体がアレなのかもしれない。

oodrawからpdfで出力したものを読ませるのがヨサゲ :

出力した pdf を、Photoshop or GIMP に読ませた場合は結構綺麗に変換される。やっぱり、oodraw の eps 出力が変ということだろうな。

2004/09/06(月) [n年前の日記]

#1 [game] PARってなんじゃろ

_コレ かしらん。

「プロアクションリプレイ」という名前から、「リプレイデータを記録できるツールなのかな?」と思い込んでたんですが>自分。特にそういう表記はないようで。無敵化とか、パラメータ増減とか、そういうツールでありましょうか。

_極悪非道なゲームも簡単クリアが可能 :

「極悪非道」という記述に、なにか、引っ掛かるというか、もやもやするというか。うまく説明できないけど。

#2 [prog] _PAR

「PAR」で検索してたら、Perlスクリプトを.exeにするツールのまとめ記事が。φ(..)メモメモ

_「はてダラ」がPARを使って.exeになってる :

ウホッ。いいツール。ダラないか(意味不明。

#3 [game][neta] PAR対策

_G-VのIR話 *1 を読んで、ふと疑問が。技術によるPAR対策は可能なのだろうか。具体的にはどんなことをすればいいのん。 *2

_ソフト側でのPAR対策はほぼ不可能 :

ありゃ。

_プレイ中のキー入力データ提出を義務付ければ不正検出に効果があるらしい :

悲観するのは早かったらしいです。なるほど。手はあるのですな。 *3

_無敵状態にするとパスワードが若干変わるような仕様 :

ふむ。そういう手もあるのか…。

RPGなどでは :

無敵状態の敵を用意して、自分が無敵になるとゲーム進行が止まるとか、アイテム数が異常になるとゲーム進行が止まるとか、そういう手段もあるらしいとどこかで目にしますた。なるほどねぇ。

パラメータを暗号化してメモリ上に持つのはどうか :

いや、思いついただけですが。効果のほどはあるのか。パラメータの増減をする場合は必ず特定の関数を呼んで、暗号化の種はアクセスする都度異なる箇所から持ってきて。ついでに無理矢理冗長な記録の仕方をして。…そんなことができるのか知らないけど。実装できたら書換値の算出が極めて面倒にならないかしら。

技術以外での対策なら話が早そうではある :

それなら開発者以外 ―― 担当者が、営業だか広報だか企画だか知らんけど、そういう人達でもできるし。
事前に行う策 : 応募条件を厳しくする。
ビデオ提出を義務付けるとか。
事前に行う策 : 賞品を工夫する。
一般的には箸にも棒にもかからないが、真面目なファン・マニアにだけ価値があるものにするとか。できれば無形のほうがヨサゲ。ヤフオクに出せないし。例えば、スタッフと座談会できるとか。ビル壁面の巨大TVでリアルタイムに自分のプレイ映像を流せるとか。スタッフロールに名前を載せるとか。
事後でもできる策 : 話のスケールを大きくしてしまう。
顔写真公開や、実演等、入賞者が露出する機会を新たに設け、不正を行った人間が尻込み・辞退してしまう効果を期待する。壇上でおごそかに表彰式をしたり、社長と写真会・食事会をしたり、その後関係者やユーザを集めて、大勢のギャラリーの前でプレイの実演を披露してもらうとか。

この手のノウハウがあるのであれば :

社内・業界でまとめておいたほうがヨサゲなんでしょうかねぇ。…「猿楽庁」よろしく、チェック・指摘・アドバイスを専門に行うメーカ御用達の会社を、大手メーカ間で出資して興してしまう、なんてのもアリかも。…本社から、グループ各社に、チェックリストの形で配布するだけでも充分かもしれんけど。 *4

こういうのってユーザさんのほうが詳しそう :

メーカ側は「まだ」不勉強なほうなのだろうから、この際、現状をよほど把握できてるユーザ側で、「○○はこんな対策をしてた」「こんな対策はどうか」等、具体的な方法について情報の集積や発案を試み、ネットで公開しつつ業界やユーザの共有知識にしてみるというのはどうか。 *5 …が。情報を集める実作業だけでも面倒臭そう。ゲームを真に愛してる人じゃないと難しげ。

*1: 全然関係ない話だけど。できれば、サイトじゃなくて、記事にリンクを張ってほしい…。言及箇所を探すの大変。
*2: ちなみに、オイラ自身はスコアだのランキングだの欠片も気にしたことないし、そもそもリアルタイムゲームはドx256ヘタクソなので、不正が行われてようがどうでもいいというか。IRなんて別世界の話だし。…ただ、技術的にどんな回避方法があるのか、そこは興味津々。そういう話は好きだったり。
*3: しかし、それらデータをどこに保存しておくんだろう。メモリカードかしら。それともHDDかしら。結構なデータ量になりそうだけど。どのくらい入力・蓄積されるのか見通しも立たないしなぁ。…でも、実際に提出できてる製品があるらしいので、解決策があるのだろうけど。…ポイントになりそうなところだけ部分的に残しておくのかしらん。
*4: でも、その手のノウハウは、チーム、もしくは個人に、蓄積されてる予感も。
*5: PAR対策が行われた状況は、何よりユーザ自身にとって嬉しい状況だろうし。それを考えれば、ユーザがこれまでイベント等で目にしてきた知恵を寄せ集め、この手の「教本」を作る行為は、最終的にユーザ自身が最も恩恵を受けられる話のようにも思える。また、ユーザの持ってる知識を業界にフィードバックできる機会自体、滅多にあるもんでもないし。コレはユーザにとってある種のチャンスなのかもしれん。と夢想したりもする。

#4 [nitijyou] 珈琲飲むと頭が回らなくなるんです

弱くなったなぁ>自分。元々合わないんだろうな。

#5 [zatta] TVの地震対策

検索検索。

_家具を固定しよう! :

下地がないとダメ。隙間があるとダメ。たるんでちゃダメ。ということかしら。

_阪神大震災の時にはほんとうにテレビが宙を飛んだそうです :

どうすれバインダー。

_家具止め(家具固定)実例 :

TVは壁に密着できないから、紐で固定するしかないのかな。

_テレビはバンドなどで置き台と固定 :

バンドか。なるへそ。

_TVの下にゲル状のマットをひく :

そんなものがあるのか。…かえって不安定になりそうな気もするけど。

_地震対策用粘着固定マット「ネバリ勝ち」 :

コレか。震度7相当でも異常なしとは。同種のもので、 _「耐震マット リンクゲル」 なるものも見つけた。

_ミュージアムジェル :

フィギュアの転倒防止グッズだとか。ヲタクの必須アイテムかしらん。

_リンクフット :

「PC,サーバ,LAN機器,計測機器,各種電子機器を固定」だそうで。

_マグニチュード7、ふんばる君、テレビ転倒防止具 :

そのものズバリの「テレビ転倒防止具」がヨサゲ。

_ナマンズ :

震度4で音が鳴るので、子供や老人でも危険性を認識できる、というのが売りの対策グッズらしい。

_一般のテレビは背面両サイドに止め金用の穴が付いています :

そんなもんついてないぞ。ウチのTVは一般的な製品じゃなかったのかー (;´Д`)

_テレビは地震後の情報を得るのに必ず必要です。 :

言われてみれば。…昔はラジオだったなぁ。

2003/09/06() [n年前の日記]

#1 [pc][linux][gentoo] Mozilla設定中

各種設定情報をWeb上で漁るためにはブラウザが不可欠なので Mozilla 1.4 をひとまず設定中。日本語パック、Lo-Fiテーマ、コンテキストメニュー拡張、タブ拡張、マウスジェスチャを、rootになって入れた。

しかし次々と問題発生。言語を日本語から英語に変えて再起動したら *1 言語選択項目自体が消滅してしまったり、テーマを切り替えて再起動したら *2 二度と起動しなくなったり。~/.mozilla/ を削除してみたけど戻らない。しかしソレ以外の解決方法が思いつかないので、、emerge unmerge mozilla でアンインストール → emerge mozilla で再インストール、というより再コンパイルを3回ぐらい繰り返し。再コンパイルだけで一日が消えた…。

それでも一通り使える状態になったので、rootから一般ユーザになって起動しようとしてみたものの。一般ユーザではなぜか起動せず。ps aux で見てみると mozilla-bin なるものが五個ぐらい動いてるし、一般ユーザのホームディレクトリに .mozilla/ 以下が作られてはいるのだけど。どこかにエラーメッセージが残ってないかと /var/log/ 以下を探すも、Vine とは構成(?)が違ってるのでどこを見ればいいのかわからず。手当たり次第に中を開いてみたものの、それらしい情報は見つからず。…力尽きて、寝る。
*1: コンテキストメニュー拡張やタブ拡張の設定項目は、インストール直後英語表記になっている。これを日本語で表示する為には、言語選択を日本語→英語→日本語と設定し直さないといけない。
*2: テーマを反映させる為には再起動が必要。

2002/09/06(金) [n年前の日記]

#1 チリも積もれば

HDDの中を見直して、画像ファイル削除したら結構な容量が。
不必要なファイルを消す作業をした方が効果的だろうか。


「北の国から2002」、面白いですね。
ケータイ小僧がぶん殴られてスッキリしました(笑)

2001/09/06(木) [n年前の日記]

#1 達沢不動滝

親父さんと、 _達沢不動滝 まで写真を撮りに行ってきました。
出発はAM3:00。
親父さん曰く、朝の写真は光線の関係でまた違った画になるとのことなので。

途中、「母成グリーンライン」を走ったんですが。
本来有料のはずだけど、真夜中は無料で走れるみたい。

着いたのはいいけど、朝の森の中は光量不足。
人間の目の性能の良さをつくづく実感。
かすかな光でも人間は見える。でも、CCDは融通利かないナリね。
デジカメ撮影不可能。液晶にはノイズしか映ってないし(爆)

ようやく日が昇ってきて、かろうじてスローシャッターでの撮影が可能に。
しかし手ブレ発生。どの画像もボケボケ。
電池は切れるし、入れ替えた電池もまた切れかかるし。もうボロボロ

その後、親父さんは裏磐梯まで車を走らせたようなのですが。
寝ないで出発した自分は、助手席でどうやら熟睡状態に。気がついたら既に帰路。うぐぅ
時々ちらりと目が覚めた時の記憶では、周りがスンゴイ綺麗な風景になってたような…
しかしいかんせん睡魔には逆らえず…失敗だ…せっかくの資料集めが…

帰りに、大和無線(電子パーツ店)に回ったり。
高校以来だから何年振りだろう。何も変わってなかった (T▽T)
家の洋間の電灯スイッチが壊れてるので、代替パーツを探してたんですが。
あまりに売れないので取り扱いを止めたとの話。ガックリ
やはり電灯丸ごと交換するしかないのか。

更にそこからの帰り、たまたま目にした電球専門店で、かろうじてON/OFFのみの電灯用スイッチ発見。
本来は4段階で切り替わるスイッチが必要ですが。
せめてON/OFFだけでも修理できれば良いのだけどなぁ。


近くのコジマで、三菱のCD-Rの在庫がはけてしまった模様。
これからドコで買えばいいんだ… (;´Д`)

2000/09/06(水) [n年前の日記]

#1 やはり眠かった

朝から歯医者。
土台(?)の上から、何かかぶせたようです。
鏡で覗くとなんか銀色のモノが。
なんとなくサイバー <違うか

午後から教習所。
コースの中で、「一瞬でいいので40km出す」というのがあったんですが。
自分で出したらむっちゃ怖かった。
こんなんで路上出たらどうなっちゃうんだろう。

自動車運転には並列処理が必要と実感する毎日。
今の自分のシーケンシャル的対応では問題がありそう。
と言っても、人間そうそう、急に並列処理なんてできそうにないし。
慣れるしかないのだろうけど。
アレかな。
おしっこと同時にウンチするのと同じ事かな>並列処理
…ムチャクチャな例えですね。

そういや昔なにかで、「アメリカ人はおしっことウンチが同時にできない」と聞いた記憶が。
そういうトイレの使い方は教わってないからとかなんとか。
じゃあ日本人はできるのか? 自分は出来るのか?
…と考えると、自信を持って出来るとは言えない自分に気がつくです。
若干シーケンシャルな私 in トイレ。

何を書いているんだらう。

つか、やっぱり眠いのです。

1999/09/06(月) [n年前の日記]

#1 (NoTitle)起床PM8:30。病院に行...

起床PM8:30。病院に行くはずが寝坊(ってレベルの話じゃないな)。

HDD整理続行。かなり便利なリネームツールが見つかって大助かり。画像変換に関してもドラッグ&ドロップに対応したツールを導入しただけで作業が大分軽減されました。…ひょっとしてこういう作業は何かのスクリプト書いた方が楽にできそうかも。やらないけど。

_師匠 の新作FLASHデータを見て衝撃を受ける。スゲー。感動。まさにいんたらくてぃぶ。これはFLASH史上名作になり得るかもしれない貴重なデータだと思ったり。なぜならそういう方面のデータって中々無いから。とにかくスゲーのです。

以上、25 日分です。

過去ログ表示

Prev - 2024/03 - 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