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


HSPTV!掲示板


未解決 解決 停止 削除要請

2024
0217
mosshgimg4のレンダリングバッファとアルファブレンドについて12解決


moss

リンク

2024/2/17(Sat) 19:42:48|NO.101252

つい最近hgimg4を始めました。
挙動確認のために2D周りの機能を試しているのですが、少々問題があったので質問させてください。
HSP歴は長いですがDirectXとOpenGLはかなり昔に少し触った程度、シェーダー等はサッパリです。

1. レンダリングバッファのα値について
レンダリングバッファの各ピクセルは作成時点ではrgba=0ですが、setclsやboxfでクリアするとα値が255になってしまいます。
バッファでの細かい作画を予定しており、α値を上手く活かせないかと考えています。
後記のスクリプトではとりあえずcelbitmapでゼロクリアしていますが、メモリからのデータ転送は速度面で少し気になります。
これ以外にα値込みでクリアする方法や命令は用意されているのでしょうか?
また、任意にα値を書き換える方法はありますか?

2. アルファブレンドについて
レンダリングバッファにブレンド率の影響を受けるもの(アンチエイリアスを伴うものやgmodeのブレンド率255以下のもの)を描画し、
それをメイン画面等に描画すると本来想定していた色が出ません。
私自身あまり詳しくないのですが、補間アルファブレンドの問題が影響しているように思いました。
後記のスクリプトを実行したとき、メイン画面に直接描画した文字に比べてバッファからコピーした文字は色が薄く、痩せています。
特にバッファのα値をゼロクリアした場合は一目でわかるレベルで痩せており、正直これでは使えません。
文字以外もブレンド率(255->127->0)に対して描画後のα値が(255->191->255)と変化するため想定した作画ができません。
これらの問題を改善する方法はありますか?



この記事に返信する


moss

リンク

2024/2/17(Sat) 19:43:36|NO.101253

アルファブレンドのテスト用
要hsp3.7b7以降

