Small cross-platform OpenGL demo

Share your advanced PureBasic knowledge/code with the community.
User avatar
Shardik
Addict
Addict
Posts: 2058
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Small cross-platform OpenGL demo

Post by Shardik »

Because of difficulties in running my above cross-platform OpenGL example in the new PB 4.70 Beta 1 of the new cocoa-framework based Mac version I further simplified the example by rendering the OpenGL content into a WindowedScreen thus eliminating all the platform-specific code to obtain a rendering context of the window in order to let PureBasic do that work. Only in Windows this new simplified code requires the subsystem to be set to OpenGL in the IDE's menu (Compiler/Compiler Options.../Library Subsystem: OpenGL). This new example runs on Macs with PB 4.61 and PB 4.70 Beta 1.5 in 32 bit and 64 bit mode (cocoa framework) and 32 bit (Subsystem: Carbon) and should of course run in all listed OSes from my first post.

Code: Select all

EnableExplicit

#GL_COLOR_BUFFER_BIT = $00004000
#GL_DEPTH_BUFFER_BIT = $00000100
#GL_MODELVIEW  = $1700
#GL_PROJECTION = $1701
#GL_TRIANGLES = 4

CompilerIf #PB_Compiler_OS = #PB_OS_Windows
  CompilerIf Subsystem("OpenGL") = #False
    MessageRequester("Error", "Please set the subsystem to OpenGL")
    End
  CompilerEndIf
CompilerEndIf

If InitSprite() = 0
  MessageRequester("Error", "Can't open screen & sprite environment!")
  End
EndIf

