プログラマブルシェーダー関係関数

宣言int SetUseDirect3DVersion( int Version ) ;

概略使用する Direct3D のバージョンを指定する

引数 Version:Direct3D のバージョン
        DX_DIRECT3D_NONE :Direct3D を使用しない
        DX_DIRECT3D_9   :Direct3D 9 を使用する
        DX_DIRECT3D_9EX :Direct3D 9Ex を使用する
        DX_DIRECT3D_11  :Direct3D 11 を使用する
戻り値 0:成功
 -1:エラー発生

解説  DXライブラリが使用する Direct3D のバージョンを指定します。
 Direct3D 9, 9Ex 用のシェーダーと、Direct3D 11 用のシェーダーは別物になるので、 オリジナルシェーダーを使用する場合はこの関数で使用する Direct3D のバージョンを指定する必要があります。

!注意!

 この関数は DxLib_Init 呼び出しの前に使用してください。
 DxLib_Init 呼び出し後にこの関数を使用しても効果はありませんので注意してください。

サンプル

 GetUseDirect3DVersion関数 のサンプルを参照してください。



宣言int GetUseDirect3DVersion( void ) ;

概略使用している Direct3D のバージョンを取得する

引数なし
戻り値Direct3D のバージョン
解説  DXライブラリが使用している Direct3D のバージョンを取得します。
 SetUseDirect3DVersion で使用する Direct3D のバージョンを指定することができますが、 実行環境が指定のバージョンに対応していない場合は指定したバージョン以外の Direct3D が使用されます( 若しくは Direct3D が使用されない場合もあります )ので、 特にオリジナルシェーダーを使用する場合は DxLib_Init 呼び出しの後、指定したバージョンの Direct3D が使用されているかをこの関数で確認する必要があります。

戻り値の種類は以下の通りです。

  DX_DIRECT3D_NONE
    Direct3Dを使用していない

  DX_DIRECT3D_9
    Direct3D 9 を使用している

  DX_DIRECT3D_9EX
    Direct3D 9Ex を使用している

  DX_DIRECT3D_11
    Direct3D 11 を使用している

サンプル

  SetUseDirect3DVersion で Direct3D 9Ex の使用を指定してから DxLib_Init を実行した後、
 GetUseDirect3DVersion で Direct3D 9Ex が使用できているかを確認します。
Windows用
#include "DxLib.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { int Direct3DVersion ; // Direct3D 9Ex の使用を指定 SetUseDirect3DVersion( DX_DIRECT3D_9EX ) ; // DXライブラリの初期化 if( DxLib_Init() < 0 ) return -1; // 使用している Direct3D のバージョンを取得 Direct3DVersion = GetUseDirect3DVersion() ; // 使用バージョンが Direct3D 9Ex かどうかをチェック if( Direct3DVersion == DX_DIRECT3D_9EX ) { DrawString( 0, 0, "Direct3D 9Ex を使用しています", GetColor( 255,255,255 ) ) ; } else { DrawString( 0, 0, "Direct3D 9Ex を使用していません", GetColor( 255,255,255 ) ) ; } // キー入力待ち WaitKey(); // DXライブラリの後始末 DxLib_End(); // ソフトの終了 return 0; }



宣言int GetValidShaderVersion( void ) ;

概略使用できるシェーダーのバージョンを取得する

引数なし
戻り値シェーダーバージョン×100
解説  使用できるプログラマブルシェーダーのバージョンに100を掛けた値を取得します。( 戻り値が 200 だったらシェーダーモデル2.0が、300だったらシェーダーモデル3.0が使用可能 )
この関数の戻り値が0だった場合はプログラマブルシェーダーを使うことはできません。
主にプログラマブルシェーダーが使用できるかどうかを確認するために使用します。

サンプル

  使用できるシェーダーモデルのバージョンを取得して、シェーダーが使用できるかどうかを画面に表示します。
Windows用
#include "DxLib.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { int ShaderVersion ; // DXライブラリの初期化 if( DxLib_Init() < 0 ) return -1; // 使用できるプログラマブルシェーダーのバージョンを取得 ShaderVersion = GetValidShaderVersion() ; // バージョン番号が0だったら使用不可能 if( ShaderVersion == 0 ) { DrawString( 0, 0, "プログラマブルシェーダーを使うことはできません", GetColor( 255,255,255 ) ) ; } else { // 0以外だったら使用可能 DrawFormatString( 0, 0, GetColor( 255,255,255 ), "プログラマブルシェーダーバージョン %.1f が使用可能です", ShaderVersion / 100.0f ) ; } // キー入力待ち WaitKey(); // DXライブラリの後始末 DxLib_End(); // ソフトの終了 return 0; }



宣言int GetMultiDrawScreenNum( void ) ;

概略同時に描画を行うことができる画面の数を取得する

引数なし
戻り値同時に描画できる画面の数
解説  ピクセルシェーダーを使用すると複数の MakeScreen で作成できる描画可能画像に対して同時に描画を行うことができるのですが、 それにはグラフィックスデバイスがその機能に対応している必要があります。
 この関数はグラフィックスデバイスが持つ同時に描画することができる画面の数を取得します。
 複数の画面に対して同時に描画する機能が無い場合は戻り値として1が返ってきます。
 主に複数の画面に対して同時に描画処理を実行することが可能かどうかを判定するために使用します。
 
サンプル

  ありません



宣言int LoadVertexShader( char *FileName ) ;

概略頂点シェーダーバイナリを読み込みシェーダーハンドルを作成する

引数 FileName : 頂点シェーダーバイナリファイルのパス
戻り値 -1    : エラー発生
-1以外 : シェーダーハンドル

解説  頂点シェーダーのプログラムをコンパイルしてできるバイナリファイルをメモリに読み込み、 それを使用するためのハンドル( int型の値 )を取得します。
 コンパイル前のシェーダープログラムを読み込むことはできませんので注意してください。( シェーダープログラムをコンパイルするためのソフトはDXライブラリのパッケージの Tool\ShaderCompiler の中に入っています )
 戻り値で得られるシェーダーハンドルは SetUseVertexShader の引数として使用します。
 同時に読み込んでおけるシェーダーの数には限りがありますので、必要が無くなったら DeleteShader で削除してください。


頂点シェーダーに渡される頂点データについて

 今の所頂点シェーダーに渡される頂点データは以下のように固定されています。


DrawPolygon3DToShader, DrawPolygonIndexed3DToShaderの場合
( DrawPolygon2DToShader, DrawPolygonIndexed2DToShader では
 頂点シェーダーは使用されません )


struct VSInput { // 座標( VERTEX3DSHADER構造体の pos の値 ) float3 Position : POSITION0 ; // 補助座標( VERTEX3DSHADER構造体の spos の値 ) float4 SubPosition : POSITION1 ; // 法線( VERTEX3DSHADER構造体の norm の値 ) float3 Normal : NORMAL0 ; // 接線( VERTEX3DSHADER構造体の tan の値 ) float3 Tangent : TANGENT ; // 従法線( VERTEX3DSHADER構造体の binorm の値 ) float3 Binormal : BINORMAL0 ; // ディフューズカラー( VERTEX3DSHADER構造体の dif の値 ) float4 DiffuseColor : COLOR0 ; // スペキュラカラー( VERTEX3DSHADER構造体の spc の値 ) float4 SpecularColor : COLOR1 ; // テクスチャ座標0( VERTEX3DSHADER構造体の u, v の値 ) float2 TextureCoord0 : TEXCOORD0 ; // テクスチャ座標1( VERTEX3DSHADER構造体の su, sv の値 ) float2 TextureCoord1 : TEXCOORD1 ; } ;

MV1DrawModel や MV1DrawFrame などの3Dモデル描画の場合

剛体メッシュ( 1フレームの影響を受ける頂点のみ )の場合
struct VS_INPUT { float4 Position : POSITION ; // 座標( ローカル空間 ) float3 Normal : NORMAL0 ; // 法線( ローカル空間 ) float4 Diffuse : COLOR0 ; // ディフューズカラー float4 Specular : COLOR1 ; // スペキュラカラー float4 TexCoords0 : TEXCOORD0 ; // テクスチャ座標 } ;

法線マップ付き剛体メッシュの場合
struct VS_INPUT { float4 Position : POSITION ; // 座標( ローカル空間 ) float3 Tan : TANGENT0 ; // 接線( ローカル空間 ) float3 Bin : BINORMAL0 ; // 従法線( ローカル空間 ) float3 Normal : NORMAL0 ; // 法線( ローカル空間 ) float4 Diffuse : COLOR0 ; // ディフューズカラー float4 Specular : COLOR1 ; // スペキュラカラー float4 TexCoords0 : TEXCOORD0 ; // テクスチャ座標 } ;

1頂点へ影響を与えるフレームの数が1~4個のスキニングメッシュの場合
struct VS_INPUT { float4 Position : POSITION ; // 座標( ローカル空間 ) int4 BlendIndices0 : BLENDINDICES0 ; // スキニング処理用 Float型定数配列インデックス float4 BlendWeight0 : BLENDWEIGHT0 ; // スキニング処理用ウエイト値 float3 Normal : NORMAL0 ; // 法線( ローカル空間 ) float4 Diffuse : COLOR0 ; // ディフューズカラー float4 Specular : COLOR1 ; // スペキュラカラー float4 TexCoords0 : TEXCOORD0 ; // テクスチャ座標 } ;

1頂点へ影響を与えるフレームの数が1~4個の法線マップ付きスキニングメッシュの場合
struct VS_INPUT { float4 Position : POSITION ; // 座標( ローカル空間 ) int4 BlendIndices0 : BLENDINDICES0 ; // スキニング処理用 Float型定数配列インデックス float4 BlendWeight0 : BLENDWEIGHT0 ; // スキニング処理用ウエイト値 float3 Tan : TANGENT0 ; // 接線( ローカル空間 ) float3 Bin : BINORMAL0 ; // 従法線( ローカル空間 ) float3 Normal : NORMAL0 ; // 法線( ローカル空間 ) float4 Diffuse : COLOR0 ; // ディフューズカラー float4 Specular : COLOR1 ; // スペキュラカラー float4 TexCoords0 : TEXCOORD0 ; // テクスチャ座標 } ;

1頂点へ影響を与えるフレームの数が1~8個のスキニングメッシュの場合
struct VS_INPUT { float4 Position : POSITION ; // 座標( ローカル空間 ) int4 BlendIndices0 : BLENDINDICES0 ; // スキニング処理用 Float型定数配列インデックス0 int4 BlendIndices1 : BLENDINDICES1 ; // スキニング処理用 Float型定数配列インデックス1 float4 BlendWeight0 : BLENDWEIGHT0 ; // スキニング処理用ウエイト値0 float4 BlendWeight1 : BLENDWEIGHT1 ; // スキニング処理用ウエイト値1 float3 Normal : NORMAL0 ; // 法線( ローカル空間 ) float4 Diffuse : COLOR0 ; // ディフューズカラー float4 Specular : COLOR1 ; // スペキュラカラー float4 TexCoords0 : TEXCOORD0 ; // テクスチャ座標 } ;

1頂点へ影響を与えるフレームの数が1~8個の法線マップ付きスキニングメッシュの場合
struct VS_INPUT { float4 Position : POSITION ; // 座標( ローカル空間 ) int4 BlendIndices0 : BLENDINDICES0 ; // スキニング処理用 Float型定数配列インデックス0 int4 BlendIndices1 : BLENDINDICES1 ; // スキニング処理用 Float型定数配列インデックス1 float4 BlendWeight0 : BLENDWEIGHT0 ; // スキニング処理用ウエイト値0 float4 BlendWeight1 : BLENDWEIGHT1 ; // スキニング処理用ウエイト値1 float3 Tan : TANGENT0 ; // 接線( ローカル空間 ) float3 Bin : BINORMAL0 ; // 従法線( ローカル空間 ) float3 Normal : NORMAL0 ; // 法線( ローカル空間 ) float4 Diffuse : COLOR0 ; // ディフューズカラー float4 Specular : COLOR1 ; // スペキュラカラー float4 TexCoords0 : TEXCOORD0 ; // テクスチャ座標 } ;

DXライブラリ内部で設定する頂点シェーダー定数について

 DXライブラリでは SetCameraPositionAndTarget_UpVecY などで設定したカメラの設定や SetLightDirection などで設定したライトの設定などはライブラリ内部でシェーダー定数として設定されています。
 以下がその一覧です。


 Direct3D 11 の場合

  Direct3D 11 版作成直後で今後変更される可能性があるので、今のところリファレンスでは非公開です。
  ( 現在でもDXライブラリのソースファイルパッケージの中の Windows\DxShader_VS_D3D11.h と
    Shader\Windows\Direct3D11\VertexShader.h で確認することができます )


 Direct3D 9 の場合

  float4型定数

