openGL textures and FB

External libraries (GTK, GSL, SDL, Allegro, OpenGL, etc) questions.
Post Reply
h4tt3n
Posts: 698
Joined: Oct 22, 2005 21:12
Location: Denmark

openGL textures and FB

Post by h4tt3n »

Hello everyone,

Here is some code with a simple .bmp loader I just wrote. It works fine, but there is a color issue. I've been using this texture from the net and several other images, but they're never displayed with the right colors.

I think the error has to do with the imagecreated buffer, but I'm not sure. Please tell me what's wrong ^^

Code: Select all

#include once "GL/gl.bi"
#include once "GL/glu.bi"

Declare Sub Initialize_openGl_2D()
Declare Sub Load_openGL_texture(byref bmp as String, byref handle as ubyte)

Const Scrn_Full = 1

Dim Shared As Integer Scrn_Wid, Scrn_Hgt, Scrn_Bpp, Scrn_X_Mid, Scrn_Y_Mid, wid, hgt
Dim Shared as Single angle, zoom

wid = 256
hgt = 256
angle = 0
zoom = 1


'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''


ScreenInfo Scrn_Wid, Scrn_Hgt, Scrn_Bpp

Scrn_X_Mid = Scrn_Wid\2
Scrn_Y_Mid = Scrn_Hgt\2

Initialize_openGl_2D()
Load_openGL_texture("metal_bronze.bmp", 0)

SetMouse ,,0

Do 
  
  ''  rotate image with leftarrow / rightarrow
  If Multikey (&h4b) Then
    Angle -= 2
  End If
  If Multikey (&h4d) Then
    Angle += 2
  End If
  
  ''  zoom image with uparrow / downarrow
  If Multikey (&h50) Then
    zoom *= 0.98
  End If
  If Multikey (&h48) Then
    zoom /= 0.98
  End If
  
  glClear GL_COLOR_BUFFER_BIT Or GL_DEPTH_BUFFER_BIT
  
  ''  draw a textured and rotozoomed square
  GLLoadIdentity()
  GlTranslatef(Scrn_X_Mid, Scrn_Y_Mid, 0)
  GLrotatef(angle, 0, 0, 1)
  Glscalef(zoom, zoom, 0)
  GlBegin (Gl_Quads)
    
    gltexcoord2f 0, 0
    glvertex2f -wid\2, -hgt\2
    
    gltexcoord2f 0, 1
    glvertex2f -wid\2, hgt\2
    
    gltexcoord2f 1, 1
    glvertex2f wid\2, hgt\2
    
    gltexcoord2f 1, 0
    glvertex2f wid\2, -hgt\2
    
  GlEnd()
  
  glFlush
  Flip
  ScreenSync
  
Loop Until Multikey(1)

End


'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''


Sub Initialize_openGl_2D()
  
  ''  define screen settings
  screenres Scrn_Wid, Scrn_Hgt, Scrn_Bpp,, 2 OR Scrn_Full
  
  '' Define matrix
  glMatrixMode(GL_PROJECTION)      
  glLoadIdentity()
  
  '' Define screen axis as FreeBasic style (0,0 in top left corner)
  glViewport (0, 0, Scrn_Wid, Scrn_Hgt)
  glOrtho(0, Scrn_Wid, Scrn_Hgt, 0, -128, 128)
  glMatrixMode(GL_MODELVIEW)
  glLoadIdentity()
  
  '' Deactivate rendering of backside
  glEnable(GL_CULL_FACE)
  glCullFace(GL_BACK)
  glLoadIdentity()
  
  '' Depth test
  glEnable(GL_DEPTH_TEST)          
  glDepthFunc(GL_LESS)
  
  '' Alpha test
  glEnable(GL_ALPHA_TEST)          
  glAlphaFunc(GL_GREATER, 0.1)
  
  '' Activate blending, including alpha channel
  glEnable(GL_BLEND)               
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
  
End Sub

