OpenGL Gadget: How to accurately display a Shape?

Everything related to 3D programming
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

OpenGL Gadget: How to accurately display a Shape?

Post by IdeasVacuum »

My program will process a number of large STL models (one-at-a-time, only one mesh loaded). They are all similar in size, Hgt 2400, Width 1200, Depth 2200 +- 500mm or so, and roughly 130,000 faces. My issue is getting the mesh to display with accurate proportions.

To demonstrate what I have wrong, below is an example which is simply the space envelope (a box that would fully contain the actual mesh). I have made various attempts to get the display to be proportional, but, using glOrtho(), the box is always squished. Observing the lines that represent the X, Y, Z world axis, the height of the mesh and the height of the Y line (green) are always very squished.

I can see there needs to be a proportional relationship between the View Port Size and The Mesh Shape/Size - but how?

My Example:

Code: Select all

;SpaceEnvExample.pb

;Typical Mesh Size
;igTotalFaces-->128737<--

;Bounding Box (Space Envelope)
;BoxWidth-->1077.0000<--
;BoxHeight-->2352.0000<--
;BoxDepth-->2180.0000<--

EnableExplicit

Enumeration
#WinMain
#OpenGlGadget
#Timer
EndEnumeration

Structure Vertices
x.f
y.f
z.f
EndStructure

Global Dim Vtx.Vertices(35)

;Space Envelope
;T1
Vtx(0)\x = -486.0882 : Vtx(0)\y = -2.17994 : Vtx(0)\z = 143.2799
Vtx(1)\x = 590.9118 : Vtx(1)\y = -2.17994 : Vtx(1)\z = 143.2799
Vtx(2)\x = 590.9118 : Vtx(2)\y = 2349.8200 : Vtx(2)\z = 143.2799

;T2
Vtx(3)\x = 590.9118 : Vtx(3)\y = 2349.8200 : Vtx(3)\z = 143.2799
Vtx(4)\x = -486.0882 : Vtx(4)\y = 2349.8200 : Vtx(4)\z = 143.2799
Vtx(5)\x = -486.0882 : Vtx(5)\y = -2.17994 : Vtx(5)\z = 143.2799

;T3
Vtx(6)\x = -486.0882 : Vtx(6)\y = 2349.8200 : Vtx(6)\z = 143.2799
Vtx(7)\x = -486.0882 : Vtx(7)\y = -2.17994 : Vtx(7)\z = -2036.7200
Vtx(8)\x = -486.0882 : Vtx(8)\y = -2.17994 : Vtx(8)\z = 143.2799

;T4
Vtx(9)\x = -486.0882 : Vtx(9)\y = 2349.8200 : Vtx(9)\z = 143.2799
Vtx(10)\x = -486.0882 : Vtx(10)\y = 2349.8200 : Vtx(10)\z = -2036.7200
Vtx(11)\x = -486.0882 : Vtx(11)\y = -2.17994 : Vtx(11)\z = -2036.7200

;T5
Vtx(12)\x = 590.9118 : Vtx(12)\y = -2.17994 : Vtx(12)\z = 143.2799
Vtx(13)\x = 590.9118 : Vtx(13)\y = -2.17994 : Vtx(13)\z = -2036.7200
Vtx(14)\x = 590.9118 : Vtx(14)\y = 2349.8200 : Vtx(14)\z = 143.2799

;T6
Vtx(15)\x = 590.9118 : Vtx(15)\y = -2.17994 : Vtx(15)\z = 143.2799
Vtx(16)\x = 590.9118 : Vtx(16)\y = 2349.8200 : Vtx(16)\z = -2036.7200
Vtx(17)\x = 590.9118 : Vtx(17)\y = 2349.8200 : Vtx(17)\z = 143.2799

;T7
Vtx(18)\x = 590.9118 : Vtx(18)\y = 2349.8200 : Vtx(18)\z = 143.2799
Vtx(19)\x = 590.9118 : Vtx(19)\y = 2349.8200 : Vtx(19)\z = -2036.7200
Vtx(20)\x = -486.0882 : Vtx(20)\y = 2349.8200 : Vtx(20)\z = -2036.7200

;T8
Vtx(21)\x = -486.0882 : Vtx(21)\y = 2349.8200 : Vtx(21)\z = 143.2799
Vtx(22)\x = 590.9118 : Vtx(22)\y = 2349.8200 : Vtx(22)\z = 143.2799
Vtx(23)\x = -486.0882 : Vtx(23)\y = 2349.8200 : Vtx(23)\z = -2036.7200