  0     x:0.0f y:1.0f
  1     マテリアルエミッシブカラー + マテリアルアンビエントカラー * グローバルアンビエントカラー
  2~5   射影行列の転置行列( ビュー座標から射影座標に変換する行列の転置行列 )
  6~9   ビュー行列の転置行列( ワールド座標からビュー座標に変換する行列の転置行列 )
  10    フォグ用パラメータ x:end/(end - start)  y:-1/(end - start)
                    z:density w:自然対数の低
  11    マテリアルディフューズカラー
  12    マテリアルスペキュラカラー
  13    マテリアルスペキュラハイライトのパワー
  14    有効ライト0番目の位置( ビュー空間 )
  15    有効ライト0番目の方向( ビュー空間 )
  16    有効ライト0番目のディフューズカラー
  17    有効ライト0番目のスペキュラカラー
  18    有効ライト0番目のアンビエントカラーとマテリアルのアンビエントカラーを乗算したもの
  19    有効ライト0番目の x:有効距離の二乗 y:Falloff
                   z:距離減衰パラメータ0 w:距離減衰パラメータ1
  20    有効ライト0番目の x:距離減衰パラメータ2
                 y:スポットライト用パラメータ0( cos( Phi / 2.0f ) )
                 z:スポットライト用パラメータ1( 1.0f / ( cos( Theta / 2.0f ) - cos( Phi / 2.0f ) ) )
  21~27  有効ライト1番目のパラメータ( 内訳は 14~20 と同じ )
  28~34  有効ライト2番目のパラメータ( 内訳は 14~20 と同じ )
  35~41  有効ライト3番目のパラメータ( 内訳は 14~20 と同じ )
  42     トゥーンレンダリング用の輪郭線の太さ
  43     ディフューズカラーとスペキュラカラーのソース
                x:ディフューズカラー( 0.0f:マテリアル 1.0f:頂点 )
                y:スペキュラカラー(  0.0f:マテリアル 1.0f:頂点 )
  44~56  シャドウマップ処理用のパラメータ

  57~87  ライブラリでは未使用

  88~89  テクスチャ座標変換行列の転置行列0( 3Dモデル描画時のみ有効 )
  90~91  テクスチャ座標変換行列の転置行列1( 3Dモデル描画時のみ有効 )
  92~93  テクスチャ座標変換行列の転置行列2( 3Dモデル描画時のみ有効 )
  94~96  ローカル座標からワールド座標に変換する行列を転置して4行目を削ったもの0
  97~255 ローカル座標からワールド座標に変換する行列を転置して4行目を削ったもの1~53
         ( スキニングメッシュの3Dモデル描画時のみ有効 )


  int4型定数

  0~15    ライブラリでは未使用


  BOOL型定数

  0     線形フォグかどうか( TRUE:線形フォグ FLASE:線形フォグ以外 )
  1     指数関数フォグかどうか( TRUE:指数関数フォグ FLASE:指数関数フォグ以外 )
  2     指数関数フォグ2かどうか( TRUE:指数関数2フォグ FLASE:指数関数2フォグ以外 )
  3     フォグを使用するかどうか( TRUE:フォグを使用する FALSE:フォグを使用しない )
  4     ライト0を使用するかどうか( TRUE:使用する FALSE:使用しない )
  5     ライト0はポイントライト若しくはスポットライトかどうか
           ( TRUE:ライトポイント又はスポットライト FALSE:ライトポイント又はスポットライト以外 )
  6     ライト0はスポットライトかどうか( TRUE:スポットライト FALSE:スポットライト以外 )
  7~9   ライト1のパラメータ( 内訳は 4~6 と同じ )
  10~12  ライト2のパラメータ( 内訳は 4~6 と同じ )
  13~15  ライト3のパラメータ( 内訳は 4~6 と同じ )


   int4型を除く定数がライブラリで殆ど使ってしまっていますが、これらの定数は SetVSConstF などの関数で
  上書き可能で、オリジナルのシェーダープログラムで使用しない定数については上記ライブラリ定数を無視して
  使うことができますのでご安心ください。
  ( 例えばライトを使用しない、若しくはオリジナルのライトパラメータを使う、という場合は
   float4型定数 14~41 を上書きして使用しても問題ありません )

 
サンプル

  Tex1.bmp を貼り付けたポリゴン2枚を頂点シェーダーを使用して左右に動かし、
 ピクセルシェーダーを使用してフェードアウト、フェードインをさせます。



C++のプログラム
Windows用
#include "DxLib.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { VERTEX3DSHADER Vertex[ 6 ] ; int vshandle ; int pshandle ; int texhandle ; int x ; int xadd ; float color ; float coloradd ; FLOAT4 f4 ; // DXライブラリの初期化 if( DxLib_Init() < 0 ) { // エラーが発生したら直ちに終了 return -1 ; } // 2ポリゴン分の頂点のデータをセットアップ Vertex[ 0 ].pos = VGet( 220.0f, 340.0f, 0.0f ) ; Vertex[ 0 ].norm = VGet( 0.0f, 0.0f, -1.0f ) ; Vertex[ 0 ].dif = GetColorU8( 255, 0,255,255 ) ; Vertex[ 0 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vertex[ 0 ].u = 0.0f ; Vertex[ 0 ].v = 0.0f ; Vertex[ 0 ].su = 0.0f ; Vertex[ 0 ].sv = 0.0f ; Vertex[ 1 ].pos = VGet( 420.0f, 340.0f, 0.0f ) ; Vertex[ 1 ].norm = VGet( 0.0f, 0.0f, -1.0f ) ; Vertex[ 1 ].dif = GetColorU8( 0, 0,255,255 ) ; Vertex[ 1 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vertex[ 1 ].u = 1.0f ; Vertex[ 1 ].v = 0.0f ; Vertex[ 1 ].su = 0.0f ; Vertex[ 1 ].sv = 0.0f ; Vertex[ 2 ].pos = VGet( 220.0f, 140.0f, 0.0f ) ; Vertex[ 2 ].norm = VGet( 0.0f, 0.0f, -1.0f ) ; Vertex[ 2 ].dif = GetColorU8( 255,255, 0,255 ) ; Vertex[ 2 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vertex[ 2 ].u = 0.0f ; Vertex[ 2 ].v = 1.0f ; Vertex[ 2 ].su = 0.0f ; Vertex[ 2 ].sv = 0.0f ; Vertex[ 3 ].pos = VGet( 220.0f, 140.0f, 0.0f ) ; Vertex[ 3 ].norm = VGet( 0.0f, 0.0f, -1.0f ) ; Vertex[ 3 ].dif = GetColorU8( 255,255, 0,255 ) ; Vertex[ 3 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vertex[ 3 ].u = 0.0f ; Vertex[ 3 ].v = 1.0f ; Vertex[ 3 ].su = 0.0f ; Vertex[ 3 ].sv = 0.0f ; Vertex[ 4 ].pos = VGet( 420.0f, 340.0f, 0.0f ) ; Vertex[ 4 ].norm = VGet( 0.0f, 0.0f, -1.0f ) ; Vertex[ 4 ].dif = GetColorU8( 0, 0,255,255 ) ; Vertex[ 4 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vertex[ 4 ].u = 1.0f ; Vertex[ 4 ].v = 0.0f ; Vertex[ 4 ].su = 0.0f ; Vertex[ 4 ].sv = 0.0f ; Vertex[ 5 ].pos = VGet( 420.0f, 140.0f, 0.0f ) ; Vertex[ 5 ].norm = VGet( 0.0f, 0.0f, -1.0f ) ; Vertex[ 5 ].dif = GetColorU8( 255, 0, 0,255 ) ; Vertex[ 5 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vertex[ 5 ].u = 1.0f ; Vertex[ 5 ].v = 1.0f ; Vertex[ 5 ].su = 0.0f ; Vertex[ 5 ].sv = 0.0f ; // 頂点シェーダーを読み込む vshandle = LoadVertexShader( "VertexShaderTestVS.vso" ) ; // ピクセルシェーダーを読み込む pshandle = LoadPixelShader( "VertexShaderTestPS.pso" ) ; // 描画に使用する画像の読み込み texhandle = LoadGraph( "Tex1.bmp" ) ; // 描画先を裏画面にする SetDrawScreen( DX_SCREEN_BACK ) ; // 表示座標を移動する処理の初期化 x = 0 ; xadd = 8 ; // 色を変化させる処理の初期化 color = 0.0f ; coloradd = 1.0f / 60.0f ; // ESCキーが押されるまでループ while( ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 ) { // 画面を初期化 ClearDrawScreen() ; // 座標を移動させる x += xadd ; if( x > 200 || x < -200 ) { xadd = -xadd ; } // 色の値を変化させる color += coloradd ; if( color <= 0.0f || color >= 1.0f ) { coloradd = -coloradd ; } // 座標値を頂点シェーダー float4型定数0番にセット f4.x = ( float )x ; f4.y = 0.0f ; f4.z = 0.0f ; f4.w = 0.0f ; SetVSConstF( 0, f4 ) ; // 色の値をピクセルシェーダー float4型定数0番にセット f4.x = color ; f4.y = color ; f4.z = color ; f4.w = 1.0f ; SetPSConstF( 0, f4 ) ; // 使用する頂点シェーダーのセット SetUseVertexShader( vshandle ) ; // 使用するピクセルシェーダーをセット SetUsePixelShader( pshandle ) ; // 使用するテクスチャを0番にセット SetUseTextureToShader( 0, texhandle ) ; // シェーダーを使用した2ポリゴンの描画 DrawPolygon3DToShader( Vertex, 2 ) ; // 裏画面の内容を表画面に反映させる ScreenFlip() ; } // 使用した頂点シェーダーの float4型定数の設定を無効化する ResetVSConstF( 0, 2 ) ; // 使用したピクセルシェーダーの float4型定数の設定を無効化する ResetPSConstF( 0, 1 ) ; // 読み込んだ頂点シェーダーの削除 DeleteShader( vshandle ) ; // 読み込んだピクセルシェーダーの削除 DeleteShader( pshandle ) ; // 読み込んだ画像のグラフィックハンドルを削除 DeleteGraph( texhandle ) ; // DXライブラリの後始末 DxLib_End() ; // ソフトの終了 return 0 ; }





頂点シェーダーのプログラム( コンパイルして VertexShaderTestVS.vso になる前のHLSLソース )
// 頂点シェーダーの入力 struct VS_INPUT { float4 Position : POSITION ; // 座標( VERTEX3DSHADER構造体の pos の値 ) float3 Normal : NORMAL0 ; // 法線( VERTEX3DSHADER構造体の norm の値 ) float4 DiffuseColor : COLOR0 ; // ディフューズカラー( VERTEX3DSHADER構造体の dif の値 ) float4 SpecularColor : COLOR1 ; // スペキュラカラー( VERTEX3DSHADER構造体の spc の値 ) float2 TextureCoord0 : TEXCOORD0 ; // テクスチャ座標0( VERTEX3DSHADER構造体の u, v の値 ) float2 TextureCoord1 : TEXCOORD1 ; // テクスチャ座標1( VERTEX3DSHADER構造体の su, sv の値 ) } ; // 頂点シェーダーの出力 struct VS_OUTPUT { float4 ProjectionPosition : POSITION ; // 座標( 射影空間 ) float4 DiffuseColor : COLOR0 ; // ディフューズカラー float2 TextureCoord0 : TEXCOORD0 ; // テクスチャ座標 } ; // C++ 側で設定する定数の定義 float4x4 cfViewMatrix : register( c6 ) ; // ワールド座標をビュー座標に変換する行列の転置行列 float4x4 cfProjectionMatrix : register( c2 ) ; // ビュー座標を射影座標に変換する行列の転置行列 // 頂点座標に加算する値 float4 cfAddPosition : register( c0 ) ; // main関数 VS_OUTPUT main( VS_INPUT VSInput ) { VS_OUTPUT VSOutput ; float4 lWorldPosition ; float4 lViewPosition ; // 入力の頂点座標にC++プログラム側で設定した頂点座標を加算する lWorldPosition = VSInput.Position + cfAddPosition ; // 頂点座標をビュー空間の座標に変換する lViewPosition = mul( lWorldPosition, cfViewMatrix ) ; // ビュー空間の座標を射影空間の座標に変換する VSOutput.ProjectionPosition = mul( lViewPosition, cfProjectionMatrix ) ; // テクスチャ座標はそのまま代入 VSOutput.TextureCoord0 = VSInput.TextureCoord0; // 頂点カラーはそのまま代入 VSOutput.DiffuseColor = VSInput.DiffuseColor ; // 関数の戻り値がピクセルシェーダーに渡される return VSOutput ; }





ピクセルシェーダーのプログラム( コンパイルして VertexShaderTestPS.pso になる前のHLSLソース )
// ピクセルシェーダーの入力 struct PS_INPUT { float4 DiffuseColor : COLOR0 ; // ディフューズカラー float2 TextureCoord0 : TEXCOORD0 ; // テクスチャ座標 } ; // ピクセルシェーダーの出力 struct PS_OUTPUT { float4 DrawColor : COLOR0 ; // 描画カラー } ; // C++ 側で設定する定数の定義 // 描画するテクスチャ sampler DiffuseMapTexture : register( s0 ) ; // 描画カラーに乗算する値 float4 cfMultiplyColor : register( c0 ) ; // main関数 PS_OUTPUT main( PS_INPUT PSInput ) { PS_OUTPUT PSOutput ; float4 lTextureColor ; // テクスチャーの色を取得 lTextureColor = tex2D( DiffuseMapTexture, PSInput.TextureCoord0 ) ; // 出力する色はテクスチャの色と C++ で設定した値とディフューズカラーを乗算したもの PSOutput.DrawColor = lTextureColor * cfMultiplyColor * PSInput.DiffuseColor ; // 関数の戻り値がラスタライザに渡される return PSOutput ; }





宣言int LoadPixelShader( char *FileName ) ;

概略ピクセルシェーダーバイナリを読み込みシェーダーハンドルを作成する

引数 FileName : ピクセルシェーダーバイナリファイルのパス
戻り値 -1    : エラー発生
-1以外 : シェーダーハンドル

解説  ピクセルシェーダーのプログラムをコンパイルしてできるバイナリファイルをメモリに読み込み、 それを使用するためのハンドル( int型の値 )を取得します。
 コンパイル前のシェーダープログラムを読み込むことはできませんので注意してください。( シェーダープログラムをコンパイルするためのソフトはDXライブラリのパッケージの Tool\ShaderCompiler の中に入っています )
 戻り値で得られるシェーダーハンドルは SetUsePixelShader の引数として使用します。
 同時に読み込んでおけるシェーダーの数には限りがありますので、必要が無くなったら DeleteShader で削除してください。


DXライブラリ内部で設定するピクセルシェーダー定数について

