1

I am trying to display a bitmap image to an OpenGL control called GL (I am using SharpGL as the wrapper). In practice, a text string is written to a GDI+ Picture box from which the Bitmap is obtained. The GLBitmap function requires a Byte() array as input; I convert the Bitmap to a Byte() array. Does not seem to work as I get a bunch of dots on screen. I have also saved the PictureBox image to a Bmp file on disk and cross-checked that it had the desired content. So, the Bmp image does not appear to be the issue here.

Actual OpenGL display Actual OpenGL display

Bmp file created from the code below Bmp file created from the code below

Wondering what I am doing wrong. Anybody would have a suggestion ? Thanks in advance.

The VB.Net code appears below.

' 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
djv
  • 15,168
  • 7
  • 48
  • 72
Azzar
  • 11
  • 4
  • Take the `BitmapData` byte array generated by `Bitmap.LockBits()`'s . That's the Image data. See the methods here: [Analyze colors of an Image](https://stackoverflow.com/a/59102380/7444103), where you see `Marshal.Copy(imageData.Scan0, buffer, 0, buffer.Length)`, `buffer` is your guy. As described there, prefer the 32Bit Format, so maybe also take the method that generates a new 32BitArgb Bitmap. – Jimi Feb 14 '20 at 20:05

1 Answers1

1

OpenGL requires raw pixel data ... BMP has encoding ...

In order to make this work you need to extract the raw pixel data from your BMP. That might be a bit too much to do correctly as there are a lot of format configurations out there ...

So make sure you change your bitmap to format that is easily handled like:

  1. uncompressed
  2. 24 or 32 bpp

Now bitmap has a BMP header at its start describing the file is BMP and stuff like resolution, encoding, organization etc ... The header also usually holds the start address of the pixels... So extract that and pass the RAW pixels to your GL texture...

Beware BMP pixels are aligned on ScanLine basis so each line of image has some gap BYTE to align to certain multiple of size (usually 1..4 Bytes) you need to skip it and then process another line. Here related QA (but solved easily by VCL which is not your case)

However you need to do this on your own so you need:

  1. dive into BMP fileformat

  2. obtain resolution and pixel data start address from the header

  3. construct your raw pixel data by copying the lines into yours memory array

    skipping header and the align bytes

  4. pass that as OpenGL texture

    its faster to pass whole image than do it on per line basis. Beware you need to set the pixel format so it matches your raw data copied from bmp. So bpp must match and also the R,G,B order.

  5. render textured quad

btw. much easier would be to print the texts directly in OpenGl. There are libs for that like FreeType but you can use textures instead like this:

Of coarse CPU side GL text rendering using such texture is much easier than in GLSL. You just handle the texture as Texture Atlas where the Texture coordinates are computed from ASCII code and Texture font organisation.

Community
  • 1
  • 1
Spektre
  • 49,595
  • 11
  • 110
  • 380