Code: Select all
; OpenGL 3D Engine
; Based on NeHe Lesson 6 OpenGL Texture Tutorial
; by Lance Jepsen
; Instructions: Use arrow keys to move around
IncludeFile "OpenGL.pbi"
Global texture
Global rquad.f
Global zoom.f
Global turn.f
zoom = -7.0
turn = 0.0
Procedure _CreateTexture(pData.l, mode.s, mipmapping.b, bmpWidth.l, bmpHeight.l)
If pData = 0
MessageBox_(0, "unable to load texture", ":PBglLib", #MB_OK | #MB_ICONERROR)
Else
glGenTextures_(1, @texture)
glBindTexture_(#GL_TEXTURE_2D, texture)
glTexEnvi_(#GL_TEXTURE_ENV, #GL_TEXTURE_ENV_MODE, #GL_MODULATE) ; Texture blends with object background
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MAG_FILTER, #GL_LINEAR) ; only first two can be used
If mipmapping = 1
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MIN_FILTER, #GL_LINEAR_MIPMAP_LINEAR) ; all of the above can be used
Else
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MIN_FILTER, #GL_LINEAR) ; all of the above can be used
EndIf
Select mode
Case LCase("rgb")
If mipmapping = 1
gluBuild2DMipmaps_(#GL_TEXTURE_2D, #GL_RGB, bmpWidth, bmpHeight, #GL_RGB, #GL_UNSIGNED_BYTE, pData):
Else
glTexImage2D_(#GL_TEXTURE_2D, 0, #GL_RGB, bmpWidth, bmpHeight, 0, #GL_RGB, #GL_UNSIGNED_BYTE, pData) ; Use when not wanting mipmaps to be built by openGL
EndIf
Case LCase("rgba")
If mipmapping = 1
gluBuild2DMipmaps_(#GL_TEXTURE_2D, #GL_RGBA, bmpWidth, bmpHeight, #GL_RGBA, #GL_UNSIGNED_BYTE, pData) ;
Else
glTexImage2D_(#GL_TEXTURE_2D, 0, #GL_RGBA, bmpWidth, bmpHeight, 0, #GL_RGBA, #GL_UNSIGNED_BYTE, pData) ; Use when not wanting mipmaps to be built by openGL
EndIf
Case LCase("luminance")
If mipmapping = 1
gluBuild2DMipmaps_(#GL_TEXTURE_2D, #GL_LUMINANCE, bmpWidth, bmpHeight, #GL_LUMINANCE, #GL_UNSIGNED_BYTE, pData)
Else
glTexImage2D_(#GL_TEXTURE_2D, 0, #GL_LUMINANCE, bmpWidth, bmpHeight, 0, #GL_LUMINANCE, #GL_UNSIGNED_BYTE, pData) ; Use when not wanting mipmaps to be built by openGL
EndIf
EndSelect
EndIf
ProcedureReturn texture
EndProcedure
;
; load BMPs from memory-locations (IncludeBinary)
; loads 8, 16 and 24bit bmps
;
Procedure loadBMPTextureMem(memloc.l, mode.s, mipmapping.b)
FileHeader.BITMAPFILEHEADER
InfoHeader.BITMAPINFOHEADER
; read the bitmap file header
FileHeader\bfType = PeekW(memloc +0) ;2
FileHeader\bfSize = PeekL(memloc +2) ;4
FileHeader\bfReserved1 = PeekW(memloc +6) ;2
FileHeader\bfReserved2 = PeekW(memloc + ;2
FileHeader\bfOffBits = PeekL(memloc+10) ;4
; check if it's a valid bmp-file
If FileHeader\bfType $4D42
; MessageBox_(0, "invalid bmpfile @"+Str(memlocation), ":PBglLib", #MB_OK)
ProcedureReturn 0
EndIf
; read the bitmap information header
InfoHeader\biSize = PeekL(memloc+14) ;4
InfoHeader\biWidth = PeekL(memloc+1 ;4
InfoHeader\biHeight = PeekL(memloc+22) ;4
InfoHeader\biPlanes = PeekW(memloc+26) ;2
InfoHeader\biBitCount = PeekW(memloc+2 ;2
InfoHeader\biCompression = PeekL(memloc+30) ;4
InfoHeader\biSizeImage = PeekL(memloc+34) ;4
InfoHeader\biXPelsPerMeter = PeekL(memloc+3 ;4
InfoHeader\biYPelsPerMeter = PeekL(memloc+42) ;4
InfoHeader\biClrUsed = PeekL(memloc+46) ;4
InfoHeader\biClrImportant = PeekL(memloc+50) ;4
If InfoHeader\biSizeImage = 0
InfoHeader\biSizeImage = (InfoHeader\biWidth * InfoHeader\biHeight * InfoHeader\biBitCount /
EndIf
; allocate enough mem to store the bitmap
; Dim bitmapImage.b (InfoHeader\biSizeImage)
AllocateMemory(0, InfoHeader\biSizeImage+2, 0)
; read in the bitmap image data
For i.l=FileHeader\bfOffBits To InfoHeader\biSizeImage
CopyMemory(memloc+i, UseMemory(0)+i2, 1)
i2.l+1
Next
If InfoHeader\biBitCount>8
; swap BGR to RGB
AllocateMemory(1,1,0)
For i.l=0 To InfoHeader\biSizeImage Step 3
CopyMemory(UseMemory(0)+i, UseMemory(1), 1)
CopyMemory(UseMemory(0)+i+2, UseMemory(0)+i, 1)
CopyMemory(UseMemory(1), UseMemory(0)+i+2, 1)
Next
EndIf
; create texture
texture = _CreateTexture(UseMemory(0), mode.s, mipmapping.b, InfoHeader\biWidth, InfoHeader\biHeight)
; cleanup
FreeMemory(0)
ProcedureReturn texture
EndProcedure
Procedure InitGL()
glClearColor_(0.0, 0.0, 0.0, 0.0)
glDepthFunc_(#GL_LESS)
glEnable_(#GL_DEPTH_TEST)
glEnable_(#GL_TEXTURE_2D);
glShadeModel_(#GL_SMOOTH)
glMatrixMode_(#GL_PROJECTION)
glLoadIdentity_()
gluPerspectivef_(45.0, 640/480, 0.1, 100.0)
glMatrixMode_(#GL_MODELVIEW)
EndProcedure
Procedure DrawScene(hDC)
glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)
glLoadIdentity_();
glTranslatef_(turn,0.0, zoom); // Move Right And Into The Screen
glRotatef_(rquad,1.0,1.0,1.0); // Rotate The Cube On X, Y & Z
glBindTexture_(#GL_TEXTURE_2D, 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_();
rquad = rquad - 0.75; // Decrease The Rotation Variable For The Quad
EndProcedure
pfd.PIXELFORMATDESCRIPTOR
hWnd = OpenWindow(0, 0, 0, 800, 580, #PB_Window_SystemMenu | #PB_Window_ScreenCentered, "NeHe OpenGL Lesson 6")
hdc = GetDC_(hWnd)
pfd\nSize = SizeOf(PIXELFORMATDESCRIPTOR)
pfd\nVersion = 1
pfd\dwFlags = #PFD_SUPPORT_OPENGL | #PFD_DOUBLEBUFFER | #PFD_DRAW_TO_WINDOW
pfd\iLayerType = #PFD_MAIN_PLANE
pfd\iPixelType = #PFD_TYPE_RGBA
pfd\cColorBits = 24
pfd\cDepthBits = 16
pixformat = ChoosePixelFormat_(hdc, pfd)
SetPixelFormat_(hdc, pixformat, pfd)
hrc = wglCreateContext_(hdc)
wglMakeCurrent_(hdc,hrc)
InitGL()
texture = LoadBMPTextureMem(?texlabel, "rgb", 0)
AddKeyboardShortcut(0, #PB_Shortcut_Up, 1)
AddKeyboardShortcut(0, #PB_Shortcut_Down, 2)
AddKeyboardShortcut(0, #PB_Shortcut_Left, 3)
AddKeyboardShortcut(0, #PB_Shortcut_Right, 4)
Repeat
EventID = WindowEvent()
If EventID = #PB_EventMenu
Select EventMenuID()
Case 1
zoom = zoom + 0.2
Case 2
zoom = zoom - 0.2
Case 3
turn = turn - 0.2
Case 4
turn = turn + 0.2
EndSelect
EndIf
DrawScene(hDC)
SwapBuffers_(hDC)
Until EventID=#PB_EventCloseWindow
End
texlabel:
IncludeBinary "NeHe.bmp"