2011-02-05 11 views
0

Visual C++ .NET 2008でOpenGLを使用してテクスチャキューブを作成しようとしています。 GLOBを使用してグーグルを行った後、gluBuild2DMipmapsを使用する必要があります。今管理対象ビットマップをアンマネージビットマップに正しく変換する方法は?

問題は、私はシステムを使用してビットマップを読み込む::描く、です:: Bitmap.FromFile()

、どのように私は、これはCONST void *型のパラメータを受け入れるgluBuild2DMipmapsにBitmapオブジェクトを管理渡します?

私はすでにこれらのコードを使用してするLockBitsを試してみてください。

BYTE * data; 
/*ambil raw data*/ 
System::Drawing::Rectangle rect = System::Drawing::Rectangle(0,0,b->Width,b->Height); 
System::Drawing::Imaging::BitmapData^bitmapData; 
    b->LockBits(
     rect, 
     System::Drawing::Imaging::ImageLockMode::ReadWrite, 
     b->PixelFormat ,bitmapData); 

    ::memcpy(data,bitmapData->Scan0.ToPointer(),b->Width * b->Height); 
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height, 
        GL_RGB, GL_UNSIGNED_BYTE, data); 

24bppのBMPファイルを使用して、メッセージSystem.ArgumentExceptionのとラインのロックビットに貼り付け:追加の情報を:パラメータは有効ではありません。

何が間違っていましたか?


私はちょうど正しい解決策を見つけました。

  1. 私が間違ってオーバーロードされた関数を使用します。問題のカップルだからです。私がlockBitsを呼び出す方法の違いを参照してください
  2. 私はポインタを初期化していませんdataBitmap
  3. また、GLuint * texture;は管理対象のポインタなので、pin_pointerを使用してアンマネージドポインタに変換する必要があります。

おかげで、これは正しい方法である:

void CBox::LoadTextureRaw(String^filename, int wrap) 
{ 
    //GLuint texture; 

    System::Drawing::Bitmap^bitmap = gcnew Bitmap(filename); 
    int h = bitmap->Height; 
    int w = bitmap->Width; 
    int s = w * h; 
    dataTexture = new BYTE[s * 3]; 

    System::Drawing::Rectangle rect = System::Drawing::Rectangle(0,0,bitmap->Width,bitmap->Height); 
    System::Drawing::Imaging::BitmapData^bitmapData = 
     bitmap->LockBits(rect,System::Drawing::Imaging::ImageLockMode::ReadWrite , System::Drawing::Imaging::PixelFormat::Format24bppRgb); 

    ::memcpy(dataTexture,bitmapData->Scan0.ToPointer(),s); 


    bitmap->UnlockBits(bitmapData); 
    pin_ptr<GLuint*> pt = &texture;//pin managed pointer, to be unmanaged... asyeeeem 
    **pt = gluBuild2DMipmaps(GL_TEXTURE_2D, 3, w, h,GL_RGB, GL_UNSIGNED_BYTE, dataTexture);  
} 

答えて

1

私はビットマップデータをコピーするには、次のコードを使用します。

Image image = null; 
Bitmap iBitmap = new Bitmap(fs); 
BitmapData iBitmapData; 
GCHandle hImageData; 

