NeHe's Texture Mapping Tutorial (Lesson 6)

Share your advanced PureBasic knowledge/code with the community.
hagibaba
Enthusiast
Enthusiast
Posts: 170
Joined: Fri Mar 05, 2004 2:55 am
Location: UK
Contact:

NeHe's Texture Mapping Tutorial (Lesson 6)

Post 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

Last edited by hagibaba on Sun Jul 01, 2007 11:10 pm, edited 1 time in total.
GBeebe
Enthusiast
Enthusiast
Posts: 263
Joined: Sat Oct 09, 2004 6:52 pm
Location: Franklin, PA - USA
Contact:

odd error with lesson 6

Post 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?
hagibaba
Enthusiast
Enthusiast
Posts: 170
Joined: Fri Mar 05, 2004 2:55 am
Location: UK
Contact:

Post 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
Last edited by hagibaba on Sun Jul 01, 2007 11:24 pm, edited 1 time in total.
GBeebe
Enthusiast
Enthusiast
Posts: 263
Joined: Sat Oct 09, 2004 6:52 pm
Location: Franklin, PA - USA
Contact:

thanks

Post 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.
hagibaba
Enthusiast
Enthusiast
Posts: 170
Joined: Fri Mar 05, 2004 2:55 am
Location: UK
Contact:

Post 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.
Dare
Addict
Addict
Posts: 1965
Joined: Mon May 29, 2006 1:01 am
Location: Outback

Post by Dare »

Hi hagibaba.

Thanks for this!
Dare2 cut down to size
mpz
Enthusiast
Enthusiast
Posts: 494
Joined: Sat Oct 11, 2008 9:07 pm
Location: Germany, Berlin > member German forum

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

Post 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


Last edited by mpz on Fri Oct 22, 2021 11:19 pm, edited 1 time in total.
Working on - MP3D Library - PB 5.73 version ready for download
Saboteur
Enthusiast
Enthusiast
Posts: 271
Joined: Fri Apr 25, 2003 7:09 pm
Location: (Madrid) Spain
Contact:

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

Post by Saboteur »

BITMAPFILEHEADER and BITMAPINFOHEADER structures don't exist in linux.
[:: PB Registered ::]

Win10 Intel core i5-3330 8GB RAM Nvidia GTX 1050Ti
mpz
Enthusiast
Enthusiast
Posts: 494
Joined: Sat Oct 11, 2008 9:07 pm
Location: Germany, Berlin > member German forum

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

Post 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
Working on - MP3D Library - PB 5.73 version ready for download
Saboteur
Enthusiast
Enthusiast
Posts: 271
Joined: Fri Apr 25, 2003 7:09 pm
Location: (Madrid) Spain
Contact:

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

Post by Saboteur »

Yes, now works perfect.
[:: PB Registered ::]

Win10 Intel core i5-3330 8GB RAM Nvidia GTX 1050Ti
Post Reply