#include "hgimg4.as" #define setfont font "Yu gothic",20,16,shadowsize+1 gpreset alpha = 255 bufalpha = 255 filter = 0 gmul = 255,255,255 g6switch = 0 g6col = 0,0,0 bgcol = 0 messtyle = 0 shadowsize = 0 teststr = "abABあ" wx = 800 : wy = 600 screen 0, wx,wy,,(ginfo_dispx-wx)/2,(ginfo_dispy-wy)/2 : setfont : title "HGIMG4 2D test" setcls 0 buffer 1, wx, wy, screen_offscreen dim vram, wx*wy // pget用 bufsize = 64 buffer 2, bufsize, bufsize, screen_offscreen : setfont celdiv 2, bufsize, bufsize dim bufclr, bufsize*bufsize ;repeat length(bufclr): bufclr(cnt) = $00FFFFFF : loop // 透明の白でクリアすると多少変わるけどダメぽい buffer 3, bufsize, bufsize, screen_offscreen : setfont celdiv 3, bufsize, bufsize buffer 4, 2, 1, screen_offscreen // 2x1 gpgetmat buf4mat, 4, GPGETMAT_OPT_SCRMAT gpmatprmf buf4mat, "wrap", "clamp" color 255,0,0 : pset 0,0 // 赤($FF0000FF)と透明($00000000) celdiv 4, 2, 1 *MAIN await 1000/60 : mc++ getkey k_ctrl, 17 : if k_ctrl : stick key : else : stick key,15 if key&2 : alpha = limit(alpha+1,0,255) // オフスクリーンからメインにコピーする時のブレンド率、ctrl押しながらで1ずつ if key&8 : alpha = limit(alpha-1,0,255) if key&1 : bufalpha = limit(bufalpha-1,0,255) // オフスクリーンに描画する時のブレンド率、ctrl押しながらで1ずつ if key&4 : bufalpha = limit(bufalpha+1,0,255) if key&2048 { g6switch = (g6switch+1)\6 // 下半分にgmode 6をかける if g6switch == 0 : g6col = 0,0,0 if g6switch == 1 : g6col = 255,255,255 if g6switch == 2 : g6col = 255,0,0 if g6switch == 3 : g6col = 0,255,0 if g6switch == 4 : g6col = 0,0,255 if g6switch == 5 : g6col = 80,0,160 } if key&4096 : gmul = rnd(256), rnd(256), rnd(256) // gmulcolorをランダムに if key&8192 : gmul = 255,255,255 // gmulcolorをリセット if key&16384: bgcol = (bgcol+1)\5 // 背景色 if key&131072 { messtyle = (messtyle+1)\4 if messtyle == 0 : mesopt = 0 if messtyle == 1 : mesopt = 2 if messtyle == 2 : mesopt = 4 if messtyle == 3 : mesopt = 8 } if key&65536 { shadowsize = (shadowsize+1)\5 gsel 2 : setfont : gsel 3 : setfont } gsel 2 // celbitmap (0x00000000) redraw 0 celbitmap 2, bufclr, celbitmap_rgb color 255,255,255 : gmode 3,,,bufalpha : grect 32,16,0,64,32 : pos 2,34 : mes teststr,mesopt redraw 1 gsel 3 // boxf (0xFF000000) redraw 0 color : boxf color 255,255,255 : gmode 3,,,bufalpha : grect 32,16,0,64,32 : pos 2,34 : mes teststr,mesopt redraw 1 gsel 0 // main screen setfont redraw 0 color bgcol*64,bgcol*64,bgcol*64 : boxf color 255,255,255 : gmode 0 pos 10,10 mes "window_size:"+wx+","+wy,4 mes "bgcolor(a):"+limit(bgcol*64,0,255),4 mes "mes opt(s):"+mesopt,4 mes "mes shadow_size(d):"+(shadowsize+1),4 mes "gmode 6 switch(z):"+g6switch+" ("+g6col+","+g6col(1)+","+g6col(2)+")",4 mes "gmul(x/c):"+gmul(0)+","+gmul(1)+","+gmul(2),4 mes "buf->main alpha(up/down):"+alpha,4 mes "draw buf alpha(left/right):"+bufalpha,4 if (mousex > 0) && (mousex < wx) && (mousey > 0) && (mousey < wy) { mcol = vram(mousex+(wy-mousey)*wx) } else { mcol = 0 } pos 300,50 mes "pget("+mousex+","+mousey+")",4 mes "->alpha:"+(((mcol&0xFF000000)>>24)&0xFF),4 mes "->r,g,b:"+(mcol&0xFF)+","+((mcol&0xFF00)>>8)+","+((mcol&0xFF0000)>>16),4 gmulcolor gmul,gmul(1),gmul(2) gfilter 2 y = 170 repeat 7 gmode 0:color 255,255,255 pos 70+cnt*64,y+20 : mes ""+cnt,4 gmode cnt,,,alpha // 直接描画 grect 40+cnt*64+32,y+56, 0, 64, 32 pos 40+cnt*64,y+74 : mes teststr,mesopt // buf2(alpha 0 クリア) pos 40+cnt*64,y+120 : celput 2,0 // buf3(alpha 255 クリア) pos 40+cnt*64,y+204 : celput 3,0 // 想定色を計算して直接描画 gmode cnt,,,alpha*bufalpha/255:color gmul(0),gmul(1),gmul(2) grect 40+cnt*64+32,y+304, 0, 64, 32 pos 40+cnt*64,y+324 : mes teststr,mesopt // 2x1引き伸ばし gmode cnt,,,alpha color 255,255,255 : boxf 40+cnt*64,y+380, 40+cnt*64+64-1,y+380+32-1 : pos 40+cnt*64,y+380 : celput 4,0, 32.0, 32.0 loop color 255,255,255 : gmode 0 pos 10,y : mes "scr0->直接描画",4 pos 10,y+100 : mes "buf2:celbitmap(alpha 0 クリア)->celput",4 pos 10,y+184 : mes "buf3:color:boxf(alpha 255 クリア)->celput",4 pos 10,y+268 : mes "buf2と3の想定色",4 pos 10,y+360 : mes "不透明($FF0000FF)+透明($00000000)の2x1ピクセルをgfilter 2で引き伸ばし白背景に置く",4 if g6switch { color g6col,g6col(1),g6col(2) : gmode 6,,,255 : grect wx/2,wy-wy*3/8,0,wx,wy*3/4 } celbitmap 1, vram, celbitmap_capture redraw 1 goto *MAIN



buhio

リンク

2024/2/18(Sun) 13:19:37|NO.101255

こんにちわ
質問の回答でなくて恐縮ですが、hsp3dish/hgimg4におけるアルファ値の取り扱いが、標準と少し違うようで、
私もよくわかっていません。

 boxfでクリアすると透明色が消えてしまうので、ほかにアイデアが浮かばなかったのですが、
