hgrotateと同様の使い方が出来るdxgrotate命令を追加するモジュール
hgimg3側に登録したテクスチャをdxgrotateで使用するには
RegDxTexidで予めIDを登録する必要が有る以外同じ使い方が出来る。
追加される命令、マクロ
>RegDxTexid dx_tid	;HGIMG3側で確保したテクスチャをdxgrotate用にIDを登録
>GetDxTexSizeX()		;RegDxTexidで登録したIDを使用してテクスチャのサイズ取得
>GetDxTexSizeY()		;RegDxTexidで登録したIDを使用してテクスチャのサイズ取得
>dxgrotate dx_tid ,lux ,luy ,rz ,csx ,csy ,dif		;矩形画像の直接描画
#include "hgimg3.as"
//hgimg3の命令が使われているのでhgimg3.asの下に配置
#module "dx8_grot"
//このモジュールは一部d3dx9_39.dllの命令を使用しています。
//そのため最低一回はDirectXの更新が必要です↓。(OSインストールやPC購入後一回してればOK)
//https://www.microsoft.com/ja-jp/download/details.aspx?id=35&
#uselib "d3dx9_39.dll"
#func  D3DXMatrixLookAtLH                "D3DXMatrixLookAtLH"                int,int,int,int
#func  D3DXMatrixPerspectiveFovLH        "D3DXMatrixPerspectiveFovLH"        int,float,float,float,float
#func  D3DXMatrixRotationX               "D3DXMatrixRotationX"               int,float
#func  D3DXMatrixRotationY               "D3DXMatrixRotationY"               int,float
#func  D3DXMatrixRotationZ               "D3DXMatrixRotationZ"               int,float
#func  D3DXMatrixScaling               "D3DXMatrixScaling"             int,float,float,float
#func  D3DXMatrixMultiply             "D3DXMatrixMultiply"             int,int,int
#usecom  IDirect3DDevice8 "{7385E5DF-8FE8-41D5-86B6-D7B48547B6CF}"
#comfunc  IDirect3DDevice8_AddRef					1	
#comfunc  IDirect3DDevice8_BeginScene                  34
#comfunc  IDirect3DDevice8_EndScene                    35
#comfunc  IDirect3DDevice8_CreateVertexBuffer          23 int,int,int,int,int
#comfunc  IDirect3DDevice8_CreateIndexBuffer 				24 int,int,int,int,int
#comfunc  IDirect3DDevice8_SetTransform                37 int,int
#comfunc  IDirect3DDevice8_SetRenderState              50 int,int
#comfunc  IDirect3DDevice8_GetRenderState              51 int,var
#comfunc  IDirect3DDevice8_SetTexture                  61 int,comobj
#comfunc  IDirect3DDevice8_DrawPrimitive               70 int,int,int
#comfunc  IDirect3DDevice8_DrawPrimitiveUP               72 int,int,int,int
#comfunc  IDirect3DDevice8_SetVertexShader		76 int,int
#comfunc  IDirect3DDevice8_SetStreamSource            83 int,comobj,int
#comfunc IDirect3DDevice8_SetIndices					85 comobj,int
#comfunc IDirect3DDevice8_DrawIndexedPrimitive	71 int,int,int,int,int
#usecom  IID_IDirect3D8 "{1DD9E8DA-1C77-4d40-B0CF-98FEFDFF9512}"
#comfunc  IDirect3D8_AddRef						1
#usecom  IID_IDirect3DTexture8 "{E4CDD575-2866-4f01-B12E-7EECE1EC9358}"
#comfunc  IDirect3DTexture8_AddRef	1 
#usecom  IID_IDirect3DVertexBuffer8 "{8AEEEAC7-05F9-44d4-B591-000B0DF1CB95}" 
#comfunc  IDirect3DVertexBuffer8_Lock         11 int,int,int,int
#comfunc  IDirect3DVertexBuffer8_UnLock       12
#usecom IID_IDirect3DIndexBuffer8 "{0E689C9A-053D-44a0-9D92-DB0E3D750F86}" 
#comfunc IDirect3DIndexBuffer8_QueryInterface	0 int,int
#comfunc IDirect3DIndexBuffer8_AddRef			1
#comfunc IDirect3DIndexBuffer8_Release			2
#comfunc IDirect3DIndexBuffer8_GetDevice			3 int
#comfunc IDirect3DIndexBuffer8_SetPrivateData	4 int,int,int,int
#comfunc IDirect3DIndexBuffer8_GetPrivateData	5 int,int,int
#comfunc IDirect3DIndexBuffer8_FreePrivateData	6 int
#comfunc IDirect3DIndexBuffer8_SetPriority		7 int
#comfunc IDirect3DIndexBuffer8_GetPriority		8
#comfunc IDirect3DIndexBuffer8_PreLoad			9
#comfunc IDirect3DIndexBuffer8_GetType			10
#comfunc IDirect3DIndexBuffer8_Lock				11 int,int,int,int
#comfunc IDirect3DIndexBuffer8_Unlock			12
#uselib "User32.dll"
#func   setFloat4  "SetRect"       var,float,float,float,float
#define MAX_PARTICLES 4
//[---モジュールの初期化---最初のRegDxTexid実行時にこの命令が使用されるので通常は実行する必要なし]
//dx8_grot_init@dx8_grot
//必ずhginiの後に実行
#deffunc local dx8_grot_init
	if dx8_grot_init_f=0 {
		dx8_grot_init_f=1
		hggetreq ret,SYSREQ_PTRD3D
		newcom g_pd3d, , -1, ret
		IDirect3D8_AddRef g_pd3d
		hggetreq ret,SYSREQ_PTRD3DDEV
		newcom g_pd3dDev, , -1, ret
		IDirect3DDevice8_AddRef g_pd3dDev	//HGIMG3側のRelease回数と数が合わなくなるっぽいので増やしとく
		dupptr dup_ptrd3ddev,ret,4*25,4	//デバイスのメモリを直接参照用
		hggetreq TEXTID_MAX,SYSREQ_MAXTEX
		dim float4,4
		dup float_0,float4(0)
		dup float_1,float4(1)
		dup float_2,float4(2)
		dup float_3,float4(3)
		mref BMSCR,67
		dupptr dup_color,varptr(BMSCR(40)),4,4
		dupptr dup_gmode_m,varptr(BMSCR(35)),4,4
		dupptr dup_gmode_x,varptr(BMSCR(33)),4,4
		dupptr dup_gmode_y,varptr(BMSCR(34)),4,4
		dupptr dup_gmode_a,varptr(BMSCR(65)),4,4
		
		dupptr dup_cpx,varptr(BMSCR(27)),4,4
		dupptr dup_cpy,varptr(BMSCR(28)),4,4
		dim blend_emode,5,10
		blend_emode(0,0)=1,0,5,6,0
		blend_emode(0,1)=1,0,5,6,0
		blend_emode(0,2)=1,1,5,6,1
		blend_emode(0,3)=1,1,5,6,1
		blend_emode(0,4)=1,1,5,6,1
		blend_emode(0,5)=1,1,5,2,1
		blend_emode(0,6)=1,1,1,6,1
		blend_emode(0,7)=0,0,5,6,1
		dim phgText,TEXTID_MAX
		dimtype com_hgText,6,TEXTID_MAX
		dim tex_sizex,TEXTID_MAX
		dim tex_sizey,TEXTID_MAX
		ddim tex_dotx,TEXTID_MAX
		ddim tex_doty,TEXTID_MAX
		#define global D3DFVF_XYZ              0x002
		#define global D3DFVF_DIFFUSE          0x040
		#define global D3DFVF_SPECULAR         0x080
		#define global D3DFVF_TEX1             0x100
		#define global  D3DFVF_XYZRHW           0x004
		#define global D3DFVF    (  D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1 )
		argbp=4
		D3DFVF_size=((argbp+1+2)*4)
		fvf_l=D3DFVF_size/4
		dim particle, fvf_l * MAX_PARTICLES
	}