 DXライブラリではフォンシェーディング( ピクセルシェーダーでライティングを行う手法 )の為にマテリアルやライトの設定をライブラリ内部でシェーダー定数として設定しています。
 以下がその一覧です。


 Direct3D 11 の場合

  Direct3D 11 版作成直後で今後変更される可能性があるので、今のところリファレンスでは非公開です。
  ( 現在でもDXライブラリのソースファイルパッケージの中の Windows\DxShader_PS_D3D11.h と
    Shader\Windows\Direct3D11\PixelShader.h で確認することができます )


 Direct3D 9 の場合

  float4型定数

  0     x:0.0f  y:0.5f z:1.0f w:2.0f
  1     マテリアルエミッシブカラー + マテリアルアンビエントカラー * グローバルアンビエントカラー
  2     マテリアルディフューズカラー
  3     マテリアルスペキュラカラー
  4     マテリアルスペキュラハイライトのパワー
  5     不透明度など
  6     トゥーンレンダリングの輪郭線の色
  7     トゥーンレンダリングの輪郭線の太さ
  8     フォグカラー
  9     有効ライト0番目のディフューズカラー
  10     有効ライト0番目のスペキュラカラー
  11     有効ライト0番目のアンビエントカラー
  12~14  有効ライト1番目のパラメータ( 内訳は 9~11 と同じ )
  15~17  有効ライト2番目のパラメータ( 内訳は 9~11 と同じ )
  18~21  シャドウマップ処理用のパラメータ

  22~31  未使用( ピクセルシェーダー2.0で使用可能な float4型定数の数は 32個です )

  32     有効ライト0番目の座標( ビュー空間 )
  33     有効ライト0番目の法線( ビュー空間 )
  34     有効ライト0番目のディフューズカラー
  35     有効ライト0番目のスペキュラカラー
  36     有効ライト0番目のアンビエントカラーとマテリアルのアンビエントカラーを乗算したもの
  37     有効ライト0番目の x:有効距離の二乗 y:Falloff
                   z:距離減衰パラメータ0 w:距離減衰パラメータ1
  38     有効ライト0番目の x:距離減衰パラメータ1
                 y:スポットライト用パラメータ0( cos( Phi / 2.0f ) )
                 z:スポットライト用パラメータ1( 1.0f / ( cos( Theta / 2.0f ) - cos( Phi / 2.0f ) ) )
  39~45  有効ライト1番目のパラメータ( 内訳は 32~38 と同じ )
  46~52  有効ライト2番目のパラメータ( 内訳は 32~38 と同じ )
  53~59  有効ライト3番目のパラメータ( 内訳は 32~38 と同じ )
  60~223  未使用( ピクセルシェーダー3.0で使用可能な float4型定数の数は 224個です )


  int4型定数

  0~15    ライブラリでは未使用( ピクセルシェーダー2.0では int4型定数はありません )


  BOOL型定数

  0~15    ライブラリでは未使用( ピクセルシェーダー2.0では int4型定数はありません )


   ライブラリが殆ど使ってしまっていますが、これらの定数は SetPSConstF などの関数で上書き可能で、
  オリジナルのシェーダープログラムで使用しない定数については上記ライブラリ定数を無視して使うことが
  できますのでご安心ください。
  ( 例えばオリジナルのマテリアル処理を行う場合は float4型定数 1~4 を上書きして使用しても問題ありません )

 
サンプル

  ピクセルシェーダーを使って Tex1.bmp の赤成分と青成分を入れ替えて画面に描画します。



C++のプログラム
Windows用
#include "DxLib.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { int texhandle, pshandle ; VERTEX2DSHADER Vert[ 6 ] ; // DXライブラリの初期化 if( DxLib_Init() < 0 ) return -1; // テクスチャを読み込む texhandle = LoadGraph( "Tex1.bmp" ) ; // ピクセルシェーダーを読み込む pshandle = LoadPixelShader( "PixelShaderTestPS.pso" ) ; // 2ポリゴン分の頂点のデータをセットアップ Vert[ 0 ].pos = VGet( 0.0f, 0.0f, 0.0f ) ; Vert[ 0 ].rhw = 1.0f ; Vert[ 0 ].dif = GetColorU8( 255,255,255,255 ) ; Vert[ 0 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vert[ 0 ].u = 0.0f ; Vert[ 0 ].v = 0.0f ; Vert[ 0 ].su = 0.0f ; Vert[ 0 ].sv = 0.0f ; Vert[ 1 ].pos = VGet( 256.0f, 0.0f, 0.0f ) ; Vert[ 1 ].rhw = 1.0f ; Vert[ 1 ].dif = GetColorU8( 255,255,255,255 ) ; Vert[ 1 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vert[ 1 ].u = 1.0f ; Vert[ 1 ].v = 0.0f ; Vert[ 1 ].su = 1.0f ; Vert[ 1 ].sv = 0.0f ; Vert[ 2 ].pos = VGet( 0.0f, 256.0f, 0.0f ) ; Vert[ 2 ].rhw = 1.0f ; Vert[ 2 ].dif = GetColorU8( 255,255,255,255 ) ; Vert[ 2 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vert[ 2 ].u = 0.0f ; Vert[ 2 ].v = 1.0f ; Vert[ 2 ].su = 0.0f ; Vert[ 2 ].sv = 1.0f ; Vert[ 3 ].pos = VGet( 256.0f, 256.0f, 0.0f ) ; Vert[ 3 ].rhw = 1.0f ; Vert[ 3 ].dif = GetColorU8( 255,255,255,255 ) ; Vert[ 3 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vert[ 3 ].u = 1.0f ; Vert[ 3 ].v = 1.0f ; Vert[ 3 ].su = 1.0f ; Vert[ 3 ].sv = 1.0f ; Vert[ 4 ].pos = VGet( 0.0f, 256.0f, 0.0f ) ; Vert[ 4 ].rhw = 1.0f ; Vert[ 4 ].dif = GetColorU8( 255,255,255,255 ) ; Vert[ 4 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vert[ 4 ].u = 0.0f ; Vert[ 4 ].v = 1.0f ; Vert[ 4 ].su = 0.0f ; Vert[ 4 ].sv = 1.0f ; Vert[ 5 ].pos = VGet( 256.0f, 0.0f, 0.0f ) ; Vert[ 5 ].rhw = 1.0f ; Vert[ 5 ].dif = GetColorU8( 255,255,255,255 ) ; Vert[ 5 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vert[ 5 ].u = 1.0f ; Vert[ 5 ].v = 0.0f ; Vert[ 5 ].su = 1.0f ; Vert[ 5 ].sv = 0.0f ; // 使用するテクスチャを0番にセット SetUseTextureToShader( 0, texhandle ) ; // 使用するピクセルシェーダーをセット SetUsePixelShader( pshandle ) ; // シェーダーを使用した2Dの2ポリゴンの描画 DrawPolygon2DToShader( Vert, 2 ) ; // キー入力待ち WaitKey() ; // 読み込んだピクセルシェーダーの削除 DeleteShader( pshandle ) ; // 読み込んだ画像のグラフィックハンドルを削除 DeleteGraph( texhandle ) ; // DXライブラリの後始末 DxLib_End(); // ソフトの終了 return 0; }





ピクセルシェーダーのプログラム( コンパイルして PixelShaderTestPS.pso になる前のHLSLソース )
// ピクセルシェーダーの入力 struct PS_INPUT { float4 DiffuseColor : COLOR0 ; float4 SpecularColor : COLOR1 ; float2 TextureCoord0 : TEXCOORD0 ; float2 TextureCoord1 : TEXCOORD1 ; } ; // ピクセルシェーダーの出力 struct PS_OUTPUT { float4 Output : COLOR0 ; } ; // C++ 側で設定する定数の定義 // 描画するテクスチャ sampler DiffuseMapTexture : register( s0 ) ; // main関数 PS_OUTPUT main( PS_INPUT PSInput ) { PS_OUTPUT PSOutput ; float4 lTextureColor ; // テクスチャーの色を取得 lTextureColor = tex2D( DiffuseMapTexture, PSInput.TextureCoord0 ) ; // 出力する色は青成分と赤成分を逆転したもの PSOutput.Output.r = lTextureColor.b ; PSOutput.Output.g = lTextureColor.g ; PSOutput.Output.b = lTextureColor.r ; PSOutput.Output.a = lTextureColor.a ; // 関数の戻り値がラスタライザに渡される return PSOutput ; }





宣言int DeleteShader( int ShaderHandle ) ;

概略シェーダーハンドルを削除する

引数 int ShaderHandle : 削除する頂点シェーダー又はピクセルシェーダーのハンドル
戻り値 0:成功
 -1:エラー発生

解説  LoadVertexShaderLoadPixelShader で読み込んだシェーダーを削除します。

 一度に読み込んでおけるシェーダーの数には限りがあるので、必要が無くなったシェーダーはこの関数を使って削除する必要があります。

サンプル

 LoadVertexShaderLoadPixelShaderのサンプルを参照してください。



宣言int InitShader( void ) ;

概略シェーダーハンドルを全て削除する

引数 なし
戻り値 0:成功
 -1:エラー発生

解説  LoadVertexShaderLoadPixelShader で読み込んだシェーダーを全て削除します。

 DeleteShader では削除したいシェーダーを一つ一つ指定しなければなりませんが、この関数を使えば一度に全てのシェーダーを削除することができます。

サンプル

 ありません。



宣言int SetVSConstF( int ConstantIndex, FLOAT4 Param ) ;

概略頂点シェーダーの FLOAT4 型定数を設定する

引数 int ConstantIndex : 変更する FLOAT4型定数の番号( 0~255 )
FLOAT4 Param : 設定する FLOAT4型の値
戻り値 0:成功
 -1:エラー発生

解説 ( この関数は Direct3D 9 用の関数です、Direct3D 11 では効果がありませんので注意してください )
   頂点シェーダーのプログラムで使用するFLOAT4型定数を設定する関数です。
 FLOAT4 は構造体で、以下のように定義されています。
struct FLOAT4 { float x, y, z, w ; } ;
 FLOAT4 の文字通り float 型の変数が4つあります。
 この x, y, z, w に値を代入して SetVSConstF で定数として設定すると、それがそのまま頂点シェーダーで使えるようになります。


<例>

[ C++側 ]

// x=10, y=20, z=30, w=0 の FLOAT4 型の値を定数110にセット
FLOAT4 Temp ;
Temp.x = 10.0f ;
Temp.y = 20.0f ;
Temp.z = 30.0f ;
Temp.w = 0.0f ;
SetVSConstF( 110, Temp ) ;


[ 頂点シェーダー側 ]

// FLOAT4型定数の 110番目を ConstF110 という名前で使うように宣言
// これで SetVSConstF( 110, Temp ) ; で設定した値が ConstF110 という名前で使用可能になる
float4 ConstF110 : register( c110 ) ;


 因みに ConstantIndex で有効な値が0~255なのは頂点シェーダー2.0と3.0での float4型定数の最大数が 256個だからです。
一度に沢山の FLOAT4型定数を設定したい場合は SetVSConstFArray を使用します。

 尚、この関数で値を設定した場合は、DrawGraph 等の描画関数を使用する前に ResetVSConstF 関数で設定した値を無効にする必要がありますので注意してください。

サンプル

 LoadVertexShader のサンプルを参照してください。



宣言int SetVSConstFMtx( int ConstantIndex, MATRIX Param ) ;

概略頂点シェーダーの FLOAT4 型定数に行列を設定する

引数 int ConstantIndex : 変更する FLOAT4型定数の番号( 0~252 )
MATRIX Param : 設定する MATRIX型の値
戻り値 0:成功
 -1:エラー発生

解説 ( この関数は Direct3D 9 用の関数です、Direct3D 11 では効果がありませんので注意してください )
SetVSConstF は FLOAT4型の構造体一つ分を頂点シェーダーの FLOAT4型定数として設定する関数でしたが、 この関数は FLOAT4型定数4つ分を一度に設定します。
 何故4つかといいますと、MATRIX型は 4×4 の行列で、float型変数16個が中にあり、FLOAT4型構造体の一つが float型変数 4個分なので、 16 ÷ 4 = 4 というわけです。

 具体的には
定数番号 ConstantIndex に MATRIX構造体の m[0][0] m[0][1] m[0][2] m[0][3] が、
定数番号 ConstantIndex + 1 に MATRIX構造体の m[1][0] m[1][1] m[1][2] m[1][3] が、
定数番号 ConstantIndex + 2 に MATRIX構造体の m[2][0] m[2][1] m[2][2] m[2][3] が、
定数番号 ConstantIndex + 3 に MATRIX構造体の m[3][0] m[3][1] m[3][2] m[3][3] が、
それぞれ左から順に x, y, z, w に代入されて設定されます。