完全な透明画像を用意して、毎回下地として使う方法で試してみました。
 cellloadしか動かず、picloadはサポート対象外?なのかな。
hgimg4をインクルードすると、celloadしたバッファに書き込んだりすることができませんでした。
そこで、書き込み用バッファを別に用意して、透明画像をまずコピーし、その上に追加で描画してみました。

 的外れ、またはアホなテストだったらごめんなさいね。


#include "hgimg4.as" gpreset //メイン画面 screen 0,256,256 //buffer1 256*256の透明画像を読込 buffer 1,256,256,screen_offscreen celload "alpha0.png",1,0 ;完全透明画像を読込 //buffer2 書き込み用 buffer 2,256,256,screen_offscreen gsel 0 gmode 2 ;gmode 0 にすると透明色がコピーされない setcls CLSMODE_SOLID,$ff0000;わかりやすく赤でクリア *main timer++ //書き込み用バッファ gsel 2 redraw 0 color 0,0,255 boxf ;試験であえて単色塗りつぶし pos 0,0 celput 1 ;透明画像で上書き pos 0,0 color 0,0,0 mes "buffer2:"+timer ;何か書き込む redraw 1 //メインバッファ gsel 0 redraw 0 gpdraw pos 50,50 celput 2 ;書き込み用バッファをコピー color 255,255,255 pos 0,0 mes "メインスクリーン" redraw 1 await 1000/60 goto *main



moss

リンク

2024/2/18(Sun) 19:01:21|NO.101256

回答ありがとうございます。
別バッファからのコピーは完全に頭から抜けていました。
さらにgmode 0はDishのマニュアルにアルファチャンネルなし(無視)と書かれていますが、
実はα値を色計算に使わないだけでα値そのままコピー、という点に気付けたのも大きな収穫です。
celbitmapとは比較にならない速度に範囲指定も可能、その他諸々汎用性がありそうなので
バッファのクリアに関してはこの手法でやってみようと思います。

#include "hgimg4.as" gpreset wx = 512 : wy = 512 screen 0,wx,wy buffer 1,wx,wy,screen_offscreen : dim vram, wx*wy buffer 2,256,256,screen_offscreen dim bufclr,256*256 repeat 256 // 適当にα(0~255)のものを作る a = cnt repeat 256 bufclr(a*256+cnt) = (a<<24)+(cnt<<16)+(cnt<<8)+(cnt) loop loop celbitmap 2, bufclr, celbitmap_rgb setcls CLSMODE_SOLID,$800000 *main timer++ gsel 0 redraw 0 pos 150,0 : gmode 0 : celput 2,0 : mes "gmode 0",4 pos 150,260 : gmode 3,,,255 : celput 2,0 : mes "gmode 3",4 color 255,255,255 pos 0,0 celbitmap 1, vram, celbitmap_capture if (mousex > 0) && (mousex < wx) && (mousey > 0) && (mousey < wy) { mcol = vram(mousex+(wy-mousey)*wx) } else { mcol = 0 } pos 10,180 mes "pget("+mousex+","+mousey+")",4 mes "alpha:"+(((mcol&$FF000000)>>24)&$FF),4 mes "r,g,b:"+(mcol&$FF)+","+((mcol&$FF00)>>8)+","+((mcol&$FF0000)>>16),4 redraw 1 await 1000/60 goto *main
レンダリングバッファに対する描画によるアルファブレンド問題は引き続き募集しています。
速度を気にしなければgdiなど別のもので作画して転送するという方法もあるのですが、
それはhgimg4を使う意味がないのでは…と、出来ればhgimg4内で実現したいというのが本音です。

なおテスト用スクリプトの2x1引き伸ばしに関しては私の検証不足だったので忘れてください。
(赤不透明と黒透明が混ざったらそりゃあの結果になるよねという話)



buhio

リンク

2024/2/19(Mon) 14:48:01|NO.101258

ちなみに NO.101256 の提示されたコードで、アルファの問題は発生していますか?

いまいちどういう問題かわからなくて、個人的には問題点をもう少しかみくだいて提示して欲しいです。



moss

リンク

2024/2/20(Tue) 01:26:16|NO.101262

NO.101256のコードの上側はgmode 0でコピーした場合にα値がそのままコピーされている事を確認するためのものです。
下側はそれをgmode 3でα値を適用してコピーしていますが、
メモリ上で任意に作成したピクセルデータをバッファに転送しているため問題はないです。