return
//RegDxTexidで登録したIDを使用してテクスチャのサイズ取得
//	Size = GetDxTexSizeX(dx_tid)
#define global ctype  GetDxTexSizeX(%1) tex_sizex@dx8_grot(%1)
#define global ctype  GetDxTexSizeY(%1) tex_sizey@dx8_grot(%1)
//[一番最近作成されたテクスチャに対してのみ有効]
//		「HGIMG3側で確保したテクスチャ(XファイルモデルのテクスチャもOK)をdxgrotate用にIDを登録」
//RegDxTexid dx_tid
//	dx_tid	=登録するID
//登録が成功したら1、0は登録出来るテクスチャが無かった、-1はデバイスロストかIDが登録出来ない数値だった
#define global RegDxTexid(%1) _RegDxTexid %1
#deffunc _RegDxTexid int dx_tid
	if dx8_grot_init_f=0 {dx8_grot_init@dx8_grot}
	hggetreq DevLost,SYSREQ_DEVLOST
	if DevLost<0 or dx_tid<0 or dx_tidcnt>=TEXTID_MAX {return -1}
	ptrd3ddev_adl=dup_ptrd3ddev(14)
	Exist_id=phgText(dx_tid)>0
	add_id=0
	repeat dup_ptrd3ddev(11)
		if ptrd3ddev_adl=0{break}
		dupptr dup_ptrd3ddev_adl,ptrd3ddev_adl,4*30,4
		if dup_ptrd3ddev_adl(18)>0 and dup_ptrd3ddev_adl(7)>0 and (dup_ptrd3ddev_adl(21)>=20 and dup_ptrd3ddev_adl(21)<=34){
			_phgText=ptrd3ddev_adl+18*4
			add_id=1
			phgText(dx_tid)=_phgText
			newcom com_hgText(dx_tid), , -1, phgText(dx_tid)
			IDirect3DTexture8_AddRef com_hgText(dx_tid)
			tex_sizex(dx_tid)=dup_ptrd3ddev_adl(27)
			tex_sizey(dx_tid)=dup_ptrd3ddev_adl(28)
			tex_dotx(dx_tid)=1.0/tex_sizex(dx_tid)
			tex_doty(dx_tid)=1.0/tex_sizey(dx_tid)
			dx_tid_list(textidcnt)=dx_tid
			if Exist_id=0 {	dx_tid_list(textidcnt)=dx_tid:textidcnt++}
			break
		}
		ptrd3ddev_adl=dup_ptrd3ddev_adl(14)
		await 0
	loop