 頂点シェーダーで使用できる FLOAT4型定数の数が256個なのに対し ConstantIndex で指定できる値が252までなのは、指定した番号から4個分の定数が必要だからです。

 尚、この関数で値を設定した場合は、DrawGraph 等の描画関数を使用する前に ResetVSConstF 関数で設定した値を無効にする必要がありますので注意してください。

サンプル

  Tex1.bmp を貼り付けたポリゴン2枚を SetVSConstFMtx で設定した回転行列と頂点シェーダーを使用して回転させます。
 回転行列を定数10番に設定しているのは定数2~9番がビュー行列と射影行列の割り当て位置になっているからです。



C++のプログラム
Windows用
#include "DxLib.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { VERTEX3DSHADER Vertex[ 6 ] ; int vshandle ; int pshandle ; int texhandle ; float angle ; FLOAT4 pos ; MATRIX mtx ; // DXライブラリの初期化 if( DxLib_Init() < 0 ) { // エラーが発生したら直ちに終了 return -1 ; } // 2ポリゴン分の頂点のデータをセットアップ Vertex[ 0 ].pos = VGet( -128.0f, 128.0f, 0.0f ) ; Vertex[ 0 ].norm = VGet( 0.0f, 0.0f, -1.0f ) ; Vertex[ 0 ].dif = GetColorU8( 255, 0,255,255 ) ; Vertex[ 0 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vertex[ 0 ].u = 0.0f ; Vertex[ 0 ].v = 0.0f ; Vertex[ 0 ].su = 0.0f ; Vertex[ 0 ].sv = 0.0f ; Vertex[ 1 ].pos = VGet( 128.0f, 128.0f, 0.0f ) ; Vertex[ 1 ].norm = VGet( 0.0f, 0.0f, -1.0f ) ; Vertex[ 1 ].dif = GetColorU8( 0, 0,255,255 ) ; Vertex[ 1 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vertex[ 1 ].u = 1.0f ; Vertex[ 1 ].v = 0.0f ; Vertex[ 1 ].su = 0.0f ; Vertex[ 1 ].sv = 0.0f ; Vertex[ 2 ].pos = VGet( -128.0f, -128.0f, 0.0f ) ; Vertex[ 2 ].norm = VGet( 0.0f, 0.0f, -1.0f ) ; Vertex[ 2 ].dif = GetColorU8( 255,255, 0,255 ) ; Vertex[ 2 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vertex[ 2 ].u = 0.0f ; Vertex[ 2 ].v = 1.0f ; Vertex[ 2 ].su = 0.0f ; Vertex[ 2 ].sv = 0.0f ; Vertex[ 3 ].pos = VGet( -128.0f, -128.0f, 0.0f ) ; Vertex[ 3 ].norm = VGet( 0.0f, 0.0f, -1.0f ) ; Vertex[ 3 ].dif = GetColorU8( 255,255, 0,255 ) ; Vertex[ 3 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vertex[ 3 ].u = 0.0f ; Vertex[ 3 ].v = 1.0f ; Vertex[ 3 ].su = 0.0f ; Vertex[ 3 ].sv = 0.0f ; Vertex[ 4 ].pos = VGet( 128.0f, 128.0f, 0.0f ) ; Vertex[ 4 ].norm = VGet( 0.0f, 0.0f, -1.0f ) ; Vertex[ 4 ].dif = GetColorU8( 0, 0,255,255 ) ; Vertex[ 4 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vertex[ 4 ].u = 1.0f ; Vertex[ 4 ].v = 0.0f ; Vertex[ 4 ].su = 0.0f ; Vertex[ 4 ].sv = 0.0f ; Vertex[ 5 ].pos = VGet( 128.0f, -128.0f, 0.0f ) ; Vertex[ 5 ].norm = VGet( 0.0f, 0.0f, -1.0f ) ; Vertex[ 5 ].dif = GetColorU8( 255, 0, 0,255 ) ; Vertex[ 5 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vertex[ 5 ].u = 1.0f ; Vertex[ 5 ].v = 1.0f ; Vertex[ 5 ].su = 0.0f ; Vertex[ 5 ].sv = 0.0f ; // 頂点シェーダーを読み込む vshandle = LoadVertexShader( "SetVSConstFMtxTestVS.vso" ) ; // ピクセルシェーダーを読み込む pshandle = LoadPixelShader( "SetVSConstFMtxTestPS.pso" ) ; // 描画に使用する画像の読み込み texhandle = LoadGraph( "Tex1.bmp" ) ; // 描画先を裏画面にする SetDrawScreen( DX_SCREEN_BACK ) ; // 回転角度の値を初期化 angle = 0.0f ; // 頂点シェーダー FLOAT4型定数0番に表示座標をセット pos.x = 320.0f ; pos.y = 240.0f ; pos.z = 0.0f ; pos.w = 0.0f ; SetVSConstF( 0, pos ) ; // ESCキーが押されるまでループ while( ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 ) { // 画面を初期化 ClearDrawScreen() ; // 回転角度を変化させる angle += 0.05f ; // 回転角度からZ軸回転行列を作成 mtx = MGetRotZ( angle ) ; // 回転行列を頂点シェーダー FLOAT4型定数10~13番にセット SetVSConstFMtx( 10, mtx ) ; // 使用する頂点シェーダーのセット SetUseVertexShader( vshandle ) ; // 使用するピクセルシェーダーをセット SetUsePixelShader( pshandle ) ; // 使用するテクスチャを0番にセット SetUseTextureToShader( 0, texhandle ) ; // シェーダーを使用した2ポリゴンの描画 DrawPolygon3DToShader( Vertex, 2 ) ; // 裏画面の内容を表画面に反映させる ScreenFlip() ; } // 使用したfloat4型定数0番の設定を無効化する ResetVSConstF( 0, 1 ) ; // 使用したfloat4型定数10~13番の設定を無効化する ResetVSConstF( 10, 4 ) ; // 読み込んだ頂点シェーダーの削除 DeleteShader( vshandle ) ; // 読み込んだピクセルシェーダーの削除 DeleteShader( pshandle ) ; // 読み込んだ画像のグラフィックハンドルを削除 DeleteGraph( texhandle ) ; // DXライブラリの後始末 DxLib_End() ; // ソフトの終了 return 0 ; }





頂点シェーダーのプログラム( コンパイルして SetVSConstFMtxTestVS.vso になる前のHLSLソース )
// 頂点シェーダーの入力 struct VS_INPUT { float4 Position : POSITION ; // 座標( VERTEX3DSHADER構造体の pos の値 ) float3 Normal : NORMAL0 ; // 法線( VERTEX3DSHADER構造体の norm の値 ) float4 DiffuseColor : COLOR0 ; // ディフューズカラー( VERTEX3DSHADER構造体の dif の値 ) float4 SpecularColor : COLOR1 ; // スペキュラカラー( VERTEX3DSHADER構造体の spc の値 ) float2 TextureCoord0 : TEXCOORD0 ; // テクスチャ座標0( VERTEX3DSHADER構造体の u, v の値 ) float2 TextureCoord1 : TEXCOORD1 ; // テクスチャ座標1( VERTEX3DSHADER構造体の su, sv の値 ) } ; // 頂点シェーダーの出力 struct VS_OUTPUT { float4 ProjectionPosition : POSITION ; // 座標( 射影空間 ) float4 DiffuseColor : COLOR0 ; // ディフューズカラー float2 TextureCoord0 : TEXCOORD0 ; // テクスチャ座標 } ; // C++ 側で設定する定数の定義 float4x4 cfViewMatrix : register( c6 ) ; // ワールド座標をビュー座標に変換する行列の転置行列 float4x4 cfProjectionMatrix : register( c2 ) ; // ビュー座標を射影座標に変換する行列の転置行列 // 回転中心になる座標 float4 cfCenterPosition : register( c0 ) ; // Z回転行列 float4x4 cfRotateZMatrix : register( c10 ) ; // main関数 VS_OUTPUT main( VS_INPUT VSInput ) { VS_OUTPUT VSOutput ; float4 lWorldPosition ; float4 lViewPosition ; // 入力座標にZ回転行列を掛けて座標を回転させる lWorldPosition = mul( cfRotateZMatrix, VSInput.Position ) ; // Z回転しただけだと原点に居るので、表示させたい座標に移動する lWorldPosition += cfCenterPosition ; // 頂点座標をビュー空間の座標に変換する lViewPosition = mul( lWorldPosition, cfViewMatrix ) ; // ビュー空間の座標を射影空間の座標に変換する VSOutput.ProjectionPosition = mul( lViewPosition, cfProjectionMatrix ) ; // テクスチャ座標はそのまま代入 VSOutput.TextureCoord0 = VSInput.TextureCoord0; // 頂点カラーはそのまま代入 VSOutput.DiffuseColor = VSInput.DiffuseColor ; // 関数の戻り値がピクセルシェーダーに渡される return VSOutput ; }





ピクセルシェーダーのプログラム( コンパイルして SetVSConstFMtxTestPS.pso になる前のHLSLソース )
// ピクセルシェーダーの入力 struct PS_INPUT { float4 DiffuseColor : COLOR0 ; // ディフューズカラー float2 TextureCoord0 : TEXCOORD0 ; // テクスチャ座標 } ; // ピクセルシェーダーの出力 struct PS_OUTPUT { float4 DrawColor : COLOR0 ; // 描画カラー } ; // C++ 側で設定する定数の定義 // 描画するテクスチャ sampler DiffuseMapTexture : register( s0 ) ; // main関数 PS_OUTPUT main( PS_INPUT PSInput ) { PS_OUTPUT PSOutput ; float4 lTextureColor ; // テクスチャーの色を取得 lTextureColor = tex2D( DiffuseMapTexture, PSInput.TextureCoord0 ) ; // 出力する色はテクスチャの色とディフューズカラーを乗算したもの PSOutput.DrawColor = lTextureColor * PSInput.DiffuseColor ; // 関数の戻り値がラスタライザに渡される return PSOutput ; }





宣言int SetVSConstFArray( int ConstantIndex, FLOAT4 *ParamArray, int ParamNum ) ;

概略頂点シェーダーの FLOAT4 型定数に行列を設定する

引数 int ConstantIndex : 変更する FLOAT4型定数の番号( 0~255 )
FLOAT4 *ParamArray : FLOAT4型配列の先頭アドレス
int ParamNum : 設定する数
戻り値 0:成功
 -1:エラー発生

解説 ( この関数は Direct3D 9 用の関数です、Direct3D 11 では効果がありませんので注意してください )
 SetVSConstF は FLOAT4型の構造体一つ分を頂点シェーダーの FLOAT4型定数として設定する関数でしたが、 この関数は FLOAT4型定数を指定数分だけ一度に設定することができます。

 例えば

FLOAT4 f4array[ 3 ] ;
f4array[ 0 ].x = 100.0f ;
f4array[ 0 ].y = 65.0f ;
f4array[ 0 ].z = 19.0f ;
f4array[ 0 ].w = 888.0f ;
f4array[ 1 ].x = 296.0f ;
f4array[ 1 ].y = 879.0f ;
f4array[ 1 ].z = 1111.0f ;
f4array[ 1 ].w = 6.0f ;
f4array[ 2 ].x = 769910.0f ;
f4array[ 2 ].y = 4023.0f ;
f4array[ 2 ].z = 61.0f ;
f4array[ 2 ].w = 735.0f ;
SetVSConstFArray( 10, f4array, 3 ) ;

 は、

FLOAT4 f4array[ 3 ] ;
f4array[ 0 ].x = 100.0f ;
f4array[ 0 ].y = 65.0f ;
f4array[ 0 ].z = 19.0f ;
f4array[ 0 ].w = 888.0f ;
f4array[ 1 ].x = 296.0f ;
f4array[ 1 ].y = 879.0f ;
f4array[ 1 ].z = 1111.0f ;
f4array[ 1 ].w = 6.0f ;
f4array[ 2 ].x = 769910.0f ;
f4array[ 2 ].y = 4023.0f ;
f4array[ 2 ].z = 61.0f ;
f4array[ 2 ].w = 735.0f ;
SetVSConstF( 10, f4array[ 0 ] ) ;
SetVSConstF( 11, f4array[ 1 ] ) ;
SetVSConstF( 12, f4array[ 2 ] ) ;

 と同じ動作をします。
 なんでこんな関数があるのかといいますと、単純に何回も SetVSConstF を呼ぶのが面倒だからという理由以外に何回も SetVSConstF を呼ぶのは処理負荷が高いからです。

 尚、この関数で値を設定した場合は、DrawGraph 等の描画関数を使用する前に ResetVSConstF 関数で設定した値を無効にする必要がありますので注意してください。

サンプル