;T9
Vtx(24)\x = -486.0882 : Vtx(24)\y = -2.17994 : Vtx(24)\z = 143.2799
Vtx(25)\x = 590.9118 : Vtx(25)\y = -2.17994 : Vtx(25)\z = 143.2799
Vtx(26)\x = -486.0882 : Vtx(26)\y = -2.17994 : Vtx(26)\z = -2036.72

;T10
Vtx(27)\x = 590.9118 : Vtx(27)\y = -2.17994 : Vtx(27)\z = 143.2799
Vtx(28)\x = -486.0882 : Vtx(29)\y = -2.17994 : Vtx(29)\z = -2036.7200
Vtx(29)\x = 590.9118 : Vtx(28)\y = -2.17994 : Vtx(28)\z = -2036.72

;T11
Vtx(30)\x = 590.9118 : Vtx(30)\y = -2.17994 : Vtx(30)\z = -2036.7200
Vtx(31)\x = -486.0882 : Vtx(31)\y = -2.17994 : Vtx(31)\z = -2036.7200
Vtx(32)\x = 590.9118 : Vtx(32)\y = 2349.8200 : Vtx(32)\z = -2036.7200

;T12
Vtx(33)\x = 590.9118 : Vtx(33)\y = 2349.8200 : Vtx(33)\z = -2036.7200
Vtx(34)\x = -486.0882 : Vtx(34)\y = 2349.8200 : Vtx(34)\z = -2036.7200
Vtx(35)\x = -486.0882 : Vtx(35)\y = -2.17994 : Vtx(35)\z = -2036.7200

XIncludeFile "CameraModule.pb"
UseModule Camera

Macro Macro_GlClear
;#-----------------
                    glClearColor_(0.0863,0.0863,0.0863, 1) ;Model Space Colour
                         glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)
EndMacro