return add_id
//dxgrotate dx_tid ,lux ,luy ,rz ,csx ,csy ,dif
//	dx_tid=0〜(0)  : RegDxTexidで登録したテクスチャID
//	lux=0〜(0)  : コピー元の左上X座標
//	luy=0〜(0)  : コピー元の左上Y座標
//	rz=0〜(0.0): 回転角度(単位はラジアン)
//	csx=0〜(?)  : Xサイズ(省略時gmodeのコピーする大きさX)
//	csy=0〜(?)  : Yサイズ(省略時gmodeのコピーする大きさY)
//	dif=0〜1(0)  : 1の時に標準命令の color を頂点色として使用(gmode2以上はgmodeのp4も有効になる)
//テクスチャIDがRegDxTexidで登録したIDを使用する以外使い方は hgrotate と同じ
//hgrotateと違い奇数サイズも表示可能
//半透明やパラメータ省略時の動作も同じにしたつもり
//但しgmode7はテクスチャのアルファ値0以外を不透明として描画
#define global dxgrotate(%1,%2=0.0,%3=0.0,%4=0.0,%5=dup_gmode_x@dx8_grot,%6=dup_gmode_y@dx8_grot,%7=0) _dxgrotate %1,%2,%3,%4,%5,%6,%7
#deffunc _dxgrotate int dx_tid,double lux,double luy,double rz,int csx,int csy,int dif
	if dx8_grot_init_f=0 {RegDxTexid dx_tid:if stat<=0 {dialog "使用できるテクスチャが\n登録されていません":end}}
	fvset fvlu,0.0,0.0,-rz
	fvdir fvlu,-0.5*csx,-0.5*csy,0.0
	fvset fvld,0.0,0.0,-rz
	fvdir fvld,-0.5*csx,0.5*csy,0.0
	setFloat4 particle         ,fvlu+dup_cpx,fvlu(1)+dup_cpy,0.0,1.0
	setFloat4 particle(fvf_l)  ,fvld+dup_cpx,fvld(1)+dup_cpy,0.0,1.0
	setFloat4 particle(fvf_l*2),-fvlu+dup_cpx,-fvlu(1)+dup_cpy,0.0,1.0
	setFloat4 particle(fvf_l*3),-fvld+dup_cpx,-fvld(1)+dup_cpy,0.0,1.0
	dup	dup_tex_dotx,tex_dotx(dx_tid)
	dup	dup_tex_doty,tex_doty(dx_tid)
	stu=dup_tex_dotx*lux
	stv=dup_tex_doty*luy
	setFloat4 float4, stu,stv, dup_tex_dotx*dup_gmode_x+stu,dup_tex_doty*dup_gmode_y+stv
	
	if dif {
		poke argb,0,peek(dup_color,2)
		poke argb,1,peek(dup_color,1)
		poke argb,2,peek(dup_color,0)
		poke argb,3,dup_gmode_a
	}else{
		if dup_gmode_m>2 {argb=(dup_gmode_a<<24)  | $ffffff}else{argb=$ffffffff}
	}
  	particle(argbp)		 =argb,float_0,float_1
	particle(fvf_l +argbp) =argb,float_0,float_3
	particle(fvf_l*2+argbp)=argb,float_2,float_3
	particle(fvf_l*3+argbp)=argb,float_2,float_1
	dup blend_emode_dup,blend_emode(0,dup_gmode_m)
	IDirect3DDevice8_SetRenderState g_pd3dDev,171,blend_emode_dup		//D3DRS_BLENDOP
	IDirect3DDevice8_SetRenderState g_pd3dDev,27,blend_emode_dup(1)	//D3DRS_ALPHABLENDENABLE
	IDirect3DDevice8_SetRenderState g_pd3dDev,19,blend_emode_dup(2)		//D3DRS_SRCBLEND
	IDirect3DDevice8_SetRenderState g_pd3dDev,20,blend_emode_dup(3)	//D3DRS_DESTBLEND 
	IDirect3DDevice8_SetRenderState g_pd3dDev,15,blend_emode_dup(4)	//D3DRS_ALPHATESTENABLE
 	IDirect3DDevice8_SetTexture g_pd3dDev, 0, com_hgText(dx_tid)
	IDirect3DDevice8_SetVertexShader g_pd3dDev,D3DFVF
	IDirect3DDevice8_DrawPrimitiveUP g_pd3dDev, 6, 2,varptr(particle),D3DFVF_size
 
