Page 1 of 1

3D demo 'Entity2'

Posted: Sun Dec 04, 2011 7:52 pm
by BasicallyPure
I have been working on this 3D demo to see if I could make it to work better than the 3D example code 'Entity.pb'.
I have had some success with this and thought I would share what I have come up with.
It will run in Windows or Linux but read the notes at the beginning of the code.

I have also discovered what may be a problem with the 'SkyBox' command.
In line 72 if you change the filename "stevecube.jpg" to a filename that does not exist
SkyBox should return 0 as a result and the program would end.
This is not what happens.
Try it, the results are interesting. (I have only tried this with Linux)

Save the code as 'Entity2' in the examples/3D folder before you run it.

Code: Select all

;
; ------------------------------------------------------------
;
; PureBasic 3D demo -  Entity2
;
; by BasicallyPure 11/29/2011
; this file must be located in examples/3D folder to run properly
;
; Note1: runs OK in Linux but for Windows, text on billboard is mirrored
; Is this a bug in Windows version of PB?
; 
; Note2: When using windowed screen the menu shortcut keys do not work in Linux.
; Menu works as expected in Windows so ...
; Is this a bug in Linux version of PB?
;
; ------------------------------------------------------------
;

IncludeFile "Screen3DRequester.pb"

EnableExplicit

Declare Verify(result.l,text.s)
Define.f KeyX, KeyY, KeyZ, MouseX, MouseY, RollZ
Define.l Quit

Verify(InitEngine3D(),"3D engine")

