• 締切済み

ローディング画面をマルチスレッドで動かせません。

ローディング画面をマルチスレッドで動かせません。 DirectXとC++をVisualStudio2010でゲームを制作しています。 ローディング画面を動かせるようにマルチスレッドにしているんですが、パソコンによってはローディング画面から動かなくなってしまいます。(開発環境では、問題なく動きます) スレッドの呼び出し部分は以下のようになっています。 HANDLE thread; CScene gamen; //タイトル画面やメインゲーム画面などのシーンを管理 void Loading() { SetDrawLoading( true ); delete gamen; gamen = new CTitleGamen(); thread = (HANDLE)_beginthreadex(NULL,0,DrawLoading,NULL,0,NULL); gamen->LoadData(); //クラス内の画像や音楽データを読み込み effect->SetDrawLoading(false); WaitForSingleObject( thread, INFINITE ); CloseHandle(thread); } マルチスレッド部分は以下のように、 drawLoading変数がtrueの間、ローディング画面を描画するようにしています。 D3DXMATRIX m_world; unsigned __stdcall DrawLoading(void *p){ LPDIRECT3DTEXTURE9 pTexture; D3DXCreateTextureFromFileEx(m_pD3DDevice, TEXT("texture.png"),16, 16, 0, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_FILTER_NONE, D3DX_DEFAULT, D3DCOLOR_XRGB(255,255,0), NULL, NULL, &pTexture)) do{ m_pD3DDevice->Clear(0,NULL,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0); if( SUCCEEDED( m_pD3DDevice->BeginScene() ) ) { D3DXMatrixIdentity( &m_world ); m_pD3DDevice->SetTransform( D3DTS_WORLD, &m_world ); m_pSprite->Begin( D3DXSPRITE_ALPHABLEND ); m_pSprite->Draw( pTexture, NULL, NULL, &D3DXVECTOR3( timeGetTime()%800), 550, 0 ), 0xffffffff ); m_pSprite->End(); m_pD3DDevice->EndScene(); } m_pD3DDevice->Present( 0, 0, 0, 0 ); }while( effect->GetDrawLoading() ); pTexture->Release(); _endthreadex(0); return 0; } どなたか、ご教授お願い致します。

みんなの回答

  • aris-wiz
  • ベストアンサー率38% (96/252)
回答No.1

DirectXって初期化した以外のスレッドで描画デバイスを 呼び出しってやっちゃダメだった気がするのですが。。。 #過去の話かもしれませんが。 マルチスレッドにしているのだから、描画は メインスレッドのみで行い、進捗状況の数値だけ 別スレッドで更新していくのが常套策だと思います。

