GPU のメモリ領域へテクスチャ情報を送信します。送信されたデータは GPU 上で保持されます。
「スロット(Slot)」の上限は OS や実行環境によって異なります。
YoYoGames の上記リファレンスによると Windows/Mac/Linux など PC では最大8枚のテクスチャをスロットへ送信でき、Android/iOS などモバイルでは最大2枚とされています。互換性を考慮した場合、GM:S では低い方へ合わせるべきなので最大2枚と見積もっておけば無難です。
この YoYoGames のリファレンスはコンシューマなど他環境で利用される場合の上限が書かれていないなど、アバウトすぎてちょっと不安。
送信するタイミングは特に決められていないため自由ですが、OpenGL はテクスチャ以外扱えません。だから送信する画像は必ず「テクスチャ」である必要があります。
例えば GM:S のリソースツリーに登録されたスプライト(Sprite)をシェーダへ送信したい場合、スプライトはテクスチャID を取得してから、それを送信する必要があります。GM:S は各グラフィックスリソース用にテクスチャ IDを取得する関数がそれぞれ用意されています。
var a,b,c; a = sprite_get_texture(sprite, 1); b = background_get_texture(bg); /* c = ??? */
しかしもっと良い方法があります。それは Surfaces です。
c = surface_get_texture( Surf );
Surface を活用しよう
GM:S の Sufaces 機能は GPU 上のメモリ領域にグローバル・スコープなリソースとしてテクスチャを作成する機能です。
Surface は volatile な(永続性の無い・消えやすい) テクスチャデータですが、ゲーム動作中でも動的に生成することのできるリソースなので応用範囲が広い。
背景やスプライトを ID で一枚ずつ取得せずとも、Surface を一枚作ってそこに描画した描画結果をテクスチャとして GPU へ渡せば、スロットの数が限られている環境でも工夫することができます。
texture_set_stage
関数は二つの引数を持ちます。
- 第一引数:Shader 名
- 第ニ引数:テクスチャ ID
第ニ引数のテクスチャ ID は、Surface の場合、
surface_create
関数上記関数の戻りを受け取った変数を
surface_get_texture 関数
の引数に与えることでテクスチャ ID を取得できます。
/* Instance Variable として Surf = noone; を定義済みとする サンプラーの定義は Create Event で行う、基本的にこのコードだけでは適切に動作しません */ var a; a = Photoshop-Overlay;//リソースツリーに登録されたシェーダ名 if !Surf { Surf = surface_create(room_width , room_height); surface_set_target(Surf); draw_background(bg,150,150);//背景を指定した位置へ描画 draw_self();//オブジェクト外観・スプライトを描画 surface_reset_target(); shader_set(a); texture_set_stage(U_sampler, surface_get_texture(Surf)); shader_reset(); } else{ shader_set(a); draw_surface(application_surface,0,0); shader_reset(); };
上記サンプルは一度だけ draw_self()
と draw_background()
を実行しただけで、次 Step 以降は application_surface だけを描画しています。
動的に生成されたテクスチャと application_surface をシェーダで合成する処理を抜粋したものですが、スロットへ送信されたテクスチャは surface に変更が無い場合には以降可能な限り再利用することで無駄な送信や描画処理を省きます。
しかしこれだけだと意味分からんと思うので、実際にシェーダ・オーバーレイのサンプルコードを見てください。
[divpage]