HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2014
0817
ほむHSP3Dishのgsquare命令について4解決


ほむ

リンク

2014/8/17(Sun) 16:15:17|NO.63889

HSP3Dish (v3.4)を利用してiOSアプリを作成しようとしているのですが、
gsquare命令の挙動が思い通りになりません。

gsquare命令について気になっていることが2点あります。

1. 画像が歪んでしまうのは仕様なのか (解決策がないのか)

2. 画面に描画された文字などをテクスチャとして利用できないのか

1と2、共に通常のWindows版のHSPでは全く問題ないように見えます。
HSPのバージョンは 3.34 です。


2. に書いたように、HSP3Dishでは最初に文字を画面に描画してから、
それをテクスチャとして利用することができないため
一度画像をファイルとして作成してから、テスト用スクリプトで読み込んでいます。


画像作成スクリプト

#include "hspcv.as" font msgothic, 60, 16 color 255, 255, 255 pos 0,0: mes "ABCDEFG\nHIJKLMN\nOPQRSTU" cvbuffer 0, 210, 200 cvputimg 0 cvsave "test_gsquare.png", 0

以下のスクリプトの #include "hsp3dish.as" をコメントアウトすれば、
通常のWindows版と同じ動作になります。

テスト用スクリプト本体

#include "hsp3dish.as" #ifdef __hsp3dish__ setreq SYSREQ_CLSMODE, 0 #endif celload "test_gsquare.png", 1 redraw 0: color 0,0,0: boxf coord_x = 300, 400, 500, 200 coord_y = 200, 200, 450, 450 tex_x = 0, 210, 210, 0 tex_y = 0, 0, 200, 200 gsquare 1, coord_x, coord_y, tex_x, tex_y redraw 1

実際に作成中のiOSアプリでは、d3moduleのd3textureという命令を使用しているのですが、
内部上、gsquare命令を使用しているのと同じであったので質問させてもらいました。
よろしくお願いします。



この記事に返信する


ほむ

リンク

2014/8/18(Mon) 15:12:57|NO.63940

すみません。書き込みにミスがありました。
HSPのバージョンは 3.34 と書きましたが、正しくは 3.4RC1 です。



FunnyMaker

リンク

2014/8/18(Mon) 21:48:14|NO.63954

1つ目の質問に対しての回答です。

結論から述べますと、「仕様です。恐らく解決策はありません。」
(元祖と同じようにbufferに書き込みできてVRAMみたいなやつも弄れるのなら、
元祖版の計算方法が分かればこっち側でなんとかできるんでしょうけど。)

hsp3dishでのgsquareの座標計算のアルゴリズムが大体分かりました。
dishと元祖ではアルゴリズムが違います。(元祖版の方が上手いのかな?)

詳しくは下のzipファイルをダウンロードして確かめてください。
http://www.mediafire.com/download/sb430na5099b0cc/gdeltacpy.zip
自作した「gdeltacpy」というのがhsp3dish版の gsquare とほとんど同じ結果をもたらします。
(計算にアラがあるのはおいておいて。)



< きっかけは? ↓ >

実は私、最近Javaを始めておりまして、AWTやらswingやらというものの存在を知りました。
hspで大変お世話になっている gsquare に似たようなメソッドが欲しくて探していたのですが見つからず...。
仕方がないので自作してやろうかと思い、山勘でアルゴリズムを考えてみたら...、
なんと、以前から違和感のあったdish版のgsquareの描画結果とドンピシャで合うではありませんか!!!

その「アルゴリズム(?)」というのは簡単で、高校数学Bの「ベクトル」というところで扱われる「三角形の周および内部の云々...」
の辺りの話でガッツリ出てくるアレです。


< 余談 >
dish版gsquareも元祖と同じ挙動だと嬉しいんですけどね。
そうはいかない事情でもあるんでしょうかね...。

