Why doesn't OpenGL correctly display the image I loaded?
delphi, image, opengl
Solution
Your bitmaps differ at least in bit depth. The one which fails you to load is 8-bit, whilst the working one is 24-bit. What you need is to convert your 8-bit bitmap to 24-bit (because of the used `format` parameter value in your `glTexImage2D` function call).
Code review:
I've made a review of your code and here's the result; the following code uses file stream for reading the file (since I'm not a fan of the old style I/O routines; anyway you forgot on file closing), removes the color channel rotation part which was, as @Rob pointed wrong (for the reason mentioned below). I've added a check for the necessary bit depth value (which must be 24-bit with the `format` flag you will use for the `glTexImage2D` function call):
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;
Now to the reason, why I removed the color channel rotation; I have almost no experience with OpenGL, but something tells me, that `GL_BGR` value of the `format` parameter of the `glTexImage2D` function might simplify this part, because I'd say that the function then expects the BGR pixel array for its `data` parameter and that's how your bitmaps are stored. So my guess is that you can leave the color channel rotation and call the `glTexImage2D` function with `GL_BGR` value of the `format` parameter:
glTexImage2D(GL_TEXTURE_2D, Level, Colorcomps, sGrass, tGrass, Border, GL_BGR,
GL_UNSIGNED_BYTE, grass);
...
Problem
I have two images, both are 24 color .bmp 32x32 pixels. If I load one with OpenGL it works, if I load the other with OpenGL it just shows black and white lines. Is there something else that could be different, thus not letting one of the images show? This one does not work in code: This one does work in code: Also checked info size and file header size. Both images were 40 on info and 14 on file size. Both images biWidth and BiHeight were still 32x32. This shows how I texture a hex with the image grass ``` //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` is a pointer and filled like so: ``` grass := Readbitmap('Grass.bmp',sGrass,tGrass); ``` And how do I get the image data (which should be OK as it works with other images, I really think its something else about an image that would make the two different)? ``` 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; ```