  Tex1.bmp を貼り付けたポリゴン2枚を SetVSConstFArray を使って予め設定した画面4隅の座標に順番に描画します。
 HLSLのソースを見ると分かると思いますが、HLSLで int4 として宣言した変数も内部では FLOAT4型として扱われるので
 ciPositionIndex の値を設定する関数も SetVSConstF となっています。



C++のプログラム
Windows用
#include "DxLib.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { VERTEX3DSHADER Vertex[ 6 ] ; int vshandle ; int pshandle ; int texhandle ; int posind ; int poscounter ; FLOAT4 pos[ 4 ] ; FLOAT4 f4 ; // DXライブラリの初期化 if( DxLib_Init() < 0 ) { // エラーが発生したら直ちに終了 return -1 ; } // 2ポリゴン分の頂点のデータをセットアップ Vertex[ 0 ].pos = VGet( -64.0f, 64.0f, 0.0f ) ; Vertex[ 0 ].norm = VGet( 0.0f, 0.0f, -1.0f ) ; Vertex[ 0 ].dif = GetColorU8( 255, 0,255,255 ) ; Vertex[ 0 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vertex[ 0 ].u = 0.0f ; Vertex[ 0 ].v = 0.0f ; Vertex[ 0 ].su = 0.0f ; Vertex[ 0 ].sv = 0.0f ; Vertex[ 1 ].pos = VGet( 64.0f, 64.0f, 0.0f ) ; Vertex[ 1 ].norm = VGet( 0.0f, 0.0f, -1.0f ) ; Vertex[ 1 ].dif = GetColorU8( 0, 0,255,255 ) ; Vertex[ 1 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vertex[ 1 ].u = 1.0f ; Vertex[ 1 ].v = 0.0f ; Vertex[ 1 ].su = 0.0f ; Vertex[ 1 ].sv = 0.0f ; Vertex[ 2 ].pos = VGet( -64.0f, -64.0f, 0.0f ) ; Vertex[ 2 ].norm = VGet( 0.0f, 0.0f, -1.0f ) ; Vertex[ 2 ].dif = GetColorU8( 255,255, 0,255 ) ; Vertex[ 2 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vertex[ 2 ].u = 0.0f ; Vertex[ 2 ].v = 1.0f ; Vertex[ 2 ].su = 0.0f ; Vertex[ 2 ].sv = 0.0f ; Vertex[ 3 ].pos = VGet( -64.0f, -64.0f, 0.0f ) ; Vertex[ 3 ].norm = VGet( 0.0f, 0.0f, -1.0f ) ; Vertex[ 3 ].dif = GetColorU8( 255,255, 0,255 ) ; Vertex[ 3 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vertex[ 3 ].u = 0.0f ; Vertex[ 3 ].v = 1.0f ; Vertex[ 3 ].su = 0.0f ; Vertex[ 3 ].sv = 0.0f ; Vertex[ 4 ].pos = VGet( 64.0f, 64.0f, 0.0f ) ; Vertex[ 4 ].norm = VGet( 0.0f, 0.0f, -1.0f ) ; Vertex[ 4 ].dif = GetColorU8( 0, 0,255,255 ) ; Vertex[ 4 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vertex[ 4 ].u = 1.0f ; Vertex[ 4 ].v = 0.0f ; Vertex[ 4 ].su = 0.0f ; Vertex[ 4 ].sv = 0.0f ; Vertex[ 5 ].pos = VGet( 64.0f, -64.0f, 0.0f ) ; Vertex[ 5 ].norm = VGet( 0.0f, 0.0f, -1.0f ) ; Vertex[ 5 ].dif = GetColorU8( 255, 0, 0,255 ) ; Vertex[ 5 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vertex[ 5 ].u = 1.0f ; Vertex[ 5 ].v = 1.0f ; Vertex[ 5 ].su = 0.0f ; Vertex[ 5 ].sv = 0.0f ; // 頂点シェーダーを読み込む vshandle = LoadVertexShader( "SetVSConstFArrayTestVS.vso" ) ; // ピクセルシェーダーを読み込む pshandle = LoadPixelShader( "SetVSConstFArrayTestPS.pso" ) ; // 描画に使用する画像の読み込み texhandle = LoadGraph( "Tex1.bmp" ) ; // 描画先を裏画面にする SetDrawScreen( DX_SCREEN_BACK ) ; // 位置番号処理用の値を初期化 posind = 0 ; poscounter = 0 ; // 頂点シェーダー FLOAT4型定数10~13番に表示座標をセット pos[ 0 ].x = 100.0f ; pos[ 0 ].y = 100.0f ; pos[ 0 ].z = 0.0f ; pos[ 0 ].w = 0.0f ; pos[ 1 ].x = 540.0f ; pos[ 1 ].y = 100.0f ; pos[ 1 ].z = 0.0f ; pos[ 1 ].w = 0.0f ; pos[ 2 ].x = 540.0f ; pos[ 2 ].y = 380.0f ; pos[ 2 ].z = 0.0f ; pos[ 2 ].w = 0.0f ; pos[ 3 ].x = 100.0f ; pos[ 3 ].y = 380.0f ; pos[ 3 ].z = 0.0f ; pos[ 3 ].w = 0.0f ; SetVSConstFArray( 10, pos, 4 ) ; // ESCキーが押されるまでループ while( ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 ) { // 画面を初期化 ClearDrawScreen() ; // 一定時間経過したら位置番号を変更する poscounter ++ ; if( poscounter == 30 ) { poscounter = 0 ; posind ++ ; if( posind == 4 ) { posind = 0 ; } } // 位置番号を FLOAT4型の x に代入して頂点シェーダー FLOAT4型定数0番にセット f4.x = ( float )posind ; f4.y = 0 ; f4.z = 0 ; f4.w = 0 ; SetVSConstF( 0, f4 ) ; // 使用する頂点シェーダーのセット SetUseVertexShader( vshandle ) ; // 使用するピクセルシェーダーをセット SetUsePixelShader( pshandle ) ; // 使用するテクスチャを0番にセット SetUseTextureToShader( 0, texhandle ) ; // シェーダーを使用した2ポリゴンの描画 DrawPolygon3DToShader( Vertex, 2 ) ; // 裏画面の内容を表画面に反映させる ScreenFlip() ; } // 使用したfloat4型定数10~13番の設定を無効化する ResetVSConstF( 10, 4 ) ; // 使用したint4型定数0番の設定を無効化する ResetVSConstI( 0, 1 ) ; // 読み込んだ頂点シェーダーの削除 DeleteShader( vshandle ) ; // 読み込んだピクセルシェーダーの削除 DeleteShader( pshandle ) ; // 読み込んだ画像のグラフィックハンドルを削除 DeleteGraph( texhandle ) ; // DXライブラリの後始末 DxLib_End() ; // ソフトの終了 return 0 ; }





頂点シェーダーのプログラム( コンパイルして SetVSConstFArrayTestVS.vso になる前のHLSLソース )
// 頂点シェーダーの入力 struct VS_INPUT { float4 Position : POSITION ; // 座標( VERTEX3DSHADER構造体の pos の値 ) float3 Normal : NORMAL0 ; // 法線( VERTEX3DSHADER構造体の norm の値 ) float4 DiffuseColor : COLOR0 ; // ディフューズカラー( VERTEX3DSHADER構造体の dif の値 ) float4 SpecularColor : COLOR1 ; // スペキュラカラー( VERTEX3DSHADER構造体の spc の値 ) float2 TextureCoord0 : TEXCOORD0 ; // テクスチャ座標0( VERTEX3DSHADER構造体の u, v の値 ) float2 TextureCoord1 : TEXCOORD1 ; // テクスチャ座標1( VERTEX3DSHADER構造体の su, sv の値 ) } ; // 頂点シェーダーの出力 struct VS_OUTPUT { float4 ProjectionPosition : POSITION ; // 座標( 射影空間 ) float4 DiffuseColor : COLOR0 ; // ディフューズカラー float2 TextureCoord0 : TEXCOORD0 ; // テクスチャ座標 } ; // C++ 側で設定する定数の定義 float4x4 cfViewMatrix : register( c6 ) ; // ワールド座標をビュー座標に変換する行列の転置行列 float4x4 cfProjectionMatrix : register( c2 ) ; // ビュー座標を射影座標に変換する行列の転置行列 // 座標値の配列 float4 cfDrawPosition[ 4 ] : register( c10 ) ; // 座標値配列のインデックス int4 ciPositionIndex : register( c0 ) ; // main関数 VS_OUTPUT main( VS_INPUT VSInput ) { VS_OUTPUT VSOutput ; float4 lWorldPosition ; float4 lViewPosition ; // 入力座標に座標インデックスで決定する座標を加算する lWorldPosition = VSInput.Position + cfDrawPosition[ ciPositionIndex.x ] ; // 頂点座標をビュー空間の座標に変換する lViewPosition = mul( lWorldPosition, cfViewMatrix ) ; // ビュー空間の座標を射影空間の座標に変換する VSOutput.ProjectionPosition = mul( lViewPosition, cfProjectionMatrix ) ; // テクスチャ座標はそのまま代入 VSOutput.TextureCoord0 = VSInput.TextureCoord0; // 頂点カラーはそのまま代入 VSOutput.DiffuseColor = VSInput.DiffuseColor ; // 関数の戻り値がピクセルシェーダーに渡される return VSOutput ; }





ピクセルシェーダーのプログラム( コンパイルして SetVSConstFArrayTestPS.pso になる前のHLSLソース )
// ピクセルシェーダーの入力 struct PS_INPUT { float4 DiffuseColor : COLOR0 ; // ディフューズカラー float2 TextureCoord0 : TEXCOORD0 ; // テクスチャ座標 } ; // ピクセルシェーダーの出力 struct PS_OUTPUT { float4 DrawColor : COLOR0 ; // 描画カラー } ; // C++ 側で設定する定数の定義 // 描画するテクスチャ sampler DiffuseMapTexture : register( s0 ) ; // main関数 PS_OUTPUT main( PS_INPUT PSInput ) { PS_OUTPUT PSOutput ; float4 lTextureColor ; // テクスチャーの色を取得 lTextureColor = tex2D( DiffuseMapTexture, PSInput.TextureCoord0 ) ; // 出力する色はテクスチャの色とディフューズカラーを乗算したもの PSOutput.DrawColor = lTextureColor * PSInput.DiffuseColor ; // 関数の戻り値がラスタライザに渡される return PSOutput ; }





宣言int ResetVSConstF( int ConstantIndex, int ParamNum ) ;

概略頂点シェーダーの FLOAT4 型定数の設定を無効にする

引数 int ConstantIndex : 設定を無効にする FLOAT4型定数の番号( 0~255 )
int ParamNum : 無効にする数
戻り値 0:成功
 -1:エラー発生

解説 ( この関数は Direct3D 9 用の関数です、Direct3D 11 では効果がありませんので注意してください )
 SetVSConstF などの関数で行った頂点シェーダーの FLOAT4型定数の設定を無効化します。
 この関数の用途は主にDXライブラリ側で設定する定数の値を使用する場合です。
 例えばある頂点シェーダーではDXライブラリ側で設定したマテリアルの定数が必要ないということで FLOAT4型定数 11~13に対して SetVSConstF で定数を上書きしたとします。 そしてその後別の頂点シェーダーではDXライブラリ側で設定したマテリアルの定数が必要、となったときに、 予め ResetVSConstF を使用して 11~13 に対して行った定数の設定を無効化することでDXライブラリ側が設定した定数を使用することができます。

サンプル

 効果的な使い方はしていませんが、LoadVertexShaderSetVSConstFMtxのサンプルで使用しています。



宣言int SetPSConstF( int ConstantIndex, FLOAT4 Param ) ;

概略ピクセルシェーダーの FLOAT4 型定数を設定する

引数 int ConstantIndex : 変更する FLOAT4型定数の番号( 0~31 or 0~223 )
FLOAT4 Param : 設定する FLOAT4型の値
戻り値 0:成功
 -1:エラー発生

解説 ( この関数は Direct3D 9 用の関数です、Direct3D 11 では効果がありませんので注意してください )
 ピクセルシェーダーのプログラムで使用するFLOAT4型定数を設定する関数です。
 FLOAT4 は構造体で、以下のように定義されています。
struct FLOAT4 { float x, y, z, w ; } ;
 FLOAT4 の文字通り float 型の変数が4つあります。
 この x, y, z, w に値を代入して SetVSConstF で定数として設定すると、それがそのまま頂点シェーダーで使えるようになります。


<例>

[ C++側 ]

// x=10, y=20, z=30, w=0 の FLOAT4 型の値を定数10にセット
FLOAT4 Temp ;
Temp.x = 10.0f ;
Temp.y = 20.0f ;
Temp.z = 30.0f ;
Temp.w = 0.0f ;
SetPSConstF( 10, Temp ) ;


[ ピクセルシェーダー側 ]

// FLOAT4型定数の 10番目を ConstF10 という名前で使うように宣言
// これで SetPSConstF( 10, Temp ) ; で設定した値が ConstF10 という名前で使用可能になる
float4 ConstF10 : register( c10 ) ;


 因みに ConstantIndex で有効な値が0~31 or 0~223なのは float4型定数の数がピクセルシェーダー2.0では 32個、3.0では 224個だからです。
一度に沢山の FLOAT4型定数を設定したい場合は SetPSConstFArray を使用します。

 尚、この関数で値を設定した場合は、DrawGraph 等の描画関数を使用する前に ResetPSConstF 関数で設定した値を無効にする必要がありますので注意してください。

サンプル