関連するQ&A

  • 描画を透明にする方法

    Directxの質問なのですがある色だけ透明にするにはどうしたらいいのでしょうか? void Draw(ID3DXSprite* g_pSprite,DDXTEX* g_pTexture) { // クリア g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, g_clrBackgroundColor, 1.0f, 0); // 描画開始 if (FAILED(g_pd3dDevice->BeginScene())) { g_pd3dDevice->Present(NULL, NULL, NULL, NULL); return; } // スプライトを描画 g_pSprite->Begin(D3DXSPRITE_ALPHABLEND); g_pSprite->Draw( g_pTexture->m_pTexture, // LPDIRECT3DTEXTURE9 pTexture NULL, // CONST RECT *pSrcRect &g_vCenter, // CONST D3DXVECTOR3 *pCenter NULL, // CONST D3DXVECTOR3 *pPosition g_pTexture->m_clrAlpha // D3DCOLOR Color ); g_pSprite->SetTransform(&g_mat); g_pSprite->End(); // シーン描画の終了とバックバッファからの表示 g_pd3dDevice->EndScene(); g_pd3dDevice->Present(NULL, NULL, NULL, NULL); } g_pTexture->m_clrAlphaで半透明するはずだとは思うのですが。できません。わかる方いらしたらご教授のほどよろしくお願いします。

  • 描画位置について

    描画を透明化する質問をしたものですが、もう1つ教えていただきたいことがあります。 void Draw(ID3DXSprite* g_pSprite,DDXTEX* g_pTexture) { // クリア g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, g_clrBackgroundColor, 1.0f, 0); // 描画開始 if (FAILED(g_pd3dDevice->BeginScene())) { g_pd3dDevice->Present(NULL, NULL, NULL, NULL); return; } // スプライトを描画 g_pSprite->Begin(D3DXSPRITE_ALPHABLEND); g_pSprite->Draw( g_pTexture->m_pTexture, // LPDIRECT3DTEXTURE9 pTexture NULL, // CONST RECT *pSrcRect &g_vCenter, // CONST D3DXVECTOR3 *pCenter NULL, // CONST D3DXVECTOR3 *pPosition g_pTexture->m_clrAlpha // D3DCOLOR Color ); g_pSprite->SetTransform(&g_mat); g_pSprite->End(); で描画範囲がCONST RECT *pSrcRectで、描画中心がCONST D3DXVECTOR3 *pPosition、描画位置がCONST D3DXVECTOR3 *pPositionのはずなのですが描画範囲も描画中心、描画位置も思い通りいきません。 描画範囲、中心、位置を指定するにはどうすればいいのでしょうか?

  • 描画について

    今DirectXでゲームを作ろうとしてるものですが、描画しようと思い打ったのですが位置が思い通りにならない(描画が範囲を下回っている)描画されなくて困っています。ソースはこれです。 HRESULT Render(void) { g_pD3DDevice->Clear(0, NULL,NULL, D3DCOLOR_XRGB(0, 255, 255), 1.0f, 0); // シーンの描画開始 if (SUCCEEDED(g_pD3DDevice->BeginScene())) { // スプライトの描画開始(アルファ・ブレンディング有効&デバイス状態を保存も復元もしない) pSprite->Begin(D3DXSPRITE_ALPHABLEND | D3DXSPRITE_DONOTSAVESTATE); // シーンの描画(2D画像の描画) RECT SrcRect = { 0,0,640,480 }; // テクスチャ内でスプライトに使う範囲(0,0)-(512,64) D3DXVECTOR3 Center(320,240,0); // スプライト内の中心の位置(256,32,0) D3DXVECTOR3 Position(320,240,0); // スプライトを表示する位置(0,0,0)+(320,240,0) static int alpha=0; pSprite->Draw(pTexture.m_texture, // スプライトに使うテクスチャ &SrcRect, // 描画範囲 &Center, // スプライト内の中心の位置 &Position, // スプライトを表示する位置 D3DCOLOR_ARGB(alpha>255?511-alpha:alpha,255,255,255)); //alpha++; alpha &= 0x1FF; //pTexture.m_colorKey); // スプライトの描画終了 pSprite->End(); // シーンの描画終了 g_pD3DDevice->EndScene(); } // シーンの表示 return g_pD3DDevice->Present(NULL, NULL, NULL, NULL); }どうしたらきちんとした位置に描画できるのでしょうか。

  • DirectXでの半透明PNG画像について

    半分が半透明で、もう半分は透明でない単色のPNG画像(128×128サイズ)を作成しました。 ソフトはAdobe Photoshop Elements 6.0で、アルファ設定されている「PNG-24」です。 D3DXCreateTextureFromFileEx関数で、そのPNG画像を読み込んで描画したのですが、半透明の部分は描画されず、透明にしていない片方しか描画されませんでした。 半透明の部分も描画されるようにするにはどうすればよいでしょうか? 自分でもいろいろ調べてみたのですが、原因がよく分からないので質問させていただきます。 一応、参考程度に… // スプライトオブジェクトの作成 if ( FAILED( D3DXCreateSprite( g_pd3dDevice, &m_pSprite ) ) ) {     // エラー処理 } D3DXIMAGE_INFO info; // テクスチャの読み込み if( FAILED( D3DXCreateTextureFromFileExA( g_pd3dDevice,                                FileName,                                D3DX_DEFAULT,                                D3DX_DEFAULT,                                D3DX_DEFAULT,                                0,                                D3DFMT_A1R5G5B5,                                D3DPOOL_MANAGED,                                D3DX_FILTER_NONE,                                D3DX_FILTER_NONE,                                0,                                &info,                                NULL,                                &g_pd3dTexture) ) ) {     // エラー処理 }

  • 描画について

    サイズを綺麗に描画したいのですが(サイズの範囲(rightとbottom)が微妙にずれている)どうしたら描画できるでしょうか? ここら辺かな?と思うところを載せます。 HRESULT ReadBMP(ID3DXSprite** g_pSprite,LPCTSTR lpszFilename,DDXTEX* g_pTexture) { HRESULT hr = S_FALSE; UINT uLevel = 0; IDirect3DSurface9* pSurface = NULL; lstrcpy(g_pTexture->m_Filename,lpszFilename); g_pTexture->m_clrAlpha=g_colorKey; g_pTexture->m_pTexture=NULL; // スプライト情報の生成 if (SUCCEEDED(hr)) hr = ::D3DXCreateSprite(g_pd3dDevice, g_pSprite); if (SUCCEEDED(hr)) hr = ::D3DXCreateTextureFromFileEx(g_pd3dDevice, g_pTexture->m_Filename, 680, 460, 1, D3DUSAGE_RENDERTARGET, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, g_pTexture->m_clrAlpha, NULL, NULL, &g_pTexture->m_pTexture); if (SUCCEEDED(hr)) hr = g_pTexture->m_pTexture->GetSurfaceLevel(uLevel, &pSurface); // サーフェイス取得 if (SUCCEEDED(hr)) hr = pSurface->GetDesc(&g_sSurfaceInfo); if (pSurface != NULL) pSurface->Release(); pSurface = NULL; // 失敗したら破棄 if (FAILED(hr)) DestroySplite(*g_pSprite,g_pTexture); return hr; } よろしくお願いします。

  • DirectX LPDIRECT3DDEVICE9のマルチスレッドでの使用について

    お世話になっております。 さて、現在DirectX 9.0cを用いたゲームを製作しています。 このゲーム内で、いわゆるNowLoadingの画面を作成しているのですが、ここで気になることがあります。 ここでのNowLoadingの要件は、"描画とは別にスレッドを作成し、そのスレッドでロード処理を行う"ことです。 そこで、ドキュメント(古いDirectXの日本語ドキュメント)でマルチスレッドについて言及している箇所を検索してみると、CreateDeviceの引数にD3DCREATE_MULTITHREADEDを入れると、マルチスレッドに対応すると書いてあります。しかし、同時にパフォーマンスを下げるとの記述もあります。 しかし、D3DXCreateTextureFromFileなどD3DXCreate**系の関数が、LPDIRECT3DDEVICE9に対して参照だけを行い、BeginSceneなど描画に関する関数の挙動には(LPDIRECT3DDEVICE9に同時にアクセスしたとしても)、なんら影響がないならば、わざわざこのD3DCREATE_MULTITHREADEDフラグを使いたくありません。 そこで、サンプルを作成してみました。 http://briefcase.yahoo.co.jp/bc/multithreaddevicesrc/lst?&.dir=/&.src=bc&.view=l このサンプルは、上記の処理をD3DCREATE_MULTITHREADEDフラグをいれず、そのまま行っているもので、テクスチャを別スレッドで、ひたすらロードと、解放を行っています。これを実行した結果、特に問題ない(強制終了などしない)ように見えました。 この結果は、"たまたま動いている"だけなのでしょうか、それとも"必然的"なもので、別段行ってもいいものなのでしょうか?もしくは、状況による(SetRenderStateなどの使い方による、など)ものなのでしょうか? ご教授よろしくお願いします。 環境は、DirectX9.0c (2008March)、XP sp3 になります。

  • マルチスレッドについて・・・

    先日マルチスレッドについて質問させていただいたものですが、助言のもと動かしてうまくいったように見えたのですが、ロードしていない部分がありました。 今回はスレッドの中身もかいておきます。 ご助力お願いいたします。 unsigned int WINAPI GameMain::loadthread(void *lpx) { GameMain* gm = (GameMain*)lpx; gm->GInit();   //ロード return 0; } HRESULT GameMain::LoadScreen() { // スレッドの生成 static bool onlyonce_createthread = FALSE; if(onlyonce_createthread ==FALSE) { hTh = (HANDLE)_beginthreadex( NULL, 0, &loadthread, this, 0, (unsigned*)&thID ); onlyonce_createthread =TRUE; } // ローディング画面の描画 static bool loopflg = TRUE; while(loopflg) { int threadCondition = CheckThread( hTh ); switch(threadCondition) { case THREAD_RUNNING: if(graphloaded_flg ==TRUE) //2D画像のロードが終わったら { EnterCriticalSection( &m_criticalSection ); float keep_item = (float)(load_item/MAX_LOAD_ITEM); LeaveCriticalSection( &m_criticalSection ); d2d_control->GaugeDraw(0, 0, keep_item); //画像の描画関数 } break; case THREAD_EXIT: loopflg =FALSE; break; case THREAD_ERROR: return E_FAIL; break; } } float keep_item = (float)(load_item/MAX_LOAD_ITEM); d2d_control->GaugeDraw(0, 0, keep_item);  //画像の描画関数 return S_OK; }

  • マルチスレッドについて

    私はいまマルチスレッドの勉強をしているのですが、ビルドが通るのに実行結果がおかしい状況に陥っています。 ロード画面の処理なのですが、プライマリスレッドでロード画面を描画し、セカンダリスレッドでロード処理を行おうとしています。 問題は、ロードが途中で止まることとロード画面を描画できません。 多分下記の関数が悪いとは思うのですがどうか、ご助力おねがいします。 HRESULT GameMain::LoadScreen() { // スレッドの生成 static bool onlyonce_createthread = FALSE; if(onlyonce_createthread ==FALSE) { hTh = (HANDLE)_beginthreadex( NULL, 0, &loadthread, this, 0, (unsigned*)&thID ); onlyonce_createthread =TRUE; } // ローディング画面の描画 static bool loopflg = TRUE; while(loopflg) { int threadCondition = CheckThread( hTh ); switch(threadCondition) { case THREAD_RUNNING: if(graphloaded_flg ==TRUE) { EnterCriticalSection( &m_criticalSection ); float keep_item = (float)(load_item/MAX_LOAD_ITEM); LeaveCriticalSection( &m_criticalSection ); d2d_control->GaugeDraw(0, 0, keep_item); } break; case THREAD_EXIT: loopflg =FALSE; break; case THREAD_ERROR: return E_FAIL; break; } } float keep_item = (float)(load_item/MAX_LOAD_ITEM); d2d_control->GaugeDraw(0, 0, keep_item); return S_OK; }

  • マルチスレッドでの画像描画

    マルチスレッドを使ってロード画面を作ろうとしているのですが、 上手く画像が描画更新してくれません。 スレッドの中身は下記の通りです。よろしくお願いします。 HRESULT GameMain::LoadScreen() { // スレッドの生成 static bool onlyonce_createthread = FALSE; if(onlyonce_createthread ==FALSE) { hTh = (HANDLE)_beginthreadex( NULL, // SECURITY_ATTRIBUTES 構造体へのポインタ 0, // 新規スレッドのスタックサイズ &loadthread, // スレッドの実行開始アドレス this, // 新規スレッドに渡される引数リスト 0, // 新規スレッドの初期状態 (unsigned*)&thID ); // スレッドのIDを格納するためのDWORD型変数へのポインタ onlyonce_createthread =TRUE; } // ローディング画面の描画 static bool loopflg = TRUE; while(loopflg) { int threadCondition = CheckThread( hTh ); switch(threadCondition) { case THREAD_RUNNING: if(graphloaded_flg ==TRUE) { EnterCriticalSection( &m_criticalSection ); load_item = (float)(load_item/MAX_LOAD_ITEM); LeaveCriticalSection( &m_criticalSection ); d2d_control->GaugeDraw(0, 0, load_item); Sleep(100); } break; case THREAD_EXIT: loopflg =FALSE; break; case THREAD_ERROR: return E_FAIL; break; } } return S_OK; }

  • Androidのマルチスレッド処理の開始タイミング

    組み込みボード上にAndroidOSをのせ、 その上でRS232C通信制御するプログラムを作成しております。 RS232C通信制御についてはThreadクラスを派生させたクラスを 作成し、マルチスレッド処理として、アプリ起動中に、常に動作させたい と考えています。 このとき、RS232C通信制御するスレッドを 開始するタイミング、終了するタイミングはメインアクティビティのどの タイミングで行うのが1番よいのでしょうか? 現状は以下で考えています。 public class MainActivity extends Activity { ComCtrl m_ComCtrl ; // RS232C通信制御スレッド protected void onCreate(Bundle savedInstanceState) { m_ComCtrl = new ComCtrl( null ) ; // スレッド生成 m_ComCtrl.start() ; // スレッド開始 } protected void onDestroy() { m_ComCtrl.halt() ; // スレッド終了(スレッドメインループを終了させる独自メソッド) } }

    • ベストアンサー
    • Java

専門家に質問してみよう