Files
Pilz/Pilz.Drawing.Drawing3D.OpenGLRenderer/Preview/ModelPreview.vb
2020-11-26 11:31:56 +01:00

335 lines
12 KiB
VB.net

Imports System.Drawing
Imports System.Windows.Forms
Imports Pilz.Drawing.Drawing3D.OpenGLFactory.CameraN
Imports Pilz.Drawing.Drawing3D.OpenGLFactory.RenderingN
Imports OpenTK
Imports OpenTK.Graphics.OpenGL
Imports Pilz.S3DFileParser
Imports Point = System.Drawing.Point
Imports Color = System.Drawing.Color
Imports System.Windows.Forms.Integration
Imports OpenTK.Mathematics
Imports System.Windows.Input
Namespace PreviewN
Public Class ModelPreview
Private WithEvents glControl1 As Wpf.GLWpfControl
Private WithEvents glControlHost As ElementHost
Private WithEvents MyCamera As New Camera
Private ProjMatrix As Matrix4 = Nothing
Private FOV As Single = 1.048F
Private camMtx As Matrix4 = Matrix4.Identity
Private savedCamPos As New Vector3
Private _isMouseDown As Boolean = False
Private isDeactivated As Boolean = False
Private ReadOnly myModels As New Dictionary(Of Object3D, Renderer)
Private WithEvents RenderTimer As New Timers.Timer(25) With {.AutoReset = True}
Private _EnableCameraControlling As Boolean = False
Public Property Scaling As Single = 500.0F
Public Property ClearColor As Color = Color.CornflowerBlue
Public Property EnableCameraControlling As Boolean
Get
Return _EnableCameraControlling
End Get
Set
_EnableCameraControlling = Value
If Value Then
If Not RenderTimer.Enabled Then
RenderTimer.Start()
End If
ElseIf RenderTimer.Enabled Then
RenderTimer.Stop()
End If
End Set
End Property
Public Property RenderInterval As Double
Get
Return RenderTimer.Interval
End Get
Set
RenderTimer.Interval = Value
End Set
End Property
Public ReadOnly Property Camera As Camera
Get
Return MyCamera
End Get
End Property
Public ReadOnly Property CameraMatrix As Matrix4
Get
Return camMtx
End Get
End Property
Public ReadOnly Property Models As IReadOnlyDictionary(Of Object3D, Renderer)
Get
Return myModels
End Get
End Property
Public ReadOnly Property GLControl As Control
Get
Return glControlHost
End Get
End Property
Private ReadOnly Property IsStrgPressed As Boolean
Get
Return Keyboard.IsKeyDown(Key.LeftCtrl) OrElse Keyboard.IsKeyDown(Key.RightCtrl)
End Get
End Property
Private ReadOnly Property IsShiftPressed As Boolean
Get
Return Keyboard.IsKeyDown(Key.LeftShift) OrElse Keyboard.IsKeyDown(Key.RightShift)
End Get
End Property
Public Property IsMouseDown As Boolean
Get
Return _isMouseDown
End Get
Set(value As Boolean)
_isMouseDown = value
glControlHost.Refresh()
End Set
End Property
Public Sub New()
Me.New({}, 1.0F)
End Sub
Public Sub New(obj As Object3D)
Me.New(obj, 1.0F)
End Sub
Public Sub New(obj As Object3D, scale As Single)
Me.New({obj}, scale)
End Sub
Public Sub New(objs As Object3D(), scale As Single)
Me.SuspendLayout()
InitializeComponent()
DoubleBuffered = True
'glControl1
Me.glControl1 = New Wpf.GLWpfControl
Me.glControlHost = New ElementHost
Me.glControlHost.BackColor = Color.Black
Me.glControlHost.Name = "glControl1"
Me.glControlHost.Anchor = AnchorStyles.Left Or AnchorStyles.Top Or AnchorStyles.Right Or AnchorStyles.Bottom
Me.glControlHost.Location = New Point(0, 0)
Me.glControlHost.MinimumSize = New Size(600, 120)
Me.glControlHost.Size = Me.ClientSize
Me.glControlHost.TabIndex = 0
Me.glControlHost.TabStop = False
Me.glControlHost.Child = glControl1
Me.Controls.Add(Me.glControlHost)
Me.ResumeLayout(False)
'RenderTimer.SynchronizingObject = Nothing
Scaling = scale
'Toolkit.Init()
Dim controlSettings As New Wpf.GLWpfControlSettings
glControl1.Start(controlSettings)
AddHandler glControl1.MouseWheel, AddressOf glControl1_Wheel
ProjMatrix = Matrix4.CreatePerspectiveFieldOfView(FOV, glControl1.Width / glControl1.Height, 100.0F, 100000.0F)
glControlHost.Enabled = True
MyCamera.SetCameraMode(CameraMode.FLY, camMtx)
MyCamera.UpdateMatrix(camMtx)
Me.ResumeLayout()
For Each obj As Object3D In objs
AddModel(obj)
Next
End Sub
Public Sub UpdateOrbitCamera()
If Camera.IsOrbitCamera Then
Camera.UpdateOrbitCamera(camMtx)
End If
End Sub
Public Sub UpdateView()
If glControl1.IsEnabled Then
glControlHost.Invoke(Sub() glControlHost.Invalidate())
End If
End Sub
Public Function AddModel(obj As Object3D) As Renderer
Dim rndr As New Renderer(obj)
AddModel(rndr)
Return rndr
End Function
Public Sub AddModel(rndr As Renderer)
myModels.Add(rndr.Model, rndr)
End Sub
Public Sub HandlesOnShown(sender As Object, e As EventArgs) Handles MyBase.Shown
glControlHost.Enabled = True
RenderModels()
glControlHost.Invalidate()
End Sub
Public Sub RenderModels()
For Each rndr As Renderer In myModels.Values
RenderModel(rndr)
Next
End Sub
Public Sub RenderModel(rndr As Renderer)
If myModels.Values.Contains(rndr) Then
rndr.ModelScaling = Scaling
rndr.RenderModel()
End If
End Sub
Private Sub glControl1_Load(sender As Object, e As EventArgs) Handles glControl1.Loaded
GL.Enable(EnableCap.Blend)
GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha)
GL.Enable(EnableCap.DepthTest)
GL.DepthFunc(DepthFunction.Lequal)
GL.Enable(EnableCap.Texture2D)
GL.Enable(EnableCap.AlphaTest)
GL.AlphaFunc(AlphaFunction.Gequal, 0.5F)
GL.Enable(EnableCap.CullFace)
End Sub
Public Sub HandlesOnActivated(sender As Object, e As EventArgs) Handles Me.Activated
If isDeactivated Then
isDeactivated = False
End If
End Sub
Public Sub HandlesOnDeactivate(sender As Object, e As EventArgs) Handles Me.Deactivate
isDeactivated = True
End Sub
Private Sub RenderTimer_Elapsed(sender As Object, e As Timers.ElapsedEventArgs) Handles RenderTimer.Elapsed
If Not isDeactivated Then
MoveCameraViaWASDQE()
End If
End Sub
Public Sub HandlesOnPaint(renderTime As TimeSpan) Handles glControl1.Render
GL.ClearColor(ClearColor)
GL.Clear(ClearBufferMask.ColorBufferBit Or ClearBufferMask.DepthBufferBit)
GL.MatrixMode(MatrixMode.Projection)
GL.LoadMatrix(ProjMatrix)
GL.MatrixMode(MatrixMode.Modelview)
GL.LoadMatrix(camMtx)
For Each rndr As Renderer In myModels.Values
If rndr.HasRendered Then
rndr.DrawModel(RenderMode.FillOutline)
End If
Next
'glControl1.SwapBuffers()
End Sub
Private Sub glControl1_Resize(sender As Object, e As EventArgs) Handles glControlHost.Resize
'glControl1.Context.Update(glControl1.WindowInfo)
GL.Viewport(0, 0, glControl1.Width, glControl1.Height)
ProjMatrix = Matrix4.CreatePerspectiveFieldOfView(FOV, glControl1.Width / glControl1.Height, 100.0F, 100000.0F)
glControlHost.Invalidate()
End Sub
Private Sub glControl1_Wheel(sender As Object, e As Windows.Input.MouseWheelEventArgs)
MyCamera.ResetMouseStuff()
MyCamera.UpdateCameraMatrixWithScrollWheel(CInt(Math.Truncate(e.Delta * (If(IsShiftPressed, 3.5F, 1.5F)))), camMtx)
savedCamPos = MyCamera.Position
glControlHost.Invalidate()
End Sub
Private Sub glControl1_MouseDown(ByVal sender As Object, ByVal e As Windows.Input.MouseButtonEventArgs) Handles glControl1.MouseDown
IsMouseDown = True
savedCamPos = MyCamera.Position
End Sub
Private Sub glControl1_MouseLeave(ByVal sender As Object, ByVal e As EventArgs) Handles glControl1.MouseLeave, glControl1.MouseUp
MyCamera.ResetMouseStuff()
IsMouseDown = False
End Sub
Private Sub glControl1_MouseMove(ByVal sender As Object, ByVal e As Windows.Forms.MouseEventArgs) Handles glControlHost.MouseMove
If IsMouseDown AndAlso e.Button = MouseButtons.Left Then
If IsShiftPressed Then
MyCamera.UpdateCameraOffsetWithMouse(savedCamPos, e.X, e.Y, glControl1.Width, glControl1.Height, camMtx)
Else
MyCamera.UpdateCameraMatrixWithMouse(e.X, e.Y, camMtx)
End If
glControlHost.Invalidate()
End If
End Sub
Public Sub MoveCameraViaWASDQE()
Dim moveSpeed As Integer = Convert.ToInt32(Math.Round((If(IsShiftPressed, 60, 30)) * (MyCamera.CamSpeedMultiplier), 0))
Dim allowCamMove As Boolean = Not (IsMouseDown AndAlso IsShiftPressed)
If allowCamMove Then
If Keyboard.IsKeyDown(Key.W) Then
'camera.Move(moveSpeed, moveSpeed, camMtx)
MyCamera.UpdateCameraMatrixWithScrollWheel(moveSpeed, camMtx)
savedCamPos = MyCamera.Position
End If
If Keyboard.IsKeyDown(Key.S) Then
'camera.Move(-moveSpeed, -moveSpeed, camMtx)
MyCamera.UpdateCameraMatrixWithScrollWheel(-moveSpeed, camMtx)
savedCamPos = MyCamera.Position
End If
If Keyboard.IsKeyDown(Key.A) Then
'camera.Move(-moveSpeed, 0, camMtx)
MyCamera.UpdateCameraOffsetDirectly(-moveSpeed, 0, camMtx)
End If
If Keyboard.IsKeyDown(Key.D) Then
'camera.Move(moveSpeed, 0, camMtx)
MyCamera.UpdateCameraOffsetDirectly(moveSpeed, 0, camMtx)
End If
If Keyboard.IsKeyDown(Key.E) Then
'camera.Move(0, -moveSpeed, camMtx)
MyCamera.UpdateCameraOffsetDirectly(0, -moveSpeed, camMtx)
End If
If Keyboard.IsKeyDown(Key.Q) Then
'camera.Move(0, moveSpeed, camMtx)
MyCamera.UpdateCameraOffsetDirectly(0, moveSpeed, camMtx)
End If
End If
End Sub
Private Sub Camera_NeedSelectedObject(sender As Object, e As Camera.NeedSelectedObjectEventArgs) Handles MyCamera.NeedSelectedObject
e.Points = Nothing
End Sub
Private Sub MyCamera_PerspectiveChanged(sender As Object, e As EventArgs) Handles MyCamera.PerspectiveChanged
UpdateView()
End Sub
Private Sub ModelPreview_FormDisposed(sender As Object, e As EventArgs) Handles Me.Disposed
For Each rndr As Renderer In myModels.Values
rndr.ReleaseBuffers()
Next
End Sub
End Class
End Namespace