|
|
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)と変化するため想定した作画ができません。
これらの問題を改善する方法はありますか?
|
|
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
| |
|
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
|
|
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引き伸ばしに関しては私の検証不足だったので忘れてください。
(赤不透明と黒透明が混ざったらそりゃあの結果になるよねという話)
| |
|
2024/2/19(Mon) 14:48:01|NO.101258
ちなみに NO.101256 の提示されたコードで、アルファの問題は発生していますか?
いまいちどういう問題かわからなくて、個人的には問題点をもう少しかみくだいて提示して欲しいです。
|
|
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)になる。(背景が透けてる)
つまりレンダリングバッファの不透明に半透明を描画したら半透明になってしまい、
メイン画面等にコピーする際に問題になるという事です。
レンダリングバッファで作画する際に半透明を使わなければ問題になりませんが、
正直半透明で重ねたい部分もあり、文字のアンチエイリアスもこの問題にひっかかるため困っています。
| |
|
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(色減算)はサポートされませんのでご注意ください。
空想のまま間違ってら流してください。
|
|
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受けれると便利になるかもですね。
|
|
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
| |
|
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
| |
|
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系はどこかで無効化されてるみたいですね。
|
|
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パラメータがある訳でないので、こっちは回避出来ないですね。。。
|
|
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とブレンド率が反映されるようになる点もおいしい。
|
|