Add3DArchive("Data/Textures", #PB_3DArchive_FileSystem)
Add3DArchive("Data/Models", #PB_3DArchive_FileSystem)
Add3DArchive("Data/Packs/skybox.zip", #PB_3DArchive_Zip)

UsePNGImageDecoder()

Verify(InitSprite(),"sprite")
Verify(InitKeyboard(),"keyboard")
Verify(InitMouse(),"mouse")

Verify(Screen3DRequester(),"Screen3DRequester")

KeyboardMode(#PB_Keyboard_International)

Verify(LoadMesh(0, "robot.mesh"),"Robot Mesh")

Verify(CreateMaterial(0, LoadTexture(0, "Caisse.png")),"CreateMaterial 'Caisse.jpg'")
Verify(CreateMaterial(1, LoadTexture(1, "r2skin.jpg")),"CreateMaterial 'r2skin.jpg'")
Verify(CreateMaterial(2, LoadTexture(2, "Wood.jpg")),"CreateMaterial 'Wood.jpg'")

LoadFont(0,"Garamond",12)

StartDrawing(TextureOutput(2))
DrawingFont(FontID(0))
DrawingMode(#PB_2DDrawing_Transparent)
DrawText(10, 10, "      CAMERA CONTROLS",$0410B4)
DrawText(15, 50, "Mouse = aim X Y",$053179)
DrawText(15, 75, "< > = roll camera",$053179)
DrawText(15,100, "Arrow keys = move X Y",$053179)
DrawText(15,125, "PgUp/Dn = forward/back",$053179)
DrawText(15,150, "Space = default position",$053179)
DrawText(15,200, "Press 'ESC' to end")
StopDrawing()

Verify(CreateEntity(0, MeshID(0), MaterialID(1)),"CreateEntity 0")
Verify(CreateEntity(1, MeshID(0), MaterialID(0), -60, 0, 0),"CreateEntity 1")
Verify(CreateEntity(2, MeshID(0), MaterialID(1),  60, 0, 0),"CreateEntity 2")

AnimateEntity(0, "Walk")

CreateBillboardGroup(0, MaterialID(2), 15, 10)
AddBillboard(0, 0, 0, 35, 200)

Verify(SkyBox("stevecube.jpg"),"Skybox 'stevecube.jpg'")

Verify(CreateCamera(0, 0, 0, 100, 100),"Camera 0")
CameraLocate(0, 0, 40, 235)

;reference MouseDelta X & Y before starting repeat loop
If ExamineMouse() : MouseDeltaX() : MouseDeltaY() : EndIf

SetFrameRate(30)

Repeat
   Screen3DEvents()
   
   If ExamineMouse()
      MouseX = -MouseDeltaX()/10 
      MouseY = -MouseDeltaY()/10
   EndIf
   
   If ExamineKeyboard()
      KeyX = 0 : KeyY = 0 : KeyZ = 0 : RollZ = 0
      If KeyboardPushed(#PB_Key_Right)
         KeyX =  1 
      ElseIf KeyboardPushed(#PB_Key_Left)
         KeyX = -1
      ElseIf KeyboardPushed(#PB_Key_Up)
         KeyY =  1 
      ElseIf KeyboardPushed(#PB_Key_Down)
         KeyY = -1
      ElseIf KeyboardPushed(#PB_Key_PageUp)
         KeyZ = -1
      ElseIf KeyboardPushed(#PB_Key_PageDown)
         KeyZ =  1
      ElseIf KeyboardPushed(#PB_Key_Period)
         Rollz =  2
      ElseIf KeyboardPushed(#PB_Key_Comma)
         Rollz = -2
      EndIf
      
      If KeyboardPushed(#PB_Key_Space)
         CameraLocate(0, 0, 40, 235)
         RotateCamera(0,0,0,0, #PB_Absolute)
      EndIf
      
   EndIf
   
   
   RotateEntity(1, 0, 1, 0, #PB_Relative)
   RotateEntity(2, 0, 1, 0, #PB_Relative)
   
   RotateCamera(0, MouseY, MouseX, RollZ, #PB_Relative)
   MoveCamera  (0, KeyX, KeyY, KeyZ)
   
   RenderWorld()
   FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1

End

Procedure Verify(result.l,text.s)
   If result = #False
      text +  " failed To initialize."
      MessageRequester("Error!",text)
      End
   EndIf
   ProcedureReturn result
EndProcedure
Also, you may want to use this version of "Screen3DRequester.pb" as it works better than the
one provided with the PB install.
This version was created by Idle and I have made some modifications as well.
"Screen3DRequester.pb" is needed when you run 'Entity2.pb'.

Code: Select all

;
; ------------------------------------------------------------
;
;   PureBasic - Common 3D functions
;
;    (c) 2003 - Fantaisie Software
;
; modified by Idle and BasicallyPure 12/02/2011
;
; ------------------------------------------------------------
;

#WINDOW_Screen3DRequester = 0

#GADGET_FullScreen        = 1
#GADGET_Windowed          = 2
#GADGET_ScreenModesLabel  = 3
#GADGET_WindowedModes     = 4
#GADGET_Launch            = 5
#GADGET_Cancel            = 6
#GADGET_Logo              = 7
#GADGET_Frame             = 8
#GADGET_ScreenModes       = 9

CompilerIf #PB_Compiler_OS = #PB_OS_Linux
   If Not Subsystem("OpenGL")
     MessageRequester("Warning :", "Compile With OpenGL subsystem") 
     End 
   EndIf   
CompilerEndIf

Structure ScreenModes
  width.i
  height.i
  depth.i
  refresh.i
EndStructure 

Global Screen3DRequester_FullScreen, Screen3DRequester_ShowStats

Procedure Screen3DRequester()
  Protected ratio.f
 
  OpenPreferences("Demos3D.prefs")
  FullScreen          = ReadPreferenceLong  ("FullScreen"        , 1)
  FullScreenMode$     = ReadPreferenceString("FullScreenMode" , "")
  WindowedScreenMode$ = ReadPreferenceString("WindowedScreenMode", "")


  If OpenWindow(#WINDOW_Screen3DRequester, 0, 0, 396, 205, "PureBasic - 3D Demos", #PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_Invisible)
    
    Top = 6
    
    ImageGadget  (#GADGET_Logo, 6, Top, 0, 0, LoadImage(0,"Data/PureBasicLogo.bmp"), #PB_Image_Border) : Top+76
    
    Frame3DGadget(#GADGET_Frame, 6, Top, 384, 80, "", 0) : Top+20
    
    OptionGadget(#GADGET_FullScreen, 70, Top, 100, 25, "Fullscreen") : Top+25
    OptionGadget(#GADGET_Windowed  , 70, Top, 100, 25, "Windowed")   : Top-25
   
    ComboBoxGadget (#GADGET_ScreenModes  , 190, Top, 150, 30) : Top+25
    ComboBoxGadget (#GADGET_WindowedModes, 190, Top, 150, 30) : Top+45
   
    ButtonGadget (#GADGET_Launch,   6, Top, 180, 25, "Launch", #PB_Button_Default)
    ButtonGadget (#GADGET_Cancel, 200, Top, 190, 25, "Cancel")
    
   Protected NewList modes.ScreenModes()

    If ExamineScreenModes()
          
          While NextScreenMode()
          
            Width       = ScreenModeWidth()
            Height      = ScreenModeHeight()
            Depth       = ScreenModeDepth()
            RefreshRate = ScreenModeRefreshRate()
            
          If (Depth > 8 And RefreshRate > 0) 
             AddElement(modes())
             modes()\depth = Depth
             modes()\height = Height
             modes()\width = width
             modes()\refresh = RefreshRate
          EndIf
           
          Wend        
          SortStructuredList(modes(),#PB_Sort_Descending,OffsetOf(ScreenModes\width),#PB_Sort_Integer) 
         
     EndIf
        
     ForEach modes() 
        strmode.s = Str(modes()\width) + "x" + Str(modes()\height) + "x" + Str(modes()\depth) + "@" + Str(modes()\refresh)
        AddGadgetItem(#GADGET_ScreenModes, -1, strmode)
         If  FullScreenMode$ = ""
           FullScreenMode$ = strmode
         EndIf
         ratio = modes()\width / modes()\height 
     Next   
    
    ExamineDesktops()
    NbScreenModes = 7
    
  If ratio < 1.6
    Restore WindowedScreenDimensions
  Else 
    Restore WindowedScreenWideDimensions  
  EndIf 
  
   Repeat      
      Read.l CurrentWidth
      Read.l CurrentHeight
      
      If CurrentWidth < DesktopWidth(0) And CurrentHeight < DesktopHeight(0)
        AddGadgetItem(#GADGET_WindowedModes, -1, Str(CurrentWidth)+ "x"+Str(CurrentHeight))
        HighestResolution$ = Str(CurrentWidth)+ "x"+Str(CurrentHeight)
        NbScreenModes - 1
      Else
         If  WindowedScreenMode$ = "" 
           WindowedScreenMode$ = HighestResolution$
         EndIf   
        NbScreenModes = 0
      EndIf
    Until NbScreenModes = 0
    
    SetGadgetState(#GADGET_FullScreen, FullScreen)
    SetGadgetState(#GADGET_Windowed  , 1-FullScreen)

    SetGadgetText (#GADGET_ScreenModes  , FullScreenMode$)
    SetGadgetText (#GADGET_WindowedModes, WindowedScreenMode$)
    
    DisableGadget (#GADGET_ScreenModes  , 1-FullScreen)
    DisableGadget (#GADGET_WindowedModes, FullScreen)
    
    HideWindow(#WINDOW_Screen3DRequester, 0)
    
    Repeat
      
      Event = WaitWindowEvent()
      
      Select Event
        
      Case #PB_Event_Gadget
        
        Select EventGadget()
          
        Case #GADGET_Launch
          Quit = 2
          
        Case #GADGET_Cancel
          Quit = 1
          
        Case #GADGET_FullScreen
          DisableGadget(#GADGET_ScreenModes  , 0)
          DisableGadget(#GADGET_WindowedModes, 1)
        
        Case #GADGET_Windowed
          DisableGadget(#GADGET_ScreenModes  , 1)
          DisableGadget(#GADGET_WindowedModes, 0)
                 
        EndSelect
        
      Case #PB_Event_CloseWindow
        Quit = 1
        
      EndSelect
      
    Until Quit > 0
    
    FullScreen          = GetGadgetState(#GADGET_FullScreen)
    FullScreenMode$     = GetGadgetText (#GADGET_ScreenModes)
    WindowedScreenMode$ = GetGadgetText (#GADGET_WindowedModes)
    
    CloseWindow(#WINDOW_Screen3DRequester)
      
  EndIf
  
  If Quit = 2 ; Launch button has been pressed
  
    CreatePreferences("Demos3D.prefs")
      WritePreferenceLong  ("FullScreen"        , FullScreen)          
      WritePreferenceString("FullScreenMode"    , FullScreenMode$)     
      WritePreferenceString("WindowedScreenMode", WindowedScreenMode$) 

    If FullScreen
      ScreenMode$ = FullScreenMode$
    Else
      ScreenMode$ = WindowedScreenMode$
    EndIf
    
    RefreshRate = Val(StringField(ScreenMode$, 2, "@"))
    
    ScreenMode$ = StringField(ScreenMode$, 1, "@") ; Remove the refresh rate info, so we can parse it easily
    
    ScreenWidth  = Val(StringField(ScreenMode$, 1, "x"))
    ScreenHeight = Val(StringField(ScreenMode$, 2, "x"))
    ScreenDepth  = Val(StringField(ScreenMode$, 3, "x"))
    
    Screen3DRequester_FullScreen = FullScreen ; Global variable, for the Screen3DEvents
    
    If FullScreen
      Result = OpenScreen(ScreenWidth, ScreenHeight, ScreenDepth, "3D Demos", #PB_Screen_WaitSynchronization, RefreshRate)
    Else
      If OpenWindow(0, 0, 0, ScreenWidth, ScreenHeight+MenuHeight(), "PureBasic - 3D Demos", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
      
        CreateMenu(0, WindowID(#WINDOW_Screen3DRequester))
          MenuTitle("Project")
          MenuItem(0, "Quit")
    
          MenuTitle("About")
          MenuItem(1, "About...")
              
        Result = OpenWindowedScreen(WindowID(#WINDOW_Screen3DRequester), 0, 0, ScreenWidth, ScreenHeight, 0, 0, 0)
      EndIf
    EndIf
  EndIf
     
  ProcedureReturn Result
EndProcedure


Procedure Screen3DEvents()

  If Screen3DRequester_FullScreen = 0 ; Handle all the events relatives to the window..
  
    Repeat
      Event = WindowEvent()
      Select Event
      
        Case #PB_Event_Menu
          Select EventMenu()
          
            Case 0
              Quit = 1
          
            Case 1
              MessageRequester("Info", "Windowed 3D in PureBasic !")
              
          EndSelect
             
        Case #PB_Event_CloseWindow
          Quit = 1
        
      EndSelect
      
      If Quit = 1 : End : EndIf  ; Quit the app immediately
    Until Event = 0
    
  EndIf
  
EndProcedure

Procedure Screen3DStats()
  If Screen3DRequester_ShowStats
    ; Nothing printed for now
  EndIf
EndProcedure

DataSection
  WindowedScreenDimensions:
    Data.l  320, 240
    Data.l  512, 384      
    Data.l  640, 480
    Data.l  800, 600     
    Data.l 1024, 768
    Data.l 1280, 1024
    Data.l 1600, 1200
  WindowedScreenWideDimensions:
    Data.l 512,   320
    Data.l 640,   400
    Data.l 800,   500
    Data.l 1024, 640
    Data.l 1280, 800 
    Data.l 1440, 900
    Data.l 1600, 1000
 EndDataSection
B.P.

Re: 3D demo 'Entity2'

Posted: Sun Dec 04, 2011 9:23 pm
by idle
when you ran it on windows did you use the opengl subsystem?

Re: 3D demo 'Entity2'

Posted: Mon Dec 05, 2011 3:23 am
by BasicallyPure
idle wrote:when you ran it on windows did you use the opengl subsystem?
Yes, the compiler option was set to use opengl library subsystem.

B.P.

Re: 3D demo 'Entity2'

Posted: Mon Dec 05, 2011 7:32 pm
by idle
maybe it should be reported as a bug it should be the same.

Re: 3D demo 'Entity2'

Posted: Tue Dec 06, 2011 2:03 am
by BasicallyPure
Is this the same bug?

http://www.purebasic.fr/english/viewtop ... rored+text

I'm not sure because there is not much of a description of the problem.

B.P.

Edit:
I think it is the same bug because after running the code in the topic above it looks just like the problem
I see with my code.

B.P.

Re: 3D demo 'Entity2'

Posted: Tue Dec 06, 2011 6:23 pm
by BasicallyPure
I have made a slight modification to 'Screen3DRequester.pb' listed above.
I have changed:

Code: Select all

If Not ratio 
  ratio = modes()\width / modes()\height 
EndIf  
to:

Code: Select all

ratio = modes()\width / modes()\height
The elimination of the 'If' statement means that 'ratio' will be determined by the
highest screen resolution, not the lowest.
I encountered a situation where the ratio was going to 'widescreen' values even
though the monitor on the system I was using was not widescreen.
This code change seems to fix that problem.

B.P.