OpenGL bitmap texture

Advanced game related topics
xorc1zt
Enthusiast
Enthusiast
Posts: 276
Joined: Sat Jul 09, 2011 7:57 am

OpenGL bitmap texture

Post by xorc1zt »

Hi,

I am trying to load a bitmap as a texture with opengl

Code: Select all

Procedure LoadBitmapTexture(TextureNum.i, Filename.s, Filter.i) 
  Define.i img = LoadImage(0, Filename)
  Define.BITMAP bmp
  
  GetObject_(img,SizeOf(BITMAP),bmp)
  Debug "[ bmp ]"
  Debug "bmBits: "      + Str( bmp\bmBits )
  Debug "bmBitsPixel: " + Str( bmp\bmBitsPixel )
  Debug "bmHeigh: "     + Str( bmp\bmHeight )
  Debug "bmPlanes: "    + Str( bmp\bmPlanes )
  Debug "bmType: "      + Str( bmp\bmType )
  Debug "bmWidth: "     + Str( bmp\bmWidth )
  Debug "bmWidthBytes: "+ Str( bmp\bmWidthBytes )
  
  glBindTexture(#GL_TEXTURE_2D, TextureNum)
 
  Select Filter
    Case #GL_NEAREST
      glTexParameterf(#GL_TEXTURE_2D, #GL_TEXTURE_MAG_FILTER, #GL_NEAREST)
      glTexParameterf(#GL_TEXTURE_2D, #GL_TEXTURE_MIN_FILTER, #GL_NEAREST)
      Debug "Mode: #GL_NEAREST"
    Case #GL_LINEAR 
      glTexParameterf(#GL_TEXTURE_2D, #GL_TEXTURE_MAG_FILTER, #GL_LINEAR)
      glTexParameterf(#GL_TEXTURE_2D, #GL_TEXTURE_MIN_FILTER, #GL_LINEAR)
      Debug "Mode: #GL_LINEAR"
  EndSelect

  glTexImage2D(#GL_TEXTURE_2D, 0, 3, bmp\bmWidth, bmp\bmHeight, 0, #GL_BGR, #GL_UNSIGNED_BYTE, bmp\bmBits)
  
  DeleteObject_(bmp)
  FreeImage(0)
EndProcedure
but the result is nowhere good as you can see on this screen shot
Image
the texture should be this
Image

Full code here: http://demo.ovh.com/en/67e6d3ef81b20d6f ... 8b94580fd/
Thorium
Addict
Addict
Posts: 1305
Joined: Sat Aug 15, 2009 6:59 pm

Re: OpenGL bitmap texture

Post by Thorium »

As i see it you need to set type to GL_UNSIGNED_INT.
If i understand it correctly type is the type of a complete element, which is in your case GL_BGR a integer with 3 channels.
User avatar
Comtois
Addict
Addict
Posts: 1431
Joined: Tue Aug 19, 2003 11:36 am
Location: Doubs - France

Re: OpenGL bitmap texture

Post by Comtois »

search on the forum hagibaba nehe tutorial and you will find a lot code source.

Extract from lesson 15

Code: Select all

Procedure.l LoadBMP(Filename.s) ;Loads A Bitmap Image

 Protected File.l=#Null ;File Handle
 
 If Filename="" ;Make Sure A Filename Was Given
  ProcedureReturn #Null ;If Not Return NULL
 EndIf
 
 File=ReadFile(#PB_Any,Filename) ;Check To See If The File Exists
 
 If File ;Does The File Exist?
  CloseFile(File) ;Close The Handle
  ProcedureReturn auxDIBImageLoad(Filename) ;Load The Bitmap And Return A Pointer
 EndIf
 
 ProcedureReturn #Null ;If Load Failed Return NULL
 
EndProcedure

Procedure.l LoadGLTextures() ;Load Bitmaps And Convert To Textures

 Protected Status.l=#False ;Status Indicator
 Protected Dim *TextureImage.AUX_RGBImageRec(1) ;Create Storage Space For The Texture
 
 ;Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit
 *TextureImage(0)=LoadBMP("Data/Lights.bmp")
 If *TextureImage(0)
  Status=#True ;Set The Status To TRUE
 
  glGenTextures_(1,@texture(0)) ;Create The Texture
 
  glBindTexture_(#GL_TEXTURE_2D,texture(0))
  glTexParameteri_(#GL_TEXTURE_2D,#GL_TEXTURE_MAG_FILTER,#GL_LINEAR)
  glTexParameteri_(#GL_TEXTURE_2D,#GL_TEXTURE_MIN_FILTER,#GL_LINEAR_MIPMAP_NEAREST)
  gluBuild2DMipmaps_(#GL_TEXTURE_2D,3,*TextureImage(0)\sizeX,*TextureImage(0)\sizeY,#GL_RGB,#GL_UNSIGNED_BYTE,*TextureImage(0)\Data)
 
  ;Note: GL_OBJECT_LINEAR did not work on my PC, GL_EYE_LINEAR/GL_SPHERE_MAP did
  glTexGeni_(#GL_S,#GL_TEXTURE_GEN_MODE,#GL_EYE_LINEAR) ;X Texturing Contour Anchored To The Object
  glTexGeni_(#GL_T,#GL_TEXTURE_GEN_MODE,#GL_EYE_LINEAR) ;Y Texturing Contour Anchored To The Object
  glEnable_(#GL_TEXTURE_GEN_S) ;Auto Texture Generation
  glEnable_(#GL_TEXTURE_GEN_T) ;Auto Texture Generation
 EndIf
 
 If *TextureImage(0) ;If Texture Exists
  If *TextureImage(0)\Data ;If Texture Image Exists
   FreeMemory(*TextureImage(0)\Data) ;Free The Texture Image Memory
  EndIf
  FreeMemory(*TextureImage(0)) ;Free The Image Structure
 EndIf
 
 ProcedureReturn Status ;Return The Status
 
EndProcedure
Hope this help ?
Please correct my english
http://purebasic.developpez.com/
xorc1zt
Enthusiast
Enthusiast
Posts: 276
Joined: Sat Jul 09, 2011 7:57 am

Re: OpenGL bitmap texture

Post by xorc1zt »

thanks but my function work well when i use GLUT for creating the window so i reversed purebasic and found the function who initialize opengl when you use OpenWindowedScreen()

Code: Select all

00403853  /$ 53             push ebx
00403854  |. 8B5C24 08      mov ebx, dword ptr [esp+08h]
00403858  |. 56             push esi
00403859  |. 8B35 70854000  mov esi, dword ptr [00408570h]           ;  OPENGL32.glEnable
0040385F  |. 57             push edi
00403860  |. 8B7C24 14      mov edi, dword ptr [esp+14h]
00403864  |. 68 710B0000    push 00000B71h
00403869  |. 891D 5C8F4000  mov dword ptr [00408F5Ch], ebx
0040386F  |. 893D 608F4000  mov dword ptr [00408F60h], edi
00403875  |. 891D E48E4000  mov dword ptr [00408EE4h], ebx
0040387B  |. 893D 648F4000  mov dword ptr [00408F64h], edi
00403881  |. FFD6           call esi                                 ;  <&OPENGL32.glEnable>
00403883  |. 68 03020000    push 00000203h
00403888  |. FF15 74854000  call dword ptr [00408574h]               ;  OPENGL32.glDepthFunc
0040388E  |. 57             push edi
0040388F  |. 53             push ebx
00403890  |. 6A 00          push 00000000h
00403892  |. 6A 00          push 00000000h
00403894  |. FF15 78854000  call dword ptr [00408578h]               ;  OPENGL32.glViewport
0040389A  |. 68 01170000    push 00001701h
0040389F  |. FF15 58854000  call dword ptr [00408558h]               ;  OPENGL32.glMatrixMode
004038A5  |. FF15 54854000  call dword ptr [00408554h]               ;  OPENGL32.glLoadIdentity
004038AB  |. DB4424 14      fild dword ptr [esp+14h]
004038AF  |. 83EC 20        sub esp, 20h
004038B2  |. DD5C24 18      fstp qword ptr [esp+18h]
004038B6  |. D9EE           fldz
004038B8  |. DD5424 10      fst qword ptr [esp+10h]
004038BC  |. DB4424 30      fild dword ptr [esp+30h]
004038C0  |. DD5C24 08      fstp qword ptr [esp+08h]
004038C4  |. DD1C24         fstp qword ptr [esp]
004038C7  |. E8 A5290000    call 00406271h
004038CC  |. BF F5840000    mov edi, 000084F5h
004038D1  |. 57             push edi
004038D2  |. FFD6           call esi                                 ;  OPENGL32.glEnable
004038D4  |. 68 00410000    push 00004100h
004038D9  |. 893D 688F4000  mov dword ptr [00408F68h], edi
004038DF  |. FF15 7C854000  call dword ptr [0040857Ch]               ;  OPENGL32.glClear
004038E5  |. 5F             pop edi
004038E6  |. 5E             pop esi
004038E7  |. C705 6C8F4000 >mov dword ptr [00408F6Ch], 00000001h
004038F1  |. 5B             pop ebx
004038F2  \. C3             ret
The problem is here

Code: Select all

004038CC  |. BF F5840000    mov edi, 000084F5h
004038D1  |. 57             push edi
004038D2  |. FFD6           call esi                                 ;  OPENGL32.glEnable
this code is doing glEnable(#GL_TEXTURE_RECTANGLE) so to fix this i just need to put glDisable(#GL_TEXTURE_RECTANGLE) into my InitGL() function
User avatar
Guimauve
Enthusiast
Enthusiast
Posts: 742
Joined: Wed Oct 22, 2003 2:51 am
Location: Canada

Re: OpenGL bitmap texture

Post by Guimauve »

Hello,

This is the procedure I use to load texture in OpenGL

Code: Select all

Procedure.l GL_LoadTexture(FileName.s, *Width.i = #Null, *Height.i = #Null)
  
  If LoadImage(0, FileName)
    
    Width = ImageWidth(0)
    Height = ImageHeight(0)
    Tex.l = FlipImage(0)
    
    If *Width <> #Null
      PokeL(*Width, Width)
    EndIf
    
    If *Height <> #Null
      PokeL(*Height, Height)
    EndIf
    
    If StartDrawing(ImageOutput(Tex))
      
      ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
      ; Note : Il faut créer la texture correctement en
      ; fonction de l'image qui est chargé. Il serait bien
      ; créer une structure (Texture) afin d'enregistrer
      ; les paramètres importants (Largeur, hauteur, type, etc)
      ; Type : Nearest Filtered, Linear Filtered, MipMapped 
      ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
      
      glGenTextures(1, @TextureID.l) ;Create The Texture
      
      glBindTexture(#GL_TEXTURE_2D, TextureID)
      glTexParameteri(#GL_TEXTURE_2D, #GL_TEXTURE_MIN_FILTER, #GL_LINEAR)
      glTexParameteri(#GL_TEXTURE_2D, #GL_TEXTURE_MAG_FILTER, #GL_LINEAR)
      glTexImage2D(#GL_TEXTURE_2D, 0, 3, Width, Height, 0, #GL_RGB, #GL_UNSIGNED_BYTE, DrawingBuffer())
      
      StopDrawing()
      
    EndIf 
    
    FreeImage(0)
    FreeImage(Tex)
    
  EndIf 
  
  ProcedureReturn TextureID
EndProcedure
Note : The Image manipulation Lib from Luis is needed. See here : http://www.purebasic.fr/english/viewtop ... 12&t=38975

Best regards.
Guimauve
DarkDragon
Addict
Addict
Posts: 2345
Joined: Mon Jun 02, 2003 9:16 am
Location: Germany
Contact:

Re: OpenGL bitmap texture

Post by DarkDragon »

You shouldn't ever use PureBasic's OpenScreen/OpenWindowedScreen for drawing 3D objects, as it might not initialize any depth buffer!
Beside this, you use glTexParameterf for specifying integer values (glTexParameteri is correct, with an i at the end instead of f) and you should also specify the WRAP_S/T parameter, e.g.:

Code: Select all

glTexParameteri(#GL_TEXTURE_2D, #GL_TEXTURE_WRAP_S, #GL_REPEAT)
glTexParameteri(#GL_TEXTURE_2D, #GL_TEXTURE_WRAP_T, #GL_REPEAT)
For the #GL_TEXTURE_RECTANGLE problem: if you replace all your #GL_TEXTURE_2D with #GL_TEXTURE_RECTANGLE, you are also able to load textures which are non-power of two.
bye,
Daniel
xorc1zt
Enthusiast
Enthusiast
Posts: 276
Joined: Sat Jul 09, 2011 7:57 am

Re: OpenGL bitmap texture

Post by xorc1zt »

i tried with GLUT and GL_texture_rectangle but still the same problem

Code: Select all

EnableExplicit
;********************************************************************
;- OPENGL INCLUDES
;********************************************************************
IncludeFile "include/gl.pbi"     ; GL constants up to OpenGL 1.1
IncludeFile "include/glext.pbi"  ; GL constants up to OpenGL 4.1
IncludeFile "include/wglext.pbi" ; GL constants for Windows-only extensions
IncludeFile "include/glimp.pbi"  ; GL imports
IncludeFile "include/glut.pbi"   ; GLUT
;IncludeFile "include/glew.pbi"   ; GLEW

Global Dim Texture.i(1)
Global TexureExt.i

Procedure LoadBitmapTexture(TextureNum.i, Filename.s, Filter.i) 
  Define.i img = LoadImage(0, Filename)
  Define.BITMAP bmp
  
  GetObject_(img,SizeOf(BITMAP),bmp)
;   Debug "[ bmp ]"
;   Debug "bmBits: "      + Str( bmp\bmBits )
;   Debug "bmBitsPixel: " + Str( bmp\bmBitsPixel )
;   Debug "bmHeigh: "     + Str( bmp\bmHeight )
;   Debug "bmPlanes: "    + Str( bmp\bmPlanes )
;   Debug "bmType: "      + Str( bmp\bmType )
;   Debug "bmWidth: "     + Str( bmp\bmWidth )
;   Debug "bmWidthBytes: "+ Str( bmp\bmWidthBytes )
  
  Debug "texture extension: " +Hex( TexureExt )
  
  glBindTexture(TexureExt, TextureNum)
  
  glTexParameteri(TexureExt, #GL_TEXTURE_WRAP_S, #GL_REPEAT)
  glTexParameteri(TexureExt, #GL_TEXTURE_WRAP_T, #GL_REPEAT)
  
  Select Filter
    Case #GL_NEAREST
      glTexParameteri(TexureExt, #GL_TEXTURE_MAG_FILTER, #GL_NEAREST)
      glTexParameteri(TexureExt, #GL_TEXTURE_MIN_FILTER, #GL_NEAREST)
      Debug "Mode: #GL_NEAREST"
    Case #GL_LINEAR 
      glTexParameteri(TexureExt, #GL_TEXTURE_MAG_FILTER, #GL_LINEAR)
      glTexParameteri(TexureExt, #GL_TEXTURE_MIN_FILTER, #GL_LINEAR)
      Debug "Mode: #GL_LINEAR"
  EndSelect

  glTexImage2D(TexureExt, 0, 3, bmp\bmWidth, bmp\bmHeight, 0, #GL_BGR_EXT, #GL_UNSIGNED_BYTE, bmp\bmBits)
  DeleteObject_(bmp)
  FreeImage(0)
EndProcedure

Procedure Draw()
  Static.f angler = 0.0
  glClearScreen(1.0,0.66,0.0)
  glBindTexture(TexureExt, 1)
  
  glMatrixMode(#GL_MODELVIEW)
  glLoadIdentity()
  
  glPushMatrix()
  glTranslatef(0.0,0.0,-10.0)
  glRotatef(angler,1.0,1.0,1.0)
  glutWireCube (1.0)
  glPopMatrix()
  
  glPushMatrix()
  glTranslatef(-2.0,2.0,-10.0)
  glRotatef(angler,1.0,1.0,1.0)
  glutSolidCube(1.0)
  glPopMatrix()
  
  glPushMatrix()
  glTranslatef(2.0,-2.0,-10.0)
  glRotatef(angler,1.0,1.0,1.0)
  glutSolidTeapot ( 1.0 )
  glPopMatrix()
  
  angler+0.01
  
  glutSwapBuffers()
EndProcedure

Procedure Idle()
 glutPostRedisplay()
EndProcedure

Procedure Resize(Width.i, Height.i)
  glViewport(0, 0, Width, Height)
  glMatrixMode(#GL_PROJECTION)
  glLoadIdentity()
  gluPerspective(45.0, Width/Height, 0.1, 100.0)
EndProcedure

Procedure Initialize()
  Define.i argc = 0
  Dim argv.s(0) : argv(0) = ""
  
  glutInit(@argc, @argv())
  glutInitWindowSize(800, 600);
  glutInitWindowPosition(300, 300);
  glutInitDisplayMode(#GLUT_RGB | #GLUT_DEPTH | #GLUT_DOUBLE)
  glutCreateWindow("PureBasic GLUT")
  
  ;Debug glGetString(#GL_EXTENSIONS)

  glEnable(#GL_DEPTH_TEST)

  glMatrixMode(#GL_PROJECTION);
  glLoadIdentity()
  gluPerspective(45.0,800/600,0.1,100.0)
  
  If( glutExtensionSupported("GL_ARB_texture_rectangle") )
    TexureExt=#GL_TEXTURE_RECTANGLE
  Else
    TexureExt=#GL_TEXTURE_2D
  EndIf
  glEnable(TexureExt)  
  
  glGenTextures( 1, @texture() )
  LoadBitmapTexture(texture(0), "res\NeHe.bmp", #GL_NEAREST)
  
  glutDisplayFunc(@Draw())
  glutReshapeFunc(@Resize())
  glutIdleFunc(@Idle())
  
EndProcedure

Initialize()
glutMainLoop()
As you can see, when i initialize glut i check if GL_ARB_texture_rectangle is supported

Code: Select all

  If( glutExtensionSupported("GL_ARB_texture_rectangle") )
    TexureExt=#GL_TEXTURE_RECTANGLE
  Else
    TexureExt=#GL_TEXTURE_2D
  EndIf
  glEnable(TexureExt)  
with GL_TEXTURE_RECTANGLE
Image

with GL_TEXTURE_2D
Image

edit : nevermind, GL_TEXTURE_RECTANGLE is not more used because of the the extension ARB_texture_non_power_of_two
Post Reply