Procedure DrawMesh()
;#------------------
                         Macro_GlClear

                         Camera::TrackBallLookAt()

                                   glColor3f_(0.4980,0.0745,0.9216)
                         glEnableClientState_(#GL_VERTEX_ARRAY)

                             glVertexPointer_(3, #GL_FLOAT, SizeOf(Vertices), @Vtx(0)\x)

                                glDrawArrays_(#GL_TRIANGLES, 0, ArraySize(Vtx()))

                        glDisableClientState_(#GL_VERTEX_ARRAY)

                                ;X Axis Red
                                 glLineWidth_(5)
                                   glColor3f_(1.0, 0.0, 0.0)
                                     glBegin_(#GL_LINES)
                                  glVertex3f_(0.0, 0.0, 0.0)
                                  glVertex3f_(300, 0, 0)
                                ;Y Axis Green
                                   glColor3f_(0.0, 1.0, 0.0)
                                     glBegin_(#GL_LINES)
                                  glVertex3f_(0.0, 0.0, 0.0)
                                  glVertex3f_(0, 300, 0)
                                ;Z Axis Blue
                                   glColor3f_(0.0, 0.0, 1.0)
                                     glBegin_(#GL_LINES)
                                  glVertex3f_(0.0, 0.0, 0.0)
                                  glVertex3f_(0, 0, 300)
                                       glEnd_()

                                glLineWidth_(0.2) ;model mesh edge thickness

                                 glPopMatrix_()
                                    glFinish_()

                           SetGadgetAttribute(#OpenGlGadget, #PB_OpenGL_FlipBuffers, #True) ;#PB_Screen_NoSynchronization
EndProcedure

Procedure SetupGL()
;#-----------------
Protected iViewPortW.i = (GadgetWidth(#OpenGlGadget) - 20)
Protected iViewPortH.i = (GadgetHeight(#OpenGlGadget) - 20)

                      glMatrixMode_(#GL_PROJECTION)
                    glLoadIdentity_()

                                    ;left  right  top   btm   zNear  zFar
                           glOrtho_(-4000, 4000, -4000, 4000, -5000, 5000) ; <== Mesh fits View Port but shape is squished and is only correct on my PC Monitor

                      glMatrixMode_(#GL_MODELVIEW)
                    glLoadIdentity_()

                        glViewport_(10, 10, iViewPortW, iViewPortH) ;10 pixels offset all round

                     glPolygonMode_(#GL_FRONT_AND_BACK, #GL_LINE) ;wireframe display ;#GL_FILL

                          glEnable_(#GL_DEPTH_TEST) ;Enabled, ensures rendered objects are inside the z-buffer?

                      glShadeModel_(#GL_SMOOTH)
                          glEnable_(#GL_POINT_SMOOTH)
                          glEnable_(#GL_LINE_SMOOTH)
                       glLineWidth_(0.2)

                      glPushMatrix_() ;store current state

                         glEnable_(#GL_LIGHT_MODEL_AMBIENT)

                         Camera::Initialize()
                         Camera::PerspectiveView()

                       glPopMatrix_()
                      glPushMatrix_()
EndProcedure

Procedure WinMain()
;#-----------------
Protected iViewWidth.i, iViewHeight.i

               If OpenWindow(#WinMain, 0, 0, 0, 0, "Right-Mouse Drag to Rotate", #PB_Window_Maximize | #PB_Window_SystemMenu)


                              iViewWidth = (WindowWidth(#WinMain) - 10)
                             iViewHeight = (WindowHeight(#WinMain) - 10)

                               OpenGLGadget(#OpenGlGadget, 5, 5, iViewWidth, iViewHeight, #PB_OpenGL_Keyboard)
                         SetGadgetAttribute(#OpenGlGadget, #PB_OpenGL_Cursor, #PB_Cursor_Cross)
                         SetGadgetAttribute(#OpenGlGadget, #PB_OpenGL_SetContext, #True)

                             AddWindowTimer(#WinMain, #Timer, 16) ;16 = Approx 60 fps
               EndIf
EndProcedure

Procedure WaitForUser()
;#---------------------
Protected iEvent.i, iKey.i, iExit.i = #False

               SetActiveGadget(#OpenGlGadget)
                       SetupGL()

               Repeat
                                iEvent = WaitWindowEvent(1)
                         Select iEvent

                                   Case #PB_Event_Timer

                                                  Select EventTimer()

                                                                 Case #Timer: DrawMesh()
                                                  EndSelect

                                   Case #PB_Event_CloseWindow

                                                  Select EventWindow()

                                                                 Case #WinMain: iExit = #True
                                                  EndSelect

                                   Case #PB_Event_Gadget

                                                  ;Debug "EventGadget()-->" + Str(EventGadget()) + "<--"

                                                  If EventType() = #PB_EventType_KeyDown

                                                                    iKey = GetGadgetAttribute(#OpenGlGadget, #PB_OpenGL_Key)
                                                                 If iKey = #PB_Shortcut_Escape: iExit = #True ;Esc key to exit

                                                                 ElseIf iKey = #PB_Shortcut_Up

                                                                                    Camera::Zooming(-1) ;direction

                                                                 ElseIf iKey = #PB_Shortcut_Down

                                                                                    Camera::Zooming(1)
                                                                 EndIf
                                                  Else

                                                                 Select EventGadget()

                                                                           Case #OpenGlGadget

                                                                                    Select EventType()

                                                                                                   Case      #PB_EventType_MouseWheel: Camera::Zooming(GetGadgetAttribute(#OpenGlGadget, #PB_OpenGL_WheelDelta)) ;use the wheel delta to drive the zoom
                                                                                                   Case #PB_EventType_RightButtonDown: Camera::StartRotation(GetGadgetAttribute(#OpenGlGadget, #PB_OpenGL_MouseX), GetGadgetAttribute(#OpenGlGadget, #PB_OpenGL_MouseY))
                                                                                                   Case   #PB_EventType_RightButtonUp: Camera::StopRotation()
                                                                                                   Case       #PB_EventType_MouseMove: Camera::TrackRotation(GetGadgetAttribute(#OpenGlGadget, #PB_OpenGL_MouseX), GetGadgetAttribute(#OpenGlGadget, #PB_OpenGL_MouseY))
                                                                                    EndSelect
                                                                 EndSelect
                                                  EndIf
                         EndSelect

               Until iExit = #True
EndProcedure

WinMain()
WaitForUser()
End
Starbotic's Camera Module
viewtopic.php?f=36&t=65829&p=488814&hil ... le#p488814

Code: Select all

;CameraModule.pb

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Project name : Trackball Camera for OpenGLGadget()
; File Name : Camera - Module.pb
; File version: 0.9.9
; Programming : OK +/-
; Programmed by : StarBootics
; Date : 29-05-2016
; Last Update : 29-05-2016
; PureBasic code : V5.42 LTS
; Platform : Windows, Linux, MacOS X
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;
; This code is free to be use where ever you like
; but you use it at your own risk.
;
; The author can in no way be held responsible
; for data loss, damage or other annoying
; situations that may occur.
;
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

DeclareModule Camera
 
  Declare.d GetMotionSensitivity()
  Declare.d GetScrollSensitivity()
  Declare.d GetDistance()
  Declare.d GetMinDistance()
  Declare SetMotionSensitivity(P_MotionSensitivity.d)
  Declare SetScrollSensitivity(P_ScrollSensitivity.d)
  Declare SetDistance(P_Distance.d)
  Declare SetMinDistance(P_MinDistance.d)
  Declare Initialize()
  Declare Reset()
  Declare PerspectiveView()
  Declare FrontView()
  Declare BackView()
  Declare RightView()
  Declare LeftView()
  Declare TopView()
  Declare BottomView()
  Declare TrackBallLookAt()
  Declare Zooming(P_Direction.d)
  Declare StartRotation(P_x.l, P_y.l)
  Declare StopRotation()
  Declare TrackRotation(P_x.l, P_y.l)
 
EndDeclareModule

Module Camera
 
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Déclaration de la Structure <<<<<
 
  Structure Instance
   
    MotionSensitivity.d
    ScrollSensitivity.d
    Distance.d
    MinDistance.d
    RotationX.d
    RotationY.d
    MouseLeftButtonHold.b
    MouseX.l
    MouseY.l
   
  EndStructure
 
  Global Instance.Instance
 
  Procedure.f WrapAngleDeg(angle.f)
   
    ; <- wraps a value into [0,360) fringe
   
    ; Author : Psychophanta
   
    !fild dword[@f] ; <- now i have 360 into st0
    !fld dword[p.v_angle]
    !fprem
    !fadd st1,st0
    !fldz
    !fcomip st1
    !fcmovnbe st0,st1
    !fstp st1
    ProcedureReturn
    !@@:dd 360
  EndProcedure
 
 
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Les observateurs <<<<<
 
  Procedure.d GetMotionSensitivity()
   
    ProcedureReturn Instance\MotionSensitivity
  EndProcedure
 
  Procedure.d GetScrollSensitivity()
   
    ProcedureReturn Instance\ScrollSensitivity
  EndProcedure
 
  Procedure.d GetDistance()
   
    ProcedureReturn Instance\Distance
  EndProcedure
 
  Procedure.d GetMinDistance()
   
    ProcedureReturn Instance\MinDistance
  EndProcedure
 
  Procedure.d GetRotationX()
   
    ProcedureReturn Instance\RotationX
  EndProcedure
 
  Procedure.d GetRotationY()
   
    ProcedureReturn Instance\RotationY
  EndProcedure
 
  ; <<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Les mutateurs <<<<<
 
  Procedure SetMotionSensitivity(P_MotionSensitivity.d)
   
    Instance\MotionSensitivity = P_MotionSensitivity
   
  EndProcedure
 
  Procedure SetScrollSensitivity(P_ScrollSensitivity.d)
   
    Instance\ScrollSensitivity = P_ScrollSensitivity
   
  EndProcedure
 
  Procedure SetDistance(P_Distance.d)
   
    Instance\Distance = P_Distance
   
  EndProcedure
 
  Procedure SetMinDistance(P_MinDistance.d)
   
    Instance\MinDistance = P_MinDistance
   
  EndProcedure
 
  Procedure SetRotationX(P_RotationX.d)
   
    Instance\RotationX = P_RotationX
   
  EndProcedure
 
  Procedure SetRotationY(P_RotationY.d)
   
    Instance\RotationY = P_RotationY
   
  EndProcedure
 
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< L'opérateur Initialize <<<<<
 
  Procedure Initialize()
   
    Instance\MotionSensitivity = 1.75
    Instance\ScrollSensitivity = 1.0
    Instance\Distance = 10.0
    Instance\MinDistance = 0.1
    Instance\RotationX = 30.0
    Instance\RotationY = -45.0
    Instance\MouseLeftButtonHold = 0
    Instance\MouseX = 0
    Instance\MouseY = 0
   
  EndProcedure
 
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< L'opérateur Reset <<<<<
 
  Procedure Reset()
   
    Instance\MotionSensitivity = 0.0
    Instance\ScrollSensitivity = 0.0
    Instance\Distance = 0.0
    Instance\MinDistance = 0.0
    Instance\RotationX = 0.0
    Instance\RotationY = 0.0
    Instance\MouseLeftButtonHold = 0
    Instance\MouseX = 0
    Instance\MouseY = 0
   
  EndProcedure
 
  Procedure PerspectiveView()
   
    Instance\RotationX = 30.0
    Instance\RotationY = -45.0
   
  EndProcedure
 
  Procedure FrontView()
   
    Instance\RotationX = 0.0
    Instance\RotationY = 0.0
   
  EndProcedure
 
  Procedure BackView()
   
    Instance\RotationX = 180.0
    Instance\RotationY = 0.0
   
  EndProcedure
 
  Procedure RightView()
   
    Instance\RotationX = 0.0
    Instance\RotationY = -90.0
   
  EndProcedure
 
  Procedure LeftView()
   
    Instance\RotationX = 0.0
    Instance\RotationY = 90.0
   
  EndProcedure
 
  Procedure TopView()
   
    Instance\RotationX = 90.0
    Instance\RotationY = 0.0
   
  EndProcedure
 
  Procedure BottomView()
   
    Instance\RotationX = -90.0
    Instance\RotationY = 0.0
   
  EndProcedure
 
  Procedure TrackBallLookAt()
   
    ;glMatrixMode(#GL_MODELVIEW)
    glLoadIdentity_()
    ; // la caméra regarde le centre (0,0,0) et est sur l'axe Z à une certaine distance du centre donc (0,0, distance)
    gluLookAt_(0, 0, Instance\Distance, 0, 0, 0, 0, 1, 0)
    glRotated_(Instance\RotationX, 1, 0, 0); //la scène est tournée autour de l'axe X
    glRotated_(Instance\RotationY, 0, 1, 0); //la scène est tournée autour de l'axe Y
   
  EndProcedure
 
  Procedure Zooming(P_Direction.d)
   
    Instance\Distance = Instance\Distance + P_Direction * Instance\ScrollSensitivity
   
    If Instance\Distance < Instance\MinDistance
      Instance\Distance = Instance\MinDistance
    EndIf
   
  EndProcedure
 
  Procedure StartRotation(P_x.l, P_y.l)
   
    Instance\MouseLeftButtonHold = #True
    Instance\MouseX = P_x
    Instance\MouseY = P_y
   
  EndProcedure
 
  Procedure StopRotation()
   
    Instance\MouseLeftButtonHold = #False
   
  EndProcedure
 
  Procedure TrackRotation(P_x.l, P_y.l)
   
    If Instance\MouseLeftButtonHold = #True
      Instance\RotationX = WrapAngleDeg(Instance\RotationX + Sign(P_y - Instance\MouseY) * Instance\MotionSensitivity)
      Instance\RotationY = WrapAngleDeg(Instance\RotationY + Sign(P_x - Instance\MouseX) * Instance\MotionSensitivity)
      Instance\MouseX = P_x
      Instance\MouseY = P_y
    EndIf
   
  EndProcedure
 
EndModule

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Code généré en : 00.001 secondes (109000.00 lignes/seconde) <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

CompilerIf #PB_Compiler_IsMainFile
 
 
  ; Global RollAxisX.f
  ; Global RollAxisY.f
  ; Global RollAxisZ.f
  ;
  ; Global RotateSpeedX.f = 1.0
  ; Global RotateSpeedY.f
  ; Global RotateSpeedZ.f = 1.0
  ;
  ; Global ZoomFactor.f = 1.0 ; Distance of the camera. Negative value = zoom back
 
  Procedure DrawCube(Gadget)
   
    SetGadgetAttribute(Gadget, #PB_OpenGL_SetContext, #True)
    Camera::TrackBallLookAt()
   
    glPushMatrix_()                  ; Save the original Matrix coordinates
    glMatrixMode_(#GL_MODELVIEW)
   
    ;   glTranslatef_(0, 0, ZoomFactor)  ;  move it forward a bit
    ;
    ;   glRotatef_ (RollAxisX, 1.0, 0, 0) ; rotate around X axis
    ;   glRotatef_ (RollAxisY, 0, 1.0, 0) ; rotate around Y axis
    ;   glRotatef_ (RollAxisZ, 0, 0, 1.0) ; rotate around Z axis
    ;
    ;   RollAxisX + RotateSpeedX
    ;   RollAxisY + RotateSpeedY
    ;   RollAxisZ + RotateSpeedZ
   
    ; clear framebuffer And depth-buffer
   
    glClear_ (#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)
   
    ; draw the faces of a cube
   
    ; draw colored faces
   
    glDisable_(#GL_LIGHTING)
    glBegin_  (#GL_QUADS)
   
    ; Build a face, composed of 4 vertex !
    ; glBegin() specify how the vertexes are considered. Here a group of
    ; 4 vertexes (GL_QUADS) form a rectangular surface.
   
    ; Now, the color stuff: It's r,v,b but with float values which
    ; can go from 0.0 To 1.0 (0 is .. zero And 1.0 is full intensity)
   
    glNormal3f_ (0,0,1.0)
    glColor3f_  (0,0,1.0)
    glVertex3f_ (0.5,0.5,0.5)   
    glColor3f_  (0,1.0,1.0)         
    glVertex3f_ (-0.5,0.5,0.5)
    glColor3f_  (1.0,1.0,1.0)
    glVertex3f_ (-0.5,-0.5,0.5)
    glColor3f_  (0,0,0)
    glVertex3f_ (0.5,-0.5,0.5)
   
    ; The other face is the same than the previous one
    ; except the colour which is nice blue To white gradiant
   
    glNormal3f_ (0,0,-1.0)
    glColor3f_  (0,0,1.0)
    glVertex3f_ (-0.5,-0.5,-0.5)
    glColor3f_  (0,0,1.0)
    glVertex3f_ (-0.5,0.5,-0.5)
    glColor3f_  (1.0,1.0,1.0)
    glVertex3f_ (0.5,0.5,-0.5)
    glColor3f_  (1.0,1.0,1.0)
    glVertex3f_ (0.5,-0.5,-0.5)
   
    glEnd_()
   
    ; draw shaded faces
   
    glEnable_(#GL_LIGHTING)
    glEnable_(#GL_LIGHT0)
    glBegin_ (#GL_QUADS)
   
    glNormal3f_ (   0, 1.0,   0)
    glVertex3f_ ( 0.5, 0.5, 0.5)
    glVertex3f_ ( 0.5, 0.5,-0.5)
    glVertex3f_ (-0.5, 0.5,-0.5)
    glVertex3f_ (-0.5, 0.5, 0.5)
   
    glNormal3f_ (0,-1.0,0)
    glVertex3f_ (-0.5,-0.5,-0.5)
    glVertex3f_ (0.5,-0.5,-0.5)
    glVertex3f_ (0.5,-0.5,0.5)
    glVertex3f_ (-0.5,-0.5,0.5)
   
    glNormal3f_ (1.0,0,0)
    glVertex3f_ (0.5,0.5,0.5)
    glVertex3f_ (0.5,-0.5,0.5)
    glVertex3f_ (0.5,-0.5,-0.5)
    glVertex3f_ (0.5,0.5,-0.5)
   
    glNormal3f_ (-1.0,   0,   0)
    glVertex3f_ (-0.5,-0.5,-0.5)
    glVertex3f_ (-0.5,-0.5, 0.5)
    glVertex3f_ (-0.5, 0.5, 0.5)
    glVertex3f_ (-0.5, 0.5,-0.5)
   
    glEnd_()
   
    glPopMatrix_()
    glFinish_()
   
    SetGadgetAttribute(Gadget, #PB_OpenGL_FlipBuffers, #True)
  EndProcedure
 
 
  Procedure SetupGL(Width, Height)
   
    glMatrixMode_(#GL_PROJECTION)
    gluPerspective_(45.0, Width/Height, 1.0, 500.0)
   
    ; position viewer
    glMatrixMode_(#GL_MODELVIEW)
   
    glTranslatef_(0, 0, -5.0)
   
    glEnable_(#GL_DEPTH_TEST)   ; Enabled, it slowdown a lot the rendering. It's to be sure than the
                                ; rendered objects are inside the z-buffer.
   
    glEnable_(#GL_CULL_FACE)    ; This will enhance the rendering speed as all the back face will be
                                ; ignored. This works only with CLOSED objects like a cube... Singles
                                ; planes surfaces will be visibles only on one side.
   
    glShadeModel_(#GL_SMOOTH)
  EndProcedure
 
 
  Procedure HandleError (Result, Text$)
    If Result = 0
      MessageRequester("Error", Text$, 0)
      End
    EndIf
  EndProcedure
 
 
  Procedure Reshape()
   
    ResizeGadget(0, #PB_Ignore, #PB_Ignore, WindowWidth(0)-10, WindowHeight(0)-10)
   
    SetGadgetAttribute(0, #PB_OpenGL_SetContext, #True)
    glViewport_(0,0, GadgetWidth(0), GadgetHeight(0))
    glMatrixMode_(#GL_PROJECTION)
    glLoadIdentity_()
    gluPerspective_(30.0, GadgetWidth(0)/GadgetHeight(0), 1.0, 500.0)
    glMatrixMode_(#GL_MODELVIEW)
   
  EndProcedure
 
 
  OpenWindow(0, 0, 0, 800, 600, "OpenGL Gadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget)
 
  OpenGLGadget(0, 5, 5, 790, 590, #PB_OpenGL_Keyboard)
  SetupGL(790, 590)
  Camera::Initialize()
  Camera::TrackBallLookAt()
  AddWindowTimer(0, 1, 16) ; about 60 fps
 
  Repeat
    Event = WaitWindowEvent()
   
    Select Event
       
      Case #PB_Event_SizeWindow
        Reshape()
       
      Case #PB_Event_Timer
        If EventTimer() = 1
          DrawCube(0)
        EndIf
       
      Case #PB_Event_Gadget
       
        Select EventGadget()
           
          Case 0
           
            Select EventType()
               
              Case #PB_EventType_MouseWheel
                Camera::Zooming(GetGadgetAttribute(0, #PB_OpenGL_WheelDelta)) ;use the wheel delta to drive the zoom
               
              Case #PB_EventType_LeftButtonDown
                Camera::StartRotation(GetGadgetAttribute(0, #PB_OpenGL_MouseX), GetGadgetAttribute(0, #PB_OpenGL_MouseY))
               
              Case #PB_EventType_LeftButtonUp
                Camera::StopRotation()
               
              Case #PB_EventType_MouseMove
                Camera::TrackRotation(GetGadgetAttribute(0, #PB_OpenGL_MouseX), GetGadgetAttribute(0, #PB_OpenGL_MouseY))
               
            EndSelect
           
        EndSelect
       
    EndSelect
   
  Until Event = #PB_Event_CloseWindow
 
CompilerEndIf

; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< END OF FILE <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
Samuel
Enthusiast
Enthusiast
Posts: 755
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Re: OpenGL Gadget: How to accurately display a Shape?

Post by Samuel »

I think this will work.

Code: Select all

glViewport_(0, 0, WinWidth, WinHeight)
If WinWidth >= WinHeight
  ratio = WinWidth / WinHeight
  glOrtho_(-4000 * ratio, 4000 * ratio, -4000, 4000, -5000, 5000)
Else
  ratio = WinHeight / WinWidth
  glOrtho_(-4000, 4000, -4000 * ratio, 4000 * ratio, -5000, 5000)
Endif
You'll need to update the orthographic matrix and viewport whenever your window changes size.
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: OpenGL Gadget: How to accurately display a Shape?

Post by applePi »

not sure if this is useful for IdeasVacuum:
i have added samuel code in addition To my primary approximate strategy to let the stl mesh fit To the window (in Ogre we have MeshRadius)
my approach is to know the biggest number in either x,y,z and consider it as radius

Code: Select all

If Abs(vertex(t)\x) > num
   radius.f = Abs(vertex(t)\x)
EndIf
...      
glOrtho_(-radius*1.0 * ratio, radius*1.0 * ratio, -radius*1.0, radius*1.0, -radius*1.0, radius*1.0)
try it to the STL meshes of any size such as owl, purebasic, spider, IdeasVacuum box. and it will fit approximately to the windows.
owl, spider, purebasic"
http://s000.tinyupload.com/index.php?fi ... 1296197433
very_big_box (ideasvacum box):
http://s000.tinyupload.com/index.php?fi ... 2680275655

put the stl mesh in the same folder as the code
in line 14 stlMesh.s = "spider.stl" change the stl file name to load it
works only with text stl and not binary

Code: Select all

Declare findNumbers(s.s)
Global t

Structure vert
 x.f
 y.f
 z.f
 nx.f ;for normals
 ny.f
 nz.f
EndStructure 

 
stlMesh.s = "spider.stl"
;stlMesh.s = "purebasic.stl"
;stlMesh.s = "very_big_box.stl"
;stlMesh.s = "owl.stl"

If ReadFile(0, stlMesh)   ; if the file could be read, we continue...
  While Eof(0) = 0                   ; loop as long the 'end of file' isn't reached
    s$ = ReadString(0)
    If FindString(s$, "vertex")
      lines+1
    EndIf
  Wend
EndIf

CloseFile(0)
;Debug lines

Global.f Dim vertex.vert(lines)
Global.f Dim tmp(2)
Global rot.f = 1
Global t, n
ExamineDesktops()
OpenWindow(0, 0, 0, DesktopWidth(0), DesktopHeight(0), "STL reader")
SetWindowColor(0, RGB(200,220,200))
OpenGLGadget(0, 10, 10, WindowWidth(0) , WindowHeight(0) , #PB_OpenGL_Keyboard)
SetWindowTitle(0, "STL reader    "+Str(lines)+" vertices")

Global radius.f
If ReadFile(0, stlMesh)   ; if the file could be read, we continue...
  While Eof(0) = 0                   ; loop as long the 'end of file' isn't reached
    s$ = ReadString(0)
    If FindString(s$, "vertex")
      findNumbers(s$)
      vertex(t)\x = tmp(0)
      If Abs(vertex(t)\x) > radius
        radius = Abs(vertex(t)\x)
      EndIf
      
      vertex(t)\y = tmp(1)
      If Abs(vertex(t)\y) > radius
        radius = Abs(vertex(t)\y)
      EndIf
      vertex(t)\z = tmp(2)
      If Abs(vertex(t)\z) > radius
        radius = Abs(vertex(t)\z)
      EndIf
      t+1
    EndIf
        
   If FindString(s$, "normal")
      findNumbers(s$)
      vertex(n)\nx = tmp(0)
      vertex(n)\ny = tmp(1)
      vertex(n)\nz = tmp(2)
      n+1      
  EndIf
    
  Wend  
  ;Debug t
  CloseFile(0)
    
  Else
    MessageRequester("Information","Couldn't open the file!")
  EndIf
  ratio.f=0

glLoadIdentity_()
glViewport_(0, 0, WindowWidth(0), WindowHeight(0)  )
If WindowWidth(0) >= WindowHeight(0)  
  ratio = WindowWidth(0) / WindowHeight(0)  
  ;glOrtho_(-30 * ratio, 30 * ratio, -30, 30, -30, 30)
  glOrtho_(-radius*1.0 * ratio, radius*1.0 * ratio, -radius*1.0, radius*1.0, -radius*1.0, radius*1.0)
Else
  ratio = WindowHeight(0)   / WindowWidth(0)
  ;glOrtho_(-30, 30, -30 * ratio, 30 * ratio, -30, 30)
  glOrtho_(-radius, radius, -radius * ratio, radius * ratio, -radius, radius)
EndIf  
;glOrtho_(-50,50,-50,50,-50,50) 
;glOrtho_(-10,10,-10,10,-10,10)
glMatrixMode_(#GL_PROJECTION);  

glEnable_(#GL_DEPTH_TEST)
glPolygonMode_(#GL_FRONT_AND_BACK, #GL_LINE )

glShadeModel_(#GL_SMOOTH) 
glEnable_(#GL_DEPTH_TEST)
glEnable_(#GL_LIGHT_MODEL_AMBIENT)

glClearColor_ (1.0, 0.6, 0.4, 0.0);

glEnable_(#GL_LIGHTING) ;Enable Lighting
glEnable_(#GL_LIGHT0)

glEnable_(#GL_NORMALIZE)

;gluLookAt_( 0, 1, 3, ; the camera looking from position 0,0.5,1  to 0,0,0 from above
 ;           0,  0, 0,
  ;          0,  1,  0 ) 

;glRotatef_(-90, 0, 1, 0)
;glTranslatef_(0,-50,0)
Repeat
 
  event = WindowEvent()
 
  glClearColor_(0.9, 0.9, 0.9, 1)
  glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)
  glRotatef_(rot, 0, 1, 0)
  
      glEnableClientState_(#GL_VERTEX_ARRAY)
      glEnableClientState_(#GL_NORMAL_ARRAY)
      
      glVertexPointer_(3, #GL_FLOAT, SizeOf(vert), @vertex(0)\x)
      glNormalPointer_(#GL_FLOAT, SizeOf(vert), @vertex(0)\nx)
      
      ;glTranslatef_(0,-1,0)
      ;glDrawArrays_(#GL_POINTS, 0, ArraySize(vertex()))
      glDrawArrays_(#GL_TRIANGLES, 0, ArraySize(vertex()))
      
      glDisableClientState_(#GL_NORMAL_ARRAY)
      glDisableClientState_(#GL_VERTEX_ARRAY);
      
  SetGadgetAttribute(0, #PB_OpenGL_FlipBuffers, #True)
Until Event = #PB_Event_CloseWindow Or quit = 1
  Procedure findNumbers(s.s)
    ;Debug t
    If CreateRegularExpression(0, "[+-]?([0-9]*[.])?[0-9]+")
    If ExamineRegularExpression(0, s)   
        For i=0 To 2
         If NextRegularExpressionMatch(0)
          tmp(c) = ValF(RegularExpressionMatchString(0))
          c+1
         EndIf
        Next
      c=0
    EndIf
    
  Else
    Debug RegularExpressionError()
  EndIf
 
EndProcedure
Last edited by applePi on Fri Nov 29, 2019 7:36 am, edited 1 time in total.
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: OpenGL Gadget: How to accurately display a Shape?

Post by IdeasVacuum »

Hi Samuel, ApplePi

Thanks both for your replies. I'm experimenting now and have already (accidentally) discovered why 4000 roughly worked in the original example - 4000 is approximately the length of the diagonal from bottom left corner to top right corner of the Shape! :)
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: OpenGL Gadget: How to accurately display a Shape?

Post by IdeasVacuum »

Hi again

It is working very well! :mrgreen:

The trackball (right mouse down drag) is working well with it too, but the Zooming does not do anything

I'm going to experiment with Scroll Sensitivity.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: OpenGL Gadget: How to accurately display a Shape?

Post by IdeasVacuum »

I couldn't get the Track Ball Zoom to work, even though all the functions work just fine. In the end I have created a working zoom effect by changing the values fed to glOrtho(). That works well, but the zoom emanates from the World Axis, so zooming-in to a detail at the top of the model is impossible because it becomes off screen :lol:

So what I need to do is figure out how to zoom at the cursor position.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
Post Reply