2016-06-29 20 views
-3

私は「what is a Creel?」のダイレクト2dチュートリアルに従っています。私はチュートリアル8: '画像を読み込む'に行きました。私はspritesheetオブジェクトにGraphicsオブジェクトへのポインタを保存していなかったので、このバージョンのVisual Studioで問題が発生したので、呼び出されるたびに渡されます。主なポイント:私はwicfactory->CreateDecoderFromFile()方法でIWICBitmapDecoderを作成しようとすると、私は次のエラーを取得:"What's a Creel?"チュートリアル:ビジュアルスタジオでIWICBitmapDecoderを作成できません2015

Exception thrown at 0x008C70A7 in Project8.exe: 0xC0000005: Access violation reading location 0x00000000.

や自動車での私が手:

hr | E_NOINTERFACE No such interface supported. this | 0x00c1a5c8 {bmp=0x00000000 <NULL> } spritesheet * wicfactory | 0x00000000<NULL> wicdecoder | 0xcccccccc{...}

コードはこのこと:

#pragma once 

#include <wincodec.h> //include windowscodecs.lib in the linker input 
#include "Graphics.h" 
#include <d2d1.h> 
#include<string> 

class spritesheet { 
public: 

    ID2D1Bitmap* bmp; 
    spritesheet() {} 

    spritesheet(LPCWSTR file, graphics* gfx) { 
     //this->gfx = gfx; 
     //bmp = NULL; 
     HRESULT hr; 
     //create an image factory 
     IWICImagingFactory *wicFactory; 
     hr = CoCreateInstance(
      CLSID_WICImagingFactory, 
      NULL, 
      CLSCTX_INPROC_SERVER, 
      CLSID_WICImagingFactory, 
      (LPVOID*)&wicFactory 
      ); 

     //create a decoder 
     IWICBitmapDecoder *wicdecoder; 
     hr = wicFactory->CreateDecoderFromFilename(
      file, 
      NULL, 
      GENERIC_READ, 
      WICDecodeMetadataCacheOnLoad, 
      &wicdecoder 
      ); 
     IWICBitmapFrameDecode* wicframe = NULL; 
     hr = wicdecoder->GetFrame(0, &wicframe); 

     IWICFormatConverter *wicconverter = NULL; 
     hr = wicFactory->CreateFormatConverter(&wicconverter); 

     hr = wicconverter->Initialize(
      wicframe, 
      GUID_WICPixelFormat32bppPBGRA, 
      WICBitmapDitherTypeNone, 
      NULL, 
      0.0, 
      WICBitmapPaletteTypeCustom 
      ); 

     gfx->gettarget()->CreateBitmapFromWicBitmap(
      wicconverter, 
      NULL, 
      &bmp 
      ); 

     if (wicdecoder) wicdecoder->Release(); 
     if (wicFactory) wicFactory->Release(); 
     if (wicconverter) wicconverter->Release(); 
     if (wicframe) wicframe->Release(); 

    } 

    void init(wchar_t * file, graphics * gfx) { 
     //this->gfx = gfx; 
     //bmp = NULL; 
     HRESULT hr; 
     //create an image factory 
     IWICImagingFactory* wicFactory; 
     hr = CoCreateInstance(
      CLSID_WICImagingFactory, 
      NULL, 
      CLSCTX_INPROC_SERVER, 
      CLSID_WICImagingFactory, 
      (LPVOID*)&wicFactory 
      ); 

     //create a decoder 
     IWICBitmapDecoder* wicdecoder; 
     hr = wicFactory->CreateDecoderFromFilename(
      file, 
      NULL, 
      GENERIC_READ, 
      WICDecodeMetadataCacheOnLoad, 
      &wicdecoder 
      ); 

     IWICBitmapFrameDecode* wicframe = NULL; 
     hr = wicdecoder->GetFrame(0, &wicframe); 

     IWICFormatConverter *wicconverter = NULL; 
     hr = wicFactory->CreateFormatConverter(&wicconverter); 

     hr = wicconverter->Initialize(
      wicframe, 
      GUID_WICPixelFormat32bppPBGRA, 
      WICBitmapDitherTypeNone, 
      NULL, 
      0.0, 
      WICBitmapPaletteTypeCustom 
      ); 

     gfx->rendertarget->CreateBitmapFromWicBitmap(
      wicconverter, 
      NULL, 
      &bmp 
      ); 

     if (wicdecoder) wicdecoder->Release(); 
     if (wicFactory) wicFactory->Release(); 
     if (wicconverter) wicconverter->Release(); 
     if (wicframe) wicframe->Release(); 

     gfx->rendertarget->DrawBitmap(
      bmp, 
      D2D1::RectF(0.0f, 0.0f, 10, 10),  //dest rect 
      1.0f, 
      D2D1_BITMAP_INTERPOLATION_MODE::D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, //effect for scaling 
     D2D1::RectF(0, 0, 10, 10));    //scource rect 


} 


void draw(graphics *gfx) { 
    gfx->rendertarget->DrawBitmap(
     bmp, 
     D2D1::RectF(0.0f, 0.0f, 10, 10),  //dest rect 
     1.0f, 
     D2D1_BITMAP_INTERPOLATION_MODE::D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, //effect for scaling 
     D2D1::RectF(0, 0, 10, 10));    //scource rect 

    } 
}; 