とりあえず問題点を一つに絞ります。

#include "hgimg4.as" gpreset wx = 256 : wy = 256 screen 0, wx,wy,,(ginfo_dispx-wx)/2,(ginfo_dispy-wy)/2 buffer 1, wx, wy, screen_offscreen : dim vram, wx*wy // pget用 bufsize = 128 buffer 2, bufsize, bufsize, screen_offscreen redraw 0 // buf2を不透明の黒で塗りつぶし // 真ん中に白の半透明(50%)を描画する color : boxf color 255,255,255 : gmode 3,,,127 : grect bufsize/2, bufsize/2, 0, bufsize-64, bufsize-64 redraw 1 *MAIN await 1000/60 gsel 0 // main screen redraw 0 color 255 : boxf pos 0, 0 : gmode 0 : celput 2 pos wx/2, 0 : gmode 3,,,255 : celput 2 celbitmap 1, vram, celbitmap_capture if (mousex > 0) && (mousex < wx) && (mousey > 0) && (mousey < wy) { mcol = vram(mousex+(wy-mousey)*wx) } else { mcol = 0 } pos 5,wy/2+5 : color 255,255,255 mes "pget("+mousex+","+mousey+")",4 mes "->alpha:"+(((mcol&0xFF000000)>>24)&0xFF),4 mes "->r,g,b:"+(mcol&0xFF)+","+((mcol&0xFF00)>>8)+","+((mcol&0xFF0000)>>16),4 redraw 1 goto *MAIN
レンダリングバッファ(RGBA=0,0,0,255)に color 255,255,255:gmode 3,,,127:grect等で描画すると
色としては 255*127/255=127 で灰色、RGBAは(127,127,127,191)になる。
それをメイン画面(RGBA=255,0,0,255)に gmode 0で描画するとα値を計算しないのでRGBAは(127,127,127,191)になる。
しかしgmode 3,,,255で描画するとα値が適用されてRGBAは(159,95,95,207)になる。(背景が透けてる)

つまりレンダリングバッファの不透明に半透明を描画したら半透明になってしまい、
メイン画面等にコピーする際に問題になるという事です。
レンダリングバッファで作画する際に半透明を使わなければ問題になりませんが、
正直半透明で重ねたい部分もあり、文字のアンチエイリアスもこの問題にひっかかるため困っています。



buhio

リンク

2024/2/20(Tue) 12:08:04|NO.101265

 風呂入りながら、ず〜と考え、なんども読み直しなんとなくわかってきた(ような)気がします。。

 1.完全透明 の黒でbuffer 1を作る(RGBA 0,0,0,0)
 2.完全不透明の白でbuffer 2を作る(RGBA 255,255,255,255)
 3.gmode 3の127(50%)で、buffer 2をbuffer 1へコピーする
 4.biuffer 1にはRGBA(127,127,127,127)の灰色画像ができる。(未検証、あってる?191だと困る)

 5.できた画像1をメインスクリーン0へ、gmode 3でコピーすると、当然buffer 0と1がブレンドされる

 6.なので、gmode 2でコピーするとアルファ値込みでブレンドせずにコピーできる。。

 と、空想の中で考えていたので、全然未検証
 そもそもなんだろう、しっくりこない。なんかいまいちゴールが分からないな。。


 hsp3dishでは、celput、gcopy等の画像コピー命令で、アルファチャンネルを含めた コピーが実行されます。そのため、gmodeによる指定は、いくつか違いが出ます。 gmode 0,1 : アルファチャンネルなし(無視) gmode 2 : アルファチャンネル有効、半透明レート無効 gmode 3,4 : アルファチャンネル有効、半透明レート有効 gmode 5 : 色加算・アルファチャンネル有効、半透明レート有効 gmode 6 : 色減算・アルファチャンネル有効、半透明レート有効 アルファチャンネルは、PNG形式などの画像データに付加される情報です。 通常のHSPにあるRGBが0の場合に透過するモードや、特定の色コードを透過するモードは選択できませんので注意してください。 現在のバージョンでは、android(NDK)ランタイムにおいてgmode 6(色減算)はサポートされませんのでご注意ください。

 空想のまま間違ってら流してください。



usagi

リンク

2024/2/20(Tue) 14:13:19|NO.101266

mossさんこんにちわ。

"NO.101262"のサンプルの挙動はあってると思うので、
おそらく理想としている期待される挙動としては、
両方の四角がグレーになるのが正解でしょうか?