if ((iBitmap.Flags & (int)ImageFlags.ColorSpaceRgb) != 0) { 
    switch (iBitmap.PixelFormat) { 
     case PixelFormat.Format1bppIndexed: 
     case PixelFormat.Format4bppIndexed: 
     case PixelFormat.Format8bppIndexed: 
      // Allocate image raster 
      image = new RasterImage<ColorBGR8>(iBitmap.Width, iBitmap.Height); 
      break; 
     case PixelFormat.Format16bppRgb565: 
      // Allocate image raster 
      image = new RasterImage<ColorBGR16>(iBitmap.Width, iBitmap.Height); 
      break; 
     case PixelFormat.Format24bppRgb: 
      // Allocate image raster 
      image = new RasterImage<ColorBGR24>(iBitmap.Width, iBitmap.Height); 
      break; 
     case PixelFormat.Format32bppRgb: 
      // Allocate image raster 
      image = new RasterImage<ColorBGR32>(iBitmap.Width, iBitmap.Height); 
      break; 
     case PixelFormat.Format32bppArgb: 
      // Allocate image raster 
      image = new RasterImage<ColorABGR32>(iBitmap.Width, iBitmap.Height); 
      break; 
     default: 
      throw new Exception("Image RGB pixel format not supported"); 
    } 
} else if ((iBitmap.Flags & (int)ImageFlags.ColorSpaceGray) != 0) { 
    switch (iBitmap.PixelFormat) { 
     case PixelFormat.Format1bppIndexed: 
     case PixelFormat.Format4bppIndexed: 
     case PixelFormat.Format8bppIndexed: 
      // Allocate image raster 
      image = new RasterImage<ColorY8>(iBitmap.Width, iBitmap.Height); 
      break; 
     default: 
      throw new Exception("Image GRAY pixel format not supported"); 
    } 

    if (RenderContext.Caps.TextureSwizzle == false) { 
     throw new Exception("unable to load GRAY pixel format image (ARB_texture_swizzle extension not supported)"); 
    } 
} else if ((iBitmap.Flags & (int)ImageFlags.ColorSpaceYcbcr) != 0) { 
    throw new Exception("Image YCbCr pixel format not supported"); 
} else if ((iBitmap.Flags & (int)ImageFlags.ColorSpaceYcck) != 0) { 
    throw new Exception("Image YCCK pixel format not supported"); 
} else if ((iBitmap.Flags & (int)ImageFlags.ColorSpaceCmyk) != 0) { 
    throw new Exception("Image CMYK pixel format not supported"); 
} else 
    throw new Exception("Image pixel format not supported"); 

// Obtain source and destination data pointers 
iBitmapData = iBitmap.LockBits(new Rectangle(0, 0, iBitmap.Width, iBitmap.Height), ImageLockMode.ReadOnly, iBitmap.PixelFormat); 
hImageData = GCHandle.Alloc(image.GetPixelData(), GCHandleType.Pinned); 

    // Alternative without using custom Image class: 
    //T[,] buffer = new ColorRGB24[iBitmap.Width, iBitmap.Height]; 
    //hImageData = GCHandle.Alloc(buffer, GCHandleType.Pinned); 

// Copy Bitmap data to Image 
memcpy(hImageData.AddrOfPinnedObject(), iBitmapData.Scan0, iBitmapData.Stride*iBitmapData.Height); 

hImageData.Free(); 
iBitmap.UnlockBits(iBitmapData); 

return (image); 

あなたは、私がP /呼び出すために持っていたに注意することができますmemcpyロックされたメモリをコピーするルーチン。 Tは、以下

ような構造である Tを返す単純なルーチン[、]など

イメージクラスがメソッドGetPixelDataを(定義私のプロジェクトで定義されたクラスである)

Using System.Drawing.Imaging.PixelFormat values, such as Indexed and Gdi, will throw an System.ArgumentException 
[StructLayout(LayoutKind.Sequential, Pack = 1)] 
public struct ColorRGB24 : IColorRGB<byte> 
{ 
    public byte r; 
    public byte g; 
    public byte b; 
} 

には、以下の引用文を読みます

インデックスがまたはGdiのピクセル値でないことを確認してください。

+0

コードは同じですが、別のLockBitsオーバーロードメソッドを呼び出すと思います。 – Luca

+0

オハイオ州、私はそれを試みるべきです。厳密には、あなたが呼び出すLockBitsメソッドとは何ですか? – swdev

+0

これは:http://msdn.microsoft.com/en-us/library/5ey6h79d.aspx – Luca

関連する問題