return
#deffunc dx8_grot_exit onexit
	repeat textidcnt
		if vartype(com_hgText(dx_tid_list(cnt)))== 6 {delcom com_hgText(dx_tid_list(cnt))}
	loop
return
#global
*main
	hgsetreq SYSREQ_FPUPRESERVE,1
	hgini
	texload dir_exe+"\\sample\\hgimg3\\chrome.bmp"
	tid=stat
	//一番最近texload等(addxfile,texmake等も含む)でテクスチャ登録された物にdxgrotate用のIDを登録します
 	RegDxTexid tid	//dxgrotateで使用できるようにID登録(IDはhg側のものと同じにする必要は無い)
	texload dir_exe+"\\sample\\hgimg3\\fontchr.bmp"
	ftid=stat
 	RegDxTexid ftid	//dxgrotateで使用できるようにID登録
 	
	f="HGIMG3 dxgrotate test"
	repeat strlen(f)
		a(cnt)=cnt*10
	loop
	clscolor $4444
*_Main
	hgdraw
	stick k,127
	if k&128 : goto *_Exit		; [ESC]で終了
	
	gmode 0,63,64,255	//横奇数サイズ指定
	pos 320,240+20
	dxgrotate tid
	pos 320,240-20
	gmode 6,63,64,255	//1ドット足りないのが見やすいように色減算合成モード
	hgrotate tid
//頂点色変更テスト
	pos 50,50
	gmode 2,16,16,a(cnt)
	r=-0.5
	repeat strlen(f)
		gmode 2,16,16,a(cnt)
		a(cnt)--
		r+0.05
		color rnd(255),rnd(255),rnd(255)
		pos 40+cnt*28,100
		dxgrotate ftid,(peek(f,cnt)\16)*16,(peek(f,cnt)/16)*16,r,48,48,1
	loop
	hgsync 16
	goto *_Main
*_Exit
	end
hgrotateよりは重いので毎フレーム数百回使用すると
負荷の違いが問題になるかも・・・