  Tex1.bmp を貼り付けたポリゴン2枚を SetPSConstF で設定した r, g, b の値を乗算して描画します。
 因みに x, y, z, w は r, g, b, a に対応しています。



C++のプログラム
Windows用
#include "DxLib.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { int texhandle, pshandle ; VERTEX2DSHADER Vert[ 6 ] ; int r, g, b ; int radd, gadd, badd ; FLOAT4 f4 ; // DXライブラリの初期化 if( DxLib_Init() < 0 ) return -1; // テクスチャを読み込む texhandle = LoadGraph( "Tex1.bmp" ) ; // ピクセルシェーダーを読み込む pshandle = LoadPixelShader( "SetPSConstFTestPS.pso" ) ; // 2ポリゴン分の頂点のデータをセットアップ Vert[ 0 ].pos = VGet( 0.0f, 0.0f, 0.0f ) ; Vert[ 0 ].rhw = 1.0f ; Vert[ 0 ].dif = GetColorU8( 255,255,255,255 ) ; Vert[ 0 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vert[ 0 ].u = 0.0f ; Vert[ 0 ].v = 0.0f ; Vert[ 0 ].su = 0.0f ; Vert[ 0 ].sv = 0.0f ; Vert[ 1 ].pos = VGet( 256.0f, 0.0f, 0.0f ) ; Vert[ 1 ].rhw = 1.0f ; Vert[ 1 ].dif = GetColorU8( 255,255,255,255 ) ; Vert[ 1 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vert[ 1 ].u = 1.0f ; Vert[ 1 ].v = 0.0f ; Vert[ 1 ].su = 1.0f ; Vert[ 1 ].sv = 0.0f ; Vert[ 2 ].pos = VGet( 0.0f, 256.0f, 0.0f ) ; Vert[ 2 ].rhw = 1.0f ; Vert[ 2 ].dif = GetColorU8( 255,255,255,255 ) ; Vert[ 2 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vert[ 2 ].u = 0.0f ; Vert[ 2 ].v = 1.0f ; Vert[ 2 ].su = 0.0f ; Vert[ 2 ].sv = 1.0f ; Vert[ 3 ].pos = VGet( 256.0f, 256.0f, 0.0f ) ; Vert[ 3 ].rhw = 1.0f ; Vert[ 3 ].dif = GetColorU8( 255,255,255,255 ) ; Vert[ 3 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vert[ 3 ].u = 1.0f ; Vert[ 3 ].v = 1.0f ; Vert[ 3 ].su = 1.0f ; Vert[ 3 ].sv = 1.0f ; Vert[ 4 ].pos = VGet( 0.0f, 256.0f, 0.0f ) ; Vert[ 4 ].rhw = 1.0f ; Vert[ 4 ].dif = GetColorU8( 255,255,255,255 ) ; Vert[ 4 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vert[ 4 ].u = 0.0f ; Vert[ 4 ].v = 1.0f ; Vert[ 4 ].su = 0.0f ; Vert[ 4 ].sv = 1.0f ; Vert[ 5 ].pos = VGet( 256.0f, 0.0f, 0.0f ) ; Vert[ 5 ].rhw = 1.0f ; Vert[ 5 ].dif = GetColorU8( 255,255,255,255 ) ; Vert[ 5 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vert[ 5 ].u = 1.0f ; Vert[ 5 ].v = 0.0f ; Vert[ 5 ].su = 1.0f ; Vert[ 5 ].sv = 0.0f ; // 描画先を裏画面にする SetDrawScreen( DX_SCREEN_BACK ) ; // r, g, b の値を変化させる準備 r = 0 ; g = 128 ; b = 255 ; radd = 10 ; gadd = 7 ; badd = 3 ; // ESCキーが押されるまでループ while( ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 ) { // 画面を初期化 ClearDrawScreen() ; // r, g, b の値を変化させる r += radd ; if( r >= 255 ) { r = 255 ; radd = -radd ; } else if( r <= 0 ) { r = 0 ; radd = -radd ; } g += gadd ; if( g >= 255 ) { g = 255 ; gadd = -gadd ; } else if( g <= 0 ) { g = 0 ; gadd = -gadd ; } b += badd ; if( b >= 255 ) { b = 255 ; badd = -badd ; } else if( b <= 0 ) { b = 0 ; badd = -badd ; } // r, g, b の値をピクセルシェーダーの FLOAT4型定数0番にセット // 定数にするときは値を 0.0f ~ 1.0f にする f4.x = r / 255.0f ; f4.y = g / 255.0f ; f4.z = b / 255.0f ; f4.w = 1.0f ; SetPSConstF( 0, f4 ) ; // 使用するテクスチャを0番にセット SetUseTextureToShader( 0, texhandle ) ; // 使用するピクセルシェーダーをセット SetUsePixelShader( pshandle ) ; // シェーダーを使用した2Dの2ポリゴンの描画 DrawPolygon2DToShader( Vert, 2 ) ; // 裏画面の内容を表画面に反映させる ScreenFlip() ; } // 読み込んだピクセルシェーダーの削除 DeleteShader( pshandle ) ; // 使用した定数を無効化する ResetPSConstF( 0, 1 ) ; // 読み込んだ画像のグラフィックハンドルを削除 DeleteGraph( texhandle ) ; // DXライブラリの後始末 DxLib_End(); // ソフトの終了 return 0; }





ピクセルシェーダーのプログラム( コンパイルして SetPSConstFTestPS.pso になる前のHLSLソース )
// ピクセルシェーダーの入力 struct PS_INPUT { float4 DiffuseColor : COLOR0 ; float4 SpecularColor : COLOR1 ; float2 TextureCoord0 : TEXCOORD0 ; float2 TextureCoord1 : TEXCOORD1 ; } ; // ピクセルシェーダーの出力 struct PS_OUTPUT { float4 Output : COLOR0 ; } ; // C++ 側で設定する定数の定義 // 描画するテクスチャ sampler DiffuseMapTexture : register( s0 ) ; // テクスチャの色に乗算する値 float4 cfMultiplyColor : register( c0 ) ; // main関数 PS_OUTPUT main( PS_INPUT PSInput ) { PS_OUTPUT PSOutput ; float4 lTextureColor ; // テクスチャーの色を取得 lTextureColor = tex2D( DiffuseMapTexture, PSInput.TextureCoord0 ) ; // 出力する色はテクスチャの色と定数を乗算したもの PSOutput.Output = lTextureColor * cfMultiplyColor ; // 関数の戻り値がラスタライザに渡される return PSOutput ; }





宣言int SetPSConstFMtx( int ConstantIndex, MATRIX Param ) ;

概略ピクセルシェーダーの FLOAT4 型定数に行列を設定する

引数 int ConstantIndex : 変更する FLOAT4型定数の番号( 0~220 )
MATRIX Param : 設定する MATRIX型の値
戻り値 0:成功
 -1:エラー発生

解説 ( この関数は Direct3D 9 用の関数です、Direct3D 11 では効果がありませんので注意してください )
 SetPSConstF は FLOAT4型の構造体一つ分をピクセルシェーダーの FLOAT4型定数として設定する関数でしたが、 この関数は FLOAT4型定数4つ分を一度に設定します。
 何故4つかといいますと、MATRIX型は 4×4 の行列で、float型変数16個が中にあり、FLOAT4型構造体の一つが float型変数 4個分なので、 16 ÷ 4 = 4 というわけです。

 具体的には
定数番号 ConstantIndex に MATRIX構造体の m[0][0] m[0][1] m[0][2] m[0][3] が、
定数番号 ConstantIndex + 1 に MATRIX構造体の m[1][0] m[1][1] m[1][2] m[1][3] が、
定数番号 ConstantIndex + 2 に MATRIX構造体の m[2][0] m[2][1] m[2][2] m[2][3] が、
定数番号 ConstantIndex + 3 に MATRIX構造体の m[3][0] m[3][1] m[3][2] m[3][3] が、
それぞれ左から順に x, y, z, w に代入されて設定されます。

 ピクセルシェーダーで使用できる FLOAT4型定数の数が224個なのに対し ConstantIndex で指定できる値が220までなのは、指定した番号から4個分の定数が必要だからです。

 尚、この関数で値を設定した場合は、DrawGraph 等の描画関数を使用する前に ResetPSConstF 関数で設定した値を無効にする必要がありますので注意してください。

サンプル

 ありません。



宣言int SetPSConstFArray( int ConstantIndex, FLOAT4 *ParamArray, int ParamNum ) ;

概略ピクセルシェーダーの FLOAT4 型定数を配列を使って設定する

引数 int ConstantIndex : 変更する FLOAT4型定数の番号( 0~31 or 0~223 )
FLOAT4 *ParamArray : FLOAT4型配列の先頭アドレス
int ParamNum : 設定する数
戻り値 0:成功
 -1:エラー発生

解説 ( この関数は Direct3D 9 用の関数です、Direct3D 11 では効果がありませんので注意してください )
 SetPSConstF は FLOAT4型の構造体一つ分をピクセルシェーダーの FLOAT4型定数として設定する関数でしたが、 この関数は FLOAT4型定数を指定数分だけ一度に設定することができます。

 例えば

FLOAT4 f4array[ 3 ] ;
f4array[ 0 ].x = 100.0f ;
f4array[ 0 ].y = 65.0f ;
f4array[ 0 ].z = 19.0f ;
f4array[ 0 ].w = 888.0f ;
f4array[ 1 ].x = 296.0f ;
f4array[ 1 ].y = 879.0f ;
f4array[ 1 ].z = 1111.0f ;
f4array[ 1 ].w = 6.0f ;
f4array[ 2 ].x = 769910.0f ;
f4array[ 2 ].y = 4023.0f ;
f4array[ 2 ].z = 61.0f ;
f4array[ 2 ].w = 735.0f ;
SetPSConstFArray( 10, f4array, 3 ) ;

 は、

FLOAT4 f4array[ 3 ] ;
f4array[ 0 ].x = 100.0f ;
f4array[ 0 ].y = 65.0f ;
f4array[ 0 ].z = 19.0f ;
f4array[ 0 ].w = 888.0f ;
f4array[ 1 ].x = 296.0f ;
f4array[ 1 ].y = 879.0f ;
f4array[ 1 ].z = 1111.0f ;
f4array[ 1 ].w = 6.0f ;
f4array[ 2 ].x = 769910.0f ;
f4array[ 2 ].y = 4023.0f ;
f4array[ 2 ].z = 61.0f ;
f4array[ 2 ].w = 735.0f ;
SetPSConstF( 10, f4array[ 0 ] ) ;
SetPSConstF( 11, f4array[ 1 ] ) ;
SetPSConstF( 12, f4array[ 2 ] ) ;

 と同じ動作をします。
 なんでこんな関数があるのかといいますと、単純に何回も SetPSConstF を呼ぶのが面倒だからという理由以外に何回も SetPSConstF を呼ぶのは処理負荷が高いからです。

 因みに ConstantIndex で有効な値が0~31 or 0~223なのは float4型定数の数がピクセルシェーダー2.0では 32個、3.0では 224個だからです。

 尚、この関数で値を設定した場合は、DrawGraph 等の描画関数を使用する前に ResetPSConstF 関数で設定した値を無効にする必要がありますので注意してください。

サンプル

 ありません。



宣言int ResetPSConstF( int ConstantIndex, int ParamNum ) ;

概略ピクセルシェーダーの FLOAT4 型定数の設定を無効にする

引数 int ConstantIndex : 設定を無効にする FLOAT4型定数の番号( 0~31 or 0~223 )
int ParamNum : 無効にする数
戻り値 0:成功
 -1:エラー発生

解説 ( この関数は Direct3D 9 用の関数です、Direct3D 11 では効果がありませんので注意してください )
 SetPSConstF などの関数で行ったピクセルシェーダーの FLOAT4型定数の設定を無効化します。
 この関数の用途は主にDXライブラリ側で設定する定数の値を使用する場合です。
 例えばあるピクセルシェーダーではDXライブラリ側で設定したマテリアルの定数が必要ないということで FLOAT4型定数 2~4に対して SetPSConstF で定数を上書きしたとします。 そしてその後別のピクセルシェーダーではDXライブラリ側で設定したマテリアルの定数が必要、となったときに、 予め ResetPSConstF を使用して 2~4 に対して行った定数の設定を無効化することでDXライブラリ側が設定した定数を使用することができます。

サンプル

 効果的な使い方はしていませんが、LoadVertexShaderSetPSConstFのサンプルで使用しています。



宣言int SetRenderTargetToShader( int TargetIndex, int DrawScreen ) ;

概略描画先を設定する

引数 int TargetIndex : 描画先を設定する出力番号
int DrawScreen : 描画先グラフィックハンドル
戻り値 0:成功
 -1:エラー発生

解説  通常描画先は SetDrawScreen を使用して変更しますが、 グラフィックスデバイスが対応していればピクセルシェーダーは複数の描画先に対して同時に描画を行うことができます。 ( ただし出力先を分けるのはピクセルシェーダーなので別画像の同一座標に描画する色を変化させる程度ですが・・・ )

 ピクセルシェーダーで出力先を複数にするのは簡単で、普段ピクセルシェーダーの出力の定義は

struct PS_OUTPUT { float4 Output : COLOR0 ; } ;
 このようになっていますが、この Output が単純に増えます。
 例えば出力先が3つの場合は。

struct PS_OUTPUT { float4 Output0 : COLOR0 ; float4 Output1 : COLOR1 ; float4 Output2 : COLOR2 ; } ;
 このようになります。

 グラフィックスデバイスが複数の描画先への描画に対応しているかどうか、 また幾つまで対応しているかは GetMultiDrawScreenNum で調べることができます。

 描画先として設定する出力番号の0番は SetDrawScreen で設定できる描画先と同じですので、 TargetIndex を 0 にした場合は内部で SetDrawScreen が呼ばれます。

 尚、TargetIndex の 1 以上の番号に設定した描画先の設定を無効にしたい場合は、DrawScreen を -1 にして呼び出します。