今、テストするだけで、私はID2D1Bitmap* bmp;を各メソッドの先頭に置いてものが得ましたが、wicdecoderエラーメッセージがメモリ内のランダムな場所に変更されました。

+1

CoCreateInstance()を正しく使用していません。適切なインターフェイスguid、IID_IWICImagingFactoryを使用してください。また、エラーチェックを追加して、無作為にクラッシュするまで耕し続けないでください。 –

+0

このコンテキストでCoCreateInstance()を使用する方法の例を挙げることができますか?私はこれに少し慣れているし、ベテランがどのようにそれを実装するのだろうと思っていた – mrsamsir

答えて

0

問題が見つかりました。 CoCreateInstance()の実装は問題ありませんでしたが、コードが古くなっているという点で、いくつかの問題がありました。ここでの実装はまだ、CoCreateInstance()のない使用可能な実装を与えない(ともthisチュートリアルの定型コードを持っているあなたを必要としhttps://msdn.microsoft.com/en-us/library/windows/desktop/dd756686(v=vs.85).aspx

:私が開始する前に

NOW、私はこのの一部から取られた、と言わなければなりません。また、チュートリアルのコードは2008年のもので、アーキテクチャはウィンドウのサイズを変更するたびにアプリケーションが使用するメモリ量を拡張しますが、私はそれを無視します。主なポイント:自分のプログラムのモデルとしてそのチュートリアルのプログラム例を使用しないでくださいしかし、それは適切なWICとD2Dオブジェクトの宣言/初期化の良い例を示しています)、DX12のMicrosoftのドキュメントも古くなっていますが、ここではこれを明確にします。

CoCreateInstance()の正しい実装、および画像をロードするための正しい方法である:

void spritesheet::load(PCWSTR uri, ID2D1HwndRenderTarget * gfx) { 

    IWICBitmapDecoder *pDecoder = NULL; 
    IWICBitmapFrameDecode *pSource = NULL; 
    IWICStream *pStream = NULL; 
    IWICFormatConverter *pConverter = NULL; 
    IWICBitmapScaler *pScaler = NULL; 


    IWICImagingFactory *wicFactory = NULL; 

    CoCreateInstance(
     CLSID_WICImagingFactory, 
     NULL, 
     CLSCTX_INPROC_SERVER, 
     IID_IWICImagingFactory, 
     (LPVOID*)&wicFactory); 

    HRESULT hr = wicFactory->CreateDecoderFromFilename(
     uri, 
     NULL, 
     GENERIC_READ, 
     WICDecodeMetadataCacheOnLoad, 
     &pDecoder 
     ); 


    if (SUCCEEDED(hr)) { 
     // Create the initial frame. 
     hr = pDecoder->GetFrame(0, &pSource); 
    } 


    if (SUCCEEDED(hr)) { 

     // Convert the image format to 32bppPBGRA 
     // (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED). 
     hr = wicFactory->CreateFormatConverter(&pConverter); 

    } 


    if (SUCCEEDED(hr)) { 
     hr = pConverter->Initialize(
      pSource, 
      GUID_WICPixelFormat32bppPBGRA, 
      WICBitmapDitherTypeNone, 
      NULL, 
      0.f, 
      WICBitmapPaletteTypeMedianCut 
      ); 
    } 
    if (SUCCEEDED(hr)) 
    { 

     // Create a Direct2D bitmap from the WIC bitmap. 
     hr = gfx->CreateBitmapFromWicBitmap(
      pConverter, 
      NULL, 
      &bmp 
      ); 
    } 

    if (pDecoder) { 
     pDecoder->Release(); 
    } 
    if (pSource) { 
     pSource->Release(); 

    } 
    if (pConverter) { 
     pConverter->Release(); 
    } 
} 

注 URIは単にPCWSTR形式で、ファイル名であり、関数に渡すときL"name.bmp"として宣言。

画像を描画するための正しい方法は次のとおりです。

void spritesheet::draw(ID2D1HwndRenderTarget * gfx, float bx, float by, float rx, float ry, float dx, float dy) { 

    D2D1_SIZE_F size = bmp->GetSize(); 
    D2D1_POINT_2F upperLeftCorner = D2D1::Point2F(dx, dy); 

    gfx->DrawBitmap(
     bmp, 
     D2D1::RectF(
      upperLeftCorner.x, 
      upperLeftCorner.y, 
      upperLeftCorner.x + rx, 
      upperLeftCorner.y + ry), 
     1, 
     D2D1_BITMAP_INTERPOLATION_MODE::D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, 
     D2D1::RectF(
      bx, 
      by, 
      rx, 
      ry) 
     ); 
} 

、D2Dのドキュメントの残りの部分は最新のものではないが、それでもあなたを使用することをそこに何の良い例を示します。オブジェクトのいくつかはもう存在しません。D2D1::Rectが缶詰めされていて、今はあなたが持っているのは:D2D1::RectFです。ドキュメントやチュートリアルのいくつかはむしろばらばらになっていますが、十分に長い時間を掘り下げればゲームを作ることができます。 C#で書かれたインストーラの一部としてx86/x64の再配布可能なパッケージを実行することを覚えておいてください(C++はWindowsではネイティブで実行されず、C#は半分の速さです)。 。

関連する問題