- ベストアンサー
DirectXでのicoファイル読み込み
今デスクトップアクセサリのような物を作成しています 作成中、DirectXでのicoファイル読み込みの部分で躓いています。 icoファイルの画像をテクスチャとして読む込む方法を教えてもらえないでしょうか?
- みんなの回答 (1)
- 専門家の回答
質問者が選んだベストアンサー
こんばんは。 アイコンを取り込んで容易にテクスチャ化する事は無理な様です。ピクセルを複写していく原始的なやり方が必要です。 LoadImage()でアイコンを読み込んで、そのイメージデータに基づいてテクスチャに書き込んでいきます。 アイコンがマスクイメージも所有している場合は、マスクデータに基づいて、テクスチャのアルファチャンネルへ書き込まないといけません。、 口で説明しきれる程、短絡的な事では無いので、取り合えず以下参考に。 struct CIcon2Texture { enum { COLOR = 0, MASK = 1, TOTAL = 3 }; LPDIRECT3DTEXTURE9 CreateTextureFromIcon(LPDIRECT3DDEVICE9 pDevice, LPCSTR pszName/*アイコンファイル名*/) { //アイコンのロード HICON hIcon = static_cast<HICON>(::LoadImage(::GetModuleHandle(NULL), pszName, IMAGE_ICON, 0, 0, LR_LOADFROMFILE)); LPDIRECT3DTEXTURE9 pd3dtex9 = this->CreateTextureFromIcon(pDevice, hIcon); ::DeleteObject(hIcon); return pd3dtex9; } LPDIRECT3DTEXTURE9 CreateTextureFromIcon(LPDIRECT3DDEVICE9 pDevice, HICON hIcon/*アイコンハンドル*/) { //アイコンのデータを記録する this->GetObject(hIcon); LPDIRECT3DTEXTURE9 pTexture = 0; LPDIRECT3DSURFACE9 pSurface = 0; //アルファチャンネル付き32ビットテクスチャの作成 ::D3DXCreateTexture(pDevice, bmp[COLOR].bmWidth, bmp[COLOR].bmHeight, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pTexture); if(!pTexture) return 0; pTexture->GetSurfaceLevel(0, &pSurface); if(!pSurface) return 0; this->PixelCopy(pSurface); return pTexture; } private: //アイコンリソースに基づいて、テクスチャサーフェースにピクセルをセットする void PixelCopy(LPDIRECT3DSURFACE9 pSurface) { D3DLOCKED_RECT rc; //サーフェースをロックする pSurface->LockRect(&rc, NULL, 0); //アイコンイメージ用のHDCを作成する HDC hDCIcon = ::CreateCompatibleDC(NULL); //逆転しているので高さの最大からスタートする for(int y = bmp[COLOR].bmHeight - 1; y >= 0 ; --y) { for(int x = 0; x < bmp[COLOR].bmWidth; ++x) { //32ビット前提でアクセスするポジションを計算する const int pos = (rc.Pitch * y) + (x * 4); LPDWORD pdw = reinterpret_cast<LPDWORD> ( static_cast<LPBYTE>(rc.pBits) + pos ); //アイコンイメージを選択 ::SelectObject(hDCIcon, ici.hbmColor); //色彩をサーフェースに書き込む *pdw = ::GetPixel(hDCIcon, x, y); //マスクイメージが無ければ引き返す if(!ici.hbmMask)continue; //マスクイメージを選択 ::SelectObject(hDCIcon, ici.hbmMask); //マスク値をサーフェースに書き込む *pdw |= ::GetPixel(hDCIcon, x, y) == 0 ? 0x0 : 0xff; } } //開放 pSurface->UnlockRect(); ::DeleteDC(hDCIcon); } void GetObject(HICON hIcon) { ::GetIconInfo(hIcon, &ici); ::GetObject(ici.hbmColor, sizeof(BITMAP), &bmp[COLOR]); ::GetObject(ici.hbmMask, sizeof(BITMAP), &bmp[MASK]); } ICONINFO ici; BITMAP bmp[TOTAL]; };
お礼
ピクセル単位で複写する方法とても参考になりました! この方法を使えば上手くいきそうですありがとうございました。