3

2 つの画像があります。どちらも 24 色の .bmp 32x32 ピクセルです。一方を OpenGL でロードすると機能し、もう一方を OpenGL でロードすると、黒と白の線だけが表示されます。

画像の1つを表示させないために、他に何か違う可能性はありますか?

これはコードでは機能しません:

草1.bmp

これはコードで機能します:

草.bmp

情報サイズとファイルヘッダーサイズも確認しました。どちらの画像も、情報では 40、ファイル サイズでは 14 でした。画像の biWidth と BiHeight はどちらも 32x32 のままです。

これは、画像の草で六角形をテクスチャリングする方法を示しています

//GRASS
glTexImage2d(GL_TEXTURE_2D,Level,Colorcomps,sGrass,tGrass,Border,GL_RGB,GL_UNSIGNED_BYTE,grass);
glLoadName(1);
glBegin(GL_POLYGON);
    for I := 0 to 6 do
    begin
      glTexCoord2f(COS(i/6.0*2*PI),SIN(i/6.0*2*pi));
      glVertex3f((((COS(i/6.0*2*PI)/12)+offsetx)+0.2),((SIN(i/6.0*2*pi)/12)+offsety),-2);
    end;
glEnd;

grassはポインターであり、次のように入力されます。

grass := Readbitmap('Grass.bmp',sGrass,tGrass);

そして、どうすれば画像データを取得できますか(他の画像でも機能するので問題ありません。2つの画像を異なるものにする画像については別のことだと思います)?

Function TFCreateMap.ReadBitmap(const FilePath:String;var sWidth,tHeight:GLsizei):pointer;
const
  szh=SizeOf(TBitmapFileHeader);
  szi=SizeOf(TBitmapInfoHeader);
var
  bmpfile: file;
  bfh:TBitmapFileHeader;
  bmi:TBitmapInfoHeader;
  t:byte;
  x,
  fpos,
  size: integer;
begin
  assignfile(bmpfile,FilePath);
  reset(bmpfile,1);
  size := FileSize(bmpfile)-szh-szi;
  blockread(bmpfile,bfh,szh);
  if bfh.bfType<>$4D42  then
    raise EinvalidGraphic.Create('Invalid Bitmap');
  blockread(bmpfile,bmi,szi);
  with bmi do
  begin
    sWidth := biWidth;
    tHeight := biHeight;
  end;
  getmem(result,size);
  blockread(bmpfile,result^,size);
  for x  := 0 to sWidth*tHeight-1 do
  with TWrap(result^)[x] do
  begin
    t := r;
    r := b;
    b := t;
  end;
end;
4

2 に答える 2

4

あなたのビットマップは、少なくともビット深度が異なります。ロードに失敗するのは 8 ビットですが、動作するのは 24 ビットです。必要なのは、8 ビットのビットマップを 24 ビットに変換することです (関数呼び出しformatでパラメーター値が使用されているため)。glTexImage2D

コードレビュー:

あなたのコードをレビューしました。結果は次のとおりです。次のコードは、ファイルを読み取るためにファイル ストリームを使用します (私は古いスタイルの I/O ルーチンのファンではないため、とにかくファイルを閉じるのを忘れていました)、@Rob が指摘したように、間違っていたカラー チャネル回転部分を削除します (理由は後述)。必要なビット深度値のチェックを追加しました (これは、関数呼び出しformatに使用するフラグで 24 ビットでなければなりません)。glTexImage2D

function TFCreateMap.ReadBitmap(const AFilePath: string; var AWidth, 
  AHeight: GLsizei): Pointer;
var
  DataSize: Integer;
  FileStream: TFileStream;
  FileHeader: TBitmapFileHeader;
  InfoHeader: TBitmapInfoHeader;
const
  FileTypeBitmap = $4D42;
  FileHeaderSize = SizeOf(TBitmapFileHeader);
  InfoHeaderSize = SizeOf(TBitmapInfoHeader);
begin 
  Result := nil;                              

  FileStream := TFileStream.Create(AFilePath, fmOpenRead);
  try
    FileStream.ReadBuffer(FileHeader, FileHeaderSize);
    if (FileHeader.bfType <> FileTypeBitmap) then
      raise EinvalidGraphic.Create('Invalid file type!');

    FileStream.ReadBuffer(InfoHeader, InfoHeaderSize);
    if (InfoHeader.biBitCount <> 24) then
      raise EinvalidGraphic.Create('Invalid bit depth!');

    DataSize := FileStream.Size - FileHeaderSize - InfoHeaderSize;
    GetMem(Result, DataSize);
    FileStream.ReadBuffer(Result^, DataSize);

    AWidth := InfoHeader.biWidth;
    AHeight := InfoHeader.biHeight;    
  finally
    FileStream.Free;
  end;    
end;

ここで、カラー チャネルの回転を削除した理由について説明します。OpenGLの経験はほとんどありませんが、関数のパラメーターのGL_BGR値がこの部分を単純化する可能性があることを教えてくれます. . だから私の推測では、カラーチャンネルの回転を残して、パラメータの値で関数を呼び出すことができます:formatglTexImage2DdataglTexImage2DGL_BGRformat

glTexImage2D(GL_TEXTURE_2D, Level, Colorcomps, sGrass, tGrass, Border, GL_BGR,
  GL_UNSIGNED_BYTE, grass);
...
于 2013-02-21T19:41:30.157 に答える
2

最初の画像はインデックス カラー形式ですが、2 番目の画像は RGB です。GIMP またはその他のエディターを使用して、色の形式を変更することができます。

于 2013-02-21T12:50:25.713 に答える