|
|
|
2023/9/16(Sat) 09:26:53|NO.100038
こんにちは!
もっと良い方法が無いか、知恵をお借りしたく スレッドを立てました。
ここで言う「UVアニメ」とは、ウディタでいう キャラチップ歩行アニメです。
1枚のテクスチャの UV座標を変えてくアニメ表現。
3D空間の板オブジェクトでやります。
2D空間の gpspr スプライトなら、簡単ですが(-ω-;)
gpplate で UVアニメを書けませんでした。
試作スクリプトを添付します。
「メッシュノードを作っては消し」まくり、力技で良くないです。
前作『ジェイルアイランド』は hgimg3 でした。
hgimg3 では texload addplate event_uv で簡単でしたが、
hgimg4 では これらを使えないように見えます。
hgimg4 のマテリアル最大数は 128 と少ないので、うまく工夫したいのですが。
#include "hgimg4.as"
#define BASETIME 30 //コマが変わる時間。
chdir dir_exe+"\\sample\\hgimg4" //サンプル素材のあるディレクトリ。
//カメラを設置
setpos GPOBJ_CAMERA, 8,8,10 //カメラ位置。
gplookat GPOBJ_CAMERA, 0,0,0 //メッシュノードのある座標を見る。
//repeat 前の準備
gptexmat id_mat, "res/ball64.png" //テクスチャマテリアルを生成。
id_node = -1 //メッシュノードのオブジェクトID。生成すると 0 に。
koma = 0 //uv アニメのコマ番号 = ボールに書かれた番号
time = BASETIME //経過時間。
repeat
if(time >= BASETIME){//コマを変える。
time = 0
//前回のコマのメッシュノードを削除。
if(id_node >= 0){
delobj id_node
id_node = -1
}
//今回のコマのメッシュノードを作成。
x1 = 64 * koma
x2 = 64 * (koma + 1)
Make_meshNode 512, x1, 0, x2, 64
//次回のコマへ。
koma ++
if(koma >= 3){ koma = 0 };コマ 0~2 だけでアニメ。
}
time ++//時間経過
//画面を描画。
redraw 0
gpdraw
redraw 1
await 1000 / 60
loop
//■■■■■■■■■■■■■■■■■■■■■■
//メッシュノードを作成する命令。
#deffunc Make_meshNode double _size, double _tl_x, double _tl_y, double _br_x, double _br_y
/// _size :テクスチャ画像の縦横(pixel)
/// _tl :UV 左上座標 x,y(pixel)
/// _br :UV 右下座標 x,y(pixel)
//pixel を「テクスチャ縦横の割合 0.0~1.0」に変換。
_uv_tl_x = _tl_x / _size
_uv_tl_y = 1.0 - _tl_y / _size
_uv_br_x = _br_x / _size
_uv_br_y = 1.0 - _br_y / _size
//カスタム3Dメッシュの登録情報を初期化。
gpmeshclear
//頂点を登録。
a = 1
gpmeshadd p1, -a, -a, 0, 0, 0, 1, _uv_tl_x, _uv_br_y;頂点
gpmeshadd p2, a, -a, 0, 0, 0, 1, _uv_br_x, _uv_br_y
gpmeshadd p3, -a, a, 0, 0, 0, 1, _uv_tl_x, _uv_tl_y
gpmeshadd p4, a, a, 0, 0, 0, 1, _uv_br_x, _uv_tl_y
//カスタム3Dメッシュにポリゴン情報を登録。
gpmeshpolygon p1,p2,p3,p4
//メッシュノード オブジェクトを生成。
id_node = 0
gpmesh id_node, $FFFFFF, id_mat
setpos id_node, 0, 0, 0
return
| |
|
2023/9/16(Sat) 14:12:10|NO.100041
あ。
gptexmat id_mat, "res/ball64.png"
をコメントアウトすると 表示されない。
最大数 600に増えないのかな、もしかして。
まぁこんな風に、HGIMG4 の開発者さまに負担かかってしまうので、
マテリアル最大数は増やさないよ〜にしたいのです(*´ω`)
|
|
2023/9/16(Sat) 14:31:19|NO.100042
ゴメンなさい、勘違い。最大数は 600に増える。
ちゃんと 600枚のマテリアルを作成してました。
|
|
2023/9/16(Sat) 15:56:16|NO.100043
UV操作じゃなくて申し訳ないですが3.7b6ならドットをつぶさずテクスチャ―の差し替えが可能です。
画像は用意してください。
…ただこれ今チェックしてたけどメモリリークしてるかもしれません。
#include "hgimg4.as"
#include "mod_gputil.as"
screen 0, 1280, 720, 0
gpreset
setcls CLSMODE_SOLID, 0 ; 画面クリア設定
setpos GPOBJ_CAMERA, 0,0,5 ; カメラ位置を設定
// テクスチャマテリアル作成
gptexmat fmat, "res/grp/z00.png", GPOBJ_MATOPT_UVOFFSET|GPOBJ_MATOPT_NOCULL |GPOBJ_MATOPT_NOLIGHT
gpmatprmf fmat, "filter", "nearest"
gpplate mdl, 1, 1, -1, fmat
gpnodeinfo mat, mdl, GPNODEINFO_MATERIAL
repeat
stick key,15
if key&128 : end
m_fTime += 1
if (m_fTime >= 60) {
m_fTime -= 60;
m_nAni++
m_nAni &= 1;
if (m_nAni == 0) {
gpmatprmt mat, , "res/grp/z00.png", GPOBJ_MATOPT_NOMIPMAP
gpmatprmf mat, "filter", "nearest"
}
else {
gpmatprmt mat, , "res/grp/z01.png", GPOBJ_MATOPT_NOMIPMAP
gpmatprmf mat, "filter", "nearest"
}
}
addang mdl, 0.0, 0.02, 0.0;
; カーソルキーでカメラ位置を動かす
if key&1 : addpos GPOBJ_CAMERA, -0.2
if key&4 : addpos GPOBJ_CAMERA, 0.2
if key&8 : addpos GPOBJ_CAMERA, 0, 0, 0.2
if key&2 : addpos GPOBJ_CAMERA, 0, 0, -0.2
redraw 0 ; 描画開始
gpdraw ; シーンの描画
redraw 1 ; 描画終了
await 1000/60 ; 待ち時間
loop
| |
|
2023/9/16(Sat) 16:55:35|NO.100044
法貴藤五郎さま、コメント本当に有難うございます! (*-ω人)
一時的に 3.6 から 3.7b6 へアプデし、動作を確認できました!
gpmatprmt 初めて知りました (。゚ω゚)
この方法なら「消すたびにオブジェクトID を取得し直す」なんて不要ですね!
書いて頂いたコードのが 私のよりずっと良いと思います。
gpmatprm の命令が増えてるみたいで、勉強してみます。
「メモリリークしてる可能性」、
私には repeat~loop 内の どこも問題ないように見え、わかりませんでした。
addang なのかな?
私はまた試作して、gpscrmat と celdiv をうまく使えないのが悔しいです (つ∀≦。)・゚。
【失敗コード】
#include "hgimg4.as"
#define BASETIME 30 //コマが変わる時間。
chdir dir_exe+"\\sample\\hgimg4" //サンプル素材のあるディレクトリ。
gpreset
//カメラを設置
setpos GPOBJ_CAMERA, 8,8,10 //カメラ位置。
gplookat GPOBJ_CAMERA, 0,3,0 //メッシュノードのある座標を見る。
id_screen = 1
/*
buffer id_screen, 512, 512, screen_offscreen
gpscrmat id_tex, id_screen
gpmatprmt id_tex, "u_diffuseTexture", "res/ball64.png"
celdiv id_screen, 64, 64, 32,32
*/
celload "res/ball64.png", -1
id_screen = stat
celdiv id_screen, 64, 64, 32, 32
gpscrmat id_mat, id_screen
gpplate id_plate, 1.8, 1.8, -1, id_mat ; 板ノードを追加
setpos id_plate, -1, 2.1, 0
newevent ev
event_uv ev, 0
event_wait ev, BASETIME
event_uv ev, 1
event_wait ev, BASETIME
event_uv ev, 2
event_wait ev, BASETIME
event_jump ev, 0
setevent id_plate, ev
; 床ノードを追加
gpfloor id_floor, 40,40, $008080
gppbind id_floor, 0
repeat
//画面を描画。
redraw 0
gpdraw
redraw 1
await 1000 / 60
loop
| |
|
2023/9/16(Sat) 17:47:40|NO.100045
シェーダーの uniform を使う方法で実装してみました。
以下の内容で sample/hgimg4/res/shaders/_tiletex.vert ファイルとして保存してください。
attribute vec4 a_position;
attribute vec2 a_texCoord;
uniform mat4 u_worldViewProjectionMatrix;
uniform vec4 u_info;
varying vec2 v_texCoord;
void main() {
vec4 position = a_position;
gl_Position = u_worldViewProjectionMatrix * position;
v_texCoord = a_texCoord * u_info.zw + u_info.xy;
}
以下の内容で sample/hgimg4/res/shaders/_tiletex.frag ファイルとして保存してください。
#if defined(OPENGL_ES) || defined(GL_ES)
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
#endif
uniform sampler2D u_tileTex;
varying vec2 v_texCoord;
void main() {
gl_FragColor = texture2D(u_tileTex, v_texCoord.xy);
}
以下の内容で sample/hgimg4/tilebyuniform.hsp ファイルとして保存して実行してください。
#include "hgimg4.as"
texfile = dirinfo(5) + "tamadot.png" // タイルテクスチャ
sdir = "res/shaders"
vsh = sdir + "/_tiletex.vert"
fsh = sdir + "/_tiletex.frag"
gpusermat mtlid, vsh, fsh
gpmatprmt mtlid, "u_tileTex", texfile, GPOBJ_MATOPT_NOMIPMAP
gpplate id1, 2, 2, -1, mtlid
setpos id1, 0, 0, 80
gpplate id2, 2, 2, -1, mtlid
setpos id2, 3, 0, 90
step = 0.02
dirindex = 0
repeat
getreq timer, SYSREQ_TIMER
topo = timer \ 2000
stick key,15
if (key & 15) == 0 {
walking = 0
} else {
walking = 1
if key & 1 { // 左
dirindex = 1
addpos id1, -step, 0,0
}
if key & 2 { // 上
dirindex = 2
addpos id1, 0, step, 0
}
if key & 4 { // 右
dirindex = 3
addpos id1, step, 0, 0
}
if key & 8 { // 下
dirindex = 0
addpos id1, 0, -step, 0
}
}
redraw 0
// 珠音1
incx = walking * 4 + topo / (2000 / 4)
incy = dirindex
inid = id1
gosub *update
// 珠音2
incx = topo / (2000 / 4)
incy = 5
inid = id2
gosub *update
gpdraw
redraw 1
await 1000/60
loop
*update
wimg = 512 // tamadot.png 全体の幅
himg = 512
w2d = wimg / 8 // tamadot.png の1セルの幅
h2d = himg / 8
x2d = incx * w2d
y2d = incy * h2d // 上から下座標系での基点Y
dw = double(wimg)
dh = double(himg)
x = double(x2d) / dw
y = 1.0 - double(y2d + h2d) / dh
z = double(w2d) / dw
w = double(h2d) / dh
gpmatprm4 inid, "u_info", x, y, z, w
return
ご参考まで。
# うーむ、0.5 テクセルずらしてもどっちかからゴミ出るなぁ。どなたか助けてw
| |
|
2023/9/16(Sat) 19:08:52|NO.100046
砂時 計さま、コメント本当に有難うございます! (*-ω人)
カメラオブジェクトを置き、正常な動作を確認しました。
こここ こんなこと出来るんですね……すごすぎる! 神か
ついでに ↓ も大丈夫でした。
setobjmode id1, OBJ_XFRONT, 0 ;オブジェクトのモード設定
たしかに、アニメの端に ゴミが。
もとの tamadot.png が セルの端ぎりぎりまでドット打ってあるので、
端をα値0のピクセルで囲めば、正常になるかと思います。
ひとまず、スレッドに解決チェックしました〜。
あの、このシェーダーを 拙作に使ってもよろしいでしょうか…?
宜しければ クレジットにお名前や、URL などを載せたいのですが。
|
|
2023/9/16(Sat) 19:57:14|NO.100047
はい、使っていただいて構いません。
※今回のシェーダーは uniform を参照する基本的なコードですので、まさにサンプルですね。
なお砂時としてのホームページはありません。
|
|
2023/9/16(Sat) 23:49:27|NO.100048
あ、、、、解決しちゃいましたね。。。
ちょっと自分用に再度メモ書きとして、UPしておこう。。。
質問内容と違ったらごめんね。
;HSP ver3.7b6で検証
#include "hgimg4.as"
chdir dir_exe+"\\sample\\hgimg4"
gpreset
setcls CLSMODE_SOLID, $000000 ; 画面クリア設定
;===カスタムマテリアルの描画元部品===
buffer 2,512,512,screen_offscreen ;バッファー2を作成
celload "res/ball64.png",2 ;64ボール画像読込
celdiv 2,64,64,0,0
;====カスタムマテリアル==============
buffer 3,64,64,screen_offscreen ;バッファー3を作成
gpscrmat id_texmat, 3 ;テクスチャマテリアル作成
;====================================
gpbox id_model, 10,, id_texmat ;描画先GPBOX+カスタムマテリアルを設定
timer=0.0f
repeat
redraw 0 ; 描画開始
addang id_model,0,0.01,0 ;GPBOXを回転
gpdraw ;シーンの描画
gosub *draw ;カスタムマテリアルの描画
redraw 1 ; 描画終了
await 1000/60 ; 待ち時間
loop
;=======================================================
*draw ;カスタムマテリアルの描画
gsel 3
redraw 0
;テスト1 色が変わる四角形
color timer,timer/2,255-timer;背景の四角
boxf 0,0
;テスト2 単純な円
color 0,255,0
circle 0,0,64,64,0
;テスト3 celput
timer+=0.1f
gmode 2
pos 0,0
celput 2,timer\64
;テスト4 文字列の描画
color 255,0,0;文字
pos 0,0
mes "test"+timer
redraw 1
gsel 0
return
;=======================================================
ちょっと改造
| |
|
2023/9/17(Sun) 02:40:46|NO.100049
透過pngを適用できないのか、なんか気になって眠れないので、試してみました。
標準のシェーダーを使用。公式のサンプルあり(gptexmat)
もう寝る。。。
;HSP ver3.7b6で検証
#include "hgimg4.as"
chdir dir_exe+"\\sample\\hgimg4"
gpreset
setcls CLSMODE_SOLID, $000000 ; 画面クリア設定
;====テクスチャマテリアル==============
gptexmat id_texmat, "res/ball64.png",GPOBJ_MATOPT_UVOFFSET|GPOBJ_MATOPT_UVREPEAT ; テクスチャマテリアル作成
;====================================
gpplate id_model, 10,10,-1, id_texmat ;描画先モデル+テクスチャマテリアルを設定
setpos id_model,0,0,60
gpbox id_model2,100 ;透過確認用ダミーモデル
setpos id_model2,0,0,-200
offsetx = 0.0f ;UVオフセット初期化
offsety = 0.0f
timer = 0.0f ;タイマー初期化
repeat
redraw 0 ; 描画開始
offsetx = 1f/8*int(timer\8) ;UVの考え方がよくわからん
offsety = -1f/8*int(timer/8)-1f/8
gpmatprm2 id_model, "u_textureOffset", offsetx , offsety ;UVオフセットのシェーダー設定
gpmatprm2 id_model, "u_textureRepeat", 1.0f/8.0f , 1.0f/8.0f ;UVリピートのシェーダー設定
addang id_model ,0,0.05,0 ;プレートモデルを回転
addang id_model2,0,0.01,0 ;ボックスモデルを回転
gpdraw ;シーンの描画
timer+=0.1f ;タイマー加算
redraw 1 ; 描画終了
await 1000/60 ; 待ち時間
loop
おやすみzzz
|
|
2023/9/17(Sun) 17:18:23|NO.100050
こんにちわ。もう解決してますが、buhioさんのアイデアを参考にして
こういうのもシンプルで良いかもしれませんね。
(セガサターンのRPGとか思い出します)
;37beta4以降限定
#include "hgimg4.as"
chdir dir_exe+"\\sample\\hgimg4" : gpreset : setcls CLSMODE_SOLID, $ff
; ★テクスチャとモデル生成
gptexmat id_tex, dir_tv+"tamadot.png", GPOBJ_MATOPT_UVOFFSET|GPOBJ_MATOPT_UVREPEAT
gpplate id_model, 4, 4,, id_tex : setpos id_model, 0,2,0
; ★オマケこういうのは見栄えを考えビルボードにした方が良いかも
setobjmode id_model, OBJ_XFRONT
setobjmode id_model, OBJ_LATE
; ★ここがceldiv的なイメージ
TEX_SIZE = 512f ; 画像のサイズ
CH_SIZE = 64f ; キャラクタのサイズ
REP_SIZE = CH_SIZE / TEX_SIZE ; テクスチャの位置を指定するのに使う
gpmatprm2 id_model, "u_textureRepeat", REP_SIZE , REP_SIZE
; アニメーション用のパターン(仮)
ani_time = 4,5,6,7
ani_dir = 6,5,4,7
; 背景(仮)
gpfloor id_floor, 32, 32, $FF00
gpbox id_box, 4, $FFFF : setpos id_box, 8,2
gpclone id_box2, id_box : setpos id_box2, -8,2
gpclone id_model2, id_model
; カメラ(仮)
setpos GPOBJ_CAMERA, 0,16,32
gplookat GPOBJ_CAMERA, 0,1,0
*MAIN
stick pad, 15
if pad&1 : ch_dir = 0 : addpos id_model, -0.2
if pad&2 : ch_dir = 1 : addpos id_model,,, -0.2
if pad&4 : ch_dir = 2 : addpos id_model, 0.2
if pad&8 : ch_dir = 3 : addpos id_model,,, 0.2
if tick\10=0 : ch_time++ : ch_time\=4
; ★テクスチャ座標は左下から右上へ指定
offset = REP_SIZE*ani_time(ch_time), REP_SIZE*ani_dir(ch_dir)
gpmatprm2 id_model, "u_textureOffset", offset.0, offset.1
redraw 0 : gpdraw : redraw 1 : await 16 : tick++
goto *MAIN
| |
|
2023/9/17(Sun) 17:38:46|NO.100051
ついでで、bata6 が使えるのであれば、オマケの下に
gpmatprmf id_model,"filter","nearest"
入れておくと、キャラが重なった時の、α抜きが綺麗いくと思います。
※ただし、補間が適応されなくなるのでドットは目立ちます。
が、コレ系のアプローチはボケないで個人的には好きです。
|
|
2023/9/18(Mon) 11:34:27|NO.100053
わ、すごい! このスレは、HGIMG4 で
「オクトパストラベラー」「ゼノギアス」みたいな
「2Dドットキャラを3D空間で動かす」とき ご活用ください!
>>NO.100048
buhio さま、コメ本当に有難うです! (*-ω人)
透過の問題あっても、celdiv gpscrmat celput で
3Dオブジェクトにセル番号で描けるのは 目から鱗!
バッファの理解が深まるコード。
>>NO.100049
シンプル、すごく良い! gpmatprm2 は ver.3.7 からか。
gpmatprm の引数「パラメーター名」 よく分からなかったのですが、
gptexmat の「マテリアルオプション値」と連動してるんですね。
★メモ: GPOBJ_MATOPT_UVOFFSET で UVオフセット値(u_textureOffset)を設定可能に。
>>NO.100050
usagi さま、ご助言 本当に有難うです! (*-ω人)
メガドライブなゲームを作るところでした(それもいい)
わぁ、完璧! NO.100051 も すごい良い効果ですね(*´ω`)
シンプルなコード、勉強になります。
UV操作とは違う話題ですが、HGIMG4 ならゲーム「RimWorld」みたく
「草や炎のビルボードをゆらゆら揺らす」のも、
ポリゴンの頂点を動かして できそーな気します(知らんけど)
|
|