Page 1 of 1

NeHe's Texture Mapping Tutorial (Lesson 6)

Posted: Fri Jan 05, 2007 9:58 am
by hagibaba
This shows how to texture map an OpenGL cube.
You can get the "NeHe.bmp" from the "lesson06.zip" here:
http://nehe.gamedev.net/data/lessons/le ... ?lesson=06

Last edited on 20 Feb 2007.

Code: Select all

;NeHe's Texture Mapping Tutorial (Lesson 6)
;http://nehe.gamedev.net
;Credits: Nico Gruener, Dreglor, traumatic
;Author: hagibaba
;Date: 5 Jan 2007
;Note: up-to-date with PB v4.02 (Windows)
;Note: requires a bitmap in path "Data/NeHe.bmp"

;Section for standard constants, structures, macros and declarations

XIncludeFile "OpenGL.pbi" ;include the gl.h constants

;wingdi.h constants
#DM_BITSPERPEL=$40000
#DM_PELSWIDTH=$80000
#DM_PELSHEIGHT=$100000

;winuser.h constants
#CDS_FULLSCREEN=4
#DISP_CHANGE_SUCCESSFUL=0
#SC_MONITORPOWER=$F170

Structure AUX_RGBImageRec ;glaux.h structure
 sizeX.l : sizeY.l
 Data.l
EndStructure

Procedure.w LoWord(value.l) ;windef.h macro
 ProcedureReturn (value & $FFFF)
EndProcedure

Procedure.w HiWord(value.l) ;windef.h macro
 ProcedureReturn ((value >> 16) & $FFFF)
EndProcedure

;glaux.lib symbols
!public ___ftoll
!___ftoll dw 0
!public __imp__wsprintfA
!__imp__wsprintfA dw 0

Import "glaux.lib"
 auxDIBImageLoad.l(filename.s) As "_auxDIBImageLoadA@4" ;loads a 24-bit Windows DIB
EndImport

Import "glu32.lib"
 gluPerspective(fovy.d,aspect.d,zNear.d,zFar.d) ;sets up a perspective projection matrix
EndImport

Import "opengl32.lib"
 glClearDepth(depth.d) ;specifies the clear value for the depth buffer
EndImport

;Start of Lesson 6

Global hDC.l ;Private GDI Device Context
Global hRC.l ;Permanent Rendering Context
Global hWnd.l ;Holds Our Window Handle
Global hInstance.l ;Holds The Instance Of The Application

Global Dim keys.b(256) ;Array Used For The Keyboard Routine
Global active.b=#True ;Window Active Flag Set To TRUE By Default
Global fullscreen.b=#True ;Fullscreen Flag Set To Fullscreen Mode By Default

Global xrot.f ;X Rotation ( NEW )
Global yrot.f ;Y Rotation ( NEW )
Global zrot.f ;Z Rotation ( NEW )

Global Dim texture.l(1) ;Storage For One Texture ( NEW )

