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 Imports Key = OpenTK3.Input.Key Imports OpenTK.Wpf 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 Private finishedLoading As Boolean = False Public Property Scaling As Single = 500.0F Public Property ClearColor As Color = Color.CornflowerBlue Public ReadOnly Property Keyboard As OpenTK3.Input.KeyboardState Get Return OpenTK3.Input.Keyboard.GetState End Get End Property 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 Public ReadOnly Property GLControlClient As GLWpfControl Get Return glControl1 End Get End Property Private ReadOnly Property IsStrgPressed As Boolean Get Dim state = Keyboard Return state.IsKeyDown(Key.ControlLeft) OrElse state.IsKeyDown(Key.ControlRight) End Get End Property Private ReadOnly Property IsShiftPressed As Boolean Get Dim state = Keyboard Return state.IsKeyDown(Key.ShiftLeft) OrElse state.IsKeyDown(Key.ShiftRight) 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) SuspendLayout() InitializeComponent() 'glControl1 Dim glControl1 As New GLWpfControl Dim glControlHost = New ElementHost glControlHost.BackColor = Color.Black glControlHost.Name = "glControl1" glControlHost.Anchor = AnchorStyles.Left Or AnchorStyles.Top Or AnchorStyles.Right Or AnchorStyles.Bottom glControlHost.Location = New Point(0, 0) glControlHost.Size = Me.ClientSize glControlHost.MinimumSize = New Size(600, 120) glControlHost.TabIndex = 0 glControlHost.TabStop = False Me.glControl1 = glControl1 Me.glControlHost = glControlHost Dim controlSettings As New GLWpfControlSettings With { .RenderContinuously = False, .GraphicsProfile = Windowing.Common.ContextProfile.Compatability } glControl1.Start(controlSettings) glControlHost.Child = glControl1 Controls.Add(glControlHost) Scaling = scale ProjMatrix = Matrix4.CreatePerspectiveFieldOfView(FOV, glControlHost.Width / glControlHost.Height, 100.0F, 100000.0F) ResumeLayout() MyCamera.SetCameraMode(CameraMode.FLY, camMtx) MyCamera.UpdateMatrix(camMtx) For Each obj As Object3D In objs AddModel(obj) Next finishedLoading = True End Sub Public Sub UpdateOrbitCamera() If Camera.IsOrbitCamera Then Camera.UpdateOrbitCamera(camMtx) End If End Sub Public Sub UpdateView() If glControlHost.Enabled AndAlso finishedLoading Then Invoke(Sub() InvalidateGL()) End If End Sub Private Sub InvalidateGL() glControl1.InvalidateVisual() glControlHost.Invalidate() 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 RenderModels() InvalidateGL() 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() Handles glControl1.Ready 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.LoadIdentity() 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 GL.End() GL.Finish() '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, glControlHost.Width, glControlHost.Height) ProjMatrix = Matrix4.CreatePerspectiveFieldOfView(FOV, glControlHost.Width / glControlHost.Height, 100.0F, 100000.0F) InvalidateGL() End Sub Private Sub glControl1_Wheel(sender As Object, e As Windows.Input.MouseWheelEventArgs) Handles glControl1.MouseWheel MyCamera.ResetMouseStuff() MyCamera.UpdateCameraMatrixWithScrollWheel(CInt(Math.Truncate(e.Delta * (If(IsShiftPressed, 3.5F, 1.5F)))), camMtx) savedCamPos = MyCamera.Position InvalidateGL() 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.Input.MouseEventArgs) Handles glControl1.MouseMove If e.LeftButton = MouseButtonState.Pressed Then Dim pos = e.GetPosition(glControl1) If IsShiftPressed Then MyCamera.UpdateCameraOffsetWithMouse(savedCamPos, pos.X, pos.Y, glControl1.Width, glControl1.Height, camMtx) Else MyCamera.UpdateCameraMatrixWithMouse(pos.X, pos.Y, camMtx) End If InvalidateGL() 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) Dim state = Keyboard If allowCamMove Then If state.IsKeyDown(Key.W) Then 'camera.Move(moveSpeed, moveSpeed, camMtx) MyCamera.UpdateCameraMatrixWithScrollWheel(moveSpeed, camMtx) savedCamPos = MyCamera.Position End If If state.IsKeyDown(Key.S) Then 'camera.Move(-moveSpeed, -moveSpeed, camMtx) MyCamera.UpdateCameraMatrixWithScrollWheel(-moveSpeed, camMtx) savedCamPos = MyCamera.Position End If If state.IsKeyDown(Key.A) Then 'camera.Move(-moveSpeed, 0, camMtx) MyCamera.UpdateCameraOffsetDirectly(-moveSpeed, 0, camMtx) End If If state.IsKeyDown(Key.D) Then 'camera.Move(moveSpeed, 0, camMtx) MyCamera.UpdateCameraOffsetDirectly(moveSpeed, 0, camMtx) End If If state.IsKeyDown(Key.E) Then 'camera.Move(0, -moveSpeed, camMtx) MyCamera.UpdateCameraOffsetDirectly(0, -moveSpeed, camMtx) End If If state.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