Sub Load_openGL_texture(byref bmp as String, byref handle as ubyte)
  
  ''  create buffer and load .bmp to it
  Dim as uinteger Ptr buffer
  buffer = ImageCreate (wid, hgt)
  Bload (bmp, buffer)
  
  ''  openGL texture settings
  glEnable(GL_TEXTURE_2D)
  glGenTextures(handle, buffer)
  GlBindTexture (GL_TEXTURE_2D, handle)
  
  ''  wrap texture
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
  
  ''  set scaling quality to highest
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
  'glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST)
  
  ''  allow lighting and coloring
  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)
  
  ''  generate texture
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, wid, hgt, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer)
  
  '''  generate mipmaps
  'gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, wid, hgt, GL_RGBA, GL_UNSIGNED_BYTE, buffer)
  
  ''  destroy buffer
  ImageDestroy (buffer)
  
End Sub
Last edited by h4tt3n on Jun 22, 2007 11:34, edited 4 times in total.
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Post by counting_pine »

I don't know anything about OpenGL so I couldn't say at what point it's going wrong, but what's wrong is the red and blue channels are swapped. If you can find a way to change the byte order when converting it to a texture, then it should work then.
1000101
Posts: 2556
Joined: Jun 13, 2005 23:14
Location: SK, Canada

Post by 1000101 »

That's because opengl used RGBA, not ARGB. You need to swap the R and B channels.
tunginobi
Posts: 655
Joined: Jan 10, 2006 0:44
Contact:

Post by tunginobi »

Change this:

Code: Select all

  ''  generate texture
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, wid, hgt, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer)
to this:

Code: Select all

  ''  generate texture
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, wid, hgt, 0, GL_BGR, GL_UNSIGNED_BYTE, buffer)
Untested, but the same technique has worked in my C++ projects. I see no reason why it wouldn't work in FB as well.
h4tt3n
Posts: 698
Joined: Oct 22, 2005 21:12
Location: Denmark

Post by h4tt3n »

Tunginobi, thank you very much! I overlooked that one small but important possibility.

For further reference: when using 24 or 32 bpp images it only works when using the GL_BGRA instead of GL_RGBA.

Here is the updated code. It includes a simple sub to initialize an openGL viewport in freebasic and a texture loader, which converts a bitmap image to an openGL texture. Both are line-by-line commented, so newbies (including myself ^^) may have a chance to understand what's happening.

NOTE: There still is a small issue with the loader. All textures are offset by a handfull of pixels to the right. Can anyone explain what might be wrong?

Code: Select all

#include once "GL/gl.bi"
#include once "GL/glu.bi"

Declare Sub Initialize_openGl_2D()
Declare Sub Load_OpenGL_Texture(Byref bmp As String, Byref handle As Ubyte)

Dim Shared As Integer Scrn_Wid, Scrn_Hgt, Scrn_Bpp, Scrn_Full = 1, Scrn_X_Mid, _
  Scrn_Y_Mid, wid, hgt
  
Dim Shared as Single angle, zoom = 1


'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''


ScreenInfo Scrn_Wid, Scrn_Hgt, Scrn_Bpp

Scrn_X_Mid = Scrn_Wid\2
Scrn_Y_Mid = Scrn_Hgt\2

Initialize_openGl_2D()

Load_openGL_texture("YOUR_IMAGE.bmp", 0)

SetMouse ,,0

Do 
  
  ''  rotate image with leftarrow / rightarrow
  If Multikey (&h4b) Then
    Angle -= 1
  End If
  If Multikey (&h4d) Then
    Angle += 1
  End If
  
  ''  zoom image with uparrow / downarrow
  If Multikey (&h50) Then
    zoom *= 0.98
  End If
  If Multikey (&h48) Then
    zoom /= 0.98
  End If
  
  glClear GL_COLOR_BUFFER_BIT Or GL_DEPTH_BUFFER_BIT
  
  ''  draw a textured and rotozoomed square
  GLLoadIdentity()
  GlBindTexture (GL_TEXTURE_2D, 0)
  GlTranslatef(Scrn_X_Mid, Scrn_Y_Mid, 0)
  GLrotatef(angle, 0, 0, 1)
  Glscalef(zoom, zoom, 0)
  GlBegin (Gl_Quads)
    
    gltexcoord2f 0, 0
    glvertex2f -wid\2, -hgt\2
    
    gltexcoord2f 0, 1
    glvertex2f -wid\2, hgt\2
    
    gltexcoord2f 1, 1
    glvertex2f wid\2, hgt\2
    
    gltexcoord2f 1, 0
    glvertex2f wid\2, -hgt\2
    
  GlEnd()
  
  glFlush
  Flip
  ScreenSync
  
Loop Until Multikey(1)

End


'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''


Sub Initialize_OpenGl_2D()
  
  ''  define screen settings
  screenres Scrn_Wid, Scrn_Hgt, Scrn_Bpp,, 2 OR Scrn_Full
  
  '' Define matrix
  glMatrixMode(GL_PROJECTION)      
  glLoadIdentity()
  
  '' Define screen axis as FreeBasic style (0,0 in top left corner)
  glViewport (0, 0, Scrn_Wid, Scrn_Hgt)
  glOrtho(0, Scrn_Wid, Scrn_Hgt, 0, -128, 128)
  glMatrixMode(GL_MODELVIEW)
  glLoadIdentity()
  
  '' Deactivate rendering of backside
  glEnable(GL_CULL_FACE)
  glCullFace(GL_BACK)
  glLoadIdentity()
  
  '' Depth test
  glEnable(GL_DEPTH_TEST)          
  glDepthFunc(GL_LESS)
  
  '' Alpha test
  glEnable(GL_ALPHA_TEST)          
  glAlphaFunc(GL_GREATER, 0.1)
  
  '' Activate blending, including alpha channel
  glEnable(GL_BLEND)               
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
  glLoadIdentity()
  
End Sub

Sub Load_OpenGL_Texture(Byref bmp As String, Byref handle As Ubyte)
  
  ''  This sub creates an OpenGL texture from a bitmap image under the fol - 
  ''  lowing three conditions:
  ''  - The image must be quadratic.
  ''  - The bit depth must be 24 or 32 bits per pixel.
  ''  - The side length must be a power of two: ... 64, 128, 256 ...
  ''  The handle is simply a number between 0 and 255, which allows you and -
  ''  OpenGl to keep track of the texture.

  Dim As Uinteger Ptr buffer
  Dim As Ushort bmfh_bftype, bmih_wid, bmih_hgt, bmih_bpp, f = FreeFile
  
  ''  open file if it exists
  If (Open (bmp For Input As #f)) = 0 Then
    
    Get #f, 1, bmfh_bftype  ''  get file header type
    
    ''  check if format type is bitmap ( &H4D42 = "BM" )
    If bmfh_bftype = &H4D42 Then 
      
      Get #f, 19, bmih_wid  ''  get image width
      Get #f, 23, bmih_hgt  ''  get image height
      Get #f, 29, bmih_bpp  ''  get image bit depth
      
      ''  check if bit depth is 24 or 32 bpp
      If bmih_bpp = 24 or bmih_bpp = 32 Then
        
        ''  check if image is square and side length is a power of two
        If bmih_wid = bmih_hgt and (bmih_wid and (bmih_wid-1)) = 0 Then
          
          ''  create image buffer and load .bmp file
          buffer = ImageCreate (bmih_wid, bmih_hgt,, 32)
          Bload (bmp, buffer)
          
          ''  enable openGL textures
          glEnable(GL_TEXTURE_2D)
          
          ''  tell OpenGL the name of source buffer and handle
          glGenTextures(handle, buffer)
          GlBindTexture (GL_TEXTURE_2D, handle)
          
          ''  enable texture wrapping (optional)
          glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
          glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
          
          ''  set scaling quality (in this case highest possible)
          glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
          glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
          
          ''  enable lighting and coloring (optional)
          glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)
          
          ''  generate texture
          glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bmih_wid, bmih_hgt, 0, _
                       GL_BGRA, GL_UNSIGNED_BYTE, buffer)
          
          ''  destroy image buffer (to free memory)
          ImageDestroy (buffer)
          
          wid = bmih_wid: hgt = bmih_hgt
          
        End If
        
      End If
      
    End If
    
    ''  close file again
    Close #f
    
  End If
  
End Sub
regards,
Michael
1000101
Posts: 2556
Joined: Jun 13, 2005 23:14
Location: SK, Canada

Post by 1000101 »

Being offset is a result of not accounting for the bitmap header.

Also, this method of loading will only work for RGB encoded bitmaps.
Dr_D
Posts: 2451
Joined: May 27, 2005 4:59
Contact:

Post by Dr_D »

Not only that, but cards that don't suport GL_BGR/GL_BGRA will produce textures with undesirable results. You would be better off manually flipping. ;)
h4tt3n
Posts: 698
Joined: Oct 22, 2005 21:12
Location: Denmark

Post by h4tt3n »

1000101 wrote:Being offset is a result of not accounting for the bitmap header.
Funny enough this doesn't seem to be a problem when making "regular" non-opengl sprites from bitmaps. Where is the difference?
1000101 wrote:Also, this method of loading will only work for RGB encoded bitmaps.
Easy now, I'm still pretty new at this. I'll take care of all the exceptions later, but for now I'm happy with making a regular, uncompressed 24 bit .bmp file into an OpenGl texture.

So, the job to be done is make the code only read image data into the buffer and swap the red and blue channels at the same time...
I assume that I'll have to do something like this (???):

1. open the bmp file and Get all the neccesary jazz, including the bfOffBits value, which tells where the image data starts.

2. dim an uinteger (4 bytes) buffer with the size img width * img height

3. start reading the image data from bfOffBits and onwards, 4 bytes at a time: R, G, B and A

4. For every 4 bytes, swap R&B channels, somehow combine the four bytes to an Uinteger number and store it as a pixel.

5. go on with all the OGL stuff.

or is there a better way at it?
1000101
Posts: 2556
Joined: Jun 13, 2005 23:14
Location: SK, Canada

Post by 1000101 »

h4tt3n wrote:
1000101 wrote:Being offset is a result of not accounting for the bitmap header.
Funny enough this doesn't seem to be a problem when making "regular" non-opengl sprites from bitmaps. Where is the difference?
There is no difference. You always have to skip the file header.
h4tt3n wrote:
1000101 wrote:Also, this method of loading will only work for RGB encoded bitmaps.
Easy now, I'm still pretty new at this. I'll take care of all the exceptions later, but for now I'm happy with making a regular, uncompressed 24 bit .bmp file into an OpenGl texture.
I was just emphasizing that you have a narrow case here. Most of the time bitmaps are not 24-bit uncompressed. Typically they are 8-bit RLE. Only a fool would store a true-colour image in a bitmap (no compression ftl!)

Also, fb has a bitmap loader which will handle that all for you providing you with a nice, clean 32-bit image buffer.
h4tt3n wrote:So, the job to be done is make the code only read image data into the buffer and swap the red and blue channels at the same time...
I assume that I'll have to do something like this (???):
Skip all that except the last two steps and use BLoad. Don't reinvent the wheel. Especially since you seem to think that a BMP will have an alpha channel.
h4tt3n wrote:4. For every 4 bytes, swap R&B channels, somehow combine the four bytes to an Uinteger number and store it as a pixel.

5. go on with all the OGL stuff.
Yeah, this is simple. Use the createtex.bi file in the /examples/gl/nehe/ directory. You pass it a 32-bit fb.image pointer and some gl flags it returns a gl texture.

I seriously recommend going through the nehe examples and tutorials until you understand what's happening and why.
h4tt3n
Posts: 698
Joined: Oct 22, 2005 21:12
Location: Denmark

Post by h4tt3n »

1000101 wrote:There is no difference. You always have to skip the file header.
If you imagecreate a buffer, bload a bmp to it and put it on the screen there is no offset. When doing the exact same thing except create ogl texture instead of put it is offset a little to the right.
1000101 wrote:I seriously recommend going through the nehe examples and tutorials until you understand what's happening and why.
Ok, I already did look at some of them, but sure you're right. I took a look at the examples/gl/nehe examples and found the createtex.bi included in a few - for exampe lesson 26. It says:

Code: Select all

dim shared texture(0 to 2) as uinteger

...

redim buffer(256*256*4+4) as ubyte
bload exepath + "/data/Envwall.bmp", @buffer(0)
texture(0) = CreateTexture(@buffer(0))
bload exepath + "/data/Ball.bmp", @buffer(0) 
texture(1) = CreateTexture(@buffer(0)) 
bload exepath + "/data/Envroll.bmp", @buffer(0) 
texture(2) = CreateTexture(@buffer(0)) 
I've tried to implement this in a number of ways , like this:

Code: Select all

dim texture as Uinteger

redim buffer(256*256*4+4) as ubyte
bload "some_texture.bmp", @buffer(0)
texture = CreateTexture(@buffer(0))
or this:

Code: Select all

dim texture as Uinteger

Dim as any ptr buffer = Imagecreate(256, 256)
bload ("some_texture.bmp", buffer)
texture = CreateTexture(buffer)
But it crashes without any error messages. What the heck's wrong? I'm doing exactly like in the tutorial.
1000101
Posts: 2556
Joined: Jun 13, 2005 23:14
Location: SK, Canada

Post by 1000101 »

h4tt3n wrote:If you imagecreate a buffer, bload a bmp to it and put it on the screen there is no offset. When doing the exact same thing except create ogl texture instead of put it is offset a little to the right.
Again, you need to skip the header. In this case, the fb.image header.
h4tt3n wrote:
1000101 wrote:I seriously recommend going through the nehe examples and tutorials until you understand what's happening and why.
Ok, I already did look at some of them, but sure you're right. I took a look at the examples/gl/nehe examples and found the createtex.bi included in a few - for exampe lesson 26. It says:

[...shortened for berevity...]

But it crashes without any error messages. What the heck's wrong? I'm doing exactly like in the tutorial.
hrm, that is a bad example. None of them should be using an array to store the image data. As to crashing without an error, could you be more specific (fbc version, build date, method you used to install, etc)?
h4tt3n
Posts: 698
Joined: Oct 22, 2005 21:12
Location: Denmark

Post by h4tt3n »

Sure, I'm using the may 14. release of fb 0.17b to be found here: http://www.freebasic.net/forum/viewtopic.php?t=8256

It's an installer, so I just double clicked it and went ahead. All FB related files and folders had been removed before the install.

When I try to compile and run any of the above examples with CreateTexture it just crashes and shows a windows error message. I've been experimenting quite a bit with it without any result.

If you've got a working example lying around somewhere I can probably figure it out from there.
h4tt3n
Posts: 698
Joined: Oct 22, 2005 21:12
Location: Denmark

Post by h4tt3n »

Ok, here is a function which loads bmp images and converts them to OpenGL textures. It has been hacked together from several existing loaders and customized to my needs.
It' still pretty minimalistic and there might still be a few hidden bugs. I've tried it with everything from 16*16 to 1024*1024 without detecting any problems. It runs fine in 0.17b, but there seems to be a few issues with "-lang deprecated".

The following code contains the function and a small test program, all with line-by-line comments. Please give me a few lines of constructive feedback.

Code: Select all

#include once "GL/gl.bi"
#include once "GL/glu.bi"

Declare Sub Initialize_OpenGl_2D()

Declare Function GL_Load_Bmp(Byref bmp As String) as Uinteger

Dim Shared As Integer Scrn_Wid, Scrn_Hgt, Scrn_Bpp, Scrn_Full = 1, _
  Scrn_X_Mid, Scrn_Y_Mid, wid = 512, hgt = 512
  
Dim Shared as uinteger handle(1 to 4)
  
Dim Shared as Single angle, zoom = 1


'******************************************************************************


''  test program to show how the function works

Initialize_openGl_2D()

handle(1) = GL_Load_Bmp("image.bmp")

setmouse ,,0

Do 
  
  ''  rotate image with leftarrow / rightarrow
  If Multikey (&h4b) Then
    Angle -= 1
  End If
  If Multikey (&h4d) Then
    Angle += 1
  End If
  
  ''  zoom image with uparrow / downarrow
  If Multikey (&h50) Then
    zoom *= 0.99
  End If
  If Multikey (&h48) Then
    zoom /= 0.99
  End If
  
  ''  clear screen buffer
  glClear GL_COLOR_BUFFER_BIT Or GL_DEPTH_BUFFER_BIT
  
  ''  reset coordinates
  GLLoadIdentity()
  ''  bind texture to whatever we're going to draw next
  GlBindTexture (GL_TEXTURE_2D, handle(1))
  ''  move coordinates to center of screen
  GlTranslatef(Scrn_X_Mid, Scrn_Y_Mid, 0)
  ''  rotate in the z axis
  GLrotatef(angle, 0, 0, 1)
  ''  scale in the x and y axis
  Glscalef(zoom, zoom, 0)
  ''  start drawing a box
  GlBegin (Gl_Quads)
    ''  top left
    gltexcoord3f 0, 0, 0
    glvertex2f -wid\2, -hgt\2
    ''  bottom left
    gltexcoord3f 0, 1, 0
    glvertex2f -wid\2, hgt\2
    ''  bottom right
    gltexcoord3f 1, 1, 0
    glvertex2f wid\2, hgt\2
    ''  top right
    gltexcoord3f 1, 0, 0
    glvertex2f wid\2, -hgt\2
  GlEnd()
  
  ''  force all drawing commands to be executed
  glFlush
  ''  swap the graphics card's internal screen buffers 
  ''  (You don't need to make two buffers with screenres)
  Flip
  ''  synchronize to screen framerate
  ScreenSync
  
Loop Until Multikey(1)

End


'*****************************************************************************


''  here is the function:

Function GL_Load_Bmp(Byref bmp As String) as Uinteger
  
  ''  This function creates an OpenGL texture from a bitmap image. 
  ''  it returns the OpenGL handle number on success and 0 on failure.
  
  Dim as Uinteger handle, bmih_wid, bmih_hgt, w, h, x, y, col, hdr, lin, f = FreeFile
  dim as uinteger ptr buffer
  
  ''  test 1: does file exist, and can we open it?
  If Open (bmp For Input Access Read As #f) <> 0 Then return 0

  ''  get image width and height from info header
  Get #f, 19, bmih_wid   
  Get #f, 23, bmih_hgt
  Close #f
  
  ''  test 2: is the image quadratic?
  if bmih_wid <> bmih_hgt Then return 0
  
  '' test 3: are width and height powers of 2
  if ((bmih_wid and (bmih_wid-1)) or (bmih_hgt and (bmih_hgt-1))) then return 0

  ''  Ok then, create image buffer and load image
  buffer = imagecreate(bmih_wid, bmih_hgt)
  Bload bmp, buffer
 
  ''  check if header is old or new style
  ''  Get width and height, set correct header size
  If buffer[0] = 7 Then
    w = buffer[2]
    h = buffer[3]
    hdr = 8
  Else
    w = (buffer[0] And &hfff8) Shr 3
    h = (buffer[0] Shr 16)
    hdr = 1
  End If
  
  ''  iterate through all pixels in order to:
  ''    -swap R and B channels so we can use the GL_RGBA texture format
  ''    -offset pixels a bit to the left to get rid of the header
  For y = 0 To h-1
    lin = y*w
    For x = 0 To w-1
      col = buffer[hdr+x+lin]
      col = RGB(col and &hFF, (col shr 8) and &hFF, (col shr 16) and &hFF)
      buffer[x+lin] = col
    Next
  Next
  
  ''  generate OpenGL texture and bind it to texture handle
  glGenTextures 1, @handle
  glBindTexture GL_TEXTURE_2D, handle
  glTexImage2D GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, Buffer
  
  ''  generate mipmaps and set a few texture parameters
  gluBuild2DMipmaps GL_TEXTURE_2D, GL_RGBA, w, h, GL_RGBA, GL_UNSIGNED_BYTE, Buffer
  glTexParameteri GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR
  glTexParameteri GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR
  
  ImageDestroy Buffer
  return handle

End Function


'******************************************************************************


Sub Initialize_OpenGl_2D()
  
  ''  check current screen settings
  ScreenInfo Scrn_Wid, Scrn_Hgt, Scrn_Bpp
  
  Scrn_X_Mid = Scrn_Wid\2
  Scrn_Y_Mid = Scrn_Hgt\2
  
  ''  define screen settings
  ScreenRes Scrn_Wid, Scrn_Hgt, Scrn_Bpp,, 2 OR Scrn_Full
  
  '' Define matrix
  glMatrixMode(GL_PROJECTION)      
  glLoadIdentity()
  
  '' Define screen axis as FreeBasic style (0,0 in top left corner)
  glViewport (0, 0, Scrn_Wid, Scrn_Hgt)
  glOrtho(0, Scrn_Wid, Scrn_Hgt, 0, -128, 128)
  
  glMatrixMode(GL_MODELVIEW)
  glLoadIdentity()
  
  glShadeModel(GL_SMOOTH)
  glClearColor(0.0, 0.0, 0.0, 0.0)
  
  ''  enable textures
  glEnable(GL_TEXTURE_2D)
  
  ''  wrap textures - make them repeat endlessly in all directions
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
  
  '' Deactivate rendering of backside
  glEnable(GL_CULL_FACE)
  glCullFace(GL_BACK)
  glLoadIdentity()
  
  '' Depth test
  glClearDepth(128.0)
  glEnable(GL_DEPTH_TEST)          
  glDepthFunc(GL_LESS)
  
  '' Alpha test
  glEnable(GL_ALPHA_TEST)          
  glAlphaFunc(GL_GREATER, 0.1)
  
  '' Activate blending, including the use of alpha channel
  glEnable(GL_BLEND)               
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
  
End Sub
regards,
Michael
Post Reply