gmodeには:αチャンネル無効、半透明レート有効
というブレンドモードが無いので、そう言った事をしたいのかと思いました。

アルファブレンドって色々な計算があるので、
この場合だと、grectを"乗算済みアルファ"的な感じで

r = 255 : g = 255 : b = 255 : a = 127 color r*a/255, g*a/255, b*a/255 : gmode 3,,,255
とcolorに計算済にしてしまうか。
α計算済で、コピーするシェーダー用意した方が良いのかもしれませんね。

※ここのサイトの下部にあるような、両方オレンジになるのが理想的な。
https://dxlib.xsrv.jp/lecture/PremulAlpha/PremulAlpha.html


>4.biuffer 1にはRGBA(127,127,127,127)の灰色画像ができる。
buhioさんの例がイイ感じですよね。
これは実際には50%グレーより薄い灰色(下地が50%透ける)になるので、
おそらくRGBA(127,127,127,255)のα計算済の画像をオフスクリーンに
生成したいように思えました。

※余談
HSPだとcolorにαが無いからか、半透明レートがソースαにも使われるようですね。
outA = srcA * A + dstA * ( 1 - A )
A: 191 ≒ 0.75 = 0.5 * 0.5 + 1 * (1-0.5) ※(0.5は127なので,dstAの1は255)

なのでソースαは二乗になってしまうので、、
RGBA(127,127,127,127)ではなく
RGBA(127,127,127,191)ができるみたいですよ。

これが意図した仕様なのか、分からないですがhgimg4の時は
オプションでcolorがRGBA受けれると便利になるかもですね。



buhio

リンク

2024/2/20(Tue) 18:44:59|NO.101267

うーむ 色々悩んだんですが思った通りにならなかったです。
難しいな。アルファ。。。なぜ127にならず、170なんだ?191はどこへ行った?
混乱してしまいました。ごめんね


#include "hgimg4.as" gpreset wx = 512 : wy = 512 screen 0,wx,wy dim vram, wx*wy // pget用 ;====buffer1 完全透明の黒==== buffer 1,256,256,screen_offscreen dim bufclr,256*256 repeat 256 // 適当にα(0~255)のものを作る a = cnt repeat 256 bufclr(a*256+cnt) = 0;(0<<24)+(0<<16)+(0<<8)+(0) loop loop celbitmap 1, bufclr, celbitmap_rgb ;↓mesやboxfすると上手くいかない?バグる?謎 ;color 255,255,255 ;pos 0,0 ;mes "buffer1" ;====buffer2 完全不透明の白==== buffer 2,256,256,screen_offscreen pos 0,0 color 255,255,255:boxf color 255,0,0:mes "buffer2" color 0,0,255:circle 0,0,255,255,0 ;====celbitmap読みだし用===== buffer 3,wx,wy,screen_offscreen ;====メインプログラム==== gsel 0 setcls CLSMODE_SOLID,$000000 *main redraw 0 pos 0,0:gmode 2,,,255 :celput 1 ;完全な透明黒で一旦塗る pos 0,0:gmode 3,,,127 :celput 2 ;不透明な白でgmode 3(50%)をコピー →灰色RGBA(127,127,127,127)、、にならない ;gmode 0→RGBA(127,127,127,85) 85?? gmode 3→RGBA(127,127,127,170) 170?? celbitmap 3, vram, celbitmap_capture if (mousex > 0) && (mousex < wx) && (mousey > 0) && (mousey < wy) { mcol = vram(mousex+(wy-mousey)*wx) } else { mcol = 0 } pos 5,wy/2+5 : color 255,255,255 mes "pget("+mousex+","+mousey+")",4 mes "->alpha:"+(((mcol&0xFF000000)>>24)&0xFF),4 mes "->r,g,b:"+(mcol&0xFF)+","+((mcol&0xFF00)>>8)+","+((mcol&0xFF0000)>>16),4 redraw 1 await 1000/60 goto *main



moss

リンク

2024/2/20(Tue) 19:51:55|NO.101268

不完全ながら自己解決できました。
色々参考になるご意見など、ありがとうございました。

>両方の四角がグレーになるのが正解でしょうか?
その通りです。
不透明に半透明を描画しても不透明のまま、というのが理想です。

色々調べたところ glBlendFuncSeparate でアルファ値の計算を変えれば良いらしい。
https://qiita.com/nariakiiwatani/items/df3eb6a49be0fa431387
との事なので試してみた結果、上手くいきませんでしたが上手くいきました。

