【问题标题】:Why doesn't OpenGL correctly display the image I loaded?为什么 OpenGL 不能正确显示我加载的图像?
【发布时间】:2019-08-31 09:16:56
【问题描述】:

我有两张图片,都是 24 色 .bmp 32x32 像素。如果我用 OpenGL 加载一个,它可以工作,如果我用 OpenGL 加载另一个,它只会显示黑白线。

是否还有其他可能不同的地方,因此不让其中一张图片显示?

这个在代码中不起作用:

这个确实在代码中工作:

还检查了信息大小和文件头大小。两张图片的信息为 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;

【问题讨论】:

  • 如果我们没有这些图像,就很难比较它们,但请尝试检查TBitmapInfoHeader 结构的biHeight 的值。这可能是负值,并且您将该值传递给的函数可能不采用负值。但这只是一个猜测,因为我不知道这些图像,而且您没有显示您使用 ReadBitmap 方法做了什么。
  • 我会测试一下,看看值是否有差异,给我几分钟。但是使用 ReadBitmap,在将数据发送到 opengl 之前,我几乎只是删除了 infoheader 和文件头。将数据存储到名为“grass”的指针中。在哪里使用它。我可以尝试提供图像的链接,但不确定我是否将它们上传到照片网站是否会以任何方式改变它们。但会在几分钟内完成。
  • 这两个位图之间的区别在于每像素值的位数。无法显示的bitmap 是 8 位,而工作的是 24 位。对于 8 位位图,像素数组中的每个字节代表一个像素,因此您在方法结束时的颜色转换实际上会移动像素。如果 glTexImage2d 函数甚至支持 8 位位图,也可以尝试 find the answer
  • 每个像素的位数存储在TBitmapInfoHeader结构的biBitCount成员中。
  • 您是否发现您的 TWrap 代码最终以您想要的方式工作?您实际上是在分配b := r,因为您在第一条语句中覆盖了t 的原始值。要旋转三个变量的值,您需要第四个临时变量。

标签: image delphi opengl


【解决方案1】:

您的位图至少在位深度上有所不同。加载失败的是 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 的经验,但有件事告诉我,format 函数的 format 参数的 GL_BGR 值可能会简化这部分,因为我会说该函数需要 BGR 像素数组它的data 参数就是你的位图的存储方式。所以我的猜测是,您可以离开颜色通道旋转并使用GL_BGR 参数的GL_BGR 值调用glTexImage2D 函数:

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

【讨论】:

  • 在查看alternative way 并运行一个简单的测试后,我可以确认我的期望。您可以移除颜色通道旋转,只需将GL_BGR 值用于format 参数。
  • yes 是调整读取的颜色,因为我被告知 opengl 以 RGB 读取,Windows 将其保存为 BGR .. 我没有在 opengGL 中看到 GL_BGR 的选项,但很高兴它在那里:D .非常感谢
【解决方案2】:

第一个图像具有索引颜色格式,但第二个图像具有 RGB。您可以尝试使用 GIMP 或其他编辑器更改颜色格式。

【讨论】:

    猜你喜欢
    • 2020-10-02
    • 1970-01-01
    • 2021-08-21
    • 1970-01-01
    • 2016-03-02
    • 1970-01-01
    • 1970-01-01
    • 2011-02-09
    • 1970-01-01
    相关资源
    最近更新 更多