2013-02-21 205 views
3

我有兩個圖像,都是24色.bmp 32x32像素。如果我使用OpenGL加載它,如果我使用OpenGL加載另一個,它只顯示黑線和白線。爲什麼OpenGL無法正確顯示我加載的圖像?

還有別的東西可能會有所不同,因此不會讓其中一幅圖像顯示出來嗎?

這一個不工作的代碼:

grass1.bmp http://turboimg.com/p/aur1361433642q.bmp

這一個確實在工作代碼:

grass.bmp http://turboimg.com/p/udj1361433715c.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); 

以及如何得到的圖像數據(這應該是好吧,因爲它與其他圖像一起工作,我真的認爲它有關圖像的其他內容會使兩者不同)?

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; 
+0

很難,如果我們沒有他們比較這些圖片,但嘗試實例檢查「TBitmapInfoHeader」結構的「biHeight」的值。這可能是負值,也許你傳遞該值的函數不會帶負值。但這只是一個猜測,因爲我不知道這些圖像,而且你沒有顯示你使用'ReadBitmap'方法做了什麼。 – TLama 2013-02-21 07:39:38

+0

我會測試一下,看看數值是否有差異,給我幾分鐘。但與ReadBitmap,我幾乎只是刪除infoheader和文件頭,然後將數據發送到opengl。將數據存儲到名爲「grass」的指針中。在哪裏使用uptop。我可以嘗試提供圖片的鏈接,但不確定是否將它們上傳到照片網站,如果它以任何方式更改它們。但會在幾分鐘內完成。 – 2013-02-21 07:45:46

+0

更新後的圖像。和標題信息/高度信息 – 2013-02-21 07:58:38

回答

4

您的位圖至少在位深度上有所不同。無法加載的是8位,而工作的是24位。你需要的是將你的8位位圖轉換爲24位(因爲在你的glTexImage2D函數調用中使用了format參數值)。

代碼回顧:

我做你的代碼審查和這裏的結果;下面的代碼使用文件流來讀取文件(因爲我不是舊式I/O例程的粉絲;無論如何,你忘記了文件關閉),刪除了顏色通道旋轉部分,就像@Rob指出的那樣因爲下面提到的原因)。我已經添加了必要的比特深度值的支票(必須是24位與format標誌,你將用於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的幾乎沒有任何經驗,但直覺告訴我,那glTexImage2D功能的format參數GL_BGR值可能簡化這一部分,因爲我說的功能,那麼預計BGR像素陣列其data參數,這就是如何你的位圖被存儲。所以我的猜測是,你可以離開顏色通道旋轉,並調用glTexImage2D功能與format參數GL_BGR值:

glTexImage2D(GL_TEXTURE_2D, Level, Colorcomps, sGrass, tGrass, Border, GL_BGR, 
    GL_UNSIGNED_BYTE, grass); 
... 
+0

看了[替代方法](http://forum.vingrad.ru/forum/s/4ad5ff79dd9daa2d80afdfe69ef94a99/topic-263976.html)並運行一個簡單的測試,我可以證實我的期望。您可以刪除顏色通道旋轉,並簡單地使用'format'參數的'GL_BGR'值。 – TLama 2013-02-22 12:54:42

+0

是的是調整顏色讀取,因爲我被告知opengl讀取RGB,其中窗口保存爲BGR ..我沒有看到GL_BGR在opengGL中的選項,但很高興在那裏:D。 Thansk很多 – 2013-02-27 05:10:20

+0

不客氣! – TLama 2013-02-27 05:18:36

2

第一個圖像有索引顏色格式,但第二個圖像有RGB。您可以嘗試使用GIMP或其他編輯器更改顏色格式。

相關問題