Page 1 of 1

OpenGL Textured and Rotating Cube...

Posted: Thu Apr 10, 2003 2:06 pm
by BackupUser
Code updated For 5.20+

Restored from previous forum. Originally posted by LJ.

Code: Select all

; NeHe Lesson 6 OpenGL Texture Tutorial
; Translated to PureBasic by Lance Jepsen
; http://nehe.gamedev.net/
; Thanks to Traumatic for the Load Texture procedures,
; Raphael for sharing them and with pointers 
; and Dmoc for finding the missing # in glBegin_(#GL_QUADS)
; Without these guys this wouldn't be possible.
; Enjoy!!

IncludeFile "OpenGL.pbi"

Global texture
Global rquad.f

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 + 8) ;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+18) ;4
  InfoHeader\biHeight        = PeekL(memloc+22) ;4
  InfoHeader\biPlanes        = PeekW(memloc+26) ;2
  InfoHeader\biBitCount      = PeekW(memloc+28) ;2
  InfoHeader\biCompression   = PeekL(memloc+30) ;4
  InfoHeader\biSizeImage     = PeekL(memloc+34) ;4
  InfoHeader\biXPelsPerMeter = PeekL(memloc+38)  ;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 / 8)
  EndIf
  
  ; allocate enough mem to store the bitmap
  ;  Dim bitmapImage.b (InfoHeader\biSizeImage)
  mem0 = AllocateMemory( InfoHeader\biSizeImage+2, 0)
  
  ; read in the bitmap image data
  For i.l=FileHeader\bfOffBits To InfoHeader\biSizeImage
    CopyMemory(memloc+i, mem0+i2, 1)
    i2+1
  Next
  
  If InfoHeader\biBitCount>8
    ; swap BGR to RGB
    mem1 = AllocateMemory(1,0)
    
    For i.l=0 To InfoHeader\biSizeImage Step 3
      CopyMemory(mem0+i, mem1, 1)
      CopyMemory(mem0+i+2, mem0+i, 1)
      CopyMemory(mem1, mem0+i+2, 1)
    Next
    
  EndIf
  
  ; create texture
  texture = _CreateTexture(mem0, mode.s, mipmapping.b, InfoHeader\biWidth, InfoHeader\biHeight)
  
  ; cleanup
  FreeMemory(mem0)
  
  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_(0,0.0,-7.0);         // 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, "NeHe OpenGL Lesson 6", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
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)

While Quit = 0
  
  Repeat
    EventID = WindowEvent()
    
    Select EventID
      Case #PB_Event_CloseWindow
        Quit = 1
    EndSelect
    
  Until EventID = 0
  
  DrawScene(hDC)
  SwapBuffers_(hDC)
  
Wend
End

texlabel:
IncludeBinary "NeHe.bmp"


Posted: Thu Apr 10, 2003 2:23 pm
by BackupUser
Restored from previous forum. Originally posted by LJ.

Compiles to a mere 12K .exe! The resource file NeHe.bmp adds another 196K.

You will need the NeHe.bmp file to run the code above. Go to the NeHe web site to get it: http://nehe.gamedev.net/
or get it here:
http://www.acethemsat.com/NeHe.bmp