元祖版には「射影変換」なるものが関係してるのかな〜という勘がします。違うかもしれません。
8変数の連立方程式が云々...とかいって、難しそうです。
線形代数を駆使するんでしょうが、計算に時間が食われてしまいそうで、実用になるかどうか。



FunnyMaker

リンク

2014/8/19(Tue) 09:15:12|NO.63968

昨日の投稿の後、別の解決策を探っていたら なかなか良い描画結果を得る方法が見つかりました。
元祖 gsquare が裏でどんな計算をしているのかなんとなく見えてきました。
しかし元祖 gsquare とは若干異なる描画結果になります。
(なんでだろ?、というか本家版の方が歪んで見えはじめたのは気のせいだろうか?)

やっていることは昨日のやつに似ていて、四角形を一様に(?)引き延ばしたらどうなるか考えます。
昨日と同様 ベクトルの嵐です。


screen 0,200,200,0 title "source" color 255,128,0 : boxf 0,0,200,200 color 255,255,255 : boxf 2,2,198,198 color 255,128,0 : line 0,0,200,200 : line 0,1,199,200 : line 1,0,200,199 font msmincho,200,16 color 0,0,0 : pos 0,0 : mes "画" ;< gsquare > screen 1,400,450,0 title "gsquare" x_dst = 0,300,400,50 y_dst = 50,0,250,450 x_src = 0,199,199,0 y_src = 0,0,199,199 gsquare 0, x_dst,y_dst, x_src,y_src font msmincho,50,16 color 255,0,0 pos 200,400 : mes "gsquare" ;< gsquareimit > screen 2,400,450,0 title "gsquareimit" redraw 0 gsquareimit 0, x_dst,y_dst, x_src,y_src font msmincho,50,16 color 255,0,0 pos 120,400 : mes "gsquareimit" redraw 1 #module testmod #deffunc gsquareimit int wid, array x_dst, array y_dst, array x_src, array y_src gmode 1,2,2 //点(x_src(0),y_src(0)), (x_src(1),y_src(1)), (x_src(2),y_src(2)), (x_src(3),y_src(3))をそれぞれA,B,C,Dとする。 //点(x_dst(0),y_dst(0)), (x_dst(1),y_dst(1)), (x_dst(2),y_dst(2)), (x_dst(3),y_dst(3))をそれぞれA’,B’,C’,D’とする。 →AB = x_src(1)-x_src(0), y_src(1)-y_src(0) →DC = x_src(2)-x_src(3), y_src(2)-y_src(3) →AD = x_src(3)-x_src(0), y_src(3)-y_src(0) →BC = x_src(2)-x_src(1), y_src(2)-y_src(1) →A’B’ = x_dst(1)-x_dst(0), y_dst(1)-y_dst(0) →D’C’ = x_dst(2)-x_dst(3), y_dst(2)-y_dst(3) →A’D’ = x_dst(3)-x_dst(0), y_dst(3)-y_dst(0) →B’C’ = x_dst(2)-x_dst(1), y_dst(2)-y_dst(1) len_A’B’ = sqrt(→A’B’(0)*→A’B’(0) + →A’B’(1)*→A’B’(1)) len_D’C’ = sqrt(→D’C’(0)*→D’C’(0) + →D’C’(1)*→D’C’(1)) if len_A’B’ > len_D’C’ : L’ = len_A’B’ : else : L’ = len_D’C’ ;A’B’,D’C’のうち長い方の長さをL’とする。 //A’B’上を動点P’がA’→B’の向きに動く。 //D’C’上を動点Q’がD’→C’の向きに動く。 //両者のリズムは同じである。すなわち、同時刻において (A’P’ : P’B’) = (D’Q’ : Q’C’) が満足される。 //□ABCD上でP’,Q’に対応する点をそれぞれP,Qとする。 num_rep1 = int(L’)+1 Δu = 1.0/num_rep1 u = 0.0 repeat num_rep1 →AP = u*→AB(0), u*→AB(1) →AQ = →AD(0) + u*→DC(0), →AD(1) + u*→DC(1) →PQ = →AQ(0) - →AP(0), →AQ(1) - →AP(1) →A’P’ = u*→A’B’(0), u*→A’B’(1) →A’Q’ = →A’D’(0) + u*→D’C’(0), →A’D’(1) + u*→D’C’(1) →P’Q’ = →A’Q’(0) - →A’P’(0), →A’Q’(1) - →A’P’(1) len_P’Q’ = sqrt(→P’Q’(0)*→P’Q’(0) + →P’Q’(1)*→P’Q’(1)) //P’Q’上を動点R'がP’→Q’の向きに動く。 //□ABCD上でR’に対応する点をRとする。 num_rep2 = int(len_P’Q’)+1 Δv = 1.0/num_rep2 v = 0.0 repeat num_rep2 //Rの色をR’に転送 pos x_dst(0) + →A’P’(0) + v*→P’Q’(0), y_dst(0) + →A’P’(1) + v*→P’Q’(1) gcopy wid, x_src(0) + →AP(0) + v*→PQ(0), y_src(0) + →AP(1) + v*→PQ(1) v += Δv loop u += Δu loop return #global

