|
|
|
2024/2/21(Wed) 23:22:58|NO.101276
OpenGLについて2つの質問があります。
●OpenGLにHSP3のバッファの画像をテクスチャとして送りたい
OpenGLにHSP3のバッファの画像を送り、背景に単なる2D画像として表示したり、3Dモデルにテクスチャとして使用したりしたいです。
OpenGLの実装については初心者なので、今はまだ構造が簡単なバージョンであるOpenGL1.1の機能を使用したいです。
動作環境はWindows 2000等の旧スペックのPCを想定しています。
例えば、以下のサンプルのようなスクリプトの場合、どうやってHSP3のスクリーンのバッファを
OpenGL側へテクスチャとして送ればいいのでしょうか?
他にもテクスチャについては以下のようなことが不明です。
・OpenGLにはHSP3上のバッファではなく、直接「何々の画像ファイルをバッファに読み込め」という命令があるのでしょうか?
・OpenGL上でレンダリング生成した画像をOepnGL側で、3Dモデルにテクスチャとして使うことはできるのでしょうか?
・OpenGL側で生成した画像をHSP3のバッファ側へ送り、HSP3上でHSP3の命令を使ってgcopyなどで加工することはできるのでしょうか?
上記のようなことは可能なのでしょうか?
ぜひアドバイスお願い致します。
(以下のサンプルは、 https://wiki.hsp.moe/OpenGL%E3%81%AB%E3%82%88%E3%82%8B%E8%A1%A8%E7%A4%BA.html から抜粋させて頂いています)
//OpenGLはWindowsにAPIとして標準搭載されているため
//DLLを同封せずに単一のEXEとして3Dをすることができます
#define global PFD_TYPE_RGBA 0
#define global PFD_MAIN_PLANE 0
#define global GL_MODELVIEW $1700
#define global GL_NORMALIZE $0BA1
#define global GL_AUTO_NORMA $0D80
#define global GL_SMOOTH $1D01
#define global GL_DEPTH_TEST $0B71
#define global GL_PROJECTION $1701
#define global GL_POLYGON_OFFSET_FILL $8037
#define global GL_COLOR_BUFFER_BIT $4000
#define global GL_DEPTH_BUFFER_BIT $0100
#define global GL_LINES $0001
#define global GL_LINE_LOOP $0002
#define global GL_POLYGON $0009
#uselib "opengl32.dll" //Win32APIですのでdllを同封しなくてすみます
#func global glClearColor "glClearColor" int,int,int,int
#func global glClear "glClear" int
#func global glColor3d "glColor3d" double,double,double
#func global glBegin "glBegin" int
#func global glVertex2d "glVertex2d" double,double
#func global glVertex3d "glVertex3d" double,double,double
#func global glNormal3d "glNormal3d" double,double,double
#func global glEnd "glEnd"
#func global glFlush "glFlush"
#func global glRotated "glRotated" double,double,double,double
#func global glLightfv "glLightfv" int,int,int
#func global glLightModelfv "glLightModelfv" int,int,int
#func global glMaterialfv "glMaterialfv" int,int,int
#func global glEnable "glEnable" int
#cfunc global wglCreateContext "wglCreateContext" int
#func global wglDeleteContext "wglDeleteContext" int
#func global wglMakeCurrent "wglMakeCurrent" int,int
#func global glMatrixMode "glMatrixMode" int
#func global glLoadIdentity "glLoadIdentity"
#func global glViewport "glViewport" int,int,int,int
#cfunc global glGenLists "glGenLists" int
#func global glNewList "glNewList" int,int
#func global glEndList "glEndList"
#func global glShadeModel "glShadeModel" int
#func global glPushMatrix "glPushMatrix"
#func global glCallList "glCallList" int
#func global glPopMatrix "glPopMatrix"
#func global glDisable "glDisable" int
#func global glLineWidth "glLineWidth" int
#func global glTranslated "glTranslated" double,double,double
#func global glPolygonOffset "glPolygonOffset" int,int
#uselib "glu32.dll"//Win32API
#func global gluLookAt "gluLookAt" double,double,double,double,double,double,double,double,double
#func global gluPerspective "gluPerspective" double,double,double,double
#uselib "gdi32.dll"//Win32API
#func global SwapBuffers "SwapBuffers" int
#cfunc global ChoosePixelFormat"ChoosePixelFormat" int,int
#func global SetPixelFormat "SetPixelFormat" int,int,int
#uselib "user32.dll"//Win32API
#cfunc global GetDC "GetDC" int
#func global ReleaseDC "ReleaseDC" int,int
#module
#defcfunc d2f double d_ //double を floatに変換する
d=d_
f=0
asdf=lpeek(d, 4)
f = asdf & 0x80000000
if d ! 0 {
f |= (((asdf >> 20) & 0x7FF) -896) << 23
f |= (asdf << 3) & 0x7FFFFF
f |= (lpeek(d, 0) >> 29) & 7
}
return f
//ウィンドウにOpenGLを関係付ける
#deffunc GLinit
;このpfdの部分はChoosePixelFormat用の構造体をOpenGLに送るための準備のようだが、値の意味はよく分からない
dim pfd ,24
pfd(0)=96
pfd(1)=37 , PFD_TYPE_RGBA
pfd(3)=24
pfd(4)=0,0,0,0,0,0
pfd(10)=0,0,0, 0,0,0,0
pfd(17)=32,0,0
pfd(20)=PFD_MAIN_PLANE,0,0,0,0
WinDC=GetDC(hwnd);HSP3のウィンドウハンドル?
pixelFormat = ChoosePixelFormat( WinDC,varptr(pfd) )
SetPixelFormat WinDC,pixelFormat,varptr(pfd)
hRC = wglCreateContext( WinDC )
wglMakeCurrent WinDC, hRC
//オブジェクト描画モードにする。
glMatrixMode GL_MODELVIEW
glLoadIdentity
//////////////////////////////////////////////
//必要な機能の有効化
//
glEnable GL_NORMALIZE
glEnable GL_AUTO_NORMAL
glShadeModel GL_SMOOTH
glEnable GL_DEPTH_TEST //Zバッファを使用する
return
#deffunc GLview
w=ginfo_winx
h=ginfo_winy
glMatrixMode GL_PROJECTION
glLoadIdentity
gluPerspective 60, 1.0*w/h, 0.3, 200
glViewport 0, 0, w , h
glMatrixMode GL_MODELVIEW
return
#deffunc GLdraw
glFlush
SwapBuffers WinDC
return
//キューブを作る
;おそらく、この部分でglTexCoord2fでUVを送ればいい?
#deffunc Cube double x,double y,double z,int mode
glBegin mode
glNormal3d 1,0,0
glVertex3d x, -y, -z
glVertex3d x, y, -z
glVertex3d x, y, z
glVertex3d x, -y, z
glEnd
glBegin mode
glNormal3d -1,0,0
glVertex3d -x, -y, -z
glVertex3d -x, y, -z
glVertex3d -x, y, z
glVertex3d -x, -y, z
glEnd
glBegin mode
glNormal3d 0,1,0
glVertex3d -x, y, -z
glVertex3d x, y, -z
glVertex3d x, y, z
glVertex3d -x, y, z
glEnd
glBegin mode
glNormal3d 0,-1,0
glVertex3d -x, -y, -z
glVertex3d x, -y, -z
glVertex3d x, -y, z
glVertex3d -x, -y, z
glEnd
glBegin mode
glNormal3d 0,0,1
glVertex3d -x, -y, z
glVertex3d x, -y, z
glVertex3d x, y, z
glVertex3d -x, y, z
glEnd
glBegin mode
glNormal3d 0,0,-1
glVertex3d -x, -y, -z
glVertex3d x, -y, -z
glVertex3d x, y, -z
glVertex3d -x, y, -z
glEnd
return
//終了時に開放する
#deffunc ReleaseOpenGL onexit
wglMakeCurrent WinDC,0
wglDeleteContext hRC
ReleaseDC hwnd,WinDC
return
#global
///////////////////////////////////////////////////////////////////////
//
// プログラム始まり
//
///////////////////////////////////////////////////////////////////////
GLinit //初期化
//クリアカラー(背景色)赤 緑 青 アルファ値 (パラメータ範囲 0.0〜1.0)
glClearColor d2f(0.118), d2f(0.255), d2f(0.353),d2f(0)
r=M_PI/4
glEnable GL_POLYGON_OFFSET_FILL
glPolygonOffset d2f(1.1),d2f(1.1)
*main
glPopMatrix //座標系を展開
glPushMatrix //座標系を記憶
//ウィンドウサイズにおける表示域の設定(ウィンドウリサイズの際に呼ばれるべき)
GLview
//クリアーカラーにもとづいて 背景塗りつぶし
glClear GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT
//カメラ位置 x,y,z カメラ目標位置 x,y,z カメラ上方向ベクトル x,y,z
gluLookAt sin(r)*30,10,cos(r)*30, 0,0,0, 0,1,0
//////////////////////描画領域はじめ//////////////////////
//軸の線を描画
glLineWidth d2f(2.0) //線幅
glBegin GL_LINES
//glColor3d の0.0〜1.0は hspのcolorでいうところの0〜255 と等価
glColor3d 1.0, 0.0, 0.0//赤
glVertex3d 0, 0, 0//x
glVertex3d 30, 0, 0
glEnd
glBegin GL_LINES
glColor3d 0.0, 1.0, 0.0//緑
glVertex3d 0, 0, 0//y
glVertex3d 0, 30, 0
glEnd
glBegin GL_LINES
glColor3d 0.0, 0.0, 1.0 //青
glVertex3d 0, 0, 0//z
glVertex3d 0, 0, 30
glEnd
//黒箱
glPushMatrix //カレント位置を記憶
glTranslated 3,1,3 //カレント位置をずらす
glColor3d 0.0,0.0,0.0 //色 (黒)
Cube 1,1,1,GL_POLYGON //ポリゴンの箱を作る
glColor3d 1.0, 0.0, 0.0 //色 (赤)
glLineWidth d2f(1.0) //線幅
Cube 1,1,1,GL_LINE_LOOP //ワイヤーでできた箱を作る
glPopMatrix //ずれたカレントを前回記憶した座標に元に戻す
//////////////////////描画領域おわり//////////////////////
GLdraw //描画&画面更新
r+=0.03 //カメラのXZ平面上の角度を加算する
await 1000/60
goto *main
●OpenGL3.3の機能も使用してみたい
これは上記の件とは別件としての考えなのですが、今はまだOpenGLの実装に慣れていないのでOpenGL1.1の機能のみに意図的に絞って使用しているのですが、
もし慣れることができたら、いずれは使用しているOpenGLのバージョンを上げてOpenGL 3.3の機能を使用してみたいです。
バージョンがOpenGL 3.3の理由は、自分の使用しているPC環境の性能を考慮して、それくらいが丁度いいであろうという判断です。
こちらはWindows10等の比較的、最近のスペックのPCでの動作を想定しています。
まだ聞きかじり程度の知識しかないのですが、以下のような機能に取り組んでみたいと考えています。
・VBO(vertex buffer object)機能やVAO(vertex array object)機能を使用したい(これらの意味や違いはまだよく分からない)
・GLSLでvertex Shaderやfragment Shaderなどのshader機能を使用したい
・MRT(Multiple render targets)機能を使用したい
・instanced arrays機能を使用したい
ですが、HSP3でこれらの機能を実装したサンプルスクリプトがネット上で見つけられなかったので、どう実装したらいいのかよく分かりません。
技術者のブログ等でスクリプトは含んでいない簡単な概要的な資料は読んだのですが、このOpenGL3.3は上記のOpenGL1.1のスクリプトに単純に何かを付け加えればいいというようなものではない、
全く手続きの手順が異なる別物のような印象を受けました。
上記のようなOpenGL3.3の機能は、HSP3ではどう実装したらいいのでしょうか?
OpenGL1.1の頃は要はglVertex3dでポリゴンを1つずつ登録していけばよいという概念だと思うのですが、
OpenGL3.3の頃になるとVBOやVAO(使ったことがないので2つともまだ概念はよく分かりません)で1度に登録するという印象を受けました。
分かるのは、OpenGL1.1でglVertex3dで登録するよりも、動作パフォーマンスが高そうだということだけです。
MRTやinstanced arraysはshader側と関係の深い機能のように思われるのですが、これを実際に
HSP3側で実装するにはどうしたらいいのかよく分かりません。
MRTやinstanced arraysは実装できれば、どちらも動作パフォーマンスが向上するのであろうと思います。
ぜひ、こちらの方もどう実装したらいいのか分かる方がいらしたらアドバイスをお願い致します。
| |
|
2024/2/22(Thu) 04:38:05|NO.101280
こんにちわ、ちょっと本が書けてしまうくらい情報が多すぎてしまうので、
自分で組めるように導入だけですみませんがコメントさせていただきます。
>OpenGLにHSP3のバッファの画像をテクスチャとして送りたい
まず、テクスチャ関係の関数が記載のサンプルには無いので、
OpenGl関係のヘッダファイルを参考に使いたい関数をHSPに定義してくださいませ。
※たしかヘッダは配布禁止だったかと思いますので、Visualstuidoお持ちであれば、
Gl.hがどこかにあると思います。
そうしたらmrefでvarmの内容をglTexImage2Dで送れば良いと思います。(下記の内容を参考にすれば分かるかと思います)
クロノス・グループが企画を標準化してますので、サイトにリファレンスがあります。
https://registry.khronos.org/OpenGL-Refpages/es1.1/xhtml/
あくまで企画しているだけなので、Windowの実装であればこちらが参考になります。
https://learn.microsoft.com/ja-jp/windows/win32/opengl/gl-functions
>・OpenGLにはHSP3上のバッファではなく、直接「何々の画像ファイルをバッファに読み込め」という命令があるのでしょうか?
ありません。
自前でテクスチャとして読み込みたいバイト配列を転送します。
その配列がどの様なフォーマットかは自分で設定する必要があります。
wglを使われるのであればファイル読み込みはgdi経由が楽かと思いますがαを使うのであれば、gdi+がより簡単だと思います。
その場合テクスチャにGL_BGRA_EXTを指定します。(Win限定で定数がある)
(BMP, GIF, JPEG, PNG, TIFFなどが読める)
※ちょっとサンプル長くなるのでイメージです。 pixelsに画像配列を用意できればgdiを使う必要は無いです。
tex = -1 : gsi = 1, 0, 0, 0
GdiplusStartup gdipToken, gsi, 0 ; GDI+開始
if gdipToken = 0 : end ; エラー処理する
GdipLoadImageFromFile file_naem, img ; 画像ファイル読込
if img = 0 : end ; エラー処理する
; イメージの読み込みと生成
GdipGetImageWidth img, w
GdipGetImageHeight img, h
; 2の倍数かチェックする事!
sdim pixels, w*h*4
k = 0
repeat h : j = cnt;
repeat w : i = cnt
GdipBitmapGetPixel img, i, j, col
lpoke pixels, k, col : k+=4
loop
loop
GdipDisposeImage img ; 画像ファイル破棄
; テクスチャ転送
glPixelStorei GL_UNPACK_ALIGNMENT, 4
glGenTextures 1, tex
glBindTexture GL_TEXTURE_2D, tex
glTexImage2D GL_TEXTURE_2D, 0, 4, w, h, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, pixels
sdim pixels, 1
GdiplusShutdown gdipToken ; GDI+終了
>・OpenGL上でレンダリング生成した画像をOepnGL側で、3Dモデルにテクスチャとして使うことはできるのでしょうか?
できます。
FBO(hspのbufferみたいなもの)を作成しバインド(gselみたいなもの)し描画します。
3Dモデルはどの程度のレベルかによりますが、glBeginからなる都度転送する形が最初は分かりやすいです。
勉強、実験レベルではそれが分かりやすいですが、たとえばモデルを読み込む場合はそういった機能は無いので、自前でバイト配列を作成し
速度を出そうとするとVBO(頂点や法線、UVを先に転送しておく)を使わないと高速描画の恩恵は受けにくいです。
※ちょっとサンプルが膨大、大変になりそうなので、できますという事だけお伝えいたします。
>OpenGL側で生成した画像をHSP3のバッファ側へ送り、HSP3上でHSP3の命令を使ってgcopyなどで加工することはできるのでしょうか?
できます。
glReadPixelsでvramに転送が簡単だと思います。(この場合αは使えません。)
※これは簡単なのでモジュールっぽいサンプル
#deffunc glScreenShot int _p1
gsel _p1
mref _vram, 66
glReadPixels 0, 0, ginfo_sx, ginfo_sy, GL_BGR_EXT, GL_UNSIGNED_BYTE, _vram
redraw 1 : gsel glinit_sel
return
>OpenGL3.3の機能は、HSP3ではどう実装したらいいのでしょうか?
拡張機能の関数は、関数ポインタを初期化後に取得する必要があります。
"wglGetProcAddress"に関数名を指定すると、ポインタが得られますので、callfuncで呼び出すのが一番簡単です。
お使いの環境がサポートしている場合にはポインタが返ります。
#cfunc wglGetProcAddress "wglGetProcAddress" sptr
_glCreateShader = wglGetProcAddress("glCreateShader")
if _glCreateShader == 0 : end ; ポインタが返らなければお使いの環境では使えない。
_prm = /*ここに値*/
callfunc(_prm, _glCreateShader, 1)
HSPっぽい引数の書き方をしたければ先にダミーを定義して、
libpotr()でSTRUCTDAT構造体のポインタを取得してproc addressを書き換える方法もあります。
(実行後に取得する必要があるので。)
;先に関数定義
#cfunc global glCreateShader "glCreateShader" int
#func global glShaderSource "glShaderSource" int,int,sptr,var
; ここ魔法
#define glex(%1, %2) dupptr _lptr, %1+24, 4 : lpoke _lptr, 0, wglGetProcAddress(%2)
; 関数呼び出しのアドレスを設定(GL初期化後にこれらは呼び出す)
glex libptr(glCreateShader), "glCreateShader"
glex libptr(glShaderSource), "glShaderSource"
これらを乗り越えると、"VBO,GLSL...などの以下の機能"と書かれてる所に差し掛かれるかと思います。
と、ここまででかなりの学習コストがかかると思いますのでひとまずご情報は一旦以上で、まずは1.1をマスターすることをお勧めします。
マルチレンダやインスタシングなどはやってるうちに
「シェーダーで3つのフレームバッファに分けて描画したらいろいろ加工できるなぁ」
「マテリアル切り替えて描画する部分ボトルネックになってるなぁ」
「ここは切り替えなくても全部ビデオに転送しておければ一気に描画できるかも」
「ライティングを大量にしたいそれにアンチエイリアスは要らん。あと同じ物を大量に描画したい」
と言う感じで、ボトルネックや加工したい所がが出てきてら(そういう作品のデザイン)ならば行えばよいと思いました。
※CPUからGPUへのドローコールが減り速度はあがりますが、準備や制限もあり利便性の無いところもありますので
必ずしも良いものと言うわけでは無く、OpenGlの機能を使ったお利口な使い方と言えばいいんですかねぇ。。。
専用の命令がある訳ではなく、ゲームエンジンみたいなボタン一つで出来るものではないので、
自前で実装するなら、3.3をマスターしたら、その機能の組み合わせなのですから、そこまで学習した後でいいと思いました。
(glDrawBufferがglDrawBuffersになるだけとかだったりなので)
以上です。楽しみにしてます!!
| |
|
2024/2/24(Sat) 00:01:34|NO.101291
>usagi さん
アドバイスありがとうございます。
ですが、usagiさんのスクリプトを参考に試行錯誤してみたのですが、3Dポリゴンにテクスチャ適用がうまくいきません。
>まず、テクスチャ関係の関数が記載のサンプルには無いので、
>OpenGl関係のヘッダファイルを参考に使いたい関数をHSPに定義してくださいませ。
>※たしかヘッダは配布禁止だったかと思いますので、Visualstuidoお持ちであれば、
> Gl.hがどこかにあると思います。
>そうしたらmrefでvarmの内容をglTexImage2Dで送れば良いと思います。(下記の内容を参考にすれば分かるかと思います)
gl.hについてはbcc55のincludeに入っていたopenGL1.1のものを参考にしています。今回はWindows 2000等で動作させることを考えて、古いgl.hを使っています。
総合環境はVisual Windows for BC++を使用しています。BCC55についてもこの機能に同梱されたものを使っています。gl.hもbccのフォルダの方に入っていました。
Visual Windows for BC++
http://phys.cool.coocan.jp/physjpn/bccwin.htm
以下のサンプルについては、テクスチャを画像ではなく、pokeで作成しています。
HSP3上の画像のGL_BGR_EXT画像でも試したのですが失敗したので、pokeでGL_RGBAのものを作成した方が確実だろうと思ってそうしてみました。
ですが、pokeでGL_RGBAのもの作成して送ってみても3Dポリゴンにテクスチャが表示されていないようなのです。
最初にOpenGLに対してformatを指定するChoosePixelFormatのフォーマット指定にも関係しているのかもしれないと思ったので色々調べてみたのですが、よく分かりませんでした。
ChoosePixelFormatのこれらの構造体は何を意味しているのでしょうか? 例えばnVersionとは何のバージョンを示すものなのでしょうか?
送ったGL_RGBAのデータ自体はglDrawPixelsで表示させるとちゃんと表示されるので、OpenGLには転送はされているようです。
glDrawPixelsであれば、HSP3上のGL_BGR_EXTでの画像データの方でも表示されました。
表示されないのは、3Dポリゴンのテクスチャとしてのみという現象が起きています。
どうしてなのでしょうか?
>glScreenShot
glScreenShotの最後の引き数の部分をポインタに変更すると動作しました。
#define global PFD_TYPE_RGBA 0
#define global PFD_MAIN_PLANE 0
#define global GL_MODELVIEW $1700
#define global GL_NORMALIZE $0BA1
#define global GL_AUTO_NORMA $0D80
#define global GL_SMOOTH $1D01
#define global GL_DEPTH_TEST $0B71
#define global GL_PROJECTION $1701
#define global GL_POLYGON_OFFSET_FILL $8037
#define global GL_COLOR_BUFFER_BIT $4000
#define global GL_DEPTH_BUFFER_BIT $0100
#define global GL_LINES $0001
#define global GL_LINE_LOOP $0002
#define global GL_POLYGON $0009
#uselib "opengl32.dll"
#func global glClearColor "glClearColor" int,int,int,int
#func global glClear "glClear" int
#func global glColor3d "glColor3d" double,double,double
#func global glBegin "glBegin" int
#func global glVertex2d "glVertex2d" double,double
#func global glVertex3d "glVertex3d" double,double,double
#func global glNormal3d "glNormal3d" double,double,double
#func global glEnd "glEnd"
#func global glFlush "glFlush"
#func global glRotated "glRotated" double,double,double,double
#func global glLightfv "glLightfv" int,int,int
#func global glLightModelfv "glLightModelfv" int,int,int
#func global glMaterialfv "glMaterialfv" int,int,int
#func global glEnable "glEnable" int
#cfunc global wglCreateContext "wglCreateContext" int
#func global wglDeleteContext "wglDeleteContext" int
#func global wglMakeCurrent "wglMakeCurrent" int,int
#func global glMatrixMode "glMatrixMode" int
#func global glLoadIdentity "glLoadIdentity"
#func global glViewport "glViewport" int,int,int,int
#cfunc global glGenLists "glGenLists" int
#func global glNewList "glNewList" int,int
#func global glEndList "glEndList"
#func global glShadeModel "glShadeModel" int
#func global glPushMatrix "glPushMatrix"
#func global glCallList "glCallList" int
#func global glPopMatrix "glPopMatrix"
#func global glDisable "glDisable" int
#func global glLineWidth "glLineWidth" int
#func global glTranslated "glTranslated" double,double,double
#func global glPolygonOffset "glPolygonOffset" int,int
;画像関係らしき命令を追加
#func global glGenTextures "glGenTextures" int, sptr;これはsptrとwptrのsptrの方かも?
#func global glBindTexture "glBindTexture" int, int
#func global glTexImage2D "glTexImage2D" int, int, int, int, int, int, int, int, sptr;これはvarとsptrとwptrのどれだろう?
#func global glReadPixels "glReadPixels" int, int, int, int, int, int, sptr;これはsptrで動作した
#func global glTexCoord2f "glTexCoord2f" float, float
;アフィン変換系及びその他
#func global glRotatef "glRotatef" float, float, float, float
#func global glScaled "glScaled" double, double, double
#func global glScalef "glScalef" float, float, float
#func global glTranslatef "glTranslatedf" float, float, float
#func global glColor3f "glColor3f" float, float, float
#func global glVertex2f "glVertex2f" float, float
#uselib "glu32.dll"//Win32API
#func global gluLookAt "gluLookAt" double,double,double,double,double,double,double,double,double
#func global gluPerspective "gluPerspective" double,double,double,double
#uselib "gdi32.dll"//Win32API
#func global SwapBuffers "SwapBuffers" int
#cfunc global ChoosePixelFormat"ChoosePixelFormat" int,int
#func global SetPixelFormat "SetPixelFormat" int,int,int
#uselib "user32.dll"//Win32API
#cfunc global GetDC "GetDC" int
#func global ReleaseDC "ReleaseDC" int,int
;--------------------------------------------------------------------------------------------------------------------
; モジュール部分
#ifndef hsp3_opengl
#module hsp3_opengl
#define PFD_TYPE_RGBA 0
#define PFD_DOUBLEBUFFER 0x01
#define PFD_DRAW_TO_WINDOW 0x04
#define PFD_SUPPORT_OPENGL 0x20
#define PFD_MAIN_PLANE 0
//double を floatに変換する
#defcfunc d2f double d_
d=d_
f=0
asdf=lpeek(d, 4)
f = asdf & 0x80000000
if d ! 0 {
f |= (((asdf >> 20) & 0x7FF) -896) << 23
f |= (asdf << 3) & 0x7FFFFF
f |= (lpeek(d, 0) >> 29) & 7
}
return f
//ウィンドウにOpenGLを関係付ける
#deffunc GLinit
dim pfd ,24
/*
;サンプル版1
pfd(0)=96
pfd(1)=37 , PFD_TYPE_RGBA
pfd(3)=24
pfd(4)=0,0,0,0,0,0
pfd(10)=0,0,0, 0,0,0,0
pfd(17)=32,0,0
pfd(20)=PFD_MAIN_PLANE,0,0,0,0
*/
/*
;サンプル版2
PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
32,
0, 0, 0, 0, 0, 0, 0, 0,
0,
0, 0, 0, 0,
24,
8,
0,
PFD_MAIN_PLANE,
0,
0, 0, 0
};
*/
pfd(0) =96 ; nSize
pfd(1) =1 ; nVersion
pfd(2) =PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER ; dwFlags
pfd(3) =PFD_TYPE_RGBA ; iPixelType
pfd(4) =32 ; cColorBits
pfd(17)=16 ; cDepthBits
pfd(18)=0 ; cStencilBits
pfd(20)=PFD_MAIN_PLANE ; iLayerType
WinDC=GetDC(hwnd)
pixelFormat = ChoosePixelFormat( WinDC,varptr(pfd) )
if (0 >= pixelFormat) : dialog "0", 1, "pixelFormat error" : end
SetPixelFormat WinDC,pixelFormat,varptr(pfd)
hRC = wglCreateContext( WinDC )
wglMakeCurrent WinDC, hRC
//オブジェクト描画モードにする。
glMatrixMode GL_MODELVIEW ;オブジェクト描画モード
glLoadIdentity
//////////////////////////////////////////////
//必要な機能の有効化
//
;glEnable GL_NORMALIZE
;glEnable GL_AUTO_NORMAL
;glShadeModel GL_SMOOTH ;GL_SMOOTHでないと頂点カラーは使用できない
glShadeModel GL_FLAT ;初期値
glEnable GL_DEPTH_TEST ;Zバッファを使用する
return
#deffunc GLcamera double u_fov, double u_aspect, double u_near, double u_far, int u_sw
fov = u_fov
aspect = u_aspect
near = u_near
far = u_far
sw = u_sw
return
#deffunc GLview
w=ginfo_winx
h=ginfo_winy
glMatrixMode GL_PROJECTION ;投影モード
glLoadIdentity
if sw == 0 {
gluPerspective fov, 1.0*w/h, near, far
} else {
;#func global glOrtho "glOrtho" double, double, double, double, double, double
;glOrtho
}
glViewport 0, 0, w , h
glMatrixMode GL_MODELVIEW ;オブジェクト描画モード
return
#deffunc GLdraw
glFlush
SwapBuffers WinDC
return
;vramからHSP3の指定のバッファへOpenGLの画像を送る命令
#deffunc glScreenShot int _p1
gsel _p1
title "ScreenShot"
redraw 0
pos 0, 0
mref _vram_ScreenShot, 66
id = varptr(_vram_ScreenShot)
;_vramの部分は直接指定ではなく、ポインタ指定
glReadPixels 0, 0, ginfo_sx, ginfo_sy, GL_BGR_EXT, GL_UNSIGNED_BYTE, id
redraw 1
;ddim _vram_ScreenShot, 0;変数クリア
return
//キューブを作る
#deffunc glmakeCube double x,double y,double z,int mode
glBegin mode
glNormal3d 1,0,0
glVertex3d x, -y, -z
glVertex3d x, y, -z
glVertex3d x, y, z
glVertex3d x, -y, z
glEnd
glBegin mode
glNormal3d -1,0,0
glVertex3d -x, -y, -z
glVertex3d -x, y, -z
glVertex3d -x, y, z
glVertex3d -x, -y, z
glEnd
glBegin mode
glNormal3d 0,1,0
glVertex3d -x, y, -z
glVertex3d x, y, -z
glVertex3d x, y, z
glVertex3d -x, y, z
glEnd
glBegin mode
glNormal3d 0,-1,0
glVertex3d -x, -y, -z
glVertex3d x, -y, -z
glVertex3d x, -y, z
glVertex3d -x, -y, z
glEnd
glBegin mode
glNormal3d 0,0,1
glVertex3d -x, -y, z
glVertex3d x, -y, z
glVertex3d x, y, z
glVertex3d -x, y, z
glEnd
glBegin mode
glNormal3d 0,0,-1
glVertex3d -x, -y, -z
glVertex3d x, -y, -z
glVertex3d x, y, -z
glVertex3d -x, y, -z
glEnd
return
//終了時に開放する
#deffunc ReleaseOpenGL onexit
wglMakeCurrent WinDC,0
wglDeleteContext hRC
ReleaseDC hwnd,WinDC
return
#global
#endif
;--------------------------------------------------------------------------------------------------------------------
#const WAITTIME 1000 / 60
gosub *make_rgba
gosub *setup
goto *main
;ノイズを作成
*make_rgba
c = 512*512*4
color_id = 0
alloc buf_rgba, c
repeat c
if color_id == 0 {
;rの部分はランダム
poke buf_rgba, cnt, rnd(255)
}
if color_id == 1 {
;gの部分はランダム
poke buf_rgba, cnt, rnd(255)
}
if color_id == 2 {
;bの部分はランダム
poke buf_rgba, cnt, rnd(255)
}
if color_id == 3 {
;aの部分は常に255
poke buf_rgba, cnt, $ff
color_id=0
} else {
color_id++
}
loop
buf_rgba_pointa = varptr(buf_rgba)
return
*setup
bgscr 0, 1024, 768, 0, 0, 0
gsel 0
pos 0, 0
GLinit
glClearColor d2f(0.118), d2f(0.255), d2f(0.353), 0.0
r=M_PI/4
glPolygonOffset d2f(1.1), d2f(1.1)
;テクスチャ生成
glEnable GL_TEXTURE_2D ;テクスチャ機能を有効
dim GLtexID, 1
glGenTextures 1, varptr(GLtexID) ;テクスチャオブジェクトを作成。ポインタで指定?
glBindTexture GL_TEXTURE_2D, GLtexID.0 ;テクスチャをバインド
;ポインタで指定
glTexImage2D GL_TEXTURE_2D, 0, 4, tex_w, tex_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, buf_rgba_pointa
;バッファを直接指定したとしても変化なし
;glTexImage2D GL_TEXTURE_2D, 0, 4, tex_w, tex_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, buf_rgba
return
*main
glPopMatrix ;座標系を展開
glPushMatrix ;座標系を記憶
;カメラ設定
GLCamera 40, 0.333333, 0.5, 128.0, 0
;ウィンドウサイズにおける表示域の設定(ウィンドウリサイズの際に呼ばれるべき)
GLview
;クリアーカラーにもとづいて 背景塗りつぶし
glClear GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT
;カメラ位置 x,y,z カメラ目標位置 x,y,z カメラ上方向ベクトル x,y,z
gluLookAt sin(r)*30,10,cos(r)*30, 0,0,0, 0,1,0
//////////////////////描画領域はじめ//////////////////////
glEnable GL_TEXTURE_2D
;glEnable GL_NORMALIZE
;glEnable GL_AUTO_NORMAL
glEnable GL_POLYGON_OFFSET_FILL
glEnable GL_DEPTH_TEST
gosub *draw_etc_line
glPushMatrix ;カレント位置を記憶
a += 2.0
glScalef 2.0, 2.0, 2.0
glTranslated 3,1,3
glRotatef a, 0.1, 0.1, 0.1
gosub *draw_test
;このワイヤーフレームのcubeの中に*draw_testのポリゴンがテクスチャ付きで表示されていれば成功
gosub *draw_wire_and_obj
glPopMatrix ;ずれたカレントを前回記憶した座標に元に戻す
;pokeで自作したrgbaデータでも表示されるので、openGLに読み込まれていることは確定
;ただしこれを直接呼ぶと画面の深度値がおかしくなるので注意
;glDrawPixels 512, 512, GL_RGBA, GL_UNSIGNED_BYTE, buf_rgba_pointa
//////////////////////描画領域おわり//////////////////////
GLdraw ;描画&画面更新
r+=0.005 ;カメラのXZ平面上の角度を加算する
await WAITTIME
goto *main
*draw_test
;とりあえずの色指定(この色がそのままポリゴンに描写されていたらテクスチャ適用失敗)
glColor3f 0.0,0.0,1.0
glEnable GL_TEXTURE_2D
;glEnable GL_NORMALIZE
;glEnable GL_AUTO_NORMAL
glEnable GL_POLYGON_OFFSET_FILL
glEnable GL_DEPTH_TEST
glBindTexture GL_TEXTURE_2D, GLtexID.0 ;テクスチャをバインド
glBegin GL_POLYGON
glTexCoord2f 0 , 0: glVertex2f -0.9 , -0.9
glTexCoord2f 0 , 1: glVertex2f -0.9 , 0.9
glTexCoord2f 1 , 1: glVertex2f 0.9 , 0.9
glTexCoord2f 1 , 0: glVertex2f 0.9 , -0.9
glEnd
return
*draw_wire_and_obj
glColor3d 1.0, 0.0, 0.0 ;色 (赤)
glLineWidth 1.0 ;線幅
;glDisable GL_TEXTURE_2D ;テクスチャを無効
glMakeCube 1,1,1,GL_LINE_LOOP ;ワイヤーでできた箱を作る
return
*draw_etc_line
//軸の線を描画
glLineWidth 2.0 //線幅
glBegin GL_LINES
//glColor3d の0.0〜1.0は hspのcolorでいうところの0〜255 と等価
glColor3d 1.0, 0.0, 0.0//赤
glVertex3d 0, 0, 0//x
glVertex3d 30, 0, 0
glEnd
glBegin GL_LINES
glColor3d 0.0, 1.0, 0.0//緑
glVertex3d 0, 0, 0//y
glVertex3d 0, 30, 0
glEnd
glBegin GL_LINES
glColor3d 0.0, 0.0, 1.0 //青
glVertex3d 0, 0, 0//z
glVertex3d 0, 0, 30
glEnd
return
| |
|
2024/2/24(Sat) 05:48:31|NO.101292
おっふ、読み解くのが中々な難解ですね。。。
>ChoosePixelFormatのこれらの構造体は何を意味しているのでしょうか?
まず、これはOpenglではなくGDIのお話ですね。(Windowsでスクリーンに描画する時によく出るやつです。)
こちらをご参照くださいませ。
https://learn.microsoft.com/ja-jp/windows/win32/api/wingdi/
それで、ChoosePixelFormat関数は、
デバイスコンテキストとPIXELFORMATDESCRIPTOR構造体を照合します。
お使いのデバイスが問題なければ値が返るので、ウインドウ(hwnd)のデバイスコンテキストに設定します。
>例えばnVersionとは何のバージョンを示すものなのでしょうか?
nVersionはPIXELFORMATDESCRIPTOR構造体のバージョンを指定しますが、
現在は1しかありませんので気になさらなくてよろしいかと思います。
>表示されないのは、3Dポリゴンのテクスチャとしてのみという現象が起きています。どうしてなのでしょうか?
デバックウインドウで見てみたら、大きく2つですね。
1)変数や定数が定義されて無い(関数も足りない)
2)テクスチャのフィルタリング方法とポリゴンの色を上書きする設定になってない。
カラーノイズのテクスチャが表示されるのが、このサンプルの正解であってますか?
そうであれば、
1)
#uselib "opengl32.dll"
#func global glTexEnvi "glTexEnvi" int,int,int
#func global glTexParameteri "glTexParameteri" int,int,int
#define global GL_TEXTURE_2D 0x0DE1
#define global GL_RGBA 0x1908
#define global GL_UNSIGNED_BYTE 0x1401
#define global GL_REPLACE 0x1E01
#define global GL_TEXTURE_ENV 0x2300
#define global GL_TEXTURE_ENV_MODE 0x2200
#define global GL_TEXTURE_ENV_COLOR 0x2201
#define global GL_LINEAR 0x2601
#define global GL_TEXTURE_MAG_FILTER 0x2800
#define global GL_TEXTURE_MIN_FILTER 0x2801
2)
;テクスチャ生成部
;tex_w : tex_h は0なので直値512を指定しました。
glGenTextures 1, varptr(GLtexID)
glBindTexture GL_TEXTURE_2D, GLtexID.0
glTexImage2D GL_TEXTURE_2D, 0, 4, 512, 512, 0, GL_RGBA, GL_UNSIGNED_BYTE, varptr(buf_rgba)
; ここフィルター方法
glTexParameteri GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR
glTexParameteri GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR
; ここポリゴンの色との合成方法。置き換えにした(初期値は混ぜる)
glTexEnvi GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE
※余談※
線にもテクスチャが反映されてしまってますね。
基本的な書き方として、1つの描画コールに対して有効にしたものは対になるように無効にします。
(軸、ボックスの描画コールも同様に)
glEnable GL_TEXTURE_2D ; ★有効にして
glBindTexture GL_TEXTURE_2D, GLtexID.0
glBegin GL_POLYGON ; この場合GL_QUADSのが早い
glTexCoord2f 0, 0: glVertex2f -1, -1
glTexCoord2f 0, 1: glVertex2f -1, 1
glTexCoord2f 1, 1: glVertex2f 1, 1
glTexCoord2f 1, 0: glVertex2f 1, -1
glEnd
glDisable GL_TEXTURE_2D ; ★無効にする
コメントから察するに、もしかしたらポインタの理解が足りないのかもしれません。
OpenGL APIはC言語関数群の形で提供されてますので、少しCの知識が必要です。
全部学ぶのは大変ですから、C言語の”参照渡し”を調べてみると理解の足がかりになるかと思われました。
; このような部分
glGenTextures 1, varptr(GLtexID)
; 変数の値の渡し戻しに使うだけなので↓のように定義しておけば、こう書けます。
#func global glGenTextures "glGenTextures" int, var
#func global glTexImage2D "glTexImage2D" int, int, int, int, int, int, int, int, var
#func global glReadPixels "glReadPixels" int, int, int, int, int, int, var
glGenTextures 1, GLtexID
glTexImage2D GL_TEXTURE_2D, 0, 4, tex_w, tex_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, buf_rgba
glReadPixels 0, 0, ginfo_sx, ginfo_sy, GL_BGR_EXT, GL_UNSIGNED_BYTE, _vram_ScreenShot
| |
|
2024/2/25(Sun) 04:09:11|NO.101304
HSPのバッファに描いた画像をテクスチャとして立方体に貼り付けるスクリプト書いてみました。
#use gdi32, user32
#uselib "opengl32"
#func glBegin "glBegin" int
#func glBindTexture "glBindTexture" int, int
#func glClear "glClear" int
#func glClearColor "glClearColor" float, float, float, float
#func glDisable "glDisable" int
#func glEnable "glEnable" int
#func glEnd "glEnd"
#func glGenTextures "glGenTextures" int, sptr
#func glLoadIdentity "glLoadIdentity"
#func glMatrixMode "glMatrixMode" int
#func glRotated "glRotated" double, double, double, double
#func glTexCoord2d "glTexCoord2d" double, double
#func glTexImage2D "glTexImage2D" int, int, int, int, int, int, int, int, sptr
#func glTexParameteri "glTexParameteri" int, int, int
#func glTranslated "glTranslated" double, double, double
#func glVertex3d "glVertex3d" double, double, double
#func glViewport "glViewport" int, int, int, int
#func wglCreateContext "wglCreateContext" int
#func wglDeleteContext "wglDeleteContext" int
#func wglMakeCurrent "wglMakeCurrent" int, int
#uselib "glu32"
#func gluPerspective "gluPerspective" double, double, double, double
#define GL_BGR $80E0
#define GL_COLOR_BUFFER_BIT $4000
#define GL_DEPTH_BUFFER_BIT $0100
#define GL_DEPTH_TEST $0B71
#define GL_LINEAR $2601
#define GL_MODELVIEW $1700
#define GL_NEAREST $2600
#define GL_PROJECTION $1701
#define GL_QUADS $0007
#define GL_TEXTURE_2D $0DE1
#define GL_TEXTURE_MAG_FILTER $2800
#define GL_TEXTURE_MIN_FILTER $2801
#define GL_UNSIGNED_BYTE $1401
#module
#deffunc drawMen int _c, int _x, int _y, str _s
hsvcolor _c, 128, 200 : grect _x+32, _y+32 : color : pos _x, _y : mes _s, mesopt_outline
return
#global
onexit goto *bye
wdc = getDC(hwnd)
; PIXELFORMATDESCRIPTOR
pfd = 40|(1<<16), $25, (24<<8), 0, 0, (32<<24), 0, 0, 0, 0
setPixelFormat wdc, choosePixelFormat(wdc, varptr(pfd)), varptr(pfd)
hrc = wglCreateContext(wdc)
wglMakeCurrent wdc, hrc
glMatrixMode GL_PROJECTION
glLoadIdentity
gluPerspective 45, 1.0 * ginfo_sx / ginfo_sy, 0.1, 100
glMatrixMode GL_MODELVIEW
glLoadIdentity
bgscr 1, 256, 256 ; テクスチャ用のバッファ、サイズは2の累乗が無難
font msgothic, 64, 0, 3
objcolor 250, 250, 250
gmode 0, 64, 64
drawMen 0, 0, 192, "1"
drawMen 32, 64, 192, "2"
drawMen 64, 128, 192, "3"
drawMen 96, 192, 192, "4"
drawMen 128, 0, 128, "5"
drawMen 160, 64, 128, "6"
mref vram, 66
dim texture
glGenTextures 1, varptr(texture)
glBindTexture GL_TEXTURE_2D, texture
glTexImage2D GL_TEXTURE_2D, 0, 3, ginfo_sx, ginfo_sy, 0, GL_BGR, GL_UNSIGNED_BYTE, varptr(vram)
glTexParameteri GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST
glTexParameteri GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST
gsel 0, 1
glClearColor 0.1, 0.2, 0.3, 0
glEnable GL_DEPTH_TEST
xrot = 0.0
yrot = 0.0
zrot = 0.0
*mainLoop
glClear GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT
glLoadIdentity
glTranslated 0, 0, -5
glRotated xrot, 1, 0, 0
glRotated yrot, 0, 1, 0
glRotated zrot, 0, 0, 1
glBindTexture GL_TEXTURE_2D, texture
glEnable GL_TEXTURE_2D
glBegin GL_QUADS
; テクスチャ座標[0,0]~[1,1]の範囲で左下が原点
; 頂点左回りが表
; 1
glTexCoord2d 0.00, 0.00 : glVertex3d -1, -1, 1
glTexCoord2d 0.25, 0.00 : glVertex3d 1, -1, 1
glTexCoord2d 0.25, 0.25 : glVertex3d 1, 1, 1
glTexCoord2d 0.00, 0.25 : glVertex3d -1, 1, 1
; 2
glTexCoord2d 0.25, 0.25 : glVertex3d -1, 1, -1
glTexCoord2d 0.25, 0.00 : glVertex3d -1, 1, 1
glTexCoord2d 0.50, 0.00 : glVertex3d 1, 1, 1
glTexCoord2d 0.50, 0.25 : glVertex3d 1, 1, -1
; 3
glTexCoord2d 0.75, 0.00 : glVertex3d 1, -1, -1
glTexCoord2d 0.75, 0.25 : glVertex3d 1, 1, -1
glTexCoord2d 0.50, 0.25 : glVertex3d 1, 1, 1
glTexCoord2d 0.50, 0.00 : glVertex3d 1, -1, 1
; 4
glTexCoord2d 0.75, 0.00 : glVertex3d -1, -1, -1
glTexCoord2d 1.00, 0.00 : glVertex3d -1, -1, 1
glTexCoord2d 1.00, 0.25 : glVertex3d -1, 1, 1
glTexCoord2d 0.75, 0.25 : glVertex3d -1, 1, -1
; 5
glTexCoord2d 0.25, 0.50 : glVertex3d -1, -1, -1
glTexCoord2d 0.00, 0.50 : glVertex3d 1, -1, -1
glTexCoord2d 0.00, 0.25 : glVertex3d 1, -1, 1
glTexCoord2d 0.25, 0.25 : glVertex3d -1, -1, 1
; 6
glTexCoord2d 0.50, 0.25 : glVertex3d -1, -1, -1
glTexCoord2d 0.50, 0.50 : glVertex3d -1, 1, -1
glTexCoord2d 0.25, 0.50 : glVertex3d 1, 1, -1
glTexCoord2d 0.25, 0.25 : glVertex3d 1, -1, -1
glEnd
glDisable GL_TEXTURE_2D
xrot += 0.2
yrot += 0.3
zrot += 0.4
wglMakeCurrent wdc, hrc
swapBuffers wdc
await 16
goto *mainLoop
*bye
gsel 0
if (hrc) {
wglMakeCurrent wdc, 0
wglDeleteContext hrc
}
if (wdc) {
releaseDC hwnd, wdc
}
end
前にOpenGLのモジュールを作っていた事があったので参考になるかもしれません
http://hsp.tv/play/pforum.php?mode=pastwch&num=58992
リンク先のダウンロードURLは無効になっているので↓からDLできます
https://1drv.ms/u/s!Ar6lqe2DjQo0gX6JLA-ujJL8YIo1?e=7Tqett
2Dメインで作りかけなのであまり参考にならないかもしれません…
>HSPっぽい引数の書き方をしたければ先にダミーを定義して、
>libpotr()でSTRUCTDAT構造体のポインタを取得してproc addressを書き換える方法もあります。
こんな方法もあったんですね。コードの見た目的にこちらの方が良さそうな気がします
| |
|
2024/2/25(Sun) 15:14:55|NO.101308
>usagi さん
ありがとうございます。usagiさんのアドバイスを元にやっとテクスチャを3Dポリゴンに貼ることができるようになりました。
ポインタの理解についてはusagiさんの指摘通り、曖昧な把握であったことは今回自分でスクリプトを書きながら感じていました。
今回改めてポインタの解説を読んで、よく分かっていなかった部分を知ることができました。
ポリゴンにテクスチャを貼れるようになったから、一気に見栄えが良くなってかなり実用的な感じになってきました。
OpenGLはとても面白いですね!
>K-s さん
アドバイスありがとうございます。
これからアドバイスして頂いたスクリプトをじっくり研究していこうと思います!
|
|
2024/2/27(Tue) 19:48:01|NO.101315
>K-sさん
おぉ、既にHSP用のOpenGLラッパーがあるのですね!(機械語まで使ってる!)
ヘッダー用意するの大変なのでこれは便利。
>こんな方法もあったんですね。
別件で、機械語を簡単に使えないかなぁと思って、
ドキュメントを眺めてた時にvoid *procの中に関数アドレスあるよ!と思って、
書き換えてみたら動作しましたので使ってました。
#funcだとfloatが設定できるので、ちょっと実数の扱いが楽になりそうなのと
おそらく callfunc で準備してから呼び出す流れよりも、
コマンド1発で済むようになるので速度的にも有利なのではと考えてます。
※完全な余談余談※
こんな感じで、さくっと使いたい。(これが動いちゃうからHSPって簡単で便利ですよね)
;DLL版
;#uselib "hoge.dll"
;#cfunc hoge "hoge" float ; int hoge(int p1) { return p1; }
; 機械語埋め込み版
; 実行、読み書き可能な変数の作成
#module
#uselib "kernel32.dll"
#func VirtualProtect "VirtualProtect" var,int,int,var
#deffunc mcode int _pfunc, array _code
VirtualProtect _code, varsize(_code),$40/*PAGE_EXECUTE_READWRITE*/, _
dupptr _sdat, _pfunc, 28 : _sdat.6 = varptr(_code) : return
#global
; 関数のダミー登録
;---------------------------------------------------
#uselib ""
#cfunc float "" float ; なんでもfloat君
; ただ引数を返すだけの機械語
_float.0 = $0424448b ; mov 0x4(%esp),%eax
_float.1 = $c3909090 ; ret
mcode libptr(float), _float ; 機械語を関数に登録
;---------------------------------------------------
; intでもdoubleでも ダンプが0x3F800000ならfloat化成功
mes strf("0x%08x", float( 1) )
mes strf("0x%08x", float(1.0) )
>youdaiさん
表示されたようで良かったです。
OpenGLの様な低レベルなものはプログラム組むのは大変ですが、
高レベルでは出来なかった様々な事が出来るようになるので楽しいですよね。
| |
|