ダメな点はgmode 0やboxfを使うと glBlendFuncSeparate の設定が無視されるようになる。
再設定してもダメでgmode 1:grect等で1回描画すると直ります。
やや使いにくい点もあれど、理想通りの描画結果になってくれるのでとりあえずOK!
とはいえ、問題点もあるしgl版だからってgl関数直接呼ぶのも大分アレな気もするので
hgimg4側で対応してほしいですね。

ついでにコレRGB無視してα値だけ操作できるのでは?と思い試したらこれもできました。
以下のスクリプトのbuf8あたりでやってます。

#module "glfunc" #uselib "opengl32" #cfunc getProc "wglGetProcAddress" sptr #define GL_ZERO 0 #define GL_ONE 1 #define GL_SRC_COLOR 0x0300 #define GL_ONE_MINUS_SRC_COLOR 0x0301 #define GL_SRC_ALPHA 0x0302 #define GL_ONE_MINUS_SRC_ALPHA 0x0303 #define GL_DST_ALPHA 0x0304 #define GL_ONE_MINUS_DST_ALPHA 0x0305 #define GL_DST_COLOR 0x0306 #define GL_ONE_MINUS_DST_COLOR 0x0307 #define GL_SRC_ALPHA_SATURATE 0x0308 #deffunc glfunc_init dim _glprm _glBlendFuncSeparate = getProc("glBlendFuncSeparate") return #deffunc glBlendFuncSeparate int p1, int p2, int p3, int p4 if _glBlendFuncSeparate == 0 : return -1 _glprm = p1,p2,p3,p4 return callfunc(_glprm,_glBlendFuncSeparate,4) #define global blendAlphaZero glBlendFuncSeparate 0,0,0,0 #define global blendAlphaOne glBlendFuncSeparate GL_SRC_ALPHA@glfunc, GL_ONE_MINUS_SRC_ALPHA@glfunc, GL_SRC_ALPHA@glfunc, GL_ONE@glfunc #define global blendAlphaOnly glBlendFuncSeparate GL_ZERO@glfunc, GL_ONE@glfunc, GL_ONE@glfunc, GL_ZERO@glfunc #define global blendAlphaDefault glBlendFuncSeparate GL_SRC_ALPHA@glfunc, GL_ONE_MINUS_SRC_ALPHA@glfunc, GL_SRC_ALPHA@glfunc, GL_ONE_MINUS_SRC_ALPHA@glfunc #global glfunc_init #include "hgimg4.as" #define setfont(%1=20,%2=17) font "Yu gothic UI", %1, %2 teststr = "abcABCあいう" gpreset wx = 640 : wy = 256 screen 0, wx,wy,,(ginfo_dispx-wx)/2,(ginfo_dispy-wy)/2 : setfont 16,16 setcls 0 buffer 1, wx, wy, screen_offscreen : dim vram, wx*wy // pget用 bufsize = 128 // buf2 不透明の黒で boxf // 真ん中に白の半透明(50%)を描画する buffer 2, bufsize, bufsize, screen_offscreen : setfont redraw 0 color : boxf color 255,255,255 : gmode 3,,,127 grect bufsize/2, bufsize/2, 0, bufsize-64, bufsize-64 pos 5,100 : gmode 3,,,255 : mes teststr redraw 1 // buf3 不透明の黒で boxf // 真ん中に白の半透明(50%)を描画する(glBlendFuncSeparate有り) buffer 3, bufsize, bufsize, screen_offscreen : setfont redraw 0 color : boxf color 255,255,255 : gmode 3,,,127 blendAlphaOne grect bufsize/2, bufsize/2, 0, bufsize-64, bufsize-64 pos 5,100 : gmode 3,,,255 : mes teststr blendAlphaDefault redraw 1 // buf4 不透明の黒で gmode 0 : grect // 真ん中に白の半透明(50%)を描画する(glBlendFuncSeparate有り) buffer 4, bufsize, bufsize, screen_offscreen : setfont redraw 0 color : gmode 0 : grect bufsize/2,bufsize/2,0,bufsize,bufsize color 255,255,255 : gmode 3,,,127 blendAlphaOne grect bufsize/2, bufsize/2, 0, bufsize-64, bufsize-64 pos 5,100 : gmode 3,,,255 : mes teststr blendAlphaDefault redraw 1 // buf5 不透明の黒で gmode 1 : grect // 真ん中に白の半透明(50%)を描画する(glBlendFuncSeparate有り) buffer 5, bufsize, bufsize, screen_offscreen : setfont redraw 0 color : gmode 1 : grect bufsize/2,bufsize/2,0,bufsize,bufsize color 255,255,255 : gmode 3,,,127 blendAlphaOne grect bufsize/2, bufsize/2, 0, bufsize-64, bufsize-64 pos 5,100 : gmode 3,,,255 : mes teststr blendAlphaDefault redraw 1 // buf6 不透明の黒で gmode 1 : grect // 真ん中に白の半透明(50%)を描画する(glBlendFuncSeparate有り、boxfを挟む) buffer 6, bufsize, bufsize, screen_offscreen : setfont redraw 0 color : gmode 1 : grect bufsize/2,bufsize/2,0,bufsize,bufsize color 255,255,255 : gmode 3,,,127 blendAlphaOne grect bufsize/2, 48, 0, bufsize-64, bufsize-96 boxf 0,0,0,0 grect bufsize/2, 80, 0, bufsize-64, bufsize-96 pos 5,100 : gmode 3,,,255 : mes teststr blendAlphaDefault redraw 1 // buf7 不透明の黒で boxf+grect // 真ん中に白の半透明(50%)を描画する(glBlendFuncSeparate有り、クリア後にgrect 0,0,0,0,0を入れる) buffer 7, bufsize, bufsize, screen_offscreen : setfont redraw 0 color : boxf : gmode 1 : grect 0,0,0,0,0 color 255,255,255 : gmode 3,,,127 blendAlphaOne grect bufsize/2, bufsize/2, 0, bufsize-64, bufsize-64 pos 5,100 : gmode 3,,,255 : mes teststr blendAlphaDefault redraw 1 // buf8 gradf 青->緑 // blendAlphaOnlyでα値のみをいじる buffer 8, bufsize, bufsize, screen_offscreen : setfont redraw 0 gmode 1 : gradf 0,0,bufsize,bufsize,0,$0000FF,$00FF00 blendAlphaOnly gmode 3,,,0 : grect bufsize/2, bufsize/2, 0, bufsize, bufsize // 全体をa=0にする repeat 16 gmode 3,,,cnt*16 // ブレンド率がそのまま書き込みα値になる grect bufsize/2, bufsize/2+cnt, 0, bufsize-64-cnt*4, bufsize-64-cnt*4 loop pos 5,100 : gmode 3,,,255 : mes teststr color 255,0,0 line 0,0,bufsize,bufsize // lineにも効く(a=255扱い) line 1,0,bufsize+1,bufsize pset bufsize-1,0:pset bufsize-2,0:pset bufsize-1,1:pset bufsize-2,1 // psetにも効く(a=255扱い) circle 80,60,90,70,1 // circleはダメ boxf 80,80,90,90 // boxfもダメ blendAlphaDefault redraw 1 *MAIN await 1000/60 gsel 0 redraw 0 color 255,127, : boxf : color 255,255,255 pos 0, 0 : gmode 0 : celput 2 : pos 0, 0 : mes "理想の色" pos 128, 0 : gmode 3,,,255 : celput 2 : pos 128, 0 : mes "buf2\nそのまま" pos 256, 0 : gmode 3,,,255 : celput 3 : pos 256, 0 : mes "buf3\nboxfクリア\nblendAlphaOne\ngrect\nmes" pos 384, 0 : gmode 3,,,255 : celput 4 : pos 384, 0 : mes "buf4\ngmode 0:grectクリア\nblendAlphaOne\ngrect\nmes" pos 512, 0 : gmode 3,,,255 : celput 5 : pos 512, 0 : mes "buf5\ngmode 1:grectクリア\nblendAlphaOne\ngrect\nmes" pos 128, 128 : gmode 3,,,255 : celput 6 : pos 128, 128 : mes "buf6\ngmode 1:grectクリア\nblendAlphaOne\ngrect\nboxf\ngrect\nmes" pos 256, 128 : gmode 3,,,255 : celput 7 : pos 256, 128 : mes "buf7\nboxfクリア\ngmode 1:grect 0,0,0,0\nblendAlphaOne\ngrect\nmes" pos 384, 128 : gmode 3,,,255 : celput 8 : pos 384, 128 : mes "buf8\ngradfクリア(青->緑)\nblendAlphaOnly\ngrect x16\nmes:line:pset\ncircle:boxf" celbitmap 1, vram, celbitmap_capture if (mousex > 0) && (mousex < wx) && (mousey > 0) && (mousey < wy) { mcol = vram(mousex+(wy-mousey)*wx) } else { mcol = 0 } pos 5,wy/2+5 : color 255,255,255 mes "pget("+mousex+","+mousey+")",4 mes "->alpha:"+(((mcol&0xFF000000)>>24)&0xFF),4 mes "->r,g,b:"+(mcol&0xFF)+","+((mcol&0xFF00)>>8)+","+((mcol&0xFF0000)>>16),4 redraw 1 goto *MAIN