Declare.l WndProc(hWnd.l,uMsg.l,wParam.l,lParam.l) ;Declaration For WndProc

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/NeHe.bmp")
 If *TextureImage(0)
  Status=#True ;Set The Status To TRUE
  
  glGenTextures_(1,@texture(0)) ;Create The Texture
  
  ;Typical Texture Generation Using Data From The Bitmap
  glBindTexture_(#GL_TEXTURE_2D,texture(0))
  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,*TextureImage(0)\sizeX,*TextureImage(0)\sizeY,0,#GL_RGB,#GL_UNSIGNED_BYTE,*TextureImage(0)\Data)
 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

Procedure ReSizeGLScene(width.l,height.l) ;Resize And Initialize The GL Window
 
 If height=0 : height=1 : EndIf ;Prevent A Divide By Zero Error
 
 glViewport_(0,0,width,height) ;Reset The Current Viewport
 
 glMatrixMode_(#GL_PROJECTION) ;Select The Projection Matrix
 glLoadIdentity_() ;Reset The Projection Matrix
 
 gluPerspective(45.0,Abs(width/height),0.1,100.0) ;Calculate The Aspect Ratio Of The Window
 
 glMatrixMode_(#GL_MODELVIEW) ;Select The Modelview Matrix
 glLoadIdentity_() ;Reset The Modelview Matrix
 
EndProcedure

Procedure.l InitGL() ;All Setup For OpenGL Goes Here

 If LoadGLTextures()=0 ;Jump To Texture Loading Routine
  ProcedureReturn #False ;If Texture Didn't Load Return FALSE
 EndIf
 
 glEnable_(#GL_TEXTURE_2D) ;Enable Texture Mapping ( NEW )
 glShadeModel_(#GL_SMOOTH) ;Enable Smooth Shading
 glClearColor_(0.0,0.0,0.0,0.5) ;Black Background
 glClearDepth(1.0) ;Depth Buffer Setup
 glEnable_(#GL_DEPTH_TEST) ;Enables Depth Testing
 glDepthFunc_(#GL_LEQUAL) ;The Type Of Depth Testing To Do
 glHint_(#GL_PERSPECTIVE_CORRECTION_HINT,#GL_NICEST) ;Really Nice Perspective Calculations  
 
 ProcedureReturn #True ;Initialization Went OK
 
EndProcedure

Procedure.l DrawGLScene() ;Here's Where We Do All The Drawing

 glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT) ;Clear Screen And Depth Buffer
 glLoadIdentity_() ;Reset The Current Matrix
 
 glTranslatef_(0.0,0.0,-5.0) ;Move Into The Screen 5 Units
 
 glRotatef_(xrot,1.0,0.0,0.0) ;Rotate On The X Axis
 glRotatef_(yrot,0.0,1.0,0.0) ;Rotate On The Y Axis
 glRotatef_(zrot,0.0,0.0,1.0) ;Rotate On The Z Axis
 
 glBindTexture_(#GL_TEXTURE_2D,texture(0)) ;Select Our Texture
 
 glBegin_(#GL_QUADS)
  ;Front Face
  glTexCoord2f_(0.0, 0.0) : glVertex3f_(-1.0,-1.0, 1.0) ;Bottom Left Of The Texture and Quad
  glTexCoord2f_(1.0, 0.0) : glVertex3f_( 1.0,-1.0, 1.0) ;Bottom Right Of The Texture and Quad
  glTexCoord2f_(1.0, 1.0) : glVertex3f_( 1.0, 1.0, 1.0) ;Top Right Of The Texture and Quad
  glTexCoord2f_(0.0, 1.0) : glVertex3f_(-1.0, 1.0, 1.0) ;Top Left Of The Texture and Quad
  ;Back Face
  glTexCoord2f_(1.0, 0.0) : glVertex3f_(-1.0,-1.0,-1.0) ;Bottom Right Of The Texture and Quad
  glTexCoord2f_(1.0, 1.0) : glVertex3f_(-1.0, 1.0,-1.0) ;Top Right Of The Texture and Quad
  glTexCoord2f_(0.0, 1.0) : glVertex3f_( 1.0, 1.0,-1.0) ;Top Left Of The Texture and Quad
  glTexCoord2f_(0.0, 0.0) : glVertex3f_( 1.0,-1.0,-1.0) ;Bottom Left Of The Texture and Quad
  ;Top Face
  glTexCoord2f_(0.0, 1.0) : glVertex3f_(-1.0, 1.0,-1.0) ;Top Left Of The Texture and Quad
  glTexCoord2f_(0.0, 0.0) : glVertex3f_(-1.0, 1.0, 1.0) ;Bottom Left Of The Texture and Quad
  glTexCoord2f_(1.0, 0.0) : glVertex3f_( 1.0, 1.0, 1.0) ;Bottom Right Of The Texture and Quad
  glTexCoord2f_(1.0, 1.0) : glVertex3f_( 1.0, 1.0,-1.0) ;Top Right Of The Texture and Quad
  ;Bottom Face
  glTexCoord2f_(1.0, 1.0) : glVertex3f_(-1.0,-1.0,-1.0) ;Top Right Of The Texture and Quad
  glTexCoord2f_(0.0, 1.0) : glVertex3f_( 1.0,-1.0,-1.0) ;Top Left Of The Texture and Quad
  glTexCoord2f_(0.0, 0.0) : glVertex3f_( 1.0,-1.0, 1.0) ;Bottom Left Of The Texture and Quad
  glTexCoord2f_(1.0, 0.0) : glVertex3f_(-1.0,-1.0, 1.0) ;Bottom Right Of The Texture and Quad
  ;Right face
  glTexCoord2f_(1.0, 0.0) : glVertex3f_( 1.0,-1.0,-1.0) ;Bottom Right Of The Texture and Quad
  glTexCoord2f_(1.0, 1.0) : glVertex3f_( 1.0, 1.0,-1.0) ;Top Right Of The Texture and Quad
  glTexCoord2f_(0.0, 1.0) : glVertex3f_( 1.0, 1.0, 1.0) ;Top Left Of The Texture and Quad
  glTexCoord2f_(0.0, 0.0) : glVertex3f_( 1.0,-1.0, 1.0) ;Bottom Left Of The Texture and Quad
  ;Left Face
  glTexCoord2f_(0.0, 0.0) : glVertex3f_(-1.0,-1.0,-1.0) ;Bottom Left Of The Texture and Quad
  glTexCoord2f_(1.0, 0.0) : glVertex3f_(-1.0,-1.0, 1.0) ;Bottom Right Of The Texture and Quad
  glTexCoord2f_(1.0, 1.0) : glVertex3f_(-1.0, 1.0, 1.0) ;Top Right Of The Texture and Quad
  glTexCoord2f_(0.0, 1.0) : glVertex3f_(-1.0, 1.0,-1.0) ;Top Left Of The Texture and Quad
 glEnd_()
 
 xrot+0.3 ;X Axis Rotation
 yrot+0.2 ;Y Axis Rotation
 zrot+0.4 ;Z Axis Rotation
 
 ProcedureReturn #True ;Keep Going
 
EndProcedure

Procedure KillGLWindow() ;Properly Kill The Window

 If fullscreen ;Are We In Fullscreen Mode?
  ChangeDisplaySettings_(#Null,0) ;If So Switch Back To The Desktop
  ShowCursor_(#True) ;Show Mouse Pointer
 EndIf
 
 If hRC ;Do We Have A Rendering Context?
  If wglMakeCurrent_(#Null,#Null)=0 ;Are We Able To Release The DC And RC Contexts?
   MessageBox_(#Null,"Release Of DC And RC Failed.","SHUTDOWN ERROR",#MB_OK | #MB_ICONINFORMATION)
  EndIf
  If wglDeleteContext_(hRC)=0 ;Are We Able To Delete The RC?
   MessageBox_(#Null,"Release Rendering Context Failed.","SHUTDOWN ERROR",#MB_OK | #MB_ICONINFORMATION)
  EndIf
  hRC=#Null ;Set RC To NULL
 EndIf
 
 If hDC And ReleaseDC_(hWnd,hDC)=0 ;Are We Able To Release The DC
  MessageBox_(#Null,"Release Device Context Failed.","SHUTDOWN ERROR",#MB_OK | #MB_ICONINFORMATION)
  hDC=#Null ;Set DC To NULL
 EndIf
 
 If hWnd And DestroyWindow_(hWnd)=0 ;Are We Able To Destroy The Window?
   MessageBox_(#Null,"Could Not Release hWnd.","SHUTDOWN ERROR",#MB_OK | #MB_ICONINFORMATION)
   hWnd=#Null ;Set hWnd To NULL
 EndIf
 
 If UnregisterClass_("OpenGL",hInstance)=0 ;Are We Able To Unregister Class
  MessageBox_(#Null,"Could Not Unregister Class.","SHUTDOWN ERROR",#MB_OK | #MB_ICONINFORMATION)
  hInstance=#Null ;Set hInstance To NULL
 EndIf
 
EndProcedure

;This Code Creates Our OpenGL Window. Parameters Are:
;title - Title To Appear At The Top Of The Window
;width - Width Of The GL Window Or Fullscreen Mode
;height - Height Of The GL Window Or Fullscreen Mode
;bits - Number Of Bits To Use For Color (8/16/24/32)
;fullscreenflag - Use Fullscreen Mode (TRUE) Or Windowed Mode (FALSE)

Procedure.b CreateGLWindow(title.s,width.l,height.l,bits.l,fullscreenflag.b)

 Protected PixelFormat.l ;Holds The Results After Searching For A Match
 Protected wc.WNDCLASS ;Windows Class Structure
 Protected dwExStyle.l ;Window Extended Style
 Protected dwStyle.l ;Window Style
 Protected WindowRect.RECT ;Grabs Rectangle Upper Left / Lower Right Values
 Protected wpos.POINT ;Window position
 
 WindowRect\left=0 ;Set Left Value To 0
 WindowRect\right=width ;Set Right Value To Requested Width
 WindowRect\top=0 ;Set Top Value To 0
 WindowRect\bottom=height ;Set Bottom Value To Requested Height
 
 fullscreen=fullscreenflag ;Set The Global Fullscreen Flag
 
 hInstance=GetModuleHandle_(#Null) ;Grab An Instance For Our Window
 
 wc\style=#CS_HREDRAW | #CS_VREDRAW | #CS_OWNDC ;Redraw On Size, And Own DC For Window
 wc\lpfnWndProc=@WndProc() ;WndProc Handles Messages
 wc\cbClsExtra=0 ;No Extra Window Data
 wc\cbWndExtra=0 ;No Extra Window Data
 wc\hInstance=hInstance ;Set The Instance
 wc\hIcon=LoadIcon_(#Null,#IDI_WINLOGO) ;Load The Default Icon
 wc\hCursor=LoadCursor_(#Null,#IDC_ARROW) ;Load The Arrow Pointer
 wc\hbrBackground=#Null ;No Background Required For GL
 wc\lpszMenuName=#Null ;We Don't Want A Menu
 wc\lpszClassName=@"OpenGL" ;Set The Class Name  
 
 If RegisterClass_(wc)=0 ;Attempt To Register The Window Class
  MessageBox_(#Null,"Failed To Register The Window Class.","ERROR",#MB_OK | #MB_ICONEXCLAMATION)
  ProcedureReturn #False
 EndIf
 
 If fullscreen ;Attempt Fullscreen Mode?
 
  Protected dmScreenSettings.DEVMODE ;Device Mode
  dmScreenSettings\dmSize=SizeOf(DEVMODE) ;Size Of The Devmode Structure
  dmScreenSettings\dmFields=#DM_BITSPERPEL | #DM_PELSWIDTH | #DM_PELSHEIGHT ;bit flags to specify the members of DEVMODE that were initialized
  dmScreenSettings\dmBitsPerPel=bits ;Selected Bits Per Pixel
  dmScreenSettings\dmPelsWidth=width ;Selected Screen Width in pixels
  dmScreenSettings\dmPelsHeight=height ;Selected Screen Height in pixels
  
  ;Try To Set Selected Mode And Get Results. Note: CDS_FULLSCREEN Gets Rid Of Start Bar
  If ChangeDisplaySettings_(dmScreenSettings,#CDS_FULLSCREEN)<>#DISP_CHANGE_SUCCESSFUL
   ;If The Mode Fails, Offer Two Options. Quit Or Use Windowed Mode
   If MessageBox_(#Null,"The Requested Fullscreen Mode Is Not Supported By"+Chr(10)+"Your Video Card. Use Windowed Mode Instead?","NeHe GL",#MB_YESNO | #MB_ICONEXCLAMATION)=#IDYES
    fullscreen=#False ;Windowed Mode Selected.  Fullscreen = FALSE
   Else
    ;Pop Up A Message Box Letting User Know The Program Is Closing
    MessageBox_(#Null,"Program Will Now Close.","ERROR",#MB_OK | #MB_ICONSTOP)
    ProcedureReturn #False
   EndIf
  EndIf
  
 EndIf
 
 If fullscreen ;Are We Still In Fullscreen Mode?
  dwExStyle=#WS_EX_APPWINDOW ;Window Extended Style
  dwStyle=#WS_POPUP ;Windows Style
  ShowCursor_(#False) ;Hide Mouse Pointer
 Else
  dwExStyle=#WS_EX_APPWINDOW | #WS_EX_WINDOWEDGE ;Window Extended Style
  dwStyle=#WS_OVERLAPPEDWINDOW ;Windows Style
 EndIf
 
 AdjustWindowRectEx_(WindowRect,dwStyle,#False,dwExStyle) ;Adjust Window To True Requested Size
 
 If fullscreen=0 ;if not fullscreen mode calculate screen centered window
  wpos\x=(GetSystemMetrics_(#SM_CXSCREEN)/2)-((WindowRect\right-WindowRect\left)/2)
  wpos\y=(GetSystemMetrics_(#SM_CYSCREEN)/2)-((WindowRect\bottom-WindowRect\top)/2)
 EndIf
 
 ;CreateWindowEx_(Extended Window Style, Class Name, Window Title, Window Style, Window X Position, Window Y Position, Width, Height, No Parent Window, No Menu, Instance, No Creation Data)
 hWnd=CreateWindowEx_(dwExStyle,"OpenGL",title,dwStyle | #WS_CLIPSIBLINGS | #WS_CLIPCHILDREN,wpos\x,wpos\y,WindowRect\right-WindowRect\left,WindowRect\bottom-WindowRect\top,#Null,#Null,hInstance,#Null)
 If hWnd=0
  KillGLWindow() ;Reset The Display
  MessageBox_(#Null,"Window Creation Error.","ERROR",#MB_OK | #MB_ICONEXCLAMATION)
  ProcedureReturn #False
 EndIf
 
 Protected pfd.PIXELFORMATDESCRIPTOR ;pfd Tells Windows How We Want Things To Be
 pfd\nSize=SizeOf(PIXELFORMATDESCRIPTOR) ;Size Of This Structure
 pfd\nVersion=1 ;Version Number
 pfd\dwFlags=#PFD_SUPPORT_OPENGL | #PFD_DOUBLEBUFFER | #PFD_DRAW_TO_WINDOW ;Format Must Support Window, OpenGL, Double Buffering
 pfd\iPixelType=#PFD_TYPE_RGBA ;Request An RGBA Format
 pfd\cColorBits=bits ;Select Our Color Depth
 pfd\cRedBits=0 ;Color Bits Ignored
 pfd\cRedShift=0
 pfd\cGreenBits=0
 pfd\cGreenShift=0
 pfd\cBlueBits=0
 pfd\cBlueShift=0
 pfd\cAlphaBits=0 ;No Alpha Buffer
 pfd\cAlphaShift=0 ;Shift Bit Ignored
 pfd\cAccumBits=0 ;No Accumulation Buffer
 pfd\cAccumRedBits=0 ;Accumulation Bits Ignored
 pfd\cAccumGreenBits=0
 pfd\cAccumBlueBits=0
 pfd\cAccumAlphaBits=0
 pfd\cDepthBits=16 ;16Bit Z-Buffer (Depth Buffer)
 pfd\cStencilBits=0 ;No Stencil Buffer
 pfd\cAuxBuffers=0 ;No Auxiliary Buffer
 pfd\iLayerType=#PFD_MAIN_PLANE ;Main Drawing Layer
 pfd\bReserved=0 ;Reserved
 pfd\dwLayerMask=0 ;Layer Masks Ignored
 pfd\dwVisibleMask=0
 pfd\dwDamageMask=0
 
 hDC=GetDC_(hWnd)
 If hDC=0 ;Did We Get A Device Context?
  KillGLWindow() ;Reset The Display
  MessageBox_(#Null,"Can't Create A GL Device Context.","ERROR",#MB_OK | #MB_ICONEXCLAMATION)
  ProcedureReturn #False
 EndIf
 
 PixelFormat=ChoosePixelFormat_(hDC,pfd)
 If PixelFormat=0 ;Did Windows Find A Matching Pixel Format?
  KillGLWindow() ;Reset The Display
  MessageBox_(#Null,"Can't Find A Suitable PixelFormat.","ERROR",#MB_OK | #MB_ICONEXCLAMATION)
  ProcedureReturn #False
 EndIf
 
 If SetPixelFormat_(hDC,PixelFormat,pfd)=0 ;Are We Able To Set The Pixel Format?
  KillGLWindow() ;Reset The Display
  MessageBox_(#Null,"Can't Set The PixelFormat.","ERROR",#MB_OK | #MB_ICONEXCLAMATION)
  ProcedureReturn #False
 EndIf
 
 hRC=wglCreateContext_(hDC)
 If hRC=0 ;Are We Able To Get A Rendering Context?
  KillGLWindow() ;Reset The Display
  MessageBox_(#Null,"Can't Create A GL Rendering Context.","ERROR",#MB_OK | #MB_ICONEXCLAMATION)
  ProcedureReturn #False
 EndIf
 
 If wglMakeCurrent_(hDC,hRC)=0 ;Try To Activate The Rendering Context
  KillGLWindow() ;Reset The Display
  MessageBox_(#Null,"Can't Activate The GL Rendering Context.","ERROR",#MB_OK | #MB_ICONEXCLAMATION)
  ProcedureReturn #False
 EndIf
 
 ShowWindow_(hWnd,#SW_SHOW) ;Show The Window
 SetForegroundWindow_(hWnd) ;Slightly Higher Priority
 SetFocus_(hWnd) ;Sets Keyboard Focus To The Window
 ReSizeGLScene(width,height) ;Set Up Our Perspective GL Screen
 
 If InitGL()=0 ;Initialize Our Newly Created GL Window
  KillGLWindow() ;Reset The Display
  MessageBox_(#Null,"Initialization Failed.","ERROR",#MB_OK | #MB_ICONEXCLAMATION)
  ProcedureReturn #False
 EndIf
 
 ProcedureReturn #True ;Success
 
EndProcedure

Procedure.l WndProc(hWnd.l,uMsg.l,wParam.l,lParam.l)

 Select uMsg ;Check For Windows Messages
 
  Case #WM_ACTIVATE ;Watch For Window Activate Message
   If HiWord(wParam)=0 ;Check Minimization State
    active=#True ;Program Is Active
   Else
    active=#False ;Program Is No Longer Active
   EndIf
   ProcedureReturn 0 ;Return To The Message Loop
   
  Case #WM_SYSCOMMAND ;Intercept System Commands
   Select wParam ;Check System Calls
    Case #SC_SCREENSAVE ;Screensaver Trying To Start?
     ProcedureReturn 0 ;Prevent From Happening
    Case #SC_MONITORPOWER ;Monitor Trying To Enter Powersave?
     ProcedureReturn 0 ;Prevent From Happening
   EndSelect
   
  Case #WM_CLOSE ;Did We Receive A Close Message?
   PostQuitMessage_(0) ;Send A Quit Message 
   ProcedureReturn 0 ;Jump Back
   
  Case #WM_KEYDOWN ;Is A Key Being Held Down?
   keys(wParam)=#True ;If So, Mark It As TRUE
   ProcedureReturn 0 ;Jump Back
   
  Case #WM_KEYUP ;Has A Key Been Released?
   keys(wParam)=#False ;If So, Mark It As FALSE
   ProcedureReturn 0 ;Jump Back
   
  Case #WM_SIZE ;Resize The OpenGL Window
   ReSizeGLScene(LoWord(lParam),HiWord(lParam)) ;LoWord=Width, HiWord=Height
   ProcedureReturn 0 ;Jump Back
   
 EndSelect
 
 ;Pass All Unhandled Messages To DefWindowProc
 ProcedureReturn DefWindowProc_(hWnd,uMsg,wParam,lParam)
 
EndProcedure

Procedure.l WinMain() ;Main Program

 Protected msg.MSG ;Windows Message Structure
 Protected done.b ;Bool Variable To Exit Loop
 
 ;Ask The User Which Screen Mode They Prefer
 If MessageBox_(#Null,"Would You Like To Run In Fullscreen Mode?","Start FullScreen?",#MB_YESNO | #MB_ICONQUESTION)=#IDNO
  fullscreen=#False ;Windowed Mode
 EndIf
 
 If CreateGLWindow("NeHe's Texture Mapping Tutorial",640,480,16,fullscreen)=0 ;Create The Window
  ProcedureReturn 0 ;Quit If Window Was Not Created
 EndIf
 
 While done=#False ;Loop That Runs While done=FALSE
 
  If PeekMessage_(msg,#Null,0,0,#PM_REMOVE) ;Is There A Message Waiting?
  
   If msg\message=#WM_QUIT ;Have We Received A Quit Message?
    done=#True ;If So done=TRUE
   Else ;If Not, Deal With Window Messages
    TranslateMessage_(msg) ;Translate The Message
    DispatchMessage_(msg) ;Dispatch The Message
   EndIf
   
  Else ;If There Are No Messages
  
   ;Draw The Scene. Watch For ESC Key And Quit Messages From DrawGLScene()
   If (active And DrawGLScene()=0) Or keys(#VK_ESCAPE) ;Active? Was There A Quit Received?
    done=#True ;ESC or DrawGLScene Signalled A Quit
   Else ;Not Time To Quit, Update Screen
    SwapBuffers_(hDC) ;Swap Buffers (Double Buffering)
   EndIf
   
   If keys(#VK_F1) ;Is F1 Being Pressed?
    keys(#VK_F1)=#False ;If So Make Key FALSE
    KillGLWindow() ;Kill Our Current Window
    fullscreen=~fullscreen & 1 ;Toggle Fullscreen / Windowed Mode
    ;Recreate Our OpenGL Window
    If CreateGLWindow("NeHe's Texture Mapping Tutorial",640,480,16,fullscreen)=0
     ProcedureReturn 0 ;Quit If Window Was Not Created
    EndIf
   EndIf
   
  EndIf
  
 Wend
 
 ;Shutdown
 KillGLWindow() ;Kill The Window
 End ;Exit The Program
 
EndProcedure

WinMain() ;run the main program


odd error with lesson 6

Posted: Sun Jun 24, 2007 12:54 am
by GBeebe
this is what i get when trying to run lesson06.pb (downloaded the zip and extracted it with the Data directory)

[ERROR] OpenGL.pbi (Line: 1127)
[ERROR] Invalid memory access

And the PB editor opens up OpenGL.pbi and, sets what i think is a break boint, highlights line 1127 which is blank. I remove that line and get the error on line 1126 and so on. If i replace:

XIncludeFile "OpenGL.pbi" ;include the gl.h constants

In lesson06.pb with the contents of OpenGL.pbi, I get the invalid memory access error on line 1 of lesson06.pb.

Lessons 1 to 5, which include OpenGL.pbi, work just fine. Lesson07 has this same error too.

Has anyone else experienced this? Does anyone have an idea of what i could be doing wrong? or could this be a glitch in my computer only?

Posted: Mon Jun 25, 2007 3:27 am
by hagibaba
Hi GBeebe,

I think this is the same issue Dare mentioned in another thread. He says it works with debugger off so try that.

The problem is, I think, to do with using glaux.lib to load the textures. Glaux is used as a quick way to just get the job done but it shouldn't be used really. I did it like that because I wanted direct translations. The correct way is to load a DIB in memory and use that.

This is an example of Lesson 6 without using Glaux. I removed the AUX_RGBImageRec struct, glaux.lib symbols and Import "glaux.lib", then replaced LoadBMP() with one returning a DIB in memory, and finally modified LoadGLTextures() to take the DIB into account, which also requires to use the #GL_BGR_EXT flag in glTexImage2D_() instead of #GL_RGB. Also, note that freeing the DIB is different to freeing a Glaux bitmap.

Code: Select all

;NeHe's Texture Mapping Tutorial (Lesson 6)
;http://nehe.gamedev.net
;Credits: Nico Gruener, Dreglor, traumatic
;Author: hagibaba
;Date: 5 Jan 2007
;Note: up-to-date with PB v4.02 (Windows)
;Note: requires a bitmap in path "Data/NeHe.bmp"

;Section for standard constants, structures, macros and declarations

XIncludeFile "OpenGL.pbi" ;include the gl.h constants

;wingdi.h constants
#DM_BITSPERPEL=$40000
#DM_PELSWIDTH=$80000
#DM_PELSHEIGHT=$100000

;winuser.h constants
#CDS_FULLSCREEN=4
#DISP_CHANGE_SUCCESSFUL=0
#SC_MONITORPOWER=$F170

Procedure.w LoWord(value.l) ;windef.h macro
 ProcedureReturn (value & $FFFF)
EndProcedure

Procedure.w HiWord(value.l) ;windef.h macro
 ProcedureReturn ((value >> 16) & $FFFF)
EndProcedure

Import "glu32.lib"
 gluPerspective(fovy.d,aspect.d,zNear.d,zFar.d) ;sets up a perspective projection matrix
EndImport

Import "opengl32.lib"
 glClearDepth(depth.d) ;specifies the clear value for the depth buffer
EndImport

;Start of Lesson 6

Global hDC.l ;Private GDI Device Context
Global hRC.l ;Permanent Rendering Context
Global hWnd.l ;Holds Our Window Handle
Global hInstance.l ;Holds The Instance Of The Application

Global Dim keys.b(256) ;Array Used For The Keyboard Routine
Global active.b=#True ;Window Active Flag Set To TRUE By Default
Global fullscreen.b=#True ;Fullscreen Flag Set To Fullscreen Mode By Default

Global xrot.f ;X Rotation ( NEW )
Global yrot.f ;Y Rotation ( NEW )
Global zrot.f ;Z Rotation ( NEW )

Global Dim texture.l(1) ;Storage For One Texture ( NEW )

Declare.l WndProc(hWnd.l,uMsg.l,wParam.l,lParam.l) ;Declaration For WndProc

Procedure.l LoadBMP(filename.s)
 ;From FreeImage source "PluginBMP.cpp"
 ;Loads Windows, OS/2 1.x and OS/2 2.x Bitmap files
 
 Protected bfh.BITMAPFILEHEADER
 Protected bih.BITMAPINFOHEADER
 Protected *pal.RGBQUAD
 Protected file.l,bhsize.l,width.l,height.l,bitcount.l
 Protected compression.l,pitch.l,ncolors.l,hDIB.l,id.l,count.l
 Protected sline.l,statusbyte.l,secondbyte.l,ix.l,iy.l
 Protected lownibble.l,deltax.l,deltay.l,align.l
 
 ;Open file
 file=ReadFile(#PB_Any,filename)
 If file=0
  MessageRequester("LOAD ERROR","File could not be opened")
  ProcedureReturn #False
 EndIf
 
 ;Read the file header
 ReadData(file,bfh,SizeOf(BITMAPFILEHEADER))
 
 ;Read the info header
 bhsize=ReadLong(file) ;Get the header size, can vary in OS/2 2.x
 FileSeek(file,SizeOf(BITMAPFILEHEADER)) ;Seek to the info header
 If bhsize=SizeOf(BITMAPCOREHEADER) ;Bitmap is OS/2 1.x
  bih\biSize=ReadLong(file) ;bcSize
  bih\biWidth=ReadWord(file) ;bcWidth
  bih\biHeight=ReadWord(file) ;bcHeight
  bih\biPlanes=ReadWord(file) ;bcPlanes
  bih\biBitCount=ReadWord(file) ;bcBitCount
 ElseIf bhsize>SizeOf(BITMAPINFOHEADER) ;Bitmap is OS/2 2.x
  ReadData(file,bih,SizeOf(BITMAPINFOHEADER))
 Else ;Bitmap is Windows or OS/2 2.x
  ReadData(file,bih,bhsize)
 EndIf
 
 ;Calculate some information
 width=bih\biWidth
 height=Abs(bih\biHeight) ;Ignore top-down bitmaps
 bitcount=bih\biBitCount
 compression=bih\biCompression
 pitch=(((width*bitcount)+31)/32)*4 ;DWORD-aligned width
 ncolors=bih\biClrUsed
 If bitcount<16 ;1/4/8-bit, calculate ncolors if needed
  If ncolors<=0 Or ncolors>1 << bitcount
   ncolors=1 << bitcount ;2/16/256 colors
  EndIf
 Else ;16/24/32
  If ncolors=0 And compression=#BI_bitfields
   ncolors=3
  EndIf
 EndIf
 bhsize=SizeOf(BITMAPINFOHEADER) ;DIB info header size
 
 ;Allocate enough memory to hold the bitmap
 hDIB=AllocateMemory(bhsize+(ncolors*4)+(pitch*height))
 If hDIB=0
  CloseFile(file)
  MessageRequester("LOAD ERROR","Memory allocation failed")
  ProcedureReturn #False
 EndIf
 
 ;Seek to the palette
 FileSeek(file,SizeOf(BITMAPFILEHEADER)+bih\biSize)
 
 ;Read the palette
 id=bfh\bfOffBits-SizeOf(BITMAPFILEHEADER)-bih\biSize ;Palette size
 If id=ncolors*4 ;Palette uses RGBQUAD
  ReadData(file,hDIB+bhsize,ncolors*4)
 Else ;Palette uses RGBTRIPLE
  *pal=hDIB+bhsize ;Pointer to DIB palette
  For count=0 To ncolors-1
   *pal\rgbBlue=ReadByte(file) ;blue
   *pal\rgbGreen=ReadByte(file) ;green
   *pal\rgbRed=ReadByte(file) ;red
   *pal+4
  Next
 EndIf
 
 ;Copy the info header to the DIB
 bih\biSize=SizeOf(BITMAPINFOHEADER) ;Set biSize to 40 now
 If compression=#BI_RLE4 Or compression=#BI_RLE8
  bih\biCompression=0 ;Reset this if we're decoding a RLE bitmap
 EndIf
 bih\biSizeImage=pitch*height
 bih\biClrUsed=ncolors
 CopyMemory(bih,hDIB,SizeOf(BITMAPINFOHEADER))
 
 ;Seek to the pixel data, this is needed because sometimes
 ;the palette is larger than the entries it contains predicts
 If bfh\bfOffBits>0
  FileSeek(file,bfh\bfOffBits)
 EndIf
 
 Select bitcount
 
  Case 1,4,8 ;1/4/8-bit bmp
  
   ;Read the pixel data
   Select compression
   
    Case #BI_RGB ;No compression
    
     ;Read the bitmap bits, bottom-up bitmaps only
     ReadData(file,hDIB+bhsize+(ncolors*4),height*pitch)
     
    Case #BI_RLE4 ;4-bit RLE
    
     sline=hDIB+bhsize+(ncolors*4)+(iy*pitch) ;Get scanline
     ix=0
     iy=0
     lownibble=0 ;Reset
     
     While iy<height ;Ignore multiple bitmaps in OS/2 2.x
     
      statusbyte=ReadByte(file) & 255
      
      Select statusbyte ;First byte
      
       Case 0 ;RLE_COMMAND=0, first byte is 0
       
        statusbyte=ReadByte(file) & 255
        
        Select statusbyte ;Second byte, Encoded mode=0/0..2
        
         Case 0 ;RLE_ENDOFLINE=0
          ix=0
          iy+1
          If iy>=height : Break : EndIf
          sline=hDIB+bhsize+(ncolors*4)+(iy*pitch) ;Get scanline
          lownibble=0 ;Reset
          
         Case 1 ;RLE_ENDOFBITMAP=1
          Break
          
         Case 2 ;RLE_DELTA=2
          deltax=ReadByte(file) & 255 ;Read the delta values
          deltay=ReadByte(file) & 255
          ix+(deltax/2) ;Apply them
          iy+deltay
          If iy>=height : Break : EndIf
          sline=hDIB+bhsize+(ncolors*4)+(iy*pitch) ;Get scanline
          
         Default ;Absolute mode=0/3..255
          
          count=0 ;Get high nibble first
          
          For id=0 To statusbyte-1 ;Read non-RLE pixels
           If count=0
            secondbyte=ReadByte(file) & 255
            align=(secondbyte & 240) >> 4
           Else
            align=secondbyte & 15
           EndIf
           If lownibble=0 ;Set high nibble
            PokeB(sline+ix,(PeekB(sline+ix) & 255) | (align << 4))
           Else ;Set low nibble
            PokeB(sline+ix,(PeekB(sline+ix) & 255) | align)
            ix+1
           EndIf
           count=~count & 1
           lownibble=~lownibble & 1
          Next
          
          align=statusbyte % 4 ;Align run to even number of bytes
          If align=1 Or align=2
           secondbyte=ReadByte(file) & 255
          EndIf
          
        EndSelect
        
       Default ;Standard RLE mode, first byte is not 0
       
        secondbyte=ReadByte(file) & 255
        count=0 ;Get high nibble first
        
        For id=0 To statusbyte-1 ;Read RLE pixels
         If count=0
          align=(secondbyte & 240) >> 4
         Else
          align=secondbyte & 15
         EndIf
         If lownibble=0 ;Set high nibble
          PokeB(sline+ix,(PeekB(sline+ix) & 255) | (align << 4))
         Else ;Set low nibble
          PokeB(sline+ix,(PeekB(sline+ix) & 255) | align)
          ix+1
         EndIf
         count=~count & 1
         lownibble=~lownibble & 1
        Next
        
      EndSelect
      
     Wend
     
    Case #BI_RLE8 ;8-bit RLE
    
     sline=hDIB+bhsize+(ncolors*4)+(iy*pitch) ;Get scanline
     ix=0
     iy=0 ;Reset
     
     While iy<height ;Ignore multiple bitmaps in OS/2 2.x
     
      statusbyte=ReadByte(file) & 255
      
      Select statusbyte ;First byte
      
       Case 0 ;RLE_COMMAND=0, first byte is 0
       
        statusbyte=ReadByte(file) & 255
        
        Select statusbyte ;Second byte, Encoded mode=0/0..2
        
         Case 0 ;RLE_ENDOFLINE=0
          ix=0
          iy+1
          If iy>=height : Break : EndIf
          sline=hDIB+bhsize+(ncolors*4)+(iy*pitch) ;Get scanline
          
         Case 1 ;RLE_ENDOFBITMAP=1
          Break
          
         Case 2 ;RLE_DELTA=2
          deltax=ReadByte(file) & 255 ;Read the delta values
          deltay=ReadByte(file) & 255
          ix+deltax ;Apply them
          iy+deltay
          If iy>=height : Break : EndIf
          sline=hDIB+bhsize+(ncolors*4)+(iy*pitch) ;Get scanline
          
         Default ;Absolute mode=0/3..255
         
          If statusbyte<width-ix ;Make sure run is not too long
           count=statusbyte
          Else
           count=width-ix
          EndIf
          
          For id=0 To count-1 ;Read non-RLE pixels
           secondbyte=ReadByte(file) & 255
           PokeB(sline+ix,secondbyte)
           ix+1
          Next
          
          If statusbyte & 1=1 ;Align run to even number of bytes
           secondbyte=ReadByte(file) & 255
          EndIf
          
        EndSelect
        
       Default ;Standard RLE mode, first byte is not 0
       
        secondbyte=ReadByte(file) & 255
        
        If statusbyte<width-ix ;Make sure run is not too long
         count=statusbyte
        Else
         count=width-ix
        EndIf
        
        For id=0 To count-1 ;Read RLE pixels
         PokeB(sline+ix,secondbyte)
         ix+1
        Next
        
      EndSelect
      
     Wend
     
    Default ;Not BI_RGB=0, BI_RLE4=1 or BI_RLE8=2
    
     CloseFile(file)
     FreeMemory(hDIB)
     MessageRequester("LOAD ERROR","Compression type not supported")
     ProcedureReturn #False
     
   EndSelect
   
  Case 16,24,32 ;16/24/32-bit bmp
  
   ;Read the bitmap bits
   ReadData(file,hDIB+bhsize+(ncolors*4),height*pitch)
   
 EndSelect
 
 CloseFile(file) ;Close the file
 ProcedureReturn hDIB
 
EndProcedure

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

 Protected Status.l=#False ;Status Indicator
 Protected Dim *hBMP.BITMAPINFOHEADER(1) ;Storage Space For Texture
 Protected bits.l
 
 ;Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit
 *hBMP(0)=LoadBMP("Data/NeHe.bmp")
 
 If *hBMP(0)
  Status=#True ;Set The Status To TRUE
  
  glGenTextures_(1,@texture(0)) ;Create The Texture
  
  ;Typical Texture Generation Using Data From The Bitmap
  bits=*hBMP(0)+*hBMP(0)\biSize+(*hBMP(0)\biClrUsed*4) ;Get the bits
  glBindTexture_(#GL_TEXTURE_2D,texture(0))
  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,*hBMP(0)\biWidth,*hBMP(0)\biHeight,0,#GL_BGR_EXT,#GL_UNSIGNED_BYTE,bits)
 EndIf
 
 If *hBMP(0) ;If Texture Exists
  FreeMemory(*hBMP(0)) ;Free The DIB
 EndIf
 
 ProcedureReturn Status ;Return The Status
 
EndProcedure

Procedure ReSizeGLScene(width.l,height.l) ;Resize And Initialize The GL Window
 
 If height=0 : height=1 : EndIf ;Prevent A Divide By Zero Error
 
 glViewport_(0,0,width,height) ;Reset The Current Viewport
 
 glMatrixMode_(#GL_PROJECTION) ;Select The Projection Matrix
 glLoadIdentity_() ;Reset The Projection Matrix
 
 gluPerspective(45.0,Abs(width/height),0.1,100.0) ;Calculate The Aspect Ratio Of The Window
 
 glMatrixMode_(#GL_MODELVIEW) ;Select The Modelview Matrix
 glLoadIdentity_() ;Reset The Modelview Matrix
 
EndProcedure

Procedure.l InitGL() ;All Setup For OpenGL Goes Here

 If LoadGLTextures()=0 ;Jump To Texture Loading Routine
  ProcedureReturn #False ;If Texture Didn't Load Return FALSE
 EndIf
 
 glEnable_(#GL_TEXTURE_2D) ;Enable Texture Mapping ( NEW )
 glShadeModel_(#GL_SMOOTH) ;Enable Smooth Shading
 glClearColor_(0.0,0.0,0.0,0.5) ;Black Background
 glClearDepth(1.0) ;Depth Buffer Setup
 glEnable_(#GL_DEPTH_TEST) ;Enables Depth Testing
 glDepthFunc_(#GL_LEQUAL) ;The Type Of Depth Testing To Do
 glHint_(#GL_PERSPECTIVE_CORRECTION_HINT,#GL_NICEST) ;Really Nice Perspective Calculations  
 
 ProcedureReturn #True ;Initialization Went OK
 
EndProcedure

Procedure.l DrawGLScene() ;Here's Where We Do All The Drawing

 glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT) ;Clear Screen And Depth Buffer
 glLoadIdentity_() ;Reset The Current Matrix
 
 glTranslatef_(0.0,0.0,-5.0) ;Move Into The Screen 5 Units
 
 glRotatef_(xrot,1.0,0.0,0.0) ;Rotate On The X Axis
 glRotatef_(yrot,0.0,1.0,0.0) ;Rotate On The Y Axis
 glRotatef_(zrot,0.0,0.0,1.0) ;Rotate On The Z Axis
 
 glBindTexture_(#GL_TEXTURE_2D,texture(0)) ;Select Our Texture
 
 glBegin_(#GL_QUADS)
  ;Front Face
  glTexCoord2f_(0.0, 0.0) : glVertex3f_(-1.0,-1.0, 1.0) ;Bottom Left Of The Texture and Quad
  glTexCoord2f_(1.0, 0.0) : glVertex3f_( 1.0,-1.0, 1.0) ;Bottom Right Of The Texture and Quad
  glTexCoord2f_(1.0, 1.0) : glVertex3f_( 1.0, 1.0, 1.0) ;Top Right Of The Texture and Quad
  glTexCoord2f_(0.0, 1.0) : glVertex3f_(-1.0, 1.0, 1.0) ;Top Left Of The Texture and Quad
  ;Back Face
  glTexCoord2f_(1.0, 0.0) : glVertex3f_(-1.0,-1.0,-1.0) ;Bottom Right Of The Texture and Quad
  glTexCoord2f_(1.0, 1.0) : glVertex3f_(-1.0, 1.0,-1.0) ;Top Right Of The Texture and Quad
  glTexCoord2f_(0.0, 1.0) : glVertex3f_( 1.0, 1.0,-1.0) ;Top Left Of The Texture and Quad
  glTexCoord2f_(0.0, 0.0) : glVertex3f_( 1.0,-1.0,-1.0) ;Bottom Left Of The Texture and Quad
  ;Top Face
  glTexCoord2f_(0.0, 1.0) : glVertex3f_(-1.0, 1.0,-1.0) ;Top Left Of The Texture and Quad
  glTexCoord2f_(0.0, 0.0) : glVertex3f_(-1.0, 1.0, 1.0) ;Bottom Left Of The Texture and Quad
  glTexCoord2f_(1.0, 0.0) : glVertex3f_( 1.0, 1.0, 1.0) ;Bottom Right Of The Texture and Quad
  glTexCoord2f_(1.0, 1.0) : glVertex3f_( 1.0, 1.0,-1.0) ;Top Right Of The Texture and Quad
  ;Bottom Face
  glTexCoord2f_(1.0, 1.0) : glVertex3f_(-1.0,-1.0,-1.0) ;Top Right Of The Texture and Quad
  glTexCoord2f_(0.0, 1.0) : glVertex3f_( 1.0,-1.0,-1.0) ;Top Left Of The Texture and Quad
  glTexCoord2f_(0.0, 0.0) : glVertex3f_( 1.0,-1.0, 1.0) ;Bottom Left Of The Texture and Quad
  glTexCoord2f_(1.0, 0.0) : glVertex3f_(-1.0,-1.0, 1.0) ;Bottom Right Of The Texture and Quad
  ;Right face
  glTexCoord2f_(1.0, 0.0) : glVertex3f_( 1.0,-1.0,-1.0) ;Bottom Right Of The Texture and Quad
  glTexCoord2f_(1.0, 1.0) : glVertex3f_( 1.0, 1.0,-1.0) ;Top Right Of The Texture and Quad
  glTexCoord2f_(0.0, 1.0) : glVertex3f_( 1.0, 1.0, 1.0) ;Top Left Of The Texture and Quad
  glTexCoord2f_(0.0, 0.0) : glVertex3f_( 1.0,-1.0, 1.0) ;Bottom Left Of The Texture and Quad
  ;Left Face
  glTexCoord2f_(0.0, 0.0) : glVertex3f_(-1.0,-1.0,-1.0) ;Bottom Left Of The Texture and Quad
  glTexCoord2f_(1.0, 0.0) : glVertex3f_(-1.0,-1.0, 1.0) ;Bottom Right Of The Texture and Quad
  glTexCoord2f_(1.0, 1.0) : glVertex3f_(-1.0, 1.0, 1.0) ;Top Right Of The Texture and Quad
  glTexCoord2f_(0.0, 1.0) : glVertex3f_(-1.0, 1.0,-1.0) ;Top Left Of The Texture and Quad
 glEnd_()
 
 xrot+0.3 ;X Axis Rotation
 yrot+0.2 ;Y Axis Rotation
 zrot+0.4 ;Z Axis Rotation
 
 ProcedureReturn #True ;Keep Going
 
EndProcedure

Procedure KillGLWindow() ;Properly Kill The Window

 If fullscreen ;Are We In Fullscreen Mode?
  ChangeDisplaySettings_(#Null,0) ;If So Switch Back To The Desktop
  ShowCursor_(#True) ;Show Mouse Pointer
 EndIf
 
 If hRC ;Do We Have A Rendering Context?
  If wglMakeCurrent_(#Null,#Null)=0 ;Are We Able To Release The DC And RC Contexts?
   MessageBox_(#Null,"Release Of DC And RC Failed.","SHUTDOWN ERROR",#MB_OK | #MB_ICONINFORMATION)
  EndIf
  If wglDeleteContext_(hRC)=0 ;Are We Able To Delete The RC?
   MessageBox_(#Null,"Release Rendering Context Failed.","SHUTDOWN ERROR",#MB_OK | #MB_ICONINFORMATION)
  EndIf
  hRC=#Null ;Set RC To NULL
 EndIf
 
 If hDC And ReleaseDC_(hWnd,hDC)=0 ;Are We Able To Release The DC
  MessageBox_(#Null,"Release Device Context Failed.","SHUTDOWN ERROR",#MB_OK | #MB_ICONINFORMATION)
  hDC=#Null ;Set DC To NULL
 EndIf
 
 If hWnd And DestroyWindow_(hWnd)=0 ;Are We Able To Destroy The Window?
   MessageBox_(#Null,"Could Not Release hWnd.","SHUTDOWN ERROR",#MB_OK | #MB_ICONINFORMATION)
   hWnd=#Null ;Set hWnd To NULL
 EndIf
 
 If UnregisterClass_("OpenGL",hInstance)=0 ;Are We Able To Unregister Class
  MessageBox_(#Null,"Could Not Unregister Class.","SHUTDOWN ERROR",#MB_OK | #MB_ICONINFORMATION)
  hInstance=#Null ;Set hInstance To NULL
 EndIf
 
EndProcedure

;This Code Creates Our OpenGL Window. Parameters Are:
;title - Title To Appear At The Top Of The Window
;width - Width Of The GL Window Or Fullscreen Mode
;height - Height Of The GL Window Or Fullscreen Mode
;bits - Number Of Bits To Use For Color (8/16/24/32)
;fullscreenflag - Use Fullscreen Mode (TRUE) Or Windowed Mode (FALSE)

Procedure.b CreateGLWindow(title.s,width.l,height.l,bits.l,fullscreenflag.b)

 Protected PixelFormat.l ;Holds The Results After Searching For A Match
 Protected wc.WNDCLASS ;Windows Class Structure
 Protected dwExStyle.l ;Window Extended Style
 Protected dwStyle.l ;Window Style
 Protected WindowRect.RECT ;Grabs Rectangle Upper Left / Lower Right Values
 Protected wpos.POINT ;Window position
 
 WindowRect\left=0 ;Set Left Value To 0
 WindowRect\right=width ;Set Right Value To Requested Width
 WindowRect\top=0 ;Set Top Value To 0
 WindowRect\bottom=height ;Set Bottom Value To Requested Height
 
 fullscreen=fullscreenflag ;Set The Global Fullscreen Flag
 
 hInstance=GetModuleHandle_(#Null) ;Grab An Instance For Our Window
 
 wc\style=#CS_HREDRAW | #CS_VREDRAW | #CS_OWNDC ;Redraw On Size, And Own DC For Window
 wc\lpfnWndProc=@WndProc() ;WndProc Handles Messages
 wc\cbClsExtra=0 ;No Extra Window Data
 wc\cbWndExtra=0 ;No Extra Window Data
 wc\hInstance=hInstance ;Set The Instance
 wc\hIcon=LoadIcon_(#Null,#IDI_WINLOGO) ;Load The Default Icon
 wc\hCursor=LoadCursor_(#Null,#IDC_ARROW) ;Load The Arrow Pointer
 wc\hbrBackground=#Null ;No Background Required For GL
 wc\lpszMenuName=#Null ;We Don't Want A Menu
 wc\lpszClassName=@"OpenGL" ;Set The Class Name  
 
 If RegisterClass_(wc)=0 ;Attempt To Register The Window Class
  MessageBox_(#Null,"Failed To Register The Window Class.","ERROR",#MB_OK | #MB_ICONEXCLAMATION)
  ProcedureReturn #False
 EndIf
 
 If fullscreen ;Attempt Fullscreen Mode?
 
  Protected dmScreenSettings.DEVMODE ;Device Mode
  dmScreenSettings\dmSize=SizeOf(DEVMODE) ;Size Of The Devmode Structure
  dmScreenSettings\dmFields=#DM_BITSPERPEL | #DM_PELSWIDTH | #DM_PELSHEIGHT ;bit flags to specify the members of DEVMODE that were initialized
  dmScreenSettings\dmBitsPerPel=bits ;Selected Bits Per Pixel
  dmScreenSettings\dmPelsWidth=width ;Selected Screen Width in pixels
  dmScreenSettings\dmPelsHeight=height ;Selected Screen Height in pixels
  
  ;Try To Set Selected Mode And Get Results. Note: CDS_FULLSCREEN Gets Rid Of Start Bar
  If ChangeDisplaySettings_(dmScreenSettings,#CDS_FULLSCREEN)<>#DISP_CHANGE_SUCCESSFUL
   ;If The Mode Fails, Offer Two Options. Quit Or Use Windowed Mode
   If MessageBox_(#Null,"The Requested Fullscreen Mode Is Not Supported By"+Chr(10)+"Your Video Card. Use Windowed Mode Instead?","NeHe GL",#MB_YESNO | #MB_ICONEXCLAMATION)=#IDYES
    fullscreen=#False ;Windowed Mode Selected.  Fullscreen = FALSE
   Else
    ;Pop Up A Message Box Letting User Know The Program Is Closing
    MessageBox_(#Null,"Program Will Now Close.","ERROR",#MB_OK | #MB_ICONSTOP)
    ProcedureReturn #False
   EndIf
  EndIf
  
 EndIf
 
 If fullscreen ;Are We Still In Fullscreen Mode?
  dwExStyle=#WS_EX_APPWINDOW ;Window Extended Style
  dwStyle=#WS_POPUP ;Windows Style
  ShowCursor_(#False) ;Hide Mouse Pointer
 Else
  dwExStyle=#WS_EX_APPWINDOW | #WS_EX_WINDOWEDGE ;Window Extended Style
  dwStyle=#WS_OVERLAPPEDWINDOW ;Windows Style
 EndIf
 
 AdjustWindowRectEx_(WindowRect,dwStyle,#False,dwExStyle) ;Adjust Window To True Requested Size
 
 If fullscreen=0 ;if not fullscreen mode calculate screen centered window
  wpos\x=(GetSystemMetrics_(#SM_CXSCREEN)/2)-((WindowRect\right-WindowRect\left)/2)
  wpos\y=(GetSystemMetrics_(#SM_CYSCREEN)/2)-((WindowRect\bottom-WindowRect\top)/2)
 EndIf
 
 ;CreateWindowEx_(Extended Window Style, Class Name, Window Title, Window Style, Window X Position, Window Y Position, Width, Height, No Parent Window, No Menu, Instance, No Creation Data)
 hWnd=CreateWindowEx_(dwExStyle,"OpenGL",title,dwStyle | #WS_CLIPSIBLINGS | #WS_CLIPCHILDREN,wpos\x,wpos\y,WindowRect\right-WindowRect\left,WindowRect\bottom-WindowRect\top,#Null,#Null,hInstance,#Null)
 If hWnd=0
  KillGLWindow() ;Reset The Display
  MessageBox_(#Null,"Window Creation Error.","ERROR",#MB_OK | #MB_ICONEXCLAMATION)
  ProcedureReturn #False
 EndIf
 
 Protected pfd.PIXELFORMATDESCRIPTOR ;pfd Tells Windows How We Want Things To Be
 pfd\nSize=SizeOf(PIXELFORMATDESCRIPTOR) ;Size Of This Structure
 pfd\nVersion=1 ;Version Number
 pfd\dwFlags=#PFD_SUPPORT_OPENGL | #PFD_DOUBLEBUFFER | #PFD_DRAW_TO_WINDOW ;Format Must Support Window, OpenGL, Double Buffering
 pfd\iPixelType=#PFD_TYPE_RGBA ;Request An RGBA Format
 pfd\cColorBits=bits ;Select Our Color Depth
 pfd\cRedBits=0 ;Color Bits Ignored
 pfd\cRedShift=0
 pfd\cGreenBits=0
 pfd\cGreenShift=0
 pfd\cBlueBits=0
 pfd\cBlueShift=0
 pfd\cAlphaBits=0 ;No Alpha Buffer
 pfd\cAlphaShift=0 ;Shift Bit Ignored
 pfd\cAccumBits=0 ;No Accumulation Buffer
 pfd\cAccumRedBits=0 ;Accumulation Bits Ignored
 pfd\cAccumGreenBits=0
 pfd\cAccumBlueBits=0
 pfd\cAccumAlphaBits=0
 pfd\cDepthBits=16 ;16Bit Z-Buffer (Depth Buffer)
 pfd\cStencilBits=0 ;No Stencil Buffer
 pfd\cAuxBuffers=0 ;No Auxiliary Buffer
 pfd\iLayerType=#PFD_MAIN_PLANE ;Main Drawing Layer
 pfd\bReserved=0 ;Reserved
 pfd\dwLayerMask=0 ;Layer Masks Ignored
 pfd\dwVisibleMask=0
 pfd\dwDamageMask=0
 
 hDC=GetDC_(hWnd)
 If hDC=0 ;Did We Get A Device Context?
  KillGLWindow() ;Reset The Display
  MessageBox_(#Null,"Can't Create A GL Device Context.","ERROR",#MB_OK | #MB_ICONEXCLAMATION)
  ProcedureReturn #False
 EndIf
 
 PixelFormat=ChoosePixelFormat_(hDC,pfd)
 If PixelFormat=0 ;Did Windows Find A Matching Pixel Format?
  KillGLWindow() ;Reset The Display
  MessageBox_(#Null,"Can't Find A Suitable PixelFormat.","ERROR",#MB_OK | #MB_ICONEXCLAMATION)
  ProcedureReturn #False
 EndIf
 
 If SetPixelFormat_(hDC,PixelFormat,pfd)=0 ;Are We Able To Set The Pixel Format?
  KillGLWindow() ;Reset The Display
  MessageBox_(#Null,"Can't Set The PixelFormat.","ERROR",#MB_OK | #MB_ICONEXCLAMATION)
  ProcedureReturn #False
 EndIf
 
 hRC=wglCreateContext_(hDC)
 If hRC=0 ;Are We Able To Get A Rendering Context?
  KillGLWindow() ;Reset The Display
  MessageBox_(#Null,"Can't Create A GL Rendering Context.","ERROR",#MB_OK | #MB_ICONEXCLAMATION)
  ProcedureReturn #False
 EndIf
 
 If wglMakeCurrent_(hDC,hRC)=0 ;Try To Activate The Rendering Context
  KillGLWindow() ;Reset The Display
  MessageBox_(#Null,"Can't Activate The GL Rendering Context.","ERROR",#MB_OK | #MB_ICONEXCLAMATION)
  ProcedureReturn #False
 EndIf
 
 ShowWindow_(hWnd,#SW_SHOW) ;Show The Window
 SetForegroundWindow_(hWnd) ;Slightly Higher Priority
 SetFocus_(hWnd) ;Sets Keyboard Focus To The Window
 ReSizeGLScene(width,height) ;Set Up Our Perspective GL Screen
 
 If InitGL()=0 ;Initialize Our Newly Created GL Window
  KillGLWindow() ;Reset The Display
  MessageBox_(#Null,"Initialization Failed.","ERROR",#MB_OK | #MB_ICONEXCLAMATION)
  ProcedureReturn #False
 EndIf
 
 ProcedureReturn #True ;Success
 
EndProcedure

Procedure.l WndProc(hWnd.l,uMsg.l,wParam.l,lParam.l)

 Select uMsg ;Check For Windows Messages
 
  Case #WM_ACTIVATE ;Watch For Window Activate Message
   If HiWord(wParam)=0 ;Check Minimization State
    active=#True ;Program Is Active
   Else
    active=#False ;Program Is No Longer Active
   EndIf
   ProcedureReturn 0 ;Return To The Message Loop
   
  Case #WM_SYSCOMMAND ;Intercept System Commands
   Select wParam ;Check System Calls
    Case #SC_SCREENSAVE ;Screensaver Trying To Start?
     ProcedureReturn 0 ;Prevent From Happening
    Case #SC_MONITORPOWER ;Monitor Trying To Enter Powersave?
     ProcedureReturn 0 ;Prevent From Happening
   EndSelect
   
  Case #WM_CLOSE ;Did We Receive A Close Message?
   PostQuitMessage_(0) ;Send A Quit Message 
   ProcedureReturn 0 ;Jump Back
   
  Case #WM_KEYDOWN ;Is A Key Being Held Down?
   keys(wParam)=#True ;If So, Mark It As TRUE
   ProcedureReturn 0 ;Jump Back
   
  Case #WM_KEYUP ;Has A Key Been Released?
   keys(wParam)=#False ;If So, Mark It As FALSE
   ProcedureReturn 0 ;Jump Back
   
  Case #WM_SIZE ;Resize The OpenGL Window
   ReSizeGLScene(LoWord(lParam),HiWord(lParam)) ;LoWord=Width, HiWord=Height
   ProcedureReturn 0 ;Jump Back
   
 EndSelect
 
 ;Pass All Unhandled Messages To DefWindowProc
 ProcedureReturn DefWindowProc_(hWnd,uMsg,wParam,lParam)
 
EndProcedure

Procedure.l WinMain() ;Main Program

 Protected msg.MSG ;Windows Message Structure
 Protected done.b ;Bool Variable To Exit Loop
 
 ;Ask The User Which Screen Mode They Prefer
 If MessageBox_(#Null,"Would You Like To Run In Fullscreen Mode?","Start FullScreen?",#MB_YESNO | #MB_ICONQUESTION)=#IDNO
  fullscreen=#False ;Windowed Mode
 EndIf
 
 If CreateGLWindow("NeHe's Texture Mapping Tutorial",640,480,16,fullscreen)=0 ;Create The Window
  ProcedureReturn 0 ;Quit If Window Was Not Created
 EndIf
 
 While done=#False ;Loop That Runs While done=FALSE
 
  If PeekMessage_(msg,#Null,0,0,#PM_REMOVE) ;Is There A Message Waiting?
  
   If msg\message=#WM_QUIT ;Have We Received A Quit Message?
    done=#True ;If So done=TRUE
   Else ;If Not, Deal With Window Messages
    TranslateMessage_(msg) ;Translate The Message
    DispatchMessage_(msg) ;Dispatch The Message
   EndIf
   
  Else ;If There Are No Messages
  
   ;Draw The Scene. Watch For ESC Key And Quit Messages From DrawGLScene()
   If (active And DrawGLScene()=0) Or keys(#VK_ESCAPE) ;Active? Was There A Quit Received?
    done=#True ;ESC or DrawGLScene Signalled A Quit
   Else ;Not Time To Quit, Update Screen
    SwapBuffers_(hDC) ;Swap Buffers (Double Buffering)
   EndIf
   
   If keys(#VK_F1) ;Is F1 Being Pressed?
    keys(#VK_F1)=#False ;If So Make Key FALSE
    KillGLWindow() ;Kill Our Current Window
    fullscreen=~fullscreen & 1 ;Toggle Fullscreen / Windowed Mode
    ;Recreate Our OpenGL Window
    If CreateGLWindow("NeHe's Texture Mapping Tutorial",640,480,16,fullscreen)=0
     ProcedureReturn 0 ;Quit If Window Was Not Created
    EndIf
   EndIf
   
  EndIf
  
 Wend
 
 ;Shutdown
 KillGLWindow() ;Kill The Window
 End ;Exit The Program
 
EndProcedure

WinMain() ;run the main program

thanks

Posted: Mon Jun 25, 2007 5:05 am
by GBeebe
hagibaba, you're awesome. Both solutions worked perfectly.

My goal is to make my game run in Linux as well as windows, but for some reason Ubuntu doesn't like Ogre3d. And when I ran into this problem in Windows, I was worried that I had run into another dead end.

Hopefully I can get this to work in Linux, with a few needed modifications, i'm sure.

Thank you very much.

Posted: Tue Jun 26, 2007 2:55 am
by hagibaba
Hi GBeebe, you're welcome.

I've no idea about Linux but I suppose if you know the commands it wouldn't be too hard to port these tutorials.

Posted: Tue Jun 26, 2007 5:19 am
by Dare
Hi hagibaba.

Thanks for this!

Re: NeHe's Texture Mapping Tutorial (Lesson 6)

Posted: Fri Oct 22, 2021 6:19 pm
by mpz
Hello,

next code actualised for x86/x64, PB 5.73.

you can choose a purebasic texture or get the original from the internet

P.S:I think the code can work with linux and mac Osx too.


Greetings Michael

C code and texture
iamyaker.googlepages.com/06_Texture.rar

Code: Select all

;NeHe's Texture Mapping Tutorial (Lesson 6) 
;http://nehe.gamedev.net 
;https://nehe.gamedev.net/tutorial/texture_mapping/12038/
;Credits: Nico Gruener, Dreglor, traumatic, hagibaba
;Author: MPz
;Date: 04 Oct 2021
;Note: up-to-date with PB v5.73 (Windows)


Global xrot.f, yrot.f, zrot.f, Texture.i

Procedure ReSizeGLScene(width.l,height.l) ;Resize And Initialize The GL Window

 If height=0 : height=1 : EndIf ;Prevent A Divide By Zero Error
 
 ResizeGadget(0, 0, 0, width, height)
 
 glViewport_(0,0,width,height) ;Reset The Current Viewport
 
 glMatrixMode_(#GL_PROJECTION) ;Select The Projection Matrix
 glLoadIdentity_() ;Reset The Projection Matrix
 
 gluPerspective_(45.0,Abs(width/height),0.1,100.0) ;Calculate The Aspect Ratio Of The Window
 
 glMatrixMode_(#GL_MODELVIEW) ;Select The Modelview Matrix
 glLoadIdentity_() ;Reset The Modelview Matrix
 
EndProcedure

Procedure InitGL() ;All Setup For OpenGL Goes Here

 glEnable_(#GL_TEXTURE_2D);                        // Enable Texture Mapping ( NEW )
 glShadeModel_(#GL_SMOOTH) ;Enable Smooth Shading
 glClearColor_(0.0,0.0,0.0,0.5) ;Black Background
 glClearDepth_(1.0) ;Depth Buffer Setup
 glEnable_(#GL_DEPTH_TEST) ;Enables Depth Testing
 glDepthFunc_(#GL_LEQUAL) ;The Type Of Depth Testing To Do
 glHint_(#GL_PERSPECTIVE_CORRECTION_HINT,#GL_NICEST) ;Really Nice Perspective Calculations  
 
 ProcedureReturn #True ;Initialization Went OK

EndProcedure

Procedure LoadGLTextures(Names.s)
  
  LoadImage(0, Names) ; Load texture with name
  *pointer = EncodeImage(0, #PB_ImagePlugin_BMP,0,24);  
  FreeImage(0)
  
  ; ----- Generate texture
  glGenTextures_(1, @TextureID.i)
  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,  PeekL(*pointer+18),  PeekL(*pointer+22), 0, #GL_BGR_EXT, #GL_UNSIGNED_BYTE,  *pointer+54);
  
  FreeMemory(*pointer)
  
  ProcedureReturn TextureID

EndProcedure

Procedure DrawScene(Gadget)
  
  SetGadgetAttribute(Gadget, #PB_OpenGL_SetContext, #True)
  glClear_ (#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)
 
  glLoadIdentity_();                   // Reset The View
  glTranslatef_(0.0,0.0,-5.0);                      // Move Into The Screen 5 Units
  
  glRotatef_(xrot,1.0,0.0,0.0);                     // Rotate On The X Axis
  glRotatef_(yrot,0.0,1.0,0.0);                     // Rotate On The Y Axis
  glRotatef_(zrot,0.0,0.0,1.0);                     // Rotate On The Z Axis
  
  glBindTexture_(#GL_TEXTURE_2D, Texture);               // Select Our Texture
  
  glBegin_(#GL_QUADS);                      // Draw A Quad
    ;// Front Face
    glTexCoord2f_(0.0, 0.0) : glVertex3f_(-1.0, -1.0,  1.0);  // Bottom Left Of The Texture and Quad
    glTexCoord2f_(1.0, 0.0) : glVertex3f_( 1.0, -1.0,  1.0);  // Bottom Right Of The Texture and Quad
    glTexCoord2f_(1.0, 1.0) : glVertex3f_( 1.0,  1.0,  1.0);  // Top Right Of The Texture and Quad
    glTexCoord2f_(0.0, 1.0) : glVertex3f_(-1.0,  1.0,  1.0);  // Top Left Of The Texture and Quad
    ;// Back Face
    glTexCoord2f_(1.0, 0.0) : glVertex3f_(-1.0, -1.0, -1.0);  // Bottom Right Of The Texture and Quad
    glTexCoord2f_(1.0, 1.0) : glVertex3f_(-1.0,  1.0, -1.0);  // Top Right Of The Texture and Quad
    glTexCoord2f_(0.0, 1.0) : glVertex3f_( 1.0,  1.0, -1.0);  // Top Left Of The Texture and Quad
    glTexCoord2f_(0.0, 0.0) : glVertex3f_( 1.0, -1.0, -1.0);  // Bottom Left Of The Texture and Quad
    ;// Top Face
    glTexCoord2f_(0.0, 1.0) : glVertex3f_(-1.0,  1.0, -1.0);  // Top Left Of The Texture and Quad
    glTexCoord2f_(0.0, 0.0) : glVertex3f_(-1.0,  1.0,  1.0);  // Bottom Left Of The Texture and Quad
    glTexCoord2f_(1.0, 0.0) : glVertex3f_( 1.0,  1.0,  1.0);  // Bottom Right Of The Texture and Quad
    glTexCoord2f_(1.0, 1.0) : glVertex3f_( 1.0,  1.0, -1.0);  // Top Right Of The Texture and Quad
    ;// Bottom Face
    glTexCoord2f_(1.0, 1.0) : glVertex3f_(-1.0, -1.0, -1.0);  // Top Right Of The Texture and Quad
    glTexCoord2f_(0.0, 1.0) : glVertex3f_( 1.0, -1.0, -1.0);  // Top Left Of The Texture and Quad
    glTexCoord2f_(0.0, 0.0) : glVertex3f_( 1.0, -1.0,  1.0);  // Bottom Left Of The Texture and Quad
    glTexCoord2f_(1.0, 0.0) : glVertex3f_(-1.0, -1.0,  1.0);  // Bottom Right Of The Texture and Quad
    ;// Right face
    glTexCoord2f_(1.0, 0.0) : glVertex3f_( 1.0, -1.0, -1.0);  // Bottom Right Of The Texture and Quad
    glTexCoord2f_(1.0, 1.0) : glVertex3f_( 1.0,  1.0, -1.0);  // Top Right Of The Texture and Quad
    glTexCoord2f_(0.0, 1.0) : glVertex3f_( 1.0,  1.0,  1.0);  // Top Left Of The Texture and Quad
    glTexCoord2f_(0.0, 0.0) : glVertex3f_( 1.0, -1.0,  1.0);  // Bottom Left Of The Texture and Quad
    ;// Left Face
    glTexCoord2f_(0.0, 0.0) : glVertex3f_(-1.0, -1.0, -1.0);  // Bottom Left Of The Texture and Quad
    glTexCoord2f_(1.0, 0.0) : glVertex3f_(-1.0, -1.0,  1.0);  // Bottom Right Of The Texture and Quad
    glTexCoord2f_(1.0, 1.0) : glVertex3f_(-1.0,  1.0,  1.0);  // Top Right Of The Texture and Quad
    glTexCoord2f_(0.0, 1.0) : glVertex3f_(-1.0,  1.0, -1.0);  // Top Left Of The Texture and Quad
        
  glEnd_();
  
  xrot + 0.3;                             // X Axis Rotation
  yrot + 0.2;                             // Y Axis Rotation
  zrot + 0.4;                             // Z Axis Rotation

   SetGadgetAttribute(Gadget, #PB_OpenGL_FlipBuffers, #True)
EndProcedure

Procedure HandleError (Result, Text$)
  If Result = 0
    MessageRequester("Error", Text$, 0)
    End
  EndIf
EndProcedure

Procedure CreateGLWindow(title.s,WindowWidth.l,WindowHeight.l,bits.l=16,fullscreenflag.b=0,Vsync.b=0)
  
  If InitKeyboard() = 0 Or InitSprite() = 0 Or InitMouse() = 0
    MessageRequester("Error", "Can't initialize Keyboards or Mouse", 0)
    End
  EndIf

  If fullscreenflag
    hWnd = OpenWindow(0, 0, 0, WindowWidth, WindowHeight, title, #PB_Window_BorderLess|#PB_Window_Maximize )
    OpenWindowedScreen(WindowID(0), 0, 0,WindowWidth(0),WindowHeight(0)) 
  Else  
    hWnd = OpenWindow(0, 1, 1, WindowWidth, WindowHeight, title,#PB_Window_MinimizeGadget |  #PB_Window_MaximizeGadget | #PB_Window_SizeGadget ) 
    OpenWindowedScreen(WindowID(0), 1, 1, WindowWidth,WindowHeight) 
  EndIf
  
  If bits = 24
    OpenGlFlags + #PB_OpenGL_24BitDepthBuffer
  EndIf
  
  If Vsync = 0
    OpenGlFlags + #PB_OpenGL_NoFlipSynchronization
  EndIf
  
  OpenGLGadget(0, 0, 0, WindowWidth(0),WindowHeight(0),OpenGlFlags)
  
  SetActiveGadget(0) 
  
  ReSizeGLScene(WindowWidth(0),WindowHeight(0))
  ;hDC = GetDC_(hWnd)
  
EndProcedure


CreateGLWindow("OpenGL Lesson 6",640,480,16,0)

InitGL() 
  
Texture.i = LoadGLTextures(#PB_Compiler_Home + "examples/3d/Data/Textures/Geebee2.bmp")
;Texture.i = LoadGLTextures("Data/NeHe.bmp")

Repeat

   Repeat 
    Event = WindowEvent()
    
    Select Event
      Case #PB_Event_CloseWindow
        Quit = 1
      Case #PB_Event_SizeWindow  
        ReSizeGLScene(WindowWidth(0),WindowHeight(0)) ;LoWord=Width, HiWord=Height
    EndSelect
  
  Until Event = 0
  
  ExamineKeyboard()
  
  If KeyboardPushed(#PB_Key_Escape) ;  Esc key to exit
    Quit = 1
  EndIf 

  
  DrawScene(0)
  Delay(20)
Until Quit = 1



Re: NeHe's Texture Mapping Tutorial (Lesson 6)

Posted: Fri Oct 22, 2021 9:33 pm
by Saboteur
BITMAPFILEHEADER and BITMAPINFOHEADER structures don't exist in linux.

Re: NeHe's Texture Mapping Tutorial (Lesson 6)

Posted: Fri Oct 22, 2021 10:07 pm
by mpz
Thanks for answer,

Please test this piece of code to load the texture,

i use the structure only for the pointer of the bmp file (biWidth, biHeight,Data)

i am not shure to use data = *pointer+54. I found here the informations "*pointer+57" for data, but i think this is not correct for the bmp file but working ?!?

Greeting Michael

Code: Select all


Procedure LoadGLTextures(Names.s)
  
  LoadImage(0, Names) ; Load texture with name
  *pointer = EncodeImage(0, #PB_ImagePlugin_BMP,0,24);  
  FreeImage(0)
  
  ; ----- Generate texture
  glGenTextures_(1, @TextureID.i)
  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,  PeekL(*pointer+18),  PeekL(*pointer+22), 0, #GL_BGR_EXT, #GL_UNSIGNED_BYTE,  *pointer+54);
  
  FreeMemory(*pointer)
  
  ProcedureReturn TextureID

EndProcedure

Re: NeHe's Texture Mapping Tutorial (Lesson 6)

Posted: Sat Oct 23, 2021 11:25 pm
by Saboteur
Yes, now works perfect.