 複数の描画先への描画の主な用途はピクセルシェーダーの出力が単純な色だけではない特殊な用途に使用する場合で、 例えば出力先0番には色を、出力先1番には法線の方向を、出力先2番にはカメラからの距離を出力したい、という場合に使用します。
 入力の二つのテクスチャにそれぞれ座標と速度を描画しておいて、 出力先の二つのテクスチャにそれぞれ座標に速度を足したものと減速後の速度を描画する、 そのテクスチャを頂点シェーダーで読み取ってその座標に絵を描画するということをすればピクセルシェーダーを使ってオブジェクトの挙動の処理を行うこともできます。

サンプル

  Tex1.bmp を二つの描画先に描画します、片方は画像の赤成分だけを描画して、もう片方には画像の緑成分だけを描画します。
 そしてその結果を画面に表示します。



C++のプログラム
Windows用
#include "DxLib.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { int texhandle, pshandle ; int screen0, screen1 ; VERTEX2DSHADER Vert[ 6 ] ; // DXライブラリの初期化 if( DxLib_Init() < 0 ) return -1; // テクスチャを読み込む texhandle = LoadGraph( "Tex1.bmp" ) ; // ピクセルシェーダーを読み込む pshandle = LoadPixelShader( "SetRenderTargetTestPS.pso" ) ; // 256×256の描画可能なグラフィックハンドルを二つ作成する screen0 = MakeScreen( 256, 256 ) ; screen1 = MakeScreen( 256, 256 ) ; // 2ポリゴン分の頂点のデータをセットアップ Vert[ 0 ].pos = VGet( 0.0f, 0.0f, 0.0f ) ; Vert[ 0 ].rhw = 1.0f ; Vert[ 0 ].dif = GetColorU8( 255,255,255,255 ) ; Vert[ 0 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vert[ 0 ].u = 0.0f ; Vert[ 0 ].v = 0.0f ; Vert[ 0 ].su = 0.0f ; Vert[ 0 ].sv = 0.0f ; Vert[ 1 ].pos = VGet( 256.0f, 0.0f, 0.0f ) ; Vert[ 1 ].rhw = 1.0f ; Vert[ 1 ].dif = GetColorU8( 255,255,255,255 ) ; Vert[ 1 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vert[ 1 ].u = 1.0f ; Vert[ 1 ].v = 0.0f ; Vert[ 1 ].su = 0.0f ; Vert[ 1 ].sv = 0.0f ; Vert[ 2 ].pos = VGet( 0.0f, 256.0f, 0.0f ) ; Vert[ 2 ].rhw = 1.0f ; Vert[ 2 ].dif = GetColorU8( 255,255,255,255 ) ; Vert[ 2 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vert[ 2 ].u = 0.0f ; Vert[ 2 ].v = 1.0f ; Vert[ 2 ].su = 0.0f ; Vert[ 2 ].sv = 0.0f ; Vert[ 3 ].pos = VGet( 256.0f, 256.0f, 0.0f ) ; Vert[ 3 ].rhw = 1.0f ; Vert[ 3 ].dif = GetColorU8( 255,255,255,255 ) ; Vert[ 3 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vert[ 3 ].u = 1.0f ; Vert[ 3 ].v = 1.0f ; Vert[ 3 ].su = 0.0f ; Vert[ 3 ].sv = 0.0f ; Vert[ 4 ].pos = VGet( 0.0f, 256.0f, 0.0f ) ; Vert[ 4 ].rhw = 1.0f ; Vert[ 4 ].dif = GetColorU8( 255,255,255,255 ) ; Vert[ 4 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vert[ 4 ].u = 0.0f ; Vert[ 4 ].v = 1.0f ; Vert[ 4 ].su = 0.0f ; Vert[ 4 ].sv = 0.0f ; Vert[ 5 ].pos = VGet( 256.0f, 0.0f, 0.0f ) ; Vert[ 5 ].rhw = 1.0f ; Vert[ 5 ].dif = GetColorU8( 255,255,255,255 ) ; Vert[ 5 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vert[ 5 ].u = 1.0f ; Vert[ 5 ].v = 0.0f ; Vert[ 5 ].su = 0.0f ; Vert[ 5 ].sv = 0.0f ; // 描画先0を描画可能画像の一つ目に設定 SetRenderTargetToShader( 0, screen0 ) ; // 描画先1を描画可能画像の二つ目に設定 SetRenderTargetToShader( 1, screen1 ) ; // 使用するテクスチャを0番にセット SetUseTextureToShader( 0, texhandle ) ; // 使用するピクセルシェーダーをセット SetUsePixelShader( pshandle ) ; // シェーダーを使用した2Dの2ポリゴンの描画 DrawPolygon2DToShader( Vert, 2 ) ; // 描画先を表画面に変更 SetDrawScreen( DX_SCREEN_FRONT ) ; // 描画先1の設定をリセット SetRenderTargetToShader( 1, -1 ) ; // 二つの描画可能画像を並べて描画 DrawGraph( 0, 0, screen0, FALSE ) ; DrawGraph( 256, 0, screen1, FALSE ) ; // キー入力待ち WaitKey() ; // 読み込んだピクセルシェーダーの削除 DeleteShader( pshandle ) ; // MakeScreen で作成したグラフィックハンドルの削除 DeleteGraph( screen0 ) ; DeleteGraph( screen1 ) ; // 読み込んだ画像のグラフィックハンドルを削除 DeleteGraph( texhandle ) ; // DXライブラリの後始末 DxLib_End(); // ソフトの終了 return 0; }





ピクセルシェーダーのプログラム( コンパイルして SetRenderTargetTestPS.pso になる前のHLSLソース )
// ピクセルシェーダーの入力 struct PS_INPUT { float4 DiffuseColor : COLOR0 ; float4 SpecularColor : COLOR1 ; float2 TextureCoord0 : TEXCOORD0 ; float2 TextureCoord1 : TEXCOORD1 ; } ; // ピクセルシェーダーの出力 struct PS_OUTPUT { float4 Output0 : COLOR0 ; float4 Output1 : COLOR1 ; } ; // C++ 側で設定する定数の定義 // 描画するテクスチャ sampler DiffuseMapTexture : register( s0 ) ; // main関数 PS_OUTPUT main( PS_INPUT PSInput ) { PS_OUTPUT PSOutput ; float4 lTextureColor ; // テクスチャーの色を取得 lTextureColor = tex2D( DiffuseMapTexture, PSInput.TextureCoord0 ) ; // 出力先0には赤成分だけ出力 PSOutput.Output0.r = lTextureColor.r ; PSOutput.Output0.g = 0.0f ; PSOutput.Output0.b = 0.0f ; PSOutput.Output0.a = 1.0f ; // 出力先1には緑成分だけ出力 PSOutput.Output1.r = 0.0f ; PSOutput.Output1.g = lTextureColor.g ; PSOutput.Output1.b = 0.0f ; PSOutput.Output1.a = 1.0f ; // 関数の戻り値がラスタライザに渡される return PSOutput ; }





宣言int SetUseTextureToShader( int StageIndex, int GraphHandle ) ;

概略シェーダー描画で使用するテクスチャを設定する

引数 int StageIndex : 設定するテクスチャステージ番号
int GraphHandle : 設定するテクスチャを持つグラフィックハンドル又は -1
戻り値 0:成功
 -1:エラー発生

解説  DrawPolygon3DToShader などのプログラマブルシェーダーを使用した描画で使用するグラフィックハンドルを設定する関数です。
 DrawGraph や DrawExtendGraph などの関数では使用する画像は一つと分かっているので関数の引数にグラフィックハンドルを渡しますが、 シェーダーを使用した描画では複数の画像を使用することができるので、DrawPolygon3DToShader などの関数の引数としてグラフィックハンドルを渡すことは無く、 代わりにこの関数を使用して事前に描画に使用するグラフィックハンドルを設定しておきます。

 この関数で指定した番号と、シェーダープログラムでの対応ですが、

sampler DiffuseMapTexture : register( s0 ) ;

 例えば↑の場合の s0 の 0 の部分が StageIndex の値になります。
 なので StageIndex に 2 を渡して設定した画像は

sampler OtherTexture : register( s2 ) ;

 という感じに s2 を指定することで使用することができます。
 尚、この関数に渡すグラフィックハンドルが持つ画像は縦横のサイズが 2 の n乗では無い場合に正常な描画結果が得られませんので注意してください。
( 2 の n乗の値は 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192 といった値です。
なのでこれに当てはまらない縦幅、横幅の画像を LoadGraph で読み込んでこの関数の引数に渡しても、正常な描画結果を得られません )

 設定したグラフィックハンドルを外したい場合は GraphHandle の値を -1 にして関数を呼んでください。

サンプル

 LoadVertexShader などのシェーダー関係関数のサンプルを参照してください。



宣言int SetUseVertexShader( int ShaderHandle ) ;

概略シェーダー描画に使用する頂点シェーダーを設定する

引数 int ShaderHandle : 使用する頂点シェーダーのハンドル
戻り値 0:成功
 -1:エラー発生

解説  DrawPolygon3DToShader などのプログラマブルシェーダーを使用した描画で使用する頂点シェーダーを設定する関数です。
 頂点シェーダーハンドルは LoadVertexShader で頂点シェーダーバイナリファイルから読み込み、 取得することができます。
 この関数で設定した頂点シェーダーは DrawPolygon3DToShader, DrawPolygonIndexed3DToShader の描画時に使用されます。
 また、MV1SetUseOrigShader で3Dモデルの描画にオリジナルシェーダーを使用するように設定されていた場合は MV1DrawModel などの3Dモデルの描画関数が呼ばれた際にも使用されます。

サンプル

 LoadVertexShader などのシェーダー関係関数のサンプルを参照してください。



宣言int SetUsePixelShader( int ShaderHandle ) ;

概略シェーダー描画に使用するピクセルシェーダーを設定する

引数 int ShaderHandle : 使用するピクセルシェーダーのハンドル
戻り値 0:成功
 -1:エラー発生

解説  DrawPolygon3DToShader などのプログラマブルシェーダーを使用した描画で使用するピクセルシェーダーを設定する関数です。
 ピクセルシェーダーハンドルは LoadPixelShader でピクセルシェーダーバイナリファイルから読み込み、 取得することができます。
 この関数で設定したピクセルシェーダーは DrawPolygon~ToShader と付いている描画関数での描画時に使用されます。
 また、MV1SetUseOrigShader で3Dモデルの描画にオリジナルシェーダーを使用するように設定されていた場合は MV1DrawModel などの3Dモデルの描画関数が呼ばれた際にも使用されます。

サンプル

 LoadVertexShader などのシェーダー関係関数のサンプルを参照してください。



宣言int DrawPolygon2DToShader( VERTEX2DSHADER *Vertex, int PolygonNum ) ;

概略シェーダーを使って2Dポリゴンを描画する

引数 VERTEX2DSHADER *Vertex : ポリゴンを構成する頂点配列の先頭アドレス
int PolygonNum : 描画するポリゴンの数
戻り値 0:成功
 -1:エラー発生

解説  LoadPixelShader で読み込んだピクセルシェーダーを使用して三角形ポリゴンの描画を行います。
 Vertex の引数として用意する必要がある VERTEX2DSHADER 構造体の数は描画するポリゴンの数×3になります。
 また、この関数を呼び出す前に SetUsePixelShader で使用するピクセルシェーダーを設定しておく必要があります。 ( テクスチャを使用する場合は SetUseTextureToShader によるテクスチャの設定も・・・ )
 描画に使用する VERTEX2DSHADER 構造体は以下のように定義されています。
struct VERTEX2DSHADER { VECTOR pos ; // スクリーン座標 float rhw ; // 同次 W の逆数、通常は 1.0f でOK COLOR_U8 dif ; // ディフューズカラー COLOR_U8 spc ; // スペキュラカラー float u, v ; // テクスチャ座標0 float su, sv ; // テクスチャ座標1 } ;
 そして、この関数では頂点処理は行われないので頂点シェーダーが使用されません、
普段頂点シェーダーでピクセルシェーダーの入力データ形式が決定しますが、
この関数を使用した場合のピクセルシェーダーの入力は固定で以下のようになります。
struct PS_INPUT { float4 DiffuseColor : COLOR0 ; // ディフューズカラー float4 SpecularColor : COLOR1 ; // スペキュラカラー float2 TextureCoord0 : TEXCOORD0 ; // テクスチャ座標0 float2 TextureCoord1 : TEXCOORD1 ; // テクスチャ座標1 } ;
 2Dのフィルター処理などを行う場合は3Dの処理が必要ないので、頂点シェーダーを書く必要も無くお手軽です。

サンプル

 LoadPixelShaderSetPSConstF のサンプルを参照してください。



宣言int DrawPolygon3DToShader( VERTEX3DSHADER *Vertex, int PolygonNum ) ;

概略シェーダーを使って3Dポリゴンを描画する

引数 VERTEX3DSHADER *Vertex : ポリゴンを構成する頂点配列の先頭アドレス
int PolygonNum : 描画するポリゴンの数
戻り値 0:成功
 -1:エラー発生

解説  LoadVertexShaderLoadPixelShader で読み込んだプログラマブルシェーダーを使用して三角形ポリゴンの描画を行います。
 Vertex の引数として用意する必要がある VERTEX3DSHADER 構造体の数は描画するポリゴンの数×3になります。

 また、この関数を呼び出す前に SetUseVertexShaderSetUsePixelShader で使用するシェーダーを設定しておく必要があります。 ( テクスチャを使用する場合は SetUseTextureToShader によるテクスチャの設定も・・・ )
 描画に使用する VERTEX3DSHADER 構造体は以下のように定義されています。
struct VERTEX3DSHADER { VECTOR pos ; // 座標 VECTOR norm ; // 法線 COLOR_U8 dif ; // ディフューズカラー COLOR_U8 spc ; // スペキュラカラー float u, v ; // テクスチャ座標0 float su, sv ; // テクスチャ座標1 } ;
 この関数で描画処理を行った場合の頂点シェーダーの入力形式は LoadVertexShader の解説を参照してください。

サンプル