usagi

リンク

2024/2/21(Wed) 20:32:22|NO.101275

mossさん

おぉ、イイ感じですね。

GL_BLENDがDisableになっているのかなぁと思って、
glEnable(GL_BLEND)呼び出してみたのですが、ダメでした。
別の原因かなぁと思い、openHSPのソースながめてたら
hgio_boxfAlpha()の中で、こんな分岐がありました。


if (alphamode) { a_val = game->setPolyColorBlend(bm->gmode, bm->gfrate); } else { a_val = game->setPolyColorBlend(0, 0); }

どうやらhgimg4のboxfには隠し第五バラメータがあるようで、
boxfでもこうしたら私の環境では回避できましたよ。


// buf3 不透明の黒で boxf // 真ん中に白の半透明(50%)を描画する(glBlendFuncSeparate有り) buffer 3, bufsize, bufsize, screen_offscreen : setfont redraw 0 gmode 1/*←ココ3,,255でもいい*/ : color : boxf ,,,, 1 /*←ココ*/ color 255,255,255 : gmode 3,,,127 blendAlphaOne grect bufsize/2, bufsize/2, 0, bufsize-64, bufsize-64 pos 5,100 : gmode 3,,,255 : mes teststr blendAlphaDefault redraw 1

ちなみにgrectではsetPolyColorBlend(0, 0);は呼び出されてないので、
この(0,0)が指定されるとglBlendFunc系はどこかで無効化されてるみたいですね。



