【DirectX】別環境におけるビルボードのサイズが変わる現象について
Posted: 2015年12月21日(月) 16:27
お世話になります。
【問題】
複数の絵が描かれた一枚の画像から、特定領域をトリミングしてビルボードに貼りつけて描画しています。
開発環境(デスクトップPC)と実行環境(ミニノートPC)が異なる場合、
ソースコードは開発環境と実行環境で同じですが、ビルボードの描画に差異が表れました。(参照画像参照)
テクスチャのトリミングエリアを開発環境では「0.25f」単位にしておりましたが、
試しに実行環境では固有値として「0.178f」に変更したところ、なんとか正常に描画されました。
(しかしこれではこのノートPC専用の値のため、意味がほとんどない対処法となってしまいます)
<質問①>
実行環境ごとにトリミングエリアの幅を自動で調整するプログラムを書ければ解決できると考えますが、
何が原因となっており、どういった要素から適正な値を算出すれば良いのか分からなかったため、
実行環境によって自動でトリミングの単位を算出するコードが書けておりません。
(モニタ解像度、ビデオカード、DirectXのバージョン辺りが怪しそうな雰囲気は有りますが解決策導き出せず…)
このような場合の解決策をご教授頂けないでしょうか。
何卒よろしくお願いいたします。
<質問②>
参照画像の通り、描画する座標も若干ずれてしまっています。
問題①と関連した無いようになりそうですが、なにかコメントを頂けたら幸いです。
<質問③>
開発環境では以下のコードを入れるとユニットビルボードを反転できましたが、
実行環境では反転できませんでした。
推測される原因についてご教示お願いいたします。
※質問①②③に対して、上記状況だけでも思い当たることがあれば気軽に書いて頂けると嬉しいです。
(関連コードが煩雑であるため、読む方に負担と思われるため。あと少し急ぎの案件ということもあり)
---------------------------------------------------------------
【開発環境 】
OS : Windows8.1
コンパイラ名 : VC++ 2008EE
DirectX9で開発しています。VC++のF5でビルドしています。
補足:Direct11もPCにはインストール済
【実行環境】
OS:Windows7
コンパイラ名 : VC++ 2008EE
DirectX9使用。VC++のF5でビルドしたら上記の結果になります。
補足:Direct11もPCには最初からインストール済
---------------------------------------------------------------
【コード】
ビルボードに関するコードの一部を記載いたします。
冗長になるため、必要じゃなさそうな部分は載せていませんが、
必要な部分が他にございましたらご指摘いただければ即コピペします。
【問題】
複数の絵が描かれた一枚の画像から、特定領域をトリミングしてビルボードに貼りつけて描画しています。
開発環境(デスクトップPC)と実行環境(ミニノートPC)が異なる場合、
ソースコードは開発環境と実行環境で同じですが、ビルボードの描画に差異が表れました。(参照画像参照)
テクスチャのトリミングエリアを開発環境では「0.25f」単位にしておりましたが、
試しに実行環境では固有値として「0.178f」に変更したところ、なんとか正常に描画されました。
(しかしこれではこのノートPC専用の値のため、意味がほとんどない対処法となってしまいます)
<質問①>
実行環境ごとにトリミングエリアの幅を自動で調整するプログラムを書ければ解決できると考えますが、
何が原因となっており、どういった要素から適正な値を算出すれば良いのか分からなかったため、
実行環境によって自動でトリミングの単位を算出するコードが書けておりません。
(モニタ解像度、ビデオカード、DirectXのバージョン辺りが怪しそうな雰囲気は有りますが解決策導き出せず…)
このような場合の解決策をご教授頂けないでしょうか。
何卒よろしくお願いいたします。
<質問②>
参照画像の通り、描画する座標も若干ずれてしまっています。
問題①と関連した無いようになりそうですが、なにかコメントを頂けたら幸いです。
<質問③>
開発環境では以下のコードを入れるとユニットビルボードを反転できましたが、
実行環境では反転できませんでした。
推測される原因についてご教示お願いいたします。
※質問①②③に対して、上記状況だけでも思い当たることがあれば気軽に書いて頂けると嬉しいです。
(関連コードが煩雑であるため、読む方に負担と思われるため。あと少し急ぎの案件ということもあり)
---------------------------------------------------------------
【開発環境 】
OS : Windows8.1
コンパイラ名 : VC++ 2008EE
DirectX9で開発しています。VC++のF5でビルドしています。
補足:Direct11もPCにはインストール済
【実行環境】
OS:Windows7
コンパイラ名 : VC++ 2008EE
DirectX9使用。VC++のF5でビルドしたら上記の結果になります。
補足:Direct11もPCには最初からインストール済
---------------------------------------------------------------
【コード】
ビルボードに関するコードの一部を記載いたします。
冗長になるため、必要じゃなさそうな部分は載せていませんが、
必要な部分が他にございましたらご指摘いただければ即コピペします。
//-----------<テクスチャの読み込み(問題①②③共通)>-----------//
void CBillBoard::load_Image(LPCSTR filename)
{
//テクスチャの読み込み
D3DXGetImageInfoFromFile(filename, &Size);
D3DXCreateTextureFromFileEx(
pD3DDevice,
filename,
Size.Width,
Size.Height,
0,
0,
D3DFMT_A8R8G8B8,//D3DFMT_UNKNOWN,
D3DPOOL_MANAGED,
D3DX_FILTER_NONE,
D3DX_FILTER_NONE,
0,
NULL,
NULL,
&pTex);
}
CBillBoard::CBillBoard(LPCSTR filename)
{
//描画リストに纏める時に、ユニットビルボードは変換する必要がある
//オブジェクトはfalse
set_UnitBillBoardFlag(false);
load_Image(filename);
//ポリゴン設定
//頂点座標の設定(ローカル)
VertexData[0].p = D3DXVECTOR3(1.0f, -1.0f, 0.0f ); //右下
VertexData[1].p = D3DXVECTOR3(1.0f, 1.0f, 0.0f ); //右上
VertexData[2].p = D3DXVECTOR3(-1.0f, -1.0f, 0.0f ); //左下
VertexData[3].p = D3DXVECTOR3(-1.0f, 1.0f, 0.0f ); //左上
// テクスチャ座標の設定(ポリゴンとは座標の種類が違うので注意)
VertexData[0].t = D3DXVECTOR2(1.0f,1.0f); //右下
VertexData[1].t = D3DXVECTOR2(1.0f,0.0f); //右上
VertexData[2].t = D3DXVECTOR2(0.0f,1.0f); //左下
VertexData[3].t = D3DXVECTOR2(0.0f,0.0f); //左上
// 頂点カラーの設定
VertexData[0].color = VertexData[1].color = VertexData[2].color = VertexData[3].color =(DWORD)D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f);
HRESULT hr;
//頂点バッファ作成(頂点4つ分)
hr = pD3DDevice->CreateVertexBuffer(
sizeof(CUSTOMVERTEX)*4,
D3DUSAGE_WRITEONLY,
FVF_CUSTOM,
D3DPOOL_MANAGED,
&pVertex,
NULL);
//頂点バッファに登録
void *pData;
hr = pVertex->Lock(0, sizeof(CUSTOMVERTEX)*4, (void**)&pData, 0);
if(hr == D3D_OK)
{
memcpy(pData, VertexData, sizeof(CUSTOMVERTEX)*4);
pVertex->Unlock();
}
else
{
return;
}
}
//------------------------<ここまで>---------------------------//
/-----------------------<ユニットの描画設定(問題①関係)>-----------------------//
void CMapUnitBillBoard::setup_AnimeTexture(int UnitAnimeMode,int TotalTexture, int (*pDrawAnimeArray)[FRONT_BACK])
{
/*
中略
*/
//上記コードを継承しつつ、ユニットビルボードは途中で以下のようにしています。
//0.178fにすると開発環境と同じように描画されます。
//テクスチャ座標を再セットする
VertexData[0].t = D3DXVECTOR2(0.25f ,0.25f);//右下
VertexData[1].t = D3DXVECTOR2(0.25f ,0.0f); //右上
VertexData[2].t = D3DXVECTOR2(0.0f ,0.25f); //左下
VertexData[3].t = D3DXVECTOR2(0.0f ,0.0f); //左上
/*
中略
*/
}
//------------------------<ここまで>---------------------------//
//------------------------<木や石の描画(問題②関係)>---------------------------//
void CBillBoard::draw_Model(D3DXMATRIX mat)
{
ObjectMat = mat;
/////一般的なビルボードの描画設定/////
//テクスチャステージの設定
// テクスチャステージの:RGBカラー要素の設定
pD3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
pD3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
pD3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
// テクスチャステージの:アルファ要素の設定
pD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
//カメラの回転に対する逆行列を取得(正面を向かせるため)
m_Inv = get_CameraInvMat();
// 座標変換(モデルの配置)
D3DXMatrixIdentity(&m_world);
D3DXMATRIX ObjectScaling;
D3DXMatrixScaling(&ObjectScaling, 1.5f, 1.5f, 1.5f);
D3DXMatrixMultiply( &m_world, &m_world, &m_Inv );
D3DXMatrixMultiply( &m_world, &m_world, &ObjectScaling );
D3DXMatrixMultiply( &m_world, &m_world, &ObjectMat );
pD3DDevice->SetTransform(D3DTS_WORLD, &m_world);
//頂点バッファの更新
void *pData;
HRESULT hr;
hr = pVertex->Lock(0, sizeof(CUSTOMVERTEX)*4, (void**)&pData, 0);
if(hr == D3D_OK)
{
memcpy(pData, VertexData, sizeof(CUSTOMVERTEX)*4);
pVertex->Unlock();
}
pD3DDevice->BeginScene(); // 描画開始
// テクスチャをパイプラインにセット
pD3DDevice->SetTexture( 0, pTex);
pD3DDevice->SetStreamSource(0, pVertex, 0, sizeof(CUSTOMVERTEX));
pD3DDevice->SetFVF(FVF_CUSTOM);
pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
pD3DDevice->EndScene(); // 描画終了
}
//------------------------<ここまで>---------------------------//
//------------------------<<反転しない描画(問題③)>---------------------------//
void CMapUnitBillBoard::draw_Model(D3DXMATRIX UnitMat,int UnitDirection,int UnitAnimeMode)
{
/*
中略
*/
/////////////////////<反転しない描画(問題③)>//////////////////////
// 座標変換(モデルの配置)
//※ ほかの座標変換に影響されるのでちゃんと初期化する必要がある ※
D3DXMatrixIdentity(&m_world);
if(NowTexDirection == FRONT_RIGHT ||NowTexDirection == BACK_LEFT)
{
D3DXMatrixScaling(&m_world, -1.0f, 1.0f, 1.0f); //これを入れると画像を反転できる
}
D3DXMatrixMultiply( &m_world, &m_world, &m_Inv );
D3DXMatrixMultiply( &m_world, &m_world, &UnitMat );
pD3DDevice->SetTransform(D3DTS_WORLD, &m_world);
//頂点バッファの更新
void *pData;
HRESULT hr;
hr = pVertex->Lock(0, sizeof(CUSTOMVERTEX)*4, (void**)&pData, 0);
if(hr == D3D_OK)
{
memcpy(pData, VertexData, sizeof(CUSTOMVERTEX)*4);
pVertex->Unlock();
}
pD3DDevice->BeginScene(); // 描画開始
// テクスチャをパイプラインにセット
pD3DDevice->SetTexture( 0, pTex);
pD3DDevice->SetStreamSource(0, pVertex, 0, sizeof(CUSTOMVERTEX));
pD3DDevice->SetFVF(FVF_CUSTOM);
pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
pD3DDevice->EndScene(); // 描画終了
}