OpenWindow(0, 270, 100, 640, 480, "Cross-platform OpenGL demo", #PB_Window_SystemMenu | #PB_Window_Invisible)
SetWindowColor(0, 0)
OpenWindowedScreen(WindowID(0), 0, 0, WindowWidth(0), WindowHeight(0), 0, 0, 0)

CompilerSelect #PB_Compiler_OS
  CompilerCase #PB_OS_Linux
    ImportC "-lGL"
      glBegin_(PrimitiveID.I) As "glBegin"
      glClear_(BuffersToClear.I) As "glClear"
      glColor3f_(Red.F, Green.F, Blue.F) As "glColor3f"
      glEnd_() As "glEnd"
      glLoadIdentity_() As "glLoadIdentity"
      glMatrixMode_(Target.I) As "glMatrixMode"
      glTranslatef_(x.F, y.F, z.F) As "glTranslatef"
      glVertex3f_(x.F, y.F, z.F) As "glVertex3f"
      glViewport_(x.I, y.I, Width.I, Height.I) As "glViewport"
      glXChooseVisual(*Display, ScreenNumber.I, *AttributeArray)
      glXCreateContext(*Display, *XVisualInfo, GLXContext.I, DirectGraphicsConnection.I)
      glXDestroyContext(*Display, GLXContext.I)
      glXMakeCurrent(*Display, GLXDrawable.I, GLXContext.I)
      glXSwapBuffers(*Display, GLXDrawable.I)
    EndImport

    ImportC "-lGLU"
      gluPerspective_(FieldOfViewAngle.D, AspectRatioWidthToHeight.D, DistanceFromViewerToNearPlane.D, DistanceFromViewerToFarPlane.D) As "gluPerspective"
    EndImport

    ImportC "-lX11" : EndImport
  CompilerCase #PB_OS_MacOS
    ImportC "/System/Library/Frameworks/OpenGL.framework/OpenGL"
      glBegin_(PrimitiveID.I) As "_glBegin"
      glClear_(BuffersToClear.I) As "_glClear"
      glColor3f_(Red.F, Green.F, Blue.F) As "_glColor3f"
      glEnd_() As "_glEnd"
      glLoadIdentity_() As "_glLoadIdentity"
      glMatrixMode_(Target.I) As "_glMatrixMode"
      glTranslatef_(x.F, y.F, z.F) As "_glTranslatef"
      gluPerspective_(FieldOfViewAngle.D, WidthToHeightRatio.D, DistanceToNearPlane.D, DistanceToFarPlane.D) As "_gluPerspective"
      glVertex3f_(x.F, y.F, z.F) As "_glVertex3f"
      glViewport_(x.I, y.I, Width.I, Height.I) As "_glViewport"
    EndImport
CompilerEndSelect

HideWindow(0, #False)

Repeat
  glViewport_(0, 0, WindowWidth(0), WindowHeight(0))
  glMatrixMode_(#GL_PROJECTION)
  glLoadIdentity_()
  gluPerspective_(30.0, Abs(WindowWidth(0) / WindowHeight(0)), 0.1, 500.0)
  glMatrixMode_(#GL_MODELVIEW)
  glLoadIdentity_()
  glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)
  glLoadIdentity_()
  glTranslatef_(0.0, 0.0, -8.0)
  glColor3f_(1.0, 1.0, 1.0)
  glBegin_(#GL_TRIANGLES)      ; Start drawing a triangle
  glColor3f_ ( 1.0,  0.0, 0.0) ; Set top point of triangle to Red
  glVertex3f_( 0.0,  1.0, 0.0) ; First point of the triangle
  glColor3f_ ( 0.0,  1.0, 0.0) ; Set left point of triangle to Green
  glVertex3f_(-1.0, -1.0, 0.0) ; Second point of the triangle
  glColor3f_ ( 0.0,  0.0, 1.0) ; Set right point of triangle to Blue
  glVertex3f_( 1.0, -1.0, 0.0) ; Third point of the triangle
  glEnd_()                     ; Done drawing the triangle

  ; Swap buffers (double buffering) 
  FlipBuffers()
Until WaitWindowEvent() = #PB_Event_CloseWindow
Update: I had to add

Code: Select all

ImportC "-lX11" : EndImport
so that this example also works in OpenSuSE 12.1. Thank you for your hint, Fred.
Last edited by Shardik on Thu Aug 16, 2012 9:15 am, edited 2 times in total.
Fred
Administrator
Administrator
Posts: 18162
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: Small cross-platform OpenGL demo

Post by Fred »

Works perfectly !
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: Small cross-platform OpenGL demo

Post by applePi »

Thank you for the example.
i have tried it to rotate the triangle by adding
spin = spin + 3
glRotatef_(spin, 0.0, 0.0, 1.0 )

before
glBegin_(#GL_TRIANGLES)

but the triangle rotate only when we move the mouse or pressing a key continuously
this is on windows xp.
User avatar
luis
Addict
Addict
Posts: 3893
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: Small cross-platform OpenGL demo

Post by luis »

applePi wrote: but the triangle rotate only when we move the mouse or pressing a key continuously
this is on windows xp.
WindowEvent() does not wait for messages like WaitWindowEvent()
"Have you tried turning it off and on again ?"
A little PureBasic review
gekkonier
User
User
Posts: 78
Joined: Mon Apr 23, 2007 9:42 am

Re: Small cross-platform OpenGL demo

Post by gekkonier »

very nice!
thank you!
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: Small cross-platform OpenGL demo

Post by applePi »

WindowEvent() does not wait for messages like WaitWindowEvent()
great, thank you luis
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: Small cross-platform OpenGL demo

Post by applePi »

the last example by Shardik at the end of page 1 have the simplest structure to contain OpenGl code i have seen (ie the complexities are hidden from the user, which is what should be) so i will use it to insert my port of a cooling fan example posted here http://www.opengl.org/discussion_boards ... on-example in vc++6 which are also have some problems, , press space key to switch the fan on/off.
the most imortant and amusing part is the very short code for fan blades construction inside the fan_render procedure, the other codes are just cosmetic.
the glMaterialfv_ and glLightfv_ functions i have copied from here
http://www.purebasic.fr/english/viewtop ... 12&t=25835
the problem with the code is that i can't cast light on the Fan blades which are just thinned boxes
if you changed line 183 to If angle_direction > 250 so to look at the back of the fan while it is rotating you will see that it is lighted but from back, while the body of the fan are lighted from front.
Image
Image

Code: Select all

InitKeyboard()
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
  CompilerIf Subsystem("OpenGL") = #False
    MessageRequester("Error", "Please set the subsystem to OpenGL")
    End
  CompilerEndIf
CompilerEndIf

If InitSprite() = 0
  MessageRequester("Error", "Can't open screen & sprite environment!")
  End
EndIf

OpenWindow(0, 0, 0, 640, 480, "press space key to switch On/Off the fan rotation", #PB_Window_SystemMenu | #PB_Window_Invisible)
SetWindowColor(0, 0)
OpenWindowedScreen(WindowID(0), 0, 0, WindowWidth(0), WindowHeight(0), 0, 0, 0)

HideWindow(0, #False)
Global running.b = 0;
Global angle_step.f = 0.3
Global angle_direction.f
lngh.f : width.f : depth.f 
Global Dim LightPos.f(4) ;Light Position
 LightPos(0)= 0.0 : LightPos(1)= 5.0 : LightPos(2)=-4.0 : LightPos(3)= 1.0
Global Dim LightAmb.f(4) ;Ambient Light Values
 LightAmb(0)= 0.2 : LightAmb(1)= 0.2 : LightAmb(2)= 0.2 : LightAmb(3)= 1.0
Global Dim LightDif.f(4) ;Diffuse Light Values
 LightDif(0)= 0.6 : LightDif(1)= 0.6 : LightDif(2)= 0.6 : LightDif(3)= 1.0
Global Dim LightSpc.f(4) ;Specular Light Values
LightSpc(0)=-0.2 : LightSpc(1)=-0.2 : LightSpc(2)=-0.2 : LightSpc(3)= 1.0

Global Dim MatAmb.f(4) ;Material - Ambient Values
 MatAmb(0)= 0.4 : MatAmb(1)= 0.4 : MatAmb(2)= 0.4 : MatAmb(3)= 1.0
Global Dim MatDif.f(4) ;Material - Diffuse Values
 MatDif(0)= 1.2 : MatDif(1)= 0.6 : MatDif(2)= 0.0 : MatDif(3)= 1.0
Global Dim MatSpc.f(4) ;Material - Specular Values
 MatSpc(0)= 0.0 : MatSpc(1)= 0.0 : MatSpc(2)= 0.0 : MatSpc(3)= 1.0
Global Dim MatShn.f(1) ;Material - Shininess
MatShn(0)= 0.0


glClearColor_ (0.0, 0.0, 0.0, 0.0);
glShadeModel_ (#GL_SMOOTH)

glEnable_(#GL_LIGHTING);
glEnable_(#GL_LIGHT0);
glEnable_(#GL_DEPTH_TEST);

glLightfv_(#GL_LIGHT1,#GL_POSITION,LightPos()) ;Set Light1 Position
glLightfv_(#GL_LIGHT1,#GL_AMBIENT,LightAmb()) ;Set Light1 Ambience
glLightfv_(#GL_LIGHT1,#GL_DIFFUSE,LightDif()) ;Set Light1 Diffuse
glLightfv_(#GL_LIGHT1,#GL_SPECULAR,LightSpc()) ;Set Light1 Specular
glEnable_(#GL_LIGHT1) ;Enable Light1
glEnable_(#GL_LIGHTING) ;Enable Lighting
 
glMaterialfv_(#GL_FRONT,#GL_AMBIENT,MatAmb()) ;Set Material Ambience
glMaterialfv_(#GL_FRONT,#GL_DIFFUSE,MatDif()) ;Set Material Diffuse
glMaterialfv_(#GL_FRONT,#GL_SPECULAR,MatSpc()) ;Set Material Specular
glMaterialfv_(#GL_FRONT,#GL_SHININESS,MatShn()) ;Set Material Shininess
Procedure.l blade(lngh.f, width.f, depth.f)
   a.f = lngh: b.f = width: c.f = depth
        
glBegin_(#GL_QUADS);

; Top face of box
    ;glColor3f_(1.0, 0.0, 0.0)
    
    glVertex3f_(a, b, -c);     // Top right vertex (Top of cube)
    glVertex3f_(-a, b, -c);    //Top left vertex (Top of cube)
    glVertex3f_(-a, b, c);     // Bottom left vertex (Top of cube)
    glVertex3f_(a, b, c);      // Bottom right vertex (Top of cube)

    ;Bottom face of box
        
    glVertex3f_(a, -b, -c);     // Top right vertex (Bottom of cube)
    glVertex3f_(-a, -b, -c);    // Top left vertex (Bottom of cube)
    glVertex3f_(-a, -b, c);   // Bottom left vertex (Bottom of cube)
    glVertex3f_( a, -b, c);   // Bottom right vertex (Bottom of cube)
    glColor3f_(1.0,0.0,0.0);
    ;Front of box
       
    glVertex3f_(a, b, c);      // Top right vertex (Front)
    glVertex3f_(-a, b, c);     // Top left vertex (Front)
    glVertex3f_(-a, -b, c);    // Bottom left vertex (Front)
    glVertex3f_(a, -b, c);     // Bottom right vertex (Front)
    glColor3f_(1.0,0.0,0.0);
    ;Back of box
        
    glVertex3f_(a, -b, -c);    // Bottom right vertex (Back)
    glVertex3f_(-a, -b, -c);   // Bottom left vertex (Back)
    glVertex3f_(-a, b, -c);    // top left vertex (Back)
    glVertex3f_(a, b, -c);     // Top right vertex (Back)
    glColor3f_(1.0,0.0,0.0);
    ;Left of box
        
    glVertex3f_(-a, b, c);     // Top right vertex (Left)
    glVertex3f_(-a, b, -c);    // Top left vertex (Left)
    glVertex3f_(-a, -b, -c);   // Bottom left vertex (Left)
    glVertex3f_(-a, -b, c);    // Bottom vertex (Left)
    glColor3f_(1.0,0.0,0.0);
    ;Right of box
        
    glVertex3f_(a, b, -c);     // Top right vertex (Right)
    glVertex3f_(a, b, c);      // Top left vertex (Right)
    glVertex3f_(a, -b, c);     // Bottom left vertex (Right)
    glVertex3f_(a, -b, -c);    // Bottom right vertex (Right)
    glColor3f_(1.0,0.0,0.0);
    ;End drawing the box
    glEnd_(); 
    ;Return TRUE;
            


EndProcedure 
Procedure.l Fan_Render(spin.f)
  glPushMatrix_();
  ;Fan
  glPushMatrix_();
  ;Fan Base:
      qobj = gluNewQuadric_();
      gluQuadricDrawStyle_(qobj, #GL_FILL); /* smooth shaded */
      gluQuadricNormals_(qobj, #GL_SMOOTH);
      glScalef_( 4 , 0.5 , 4 );
      glEnable_(#GL_NORMALIZE);
      ;Sphere With radius 0.25 then scaled
      gluSphere_(qobj, 0.25, 20, 20);
      glPopMatrix_();
   ;Fan stand:  
    glPushMatrix_();
      gluQuadricDrawStyle_(qobj, #GL_FILL); /* flat shaded */
      gluQuadricNormals_(qobj, #GL_FLAT);
      glRotatef_(-90, 1.0, 0.0, 0.0);
      gluCylinder_(qobj, 0.125, 0.125, 3, 16, 10);
    
    glPopMatrix_();
    ;Fan Motor:
    glRotatef_(angle_direction, 0.0, 1.0, 0.0)
    glPushMatrix_();
     gluQuadricDrawStyle_(qobj, #GL_FILL); /* smooth shaded */
      gluQuadricNormals_(qobj, #GL_SMOOTH);
      glTranslatef_(0.0, 2.5, 0.0);
      glScalef_( 0.5, 0.5, 1);
      glEnable_(#GL_NORMALIZE);
      gluSphere_(qobj, 1 , 20 , 20 ); 
      glPopMatrix_();
      
    ;**********************************************
   
   ;Blades construction
   glTranslatef_(0.0, 2.5, 0.5)
   ;glClear_ (#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT) 
  glRotatef_(spin, 0.0, 0.0, 1.0 );
   For i = 1 To 360  Step 60
   
      glPushMatrix_();
      glRotatef_( i, 0.0, 0.0, 1.0 );
      glTranslatef_(1.2, 0.0, 0.0);
      glRotatef_( -45, 1.0, 0.0, 0.0 );
      glShadeModel_(#GL_FLAT);   
      glEnable_(#GL_DEPTH_TEST);
      glEnable_(#GL_LIGHTING);
    glEnable_(#GL_LIGHT0);  
     ;glMaterialfv_p(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_amb_diff_color);
     glPushMatrix_();
      ;calling blade ie: drawing the Blade of the fan*/
      ;glClear_ (#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT) 
      blade(0.8,0.3,0.01);
      glPopMatrix_();
      glPopMatrix_();
      
   Next
glPopMatrix_();
glPopMatrix_();
glPopMatrix_();
EndProcedure 
Procedure.f Fan_Physics()
   Static spin.f
   Static speed.f
   If running = 1
     speed = speed + 1
     angle_direction = angle_direction + angle_step
    If angle_direction > 110 
      angle_step = -0.3
      ElseIf angle_direction < 0 
           angle_step = 0.3
    EndIf  
   EndIf
   If speed > 360.0: speed = 360.0: EndIf
   If running = 0 :speed = speed - 1.8: EndIf
  If speed < 0: speed = 0: EndIf
  spin = spin + speed/100
  ProcedureReturn spin
      
EndProcedure
HideWindow(0, #False)

  Procedure.l Fan_Run()
  glViewport_(0, 0, WindowWidth(0), WindowHeight(0))
  glMatrixMode_(#GL_PROJECTION)
  glLoadIdentity_()
  gluPerspective_(30.0, Abs(WindowWidth(0) / WindowHeight(0)), 0.1, 500.0)
  glMatrixMode_(#GL_MODELVIEW)
  glLoadIdentity_()
  glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)
   glLoadIdentity_ ()
   ; viewing transformation  
   glTranslatef_(0.0, 0.0, -6.0); 
   gluLookAt_(5,5,5,0,1.5,0,0,1,0);
   spin.f = Fan_Physics();
   
   Fan_Render(spin);
  
EndProcedure


While Quit.b = 0

  Repeat 
    EventID = WindowEvent()
    Select EventID
           
      Case #PB_Event_CloseWindow
        Quit = 1
    EndSelect
    ExamineKeyboard()
  If KeyboardReleased(#PB_Key_Space)
      running ! 1
      
   EndIf
  
  Fan_Run()
  FlipBuffers()
  Delay(1)
  
  Until EventID = 0
  
Wend

End
Last edited by applePi on Sun Jul 20, 2014 1:07 pm, edited 2 times in total.
User avatar
luis
Addict
Addict
Posts: 3893
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: Small cross-platform OpenGL demo

Post by luis »

Uhmmm... I see some problems with the code above, but I'm too lazy to try to understand all the push/pop involved :)

Anyway I see some push/pop unbalanced, unless I'm mistaken. About the blades, probably the problem is you didn't set the normals ?
For the other objects using the glu_ library I believe the normals are created automatically, even if using the scaling distort them (so you have to use #GL_NORMALIZE).

I have enabled color tracking to simplify things and I made this quick hack (horrible as it is):

Code: Select all

IncludeFile #PB_Compiler_Home + "Examples\Sources - Advanced\OpenGL Cube\OpenGL.pbi"
InitKeyboard()
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
  CompilerIf Subsystem("OpenGL") = #False
    MessageRequester("Error", "Please set the subsystem to OpenGL")
    End
  CompilerEndIf
CompilerEndIf

If InitSprite() = 0
  MessageRequester("Error", "Can't open screen & sprite environment!")
  End
EndIf

OpenWindow(0, 0, 0, 640, 480, "press space key to switch On/Off the fan rotation", #PB_Window_SystemMenu | #PB_Window_Invisible)
SetWindowColor(0, 0)
OpenWindowedScreen(WindowID(0), 0, 0, WindowWidth(0), WindowHeight(0), 0, 0, 0)

HideWindow(0, #False)
Global running.b = 0;
Global angle_step.f = 0.3
Global angle_direction.f
lngh.f : width.f : depth.f
Global Dim LightPos.f(4) ;Light Position
 LightPos(0)= 0.0 : LightPos(1)= 5.0 : LightPos(2)=-4.0 : LightPos(3)= 1.0
Global Dim LightAmb.f(4) ;Ambient Light Values
 LightAmb(0)= 0.2 : LightAmb(1)= 0.2 : LightAmb(2)= 0.2 : LightAmb(3)= 1.0
Global Dim LightDif.f(4) ;Diffuse Light Values
 LightDif(0)= 0.6 : LightDif(1)= 0.6 : LightDif(2)= 0.6 : LightDif(3)= 1.0
Global Dim LightSpc.f(4) ;Specular Light Values
LightSpc(0)=-0.2 : LightSpc(1)=-0.2 : LightSpc(2)=-0.2 : LightSpc(3)= 1.0

Global Dim MatAmb.f(4) ;Material - Ambient Values
 MatAmb(0)= 0.4 : MatAmb(1)= 0.4 : MatAmb(2)= 0.4 : MatAmb(3)= 1.0
Global Dim MatDif.f(4) ;Material - Diffuse Values
 MatDif(0)= 1.0 : MatDif(1)= 0.6 : MatDif(2)= 0.0 : MatDif(3)= 1.0
Global Dim MatSpc.f(4) ;Material - Specular Values
 MatSpc(0)= 0.0 : MatSpc(1)= 0.0 : MatSpc(2)= 0.0 : MatSpc(3)= 1.0
Global Dim MatShn.f(1) ;Material - Shininess
MatShn(0)= 0.0


glClearColor_ (0.0, 0.0, 0.0, 0.0);
glShadeModel_ (#GL_SMOOTH)

glEnable_(#GL_LIGHTING);
glEnable_(#GL_LIGHT0);
glEnable_(#GL_DEPTH_TEST);

glLightfv_(#GL_LIGHT1,#GL_POSITION,LightPos()) ;Set Light1 Position
glLightfv_(#GL_LIGHT1,#GL_AMBIENT,LightAmb()) ;Set Light1 Ambience
glLightfv_(#GL_LIGHT1,#GL_DIFFUSE,LightDif()) ;Set Light1 Diffuse
glLightfv_(#GL_LIGHT1,#GL_SPECULAR,LightSpc()) ;Set Light1 Specular
;glEnable_(#GL_LIGHT1) ;Enable Light1
glEnable_(#GL_LIGHTING) ;Enable Lighting
 
; glMaterialfv_(#GL_FRONT,#GL_AMBIENT,MatAmb()) ;Set Material Ambience
; glMaterialfv_(#GL_FRONT,#GL_DIFFUSE,MatDif()) ;Set Material Diffuse
; glMaterialfv_(#GL_FRONT,#GL_SPECULAR,MatSpc()) ;Set Material Specular
; glMaterialfv_(#GL_FRONT,#GL_SHININESS,MatShn()) ;Set Material Shininess

glColorMaterial_(#GL_FRONT,  #GL_AMBIENT_AND_DIFFUSE)
glEnable_(#GL_COLOR_MATERIAL) ; color tracking

glEnable_(#GL_NORMALIZE)

Procedure.l blade(lngh.f, width.f, depth.f)
   a.f = lngh: b.f = width: c.f = depth
       
glBegin_(#GL_QUADS);

; Top face of box
    glColor3f_(1.0, 0.0, 0.0) ; red blades !
    glNormal3f_(0.0, 1.0, 0.0)
   
    glVertex3f_(a, b, -c);     // Top right vertex (Top of cube)
    glVertex3f_(-a, b, -c);    //Top left vertex (Top of cube)
    glVertex3f_(-a, b, c);     // Bottom left vertex (Top of cube)
    glVertex3f_(a, b, c);      // Bottom right vertex (Top of cube)

    ;Bottom face of box
   
    glNormal3f_(0.0, -1.0, 0.0)   
    glVertex3f_(a, -b, -c);     // Top right vertex (Bottom of cube)
    glVertex3f_(-a, -b, -c);    // Top left vertex (Bottom of cube)
    glVertex3f_(-a, -b, c);   // Bottom left vertex (Bottom of cube)
    glVertex3f_( a, -b, c);   // Bottom right vertex (Bottom of cube)
   
    ;Front of box
   
    glNormal3f_(0.0, 0.0, 1.0)     
    glVertex3f_(a, b, c);      // Top right vertex (Front)
    glVertex3f_(-a, b, c);     // Top left vertex (Front)
    glVertex3f_(-a, -b, c);    // Bottom left vertex (Front)
    glVertex3f_(a, -b, c);     // Bottom right vertex (Front)
   
    ;Back of box
   
    glNormal3f_(0.0, 0.0, -1.0)     
    glVertex3f_(a, -b, -c);    // Bottom right vertex (Back)
    glVertex3f_(-a, -b, -c);   // Bottom left vertex (Back)
    glVertex3f_(-a, b, -c);    // top left vertex (Back)
    glVertex3f_(a, b, -c);     // Top right vertex (Back)
   
    ;Left of box
   
    glNormal3f_(-1.0, 0.0, 0.0)         
    glVertex3f_(-a, b, c);     // Top right vertex (Left)
    glVertex3f_(-a, b, -c);    // Top left vertex (Left)
    glVertex3f_(-a, -b, -c);   // Bottom left vertex (Left)
    glVertex3f_(-a, -b, c);    // Bottom vertex (Left)
   
    ;Right of box
       
    glNormal3f_(1.0, 0.0, 0.0)   
    glVertex3f_(a, b, -c);     // Top right vertex (Right)
    glVertex3f_(a, b, c);      // Top left vertex (Right)
    glVertex3f_(a, -b, c);     // Bottom left vertex (Right)
    glVertex3f_(a, -b, -c);    // Bottom right vertex (Right)
   
    ;End drawing the box
    glEnd_();
    ;Return TRUE;
           


EndProcedure

Procedure.l Fan_Render(spin.f)
glPushMatrix_();

  glColor3f_(1.0, 1.0, 0.0)
 
  ;Fan
  glPushMatrix_();
  ;Fan Base:
        qobj = gluNewQuadric_();
      gluQuadricDrawStyle_(qobj, #GL_FILL); /* smooth shaded */
      gluQuadricNormals_(qobj, #GL_SMOOTH);
      glScalef_( 4 , 0.5 , 4 );
      ;glEnable_(#GL_NORMALIZE);
      ;Sphere With radius 0.25 then scaled
      gluSphere_(qobj, 0.25, 20, 20);
  glPopMatrix_();
   
   ;Fan stand:
  glPushMatrix_();
      gluQuadricDrawStyle_(qobj, #GL_FILL); /* flat shaded */
      gluQuadricNormals_(qobj, #GL_FLAT);
      glRotatef_(-90, 1.0, 0.0, 0.0);
      gluCylinder_(qobj, 0.125, 0.125, 3, 16, 10);
   
  glPopMatrix_();
   
    ;Fan Motor:
    glRotatef_(angle_direction, 0.0, 1.0, 0.0)
  glPushMatrix_();
     gluQuadricDrawStyle_(qobj, #GL_FILL); /* smooth shaded */
     gluQuadricNormals_(qobj, #GL_SMOOTH);
      glTranslatef_(0.0, 2.5, 0.0);
      glScalef_( 0.5, 0.5, 1);
      ;glEnable_(#GL_NORMALIZE);
      gluSphere_(qobj, 1 , 20 , 20 );
  glPopMatrix_();

   ;Blades construction
   glTranslatef_(0.0, 2.5, 0.5)
   ;glClear_ (#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)
  glRotatef_(spin, 0.0, 0.0, 1.0 );
   For i = 1 To 360  Step 60
   
    glPushMatrix_();
      glRotatef_( i, 0.0, 0.0, 1.0 );
      glTranslatef_(1.2, 0.0, 0.0);
      glRotatef_( -45, 1.0, 0.0, 0.0 );
      glShadeModel_(#GL_FLAT);   
      glEnable_(#GL_DEPTH_TEST);
;      glEnable_(#GL_LIGHTING);
;    glEnable_(#GL_LIGHT0);
     ;glMaterialfv_p(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_amb_diff_color);
     glPushMatrix_();
      ;calling blade ie: drawing the Blade of the fan*/
      ;glClear_ (#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)
      blade(0.8,0.3,0.01);
     glPopMatrix_();
    glPopMatrix_();     
   Next
       
 ;   **********************************************
   
glPopMatrix_();
;glPopMatrix_();
;glPopMatrix_();
EndProcedure
Procedure.f Fan_Physics()
   Static spin.f
   Static speed.f
   If running = 1
     speed = speed + 1
     angle_direction = angle_direction + angle_step
    If angle_direction > 110
      angle_step = -0.3
      ElseIf angle_direction < 0
           angle_step = 0.3
    EndIf
   EndIf
   If speed > 360.0: speed = 360.0: EndIf
   If running = 0 :speed = speed - 1.8: EndIf
  If speed < 0: speed = 0: EndIf
  spin = spin + speed/100
  ProcedureReturn spin
     
EndProcedure
HideWindow(0, #False)

  Procedure.l Fan_Run()
  glViewport_(0, 0, WindowWidth(0), WindowHeight(0))
  glMatrixMode_(#GL_PROJECTION)
  glLoadIdentity_()
  gluPerspective_(30.0, Abs(WindowWidth(0) / WindowHeight(0)), 0.1, 500.0)
  glMatrixMode_(#GL_MODELVIEW)
  glLoadIdentity_()
  glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)
   glLoadIdentity_ ()
   ; viewing transformation
   glTranslatef_(0.0, 0.0, -6.0);
   gluLookAt_(5,5,5,0,1.5,0,0,1,0);
   spin.f = Fan_Physics();
   
   Fan_Render(spin);
 
EndProcedure


While Quit.b = 0

  Repeat
    EventID = WindowEvent()
    Select EventID
           
      Case #PB_Event_CloseWindow
        Quit = 1
    EndSelect
    ExamineKeyboard()
  If KeyboardReleased(#PB_Key_Space)
      running ! 1
   EndIf
 
  Fan_Run()
  FlipBuffers()
  Delay(1)
 
  Until EventID = 0
 
Wend

End
BTW: NOT is an unary operator and I believe that code should be refused by the compiler, I changed that line with a bitwise XOR that should work better.

Nice demo, thanks for the PB conversion, I like the simulated inertia of the blades !

Maybe I'll adapt it and steal it as a demo to be included in the lib I'm writing eh eh eh.
"Have you tried turning it off and on again ?"
A little PureBasic review
Polo
Addict
Addict
Posts: 2422
Joined: Tue May 06, 2003 5:07 pm
Location: UK

Re: Small cross-platform OpenGL demo

Post by Polo »

Is it just me or OpenWindowedScreen doesn't create a depth buffer on OSX (but does create one on Windows)?
DarkDragon
Addict
Addict
Posts: 2344
Joined: Mon Jun 02, 2003 9:16 am
Location: Germany
Contact:

Re: Small cross-platform OpenGL demo

Post by DarkDragon »

Polo wrote:Is it just me or OpenWindowedScreen doesn't create a depth buffer on OSX (but does create one on Windows)?
It never creates a depth buffer, except if you use ogre. It doesn't even create a depth buffer on windows here, or at least I've had this problem once with an earlier PB version. However, it should never initialize one if it isn't needed.

@applePi: enable cull face and draw 2 quads for each wing with negated normals.
bye,
Daniel
xorc1zt
Enthusiast
Enthusiast
Posts: 276
Joined: Sat Jul 09, 2011 7:57 am

Re: Small cross-platform OpenGL demo

Post by xorc1zt »

the windows context has zbuffer by default now

Code: Select all

InitSprite()
OpenWindow(0, 100, 100, 1280, 800, "gl" , #PB_Window_SystemMenu)
OpenWindowedScreen(WindowID(0), 0, 0, 1280, 800, 1, 0, 0, #PB_Screen_NoSynchronization)

Define pfd.PIXELFORMATDESCRIPTOR
Define hdc.i = wglGetCurrentDC_()
Define iPixelFormat.i = GetPixelFormat_(hdc)

DescribePixelFormat_(hdc, iPixelFormat, SizeOf(PIXELFORMATDESCRIPTOR), @pfd)

Debug pfd\cDepthBits
End
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: Small cross-platform OpenGL demo

Post by applePi »

thank you luis for the corrections, at least we have a red fan blades for a summer cooling air, in fact i have copied the vc++6 code blindly and applied instead the c++ functions the PB functions, as you may have noticed there is still the c++ ";" that c++ code also ported erroneously from another place and so on, so you can use and improve it. i like especialy the physics , and i thought of a very small rotate back of the fan when it stop as the usual oldy fans. i have imagined last night the code in PB Ogre, with fan blades connected to one node, also casting shadow on a table, i hope it is much smaller and simpler, i will try it.
@DarkDragon, i will try your suggestions, thank you.
Fred
Administrator
Administrator
Posts: 18162
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: Small cross-platform OpenGL demo

Post by Fred »

You can use a CompilerError to notify the subsystem error:

Code: Select all

CompilerIf #PB_Compiler_OS = #PB_OS_Windows And Subsystem("OpenGL") = #False
  CompilerError "Please set the subsystem To OpenGL"
CompilerEndIf
Nice code !
User avatar
fsw
Addict
Addict
Posts: 1603
Joined: Tue Apr 29, 2003 9:18 pm
Location: North by Northwest

Re: Small cross-platform OpenGL demo

Post by fsw »

Fred wrote:You can use a CompilerError to notify the subsystem error:

Code: Select all

CompilerIf #PB_Compiler_OS = #PB_OS_Windows And Subsystem("OpenGL") = #False
  CompilerError "Please set the subsystem To OpenGL"
CompilerEndIf
Nice code !
It would be nice if this would be possible:

Code: Select all

CompilerIf #PB_Compiler_OS = #PB_OS_Windows And Subsystem("OpenGL") = #False
  SetSubsystem("OpenGL")
  CompilerIf Subsystem("OpenGL") = #False
    CompilerError "Unable to set the OpenGL subsystem!"
  CompilerEndIf
CompilerEndIf

I am to provide the public with beneficial shocks.
Alfred Hitshock
DarkDragon
Addict
Addict
Posts: 2344
Joined: Mon Jun 02, 2003 9:16 am
Location: Germany
Contact:

Re: Small cross-platform OpenGL demo

Post by DarkDragon »

xorc1zt wrote:the windows context has zbuffer by default now
Seems to be a bug, since we don't need a z-buffer until we use OGRE. Once upon a time it was already like this, I don't know why it has been changed on windows and not on other operating systems. Eating system resources which are not needed isn't good. Its possible to choose another pixelformat for better performance (but that has to be decided for each device), but enabling the depth buffer won't increase the speed, so there's no reason to enable it.
bye,
Daniel
Post Reply