usagi

リンク

2024/2/22(Thu) 04:33:31|NO.101279

>buhioさん
ホントだ、サンプルα170になってる。なんでだろう。。。これは察しが付なく難しいですね。
celbitmap_captureって実験的な機能なのでちょっと不安定かもですね。
私の別のPCでは描画結果は同じでも255でした。

あと0番スクリーンしか対応してなかったと思うので、0番って透明ではないですからRGBしか参考にならないかもしれません。
サンプルのbuffer 1,2の配列が見れれば分かりそうなんですけど。。。私にはお手上げです。

>mossさん
ついでにcircleの中身ものぞいてみたら、こちらは常にsetPolyColorBlend(0, 0)が呼び出されるようで、
同じようにglBlendFunc系は効かなくなりました。
boxfのようにalphamode用の第5パラメータがある訳でないので、こっちは回避出来ないですね。。。



moss

リンク

2024/2/22(Thu) 22:26:58|NO.101283

>NO.101267のスクリプト
celput 1と2のどちら側のgmodeを変えるのを想定しているのか分からなかったけど、
どちらをどう弄っても85や170にならなかったです。
GPUやドライバによって結果が変わる可能性もあるのか、
状況がうまく共有できなかったのはその辺の影響もありそうですね。
私の環境はRyzen 3400Gの内蔵GPUですがNO.101266の計算式通りの値になります。

>hgimg4のboxfには隠し第五バラメータ
こんなのあったんかい…
何気にgmodeとブレンド率が反映されるようになる点もおいしい。



記事削除

記事NO.パスワード
(質問が解決したスレッドは他の利用者に活用してもらうため、削除しないようお願いします)

NO.101252への返信

マスコット

好きなマスコットを選んでください。

名前

e-mail
HOME
  1. 初めて利用する方は、HSP3掲示板の使い方をお読みください。
  2. 不要部分の多い長いスクリプトの投稿は ご遠慮ください。
  3. 書き込みは自動改行されません。適度に改行を入れてください。
  4. スクリプトは小文字の<pre>〜</pre>で囲むと見やすく表示できます。

削除用パスワード

解決したら質問者本人がここをチェックしてください。

エラー発生時、再送信すると二重送信になることがあります。
回答が得られたら、お礼書き込み時に[解決]チェックしてください。
SPAM防止のためURLから始まる文章は投稿できません。
SPAM防止のため英文字のみの本文を投稿することはできません。

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