 LoadVertexShaderSetVSConstFMtx のサンプルを参照してください。



宣言int DrawPolygonIndexed2DToShader( VERTEX2DSHADER *Vertex, int VertexNum, unsigned short *Indices, int PolygonNum ) ;

概略シェーダーを使って2Dポリゴンを描画する(インデックスを使用)

引数 VERTEX2DSHADER *Vertex : ポリゴンを構成する頂点配列の先頭アドレス
int VertexNum : 頂点の数( Vertex で渡す配列の長さ )
unsigned short *Indices : 頂点番号配列の先頭アドレス
int PolygonNum : 描画するポリゴンの数
戻り値 0:成功
 -1:エラー発生

解説  DrawPolygon2DToShader と機能は殆ど同じですが、頂点番号配列を使用するところが違います。
 例えば LoadPixelShader のサンプルプログラムでは VERTEX2DSHADER 6個の配列を用意していますが、 値を代入しているところを良く見ると配列要素1番と5番、2番と4番が全く同じなのが分かります。
 プログラムを実行してみるとわかりますが、これは二つの三角形ポリゴンをぴったりつなぎ合わせて1枚の四角いポリゴンを表現していて、 二つのポリゴン中で接している頂点同士は全く同じ情報を持つからです。
 全く同じ情報を持つならその分その情報は余計なものとなります。本来なら4頂点分の情報で済むところが6頂点分の情報を持っているわけですから・・・
 そんなときに頂点番号配列を使用します。

 頂点番号配列は三角形ポリゴンが Vertex で渡した頂点配列の何番目と何番目と何番目を使って三角形ポリゴンを表現するか、という頂点番号3つの組み合わせがひたすら代入された配列です。
 例えば四角を表現する場合は四角の(0)左上の頂点、(1)右上の頂点、(2)左下の頂点、(3)右下の頂点の4頂点を使って、
(0)左上の頂点、(1)右上の頂点、(2)左下の頂点で三角形ポリゴン一つ、
(2)左下の頂点、(1)右上の頂点、(3)右下の頂点で三角形ポリゴンをもう一つ表現すれば
四角を表現することができます。
 このように、頂点の配列+3角形を表現するための頂点番号の配列で三角形ポリゴンを描画するのが DrawPolygonIndexed 系の関数です。

 例えば上記の場合を具体的にすると、引数 Vertex に渡す頂点の配列は
配列の0番目に四角の左上の頂点の情報
1番目に四角の右上の頂点の情報
2番目に四角の左下の頂点の情報
3番目に四角の右下の頂点の情報を代入しておきます。
そして VertexNum の数は 4 です。

 引数 Indices に渡す頂点番号配列は
配列の0番目に0( 左上の頂点が代入されている配列番号 )、
配列の1番目に1( 右上の頂点が代入されている配列番号 )、
配列の2番目に2( 左下の頂点が代入されている配列番号 )、
配列の3番目に2( 左下の頂点が代入されている配列番号 )、
配列の4番目に1( 右上の頂点が代入されている配列番号 )、
配列の5番目に3( 右下の頂点が代入されている配列番号 )を代入しておきます。
そして PolygonNum の数は 2 です。

 DrwaPolygon2DToShader の場合は Vertex 配列の要素の数が PolygonNum × 3 である必要がありましたが、
DrawPolygonIndexed2DToShader では Vertex 配列の代わりに Indices 配列の要素の数が PolygonNum × 3 である必要があります。

 四角ポリゴン1枚くらいなら Indexed の関数を使う必要は無いかもしれませんが、重複する頂点の多いポリゴン集合を描画しようとした場合は結構有用です。

サンプル

  LoadPixelShader のサンプルプログラムのC++の部分のみを DrawPolygonIndexed2DToShader を使用するようにしたプログラムです。



C++のプログラム
Windows用
#include "DxLib.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { int texhandle, pshandle ; VERTEX2DSHADER Vert[ 4 ] ; unsigned short Index[ 6 ] ; // DXライブラリの初期化 if( DxLib_Init() < 0 ) return -1; // テクスチャを読み込む texhandle = LoadGraph( "Tex1.bmp" ) ; // ピクセルシェーダーを読み込む pshandle = LoadPixelShader( "PixelShaderTestPS.pso" ) ; // 2ポリゴン分の頂点のデータをセットアップ Vert[ 0 ].pos = VGet( 0.0f, 0.0f, 0.0f ) ; Vert[ 0 ].rhw = 1.0f ; Vert[ 0 ].dif = GetColorU8( 255,255,255,255 ) ; Vert[ 0 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vert[ 0 ].u = 0.0f ; Vert[ 0 ].v = 0.0f ; Vert[ 0 ].su = 0.0f ; Vert[ 0 ].sv = 0.0f ; Vert[ 1 ].pos = VGet( 256.0f, 0.0f, 0.0f ) ; Vert[ 1 ].rhw = 1.0f ; Vert[ 1 ].dif = GetColorU8( 255,255,255,255 ) ; Vert[ 1 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vert[ 1 ].u = 1.0f ; Vert[ 1 ].v = 0.0f ; Vert[ 1 ].su = 1.0f ; Vert[ 1 ].sv = 0.0f ; Vert[ 2 ].pos = VGet( 0.0f, 256.0f, 0.0f ) ; Vert[ 2 ].rhw = 1.0f ; Vert[ 2 ].dif = GetColorU8( 255,255,255,255 ) ; Vert[ 2 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vert[ 2 ].u = 0.0f ; Vert[ 2 ].v = 1.0f ; Vert[ 2 ].su = 0.0f ; Vert[ 2 ].sv = 1.0f ; Vert[ 3 ].pos = VGet( 256.0f, 256.0f, 0.0f ) ; Vert[ 3 ].rhw = 1.0f ; Vert[ 3 ].dif = GetColorU8( 255,255,255,255 ) ; Vert[ 3 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vert[ 3 ].u = 1.0f ; Vert[ 3 ].v = 1.0f ; Vert[ 3 ].su = 1.0f ; Vert[ 3 ].sv = 1.0f ; // 2ポリゴン分の頂点番号配列のセットアップ Index[ 0 ] = 0 ; Index[ 1 ] = 1 ; Index[ 2 ] = 2 ; Index[ 3 ] = 2 ; Index[ 4 ] = 1 ; Index[ 5 ] = 3 ; // 使用するテクスチャを0番にセット SetUseTextureToShader( 0, texhandle ) ; // 使用するピクセルシェーダーをセット SetUsePixelShader( pshandle ) ; // シェーダーを使用した2Dの2ポリゴンの描画 DrawPolygonIndexed2DToShader( Vert, 4, Index, 2 ) ; // キー入力待ち WaitKey() ; // 読み込んだピクセルシェーダーの削除 DeleteShader( pshandle ) ; // 読み込んだ画像のグラフィックハンドルを削除 DeleteGraph( texhandle ) ; // DXライブラリの後始末 DxLib_End(); // ソフトの終了 return 0; }





宣言int DrawPolygonIndexed3DToShader( VERTEX3DSHADER *Vertex, int VertexNum, unsigned short *Indices, int PolygonNum ) ;

概略シェーダーを使って2Dポリゴンを描画する(インデックスを使用)

引数 VERTEX3DSHADER *Vertex : ポリゴンを構成する頂点配列の先頭アドレス
int VertexNum : 頂点の数( Vertex で渡す配列の長さ )
unsigned short *Indices : 頂点番号配列の先頭アドレス
int PolygonNum : 描画するポリゴンの数
戻り値 0:成功
 -1:エラー発生

解説  DrawPolygonIndexed2DToShader の3D版です、 Indexed な描画関数と Indexed が付かない描画関数との違いについては DrawPolygonIndexed2DToShader の解説を参照してください。
 シェーダーを使用した3Dポリゴン描画の基本的な解説については DrawPolygon3DToShader の解説を参照してください。

サンプル

  LoadVertexShader のサンプルプログラムのC++の部分のみを DrawPolygonIndexed3DToShader を使用するようにしたプログラムです。



C++のプログラム
Windows用
#include "DxLib.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { VERTEX3DSHADER Vertex[ 4 ] ; unsigned short Index[ 6 ] ; int vshandle ; int pshandle ; int texhandle ; int x ; int xadd ; float color ; float coloradd ; FLOAT4 f4 ; // DXライブラリの初期化 if( DxLib_Init() < 0 ) { // エラーが発生したら直ちに終了 return -1 ; } // 2ポリゴン分の頂点のデータをセットアップ Vertex[ 0 ].pos = VGet( 220.0f, 340.0f, 0.0f ) ; Vertex[ 0 ].norm = VGet( 0.0f, 0.0f, -1.0f ) ; Vertex[ 0 ].dif = GetColorU8( 255, 0,255,255 ) ; Vertex[ 0 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vertex[ 0 ].u = 0.0f ; Vertex[ 0 ].v = 0.0f ; Vertex[ 0 ].su = 0.0f ; Vertex[ 0 ].sv = 0.0f ; Vertex[ 1 ].pos = VGet( 420.0f, 340.0f, 0.0f ) ; Vertex[ 1 ].norm = VGet( 0.0f, 0.0f, -1.0f ) ; Vertex[ 1 ].dif = GetColorU8( 0, 0,255,255 ) ; Vertex[ 1 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vertex[ 1 ].u = 1.0f ; Vertex[ 1 ].v = 0.0f ; Vertex[ 1 ].su = 0.0f ; Vertex[ 1 ].sv = 0.0f ; Vertex[ 2 ].pos = VGet( 220.0f, 140.0f, 0.0f ) ; Vertex[ 2 ].norm = VGet( 0.0f, 0.0f, -1.0f ) ; Vertex[ 2 ].dif = GetColorU8( 255,255, 0,255 ) ; Vertex[ 2 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vertex[ 2 ].u = 0.0f ; Vertex[ 2 ].v = 1.0f ; Vertex[ 2 ].su = 0.0f ; Vertex[ 2 ].sv = 0.0f ; Vertex[ 3 ].pos = VGet( 420.0f, 140.0f, 0.0f ) ; Vertex[ 3 ].norm = VGet( 0.0f, 0.0f, -1.0f ) ; Vertex[ 3 ].dif = GetColorU8( 255,255, 0,255 ) ; Vertex[ 3 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vertex[ 3 ].u = 1.0f ; Vertex[ 3 ].v = 1.0f ; Vertex[ 3 ].su = 0.0f ; Vertex[ 3 ].sv = 0.0f ; // 2ポリゴン分の頂点番号配列をセットアップ Index[ 0 ] = 0 ; Index[ 1 ] = 1 ; Index[ 2 ] = 2 ; Index[ 3 ] = 2 ; Index[ 4 ] = 1 ; Index[ 5 ] = 3 ; // 頂点シェーダーを読み込む vshandle = LoadVertexShader( "VertexShaderTestVS.vso" ) ; // ピクセルシェーダーを読み込む pshandle = LoadPixelShader( "VertexShaderTestPS.pso" ) ; // 描画に使用する画像の読み込み texhandle = LoadGraph( "Tex1.bmp" ) ; // 描画先を裏画面にする SetDrawScreen( DX_SCREEN_BACK ) ; // 表示座標を移動する処理の初期化 x = 0 ; xadd = 8 ; // 色を変化させる処理の初期化 color = 0.0f ; coloradd = 1.0f / 60.0f ; // ESCキーが押されるまでループ while( ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 ) { // 画面を初期化 ClearDrawScreen() ; // 座標を移動させる x += xadd ; if( x > 200 || x < -200 ) { xadd = -xadd ; } // 色の値を変化させる color += coloradd ; if( color <= 0.0f || color >= 1.0f ) { coloradd = -coloradd ; } // 座標値を頂点シェーダー float4型定数0番にセット f4.x = ( float )x ; f4.y = 0.0f ; f4.z = 0.0f ; f4.w = 0.0f ; SetVSConstF( 0, f4 ) ; // 色の値をピクセルシェーダー float4型定数0番にセット f4.x = color ; f4.y = color ; f4.z = color ; f4.w = 1.0f ; SetPSConstF( 0, f4 ) ; // 使用する頂点シェーダーのセット SetUseVertexShader( vshandle ) ; // 使用するピクセルシェーダーをセット SetUsePixelShader( pshandle ) ; // 使用するテクスチャを0番にセット SetUseTextureToShader( 0, texhandle ) ; // シェーダーを使用した2ポリゴンの描画 DrawPolygonIndexed3DToShader( Vertex, 4, Index, 2 ) ; // 裏画面の内容を表画面に反映させる ScreenFlip() ; } // 使用した頂点シェーダーの float4型定数の設定を無効化する ResetVSConstF( 0, 2 ) ; // 使用したピクセルシェーダーの float4型定数の設定を無効化する ResetPSConstF( 0, 1 ) ; // 読み込んだ頂点シェーダーの削除 DeleteShader( vshandle ) ; // 読み込んだピクセルシェーダーの削除 DeleteShader( pshandle ) ; // 読み込んだ画像のグラフィックハンドルを削除 DeleteGraph( texhandle ) ; // DXライブラリの後始末 DxLib_End() ; // ソフトの終了 return 0 ; }






戻る