【问题标题】:Display a Bitmap in OpenGL在 OpenGL 中显示位图
【发布时间】:2020-05-30 13:48:06
【问题描述】:

我正在尝试向名为 GL 的 OpenGL 控件显示位图图像(我使用 SharpGL 作为包装器)。在实践中,文本字符串被写入 GDI+ 图片框,从中获取位图。 GLBitmap 函数需要一个 Byte() 数组作为输入;我将位图转换为 Byte() 数组。似乎不起作用,因为我在屏幕上看到一堆点。我还将 PictureBox 图像保存到磁盘上的 Bmp 文件并交叉检查它是否具有所需的内容。所以,Bmp 图像在这里似乎不是问题。

实际的 OpenGL 显示

从以下代码创建的 Bmp 文件

想知道我做错了什么。有人会有建议吗?提前致谢。

VB.Net 代码如下所示。

' Create Bitmap & Graphics context for string
'
' iWidth and iHeight are the dimensions of the bitmap;
' they are a power of 2.
Dim SharpBMap As Bitmap = New Bitmap(iWidth, iHeight) 
Dim SharpGraf As Graphics = Graphics.FromImage(SharpBMap)

' Draw text string to SharpGraf PictureBox
'
SharpGraf.SmoothingMode = Drawing2D.SmoothingMode.HighQuality              
SharpGraf.Clear(Color.White) 
SharpGraf.DrawString(TxtStr, CurrFont, CurrBrush, 0, 0, CurrFormat)

' OutSharpGL is the Picture box to which the text string is sent
OutSharpGL.Image = SharpBMap

' Save the bitmap to disk: when the file is viewed, the image is Ok.
SharpBMap.Save(FilNameStr)

' Set the color
Gl.Color(1.0f, 1.0f, 1.0f)

' Set the Raster position
Gl.RasterPos(0, 0) 

' Transfer the Bitmap
Gl.Bitmap(iWidth, iHeight, 0.0f, 0.0f, 0.0f, 0.0f, BitmapToByte(SharpBMap))


' Function to convert a Bitmap to a Byte() array
Friend Function BitmapToByte(ByRef Bmp As Bitmap) As Byte()

    Dim converter As New ImageConverter()

    Return DirectCast(converter.ConvertTo(Bmp, GetType(Byte())), Byte())
End Function

【问题讨论】:

  • Bitmap.LockBits()'s 生成的BitmapData 字节数组。那是图像数据。请参阅此处的方法:Analyze colors of an Image,您在哪里看到Marshal.Copy(imageData.Scan0, buffer, 0, buffer.Length)buffer 是您的家伙。如那里所述,更喜欢 32Bit 格式,因此也可以采用生成新的 32BitArgb 位图的方法。

标签: vb.net opengl bitmap


【解决方案1】:

OpenGL 需要原始像素数据 ... BMP 有编码 ...

为了完成这项工作,您需要从 BMP 中提取原始像素数据。正确地做这件事可能有点太多了,因为那里有很多格式配置......

因此,请确保将位图更改为易于处理的格式,例如:

  1. 未压缩
  2. 24 或 32 bpp

现在位图在其开头有一个 BMP 标头,描述文件是 BMP 以及诸如分辨率、编码、组织等之类的东西……标头通常还包含像素的起始地址……所以提取它并传递 RAW像素到您的 GL 纹理...

注意 BMP 像素是在 ScanLine 基础上对齐的,因此每行图像都有一些间隙 BYTE 以对齐到某个大小的倍数(通常为 1..4 字节),您需要跳过它然后处理另一行。这里相关的 QA(但 VCL 很容易解决,这不是你的情况)

但是您需要自己执行此操作,因此您需要:

  1. 进入BMP fileformat

  2. 从头部获取分辨率和像素数据起始地址

  3. 通过将线条复制到您的内存阵列中来构建您的原始像素数据

    跳过标头和对齐字节

  4. 将其作为 OpenGL 纹理传递

    传递整个图像比逐行传递更快。请注意,您需要设置像素格式,使其与从 bmp 复制的原始数据相匹配。所以 bpp 必须匹配,并且 R,G,B 顺序也必须匹配。

  5. 渲染带纹理的四边形

btw. 直接在 OpenGL 中打印文本要容易得多。有类似 FreeType 的库,但您可以像这样使用纹理:

使用这种纹理的粗略 CPU 端 GL 文本渲染比在 GLSL 中容易得多。您只需将纹理作为纹理图集处理,其中纹理坐标是根据 ASCII 代码和纹理字体组织计算得出的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-05
    • 1970-01-01
    相关资源
    最近更新 更多