モジュール自体はdishでも動くはずです。
これはプロトタイプですが、半透明コピーも実装すれば元祖 gsquare っぽくなります。

但し激遅です。このサンプルでも数百msec要している気がします。(スクリプトですから、当然。)
一発芸的な使い方なら問題ないですがアニメーションには厳しいかと。
d3moduleのテクスチャ表示部分を改造してgsquareの代わりにgsquareimitをセットしても速度的にキツイはずです。




続いて、2つ目の質問に対する私なりの回答です。

否定的ですが、無理だと思います。
screen0 to screen0 のgsquareコピーに希望を託すも、真っ白けです。

どうにかしてbufferにちょっかい出せないかと無い知恵を絞って考えたことがありますがどうにもなりませんでした。
せめてscreen0に対してbmpsaveが使えれば、
screen0 描き描き → bmpsave → bufferにロード → 使い放題
となるんですが。
いや、せめてpgetだけでも使えれば、
screen0 描き描き → pgetで情報収集 & bmpファイルのバイナリデータを自前で作成 & bsaveで出力 → bufferにロード → 使い放題
となるんですが、pgetすらも使えないようです(p"set"は許されるのにp"get"許がされないなんて...)。
八方塞がりな感じがします。

厳しい制約の中でいかにinterestingなものを作るかということもdishの醍醐味なのかもしれませんね。




あれこれ言ったものの結局、質問者さんの満足できるソリューションを提案できませんでした。



ほむ

リンク

2014/8/19(Tue) 13:07:41|NO.63979

ありがとうございます。
gsquareimitのスクリプトはまだあまり理解できていませんが、
役に立てられそうな部分はたくさんあると思われます。
ベクトルの云々はコードでなくても数学的に理解できていないかもしれません。

確かにgsquareimitの方がgsquareよりも自然に見えますね…

制作しているのはゲームに近いものなので、FPS60をキープしつつ結構な数のオブジェクトを
描画しなければならないので、やはり厳しいですね。

>>d3moduleのテクスチャ表示部分を改造してgsquareの代わりにgsquareimitをセットしても速度的にキツイはずです。
一応確かめてみましたが、FPSは0〜2ほどになってしまいました…

HSP3Dishで利用する場合は面を細かく分割して描画しようと思います。
Windows上ではd3moduleの描画系命令をDirectXに対応させたものを利用し、
変形した図形の上から1ラインずつ描画する方法を取っています。
(これだと台形しか描画できないが、現在制作しているものはこれで足りるため)


問題は残ったままですが、仕様ということで解決とさせていただきます。
しかし、もし進展がありましたら書き込んで頂けるとありがたいです。



ONION software Copyright 1997-2023(c) All rights reserved.