間が開いてしまいましたが、未だにエフェクト描画中にモデルが黒くなってしまう事象が
解決しておらず大変困っています。。
自分のコードが独特なことが原因である可能性も考え、
まったく別のコードに組み込んでみましたが
やはり結果は変わりませんでした。
以下、オープンソースの簡単なサンプルコードにBISHAMONを組み込んだものです。
プロジェクトを新規につくり、以下のコードをコピー&ペーストすれば実行可能です。
// 2D板ポリゴン描画サンプルプログラム
#pragma comment(lib, "dxguid.lib")
#pragma comment(lib, "d3d9.lib")
#include <windows.h>
#include <tchar.h>
#include <d3d9.h>
#include <math.h>
#include "BMSDK/BMManager.h"
#include "BMSDK/BMEffect.h"
#include "BMSDK/BMBinary.h"
static const wchar_t *EFFECT_NAME = L"BMvol2_all";
struct CUSTOMVERTEX{
float x, y, z; // 頂点座標
float rhw; // 除算数
DWORD dwColor; // 頂点の色
float u, v; // テクスチャ座標
};
#define FVF_CUSTOM ( D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1 )
TCHAR gName[100] = _T("2D板ポリゴン描画サンプルプログラム");
// 虹色関数
DWORD RainbowRGB(DWORD num){
#define RAINBOWVAL(C) ((DWORD)((C>=1024) ?0 : (C<256) ? C : (C>768) ? (1023-C) : 255))
DWORD R = num%1536;
DWORD G = ((num%1536)+1024)%1536;
DWORD B = ((num%1536)+ 512)%1536;
return 0xff000000 + (RAINBOWVAL(R)<<16) + (RAINBOWVAL(G)<<8) + RAINBOWVAL(B);
}
// 頂点回転関数
void SetPos(float Cx, float Cy, float r, float ratio, float Ix, float Iy, float *Ox, float *Oy){
*Ox = Cx + ratio*(Ix*cos(r) - Iy*sin(r));
*Oy = Cy + ratio*(Ix*sin(r) + Iy*cos(r));
}
// ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT mes, WPARAM wParam, LPARAM lParam){
if(mes == WM_DESTROY || mes == WM_CLOSE ) {PostQuitMessage(0); return 0;}
return DefWindowProc(hWnd, mes, wParam, lParam);
}
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
// アプリケーションの初期化
MSG msg; HWND hWnd;
WNDCLASSEX wcex ={sizeof(WNDCLASSEX), CS_HREDRAW | CS_VREDRAW, WndProc, 0, 0, hInstance, NULL, NULL,
(HBRUSH)(COLOR_WINDOW+1), NULL, (TCHAR*)gName, NULL};
if(!RegisterClassEx(&wcex))
return 0;
if(!(hWnd = CreateWindow(gName, gName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
NULL, NULL, hInstance, NULL)))
return 0;
// Direct3Dの初期化
LPDIRECT3D9 g_pD3D;
LPDIRECT3DDEVICE9 g_pD3DDev;
if( !(g_pD3D = Direct3DCreate9( D3D_SDK_VERSION )) ) return 0;
D3DPRESENT_PARAMETERS d3dpp = {0,0,D3DFMT_UNKNOWN,0,D3DMULTISAMPLE_NONE,0,
D3DSWAPEFFECT_DISCARD,NULL,TRUE,0,D3DFMT_UNKNOWN,0,0};
if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &g_pD3DDev ) ) )
if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pD3DDev ) ) )
if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &g_pD3DDev ) ) )
if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pD3DDev ) ) )
{
g_pD3D->Release();
return 0;
}
ShowWindow(hWnd, nCmdShow);
// 頂点(初期位置)の設定
float Ratio = 1.0f;
float width = 240.0f * Ratio;
float height = 180.0f * Ratio;
CUSTOMVERTEX v[4]=
{
{ width/2, -height/2, 0.0f, 1.0f, 0x00000000, 0.0f, 0.0f},
{ width/2, height/2, 0.0f, 1.0f, 0x000000ff, 0.0f, 1.0f},
{-width/2, -height/2, 0.0f, 1.0f, 0x00000300, 1.0f, 0.0f},
{-width/2, height/2, 0.0f, 1.0f, 0x00000400, 1.0f, 1.0f}
};
// 頂点バッファの作成
IDirect3DVertexBuffer9* pVertex;
if(FAILED(g_pD3DDev->CreateVertexBuffer( sizeof(CUSTOMVERTEX)*4, D3DUSAGE_WRITEONLY, FVF_CUSTOM, D3DPOOL_MANAGED, &pVertex, NULL))){
g_pD3DDev->Release(); g_pD3D->Release();
return 0;
}
float Cx, Cy, t=0;
DWORD Rainbow = 0;
CUSTOMVERTEX CurV[4];
memcpy(CurV, v, sizeof(CUSTOMVERTEX)*4);
//BISHAMON設定
BMManager *manager = new BMManager(g_pD3DDev);
BMEffect *effect = manager->CreateEffect(EFFECT_NAME);
int testcount = 0;
// メッセージ ループ
int i;
do{
Sleep(1);
if( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) ){ DispatchMessage(&msg);}
// 頂点位置と色の計算(適当な計算です)
// 頂点情報CurVを確定するのが目的
t += 0.03146f/2;
Ratio = 1.5f+cos(t);
SetPos(320, 240, t*1.23, Ratio, 64, 64, &Cx, &Cy);
for(i=0; i<4; i++){
SetPos(Cx, Cy, t, Ratio, v[i].x, v[i].y, &CurV[i].x, &CurV[i].y);
CurV[i].dwColor = RainbowRGB(v[i].dwColor+(Rainbow++)*(i+1));
}
// 頂点バッファに頂点を書き込みできた時にだけ描画
void *pData;
if(SUCCEEDED(pVertex->Lock(0, sizeof(CUSTOMVERTEX)*4, (void**)&pData, 0))){
memcpy(pData, CurV, sizeof(CUSTOMVERTEX)*4);
pVertex->Unlock();
////
//エフェクト更新
effect->Update();
if(effect->IsExpired()) {
effect->Reset();
}
////
// Direct3Dの処理
g_pD3DDev->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,255), 1.0f, 0 );
g_pD3DDev->BeginScene();
// 描画
g_pD3DDev->SetStreamSource(0, pVertex, 0, sizeof(CUSTOMVERTEX));
g_pD3DDev->SetFVF(FVF_CUSTOM);
g_pD3DDev->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
//※※BISHAMONエフェクト描画処理※※//
//(ここを実行すると、モデルが黒くなります)
manager->Begin();
manager->DrawEffect(effect);
manager->End();
g_pD3DDev->EndScene();
g_pD3DDev->Present( NULL, NULL, NULL, NULL );
}
}while(msg.message != WM_QUIT);
pVertex->Release();
g_pD3DDev->Release();
g_pD3D->Release();
return 0;
}
上記のコードにおいても、BISHAMONエフェクトの描画中は、
長方形の部分だけ、真っ黒に描画されてしまいます。
【お願い】
大変お手数をおかけして申し訳ないのですが、
上記コードを修正したコードを全文で載せていただけないでしょうか。
(「この部分をこうやって直すと良いです」という形式ですと、
おそらくこれまでの様に解決できない可能性が考えられるため)
【考え】
ちなみに原因となっている部分は、やはり以下の部分で、
エフェクトの描画を始めると長方形が真っ黒になります。
manager->Begin();
manager->DrawEffect(effect);
manager->End();
また、上記部分に該当するXACTGame(BISHAMON版)に
導入されているソースでは、以下のようになっており、カメラの制御等はしていますが、
ご教示いただいております「SetRenderState関連のコード(保存と復帰関連)」
は元々のコードにあったもの以外、プロジェクト全体で検索しても
付け足されていないように見えます。
サンプルでは別の部分で保存と復帰をしているということでしょうか。
//game.cpp内
g_BMManager.DrawAllEffect(g_Camera.GetViewMatrix(), g_Camera.GetProjMatrix());
//DrawAllEffect関数本体
void BMManager::DrawAllEffect(const D3DXMATRIX* viewMatrix, const D3DXMATRIX* projMatrix)
{
if (s_instance == NULL){
// 既に破棄されているとき
return;
}
// Camera 情報更新
ml::matrix44 view(
viewMatrix->_11, viewMatrix->_12, viewMatrix->_13, viewMatrix->_14,
viewMatrix->_21, viewMatrix->_22, viewMatrix->_23, viewMatrix->_24,
viewMatrix->_31, viewMatrix->_32, viewMatrix->_33, viewMatrix->_34,
viewMatrix->_41, viewMatrix->_42, viewMatrix->_43, viewMatrix->_44);
ml::matrix44 proj(
projMatrix->_11, projMatrix->_12, projMatrix->_13, projMatrix->_14,
projMatrix->_21, projMatrix->_22, projMatrix->_23, projMatrix->_24,
projMatrix->_31, projMatrix->_32, projMatrix->_33, projMatrix->_34,
projMatrix->_41, projMatrix->_42, projMatrix->_43, projMatrix->_44);
SetView(view);
SetProjection(proj);
// Effect 描画処理
Begin();
BMEffectListType::iterator ite = listEffect.begin();
BMEffectListType::iterator end = listEffect.end();
for ( ; ite != end ; ++ite ){
BMEffect* effect = reinterpret_cast<BMEffect*>(*ite);
if ( effect != NULL ){
DrawEffect(effect);
}
}
End();
}
[補足]
※元のサンプルコードはこちらのサイト様のものです
http://marupeke296.com/index.html
DirectX9技術編-> その2 座標変換済み頂点で2D板ポリゴンを描画 サンプルプログラム