Files
Pilz/Pilz.Drawing.Drawing3D.OpenGLRenderer/Preview/ModelPreview.vb
2019-07-02 06:31:34 +02:00

379 lines
14 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 KeyboardState = OpenTK.Input.KeyboardState
Imports Keyboard = OpenTK.Input.Keyboard
Imports Key = OpenTK.Input.Key
Namespace PreviewN
Public Class ModelPreview
Public Event WandUpdateView()
Private WithEvents glControl1 As GLControl
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 myPressedKeys As New List(Of Keys)
Private isDeactivated As Boolean = False
Private ReadOnly myModels As New Dictionary(Of Object3D, Renderer)
Public Property RenderWhenWindowsIsInactive As Boolean = False
Public Property EnableCameraControlling As Boolean = True
Public Property Scaling As Single = 500.0F
Public Property ClearColor As Color = Color.CornflowerBlue
'Public ReadOnly Property PressedKeys As IReadOnlyList(Of Keys)
' Get
' Return myPressedKeys
' End Get
'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
Private ReadOnly Property IsStrgPressed As Boolean
Get
'Return myPressedKeys.Contains(Keys.ControlKey)
Dim state As KeyboardState = Keyboard.GetState()
Return state(Key.ControlLeft) OrElse state(Key.ControlRight)
End Get
End Property
Private ReadOnly Property IsShiftPressed As Boolean
Get
'Return myPressedKeys.Contains(Keys.ShiftKey)
Dim state As KeyboardState = Keyboard.GetState()
Return state(Key.ShiftLeft) OrElse state(Key.ShiftRight)
End Get
End Property
Public Property IsMouseDown As Boolean
Get
Return _isMouseDown
End Get
Set(value As Boolean)
_isMouseDown = value
glControl1.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 GLControl
Me.glControl1.BackColor = Color.Black
Me.glControl1.Location = New Point(0, 0)
Me.glControl1.MinimumSize = New Size(600, 120)
Me.glControl1.Name = "glControl1"
Me.glControl1.Anchor = AnchorStyles.Left Or AnchorStyles.Top Or AnchorStyles.Right Or AnchorStyles.Bottom
Me.glControl1.Location = New Point(0, 0)
Me.glControl1.Size = Me.ClientSize
Me.glControl1.TabIndex = 0
Me.glControl1.TabStop = False
Me.glControl1.VSync = False
Me.Controls.Add(Me.glControl1)
Me.ResumeLayout(False)
AddHandler Windows.Media.CompositionTarget.Rendering, AddressOf CompositionTarget_Rendering
Scaling = scale
'Toolkit.Init()
glControl1.CreateControl()
AddHandler glControl1.MouseWheel, AddressOf glControl1_Wheel
ProjMatrix = Matrix4.CreatePerspectiveFieldOfView(FOV, glControl1.Width / glControl1.Height, 100.0F, 100000.0F)
glControl1.Enabled = False
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()
glControl1.Invalidate()
'glControl1.Update()
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
glControl1.Enabled = True
RenderModels()
glControl1.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.Load
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 CompositionTarget_Rendering(sender As Object, e As EventArgs)
If Not isDeactivated OrElse RenderWhenWindowsIsInactive Then
RaiseEvent WandUpdateView()
glControl1.Invalidate()
End If
End Sub
Public Sub HandlesOnPaint(sender As Object, e As PaintEventArgs) Handles glControl1.Paint
If EnableCameraControlling Then
MoveCameraViaWASDQE()
End If
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()
'If Not IsMouseDown AndAlso obj3d IsNot Nothing Then
' e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
' e.Graphics.DrawString(GetModelInfoAsString, New Font(FontFamily.GenericSerif, 10), New SolidBrush(Panel1.ForeColor), New Drawing.Point(10, 10))
'End If
End Sub
Private Function GetModelInfoAsString() As String
Dim matsCount As Long = 0
Dim facesCount As Long = 0
Dim vertsCount As Long = 0
Dim vcCount As Long = 0
Dim uvCount As Long = 0
For Each obj3d As Object3D In myModels.Keys
matsCount += obj3d.Materials.Count
For Each m As Mesh In obj3d.Meshes
vertsCount += m.Vertices.Count
facesCount += m.Faces.Count
vcCount += m.VertexColors.Count
uvCount += m.UVs.Count
Next
Next
Return String.Format("Materials:{0}{1}
Faces:{0}{0}{2}
Vertices:{0}{3}
Vertex Colors{0}{4}
UVs:{0}{0}{5}",
vbTab, matsCount, facesCount, vertsCount, vcCount, uvCount)
End Function
Private Sub glControl1_Resize(sender As Object, e As EventArgs) Handles glControl1.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)
glControl1.Invalidate()
End Sub
Private Sub glControl1_Wheel(sender As Object, e As MouseEventArgs)
MyCamera.ResetMouseStuff()
MyCamera.UpdateCameraMatrixWithScrollWheel(CInt(Math.Truncate(e.Delta * (If(IsShiftPressed, 3.5F, 1.5F)))), camMtx)
savedCamPos = MyCamera.Position
glControl1.Invalidate()
End Sub
Private Sub glControl1_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) 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 MouseEventArgs) Handles glControl1.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
glControl1.Invalidate()
End If
End Sub
'Public Sub HandlesOnKeyDown(sender As Object, e As KeyEventArgs) Handles glControl1.KeyDown
' If Not myPressedKeys.Contains(e.KeyCode) Then myPressedKeys.Add(e.KeyCode)
'End Sub
'Public Sub HandlesOnKeyUp(sender As Object, e As KeyEventArgs) Handles MyBase.KeyUp
' If myPressedKeys.Contains(e.KeyCode) Then myPressedKeys.Remove(e.KeyCode)
'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)
'For Each k As Keys In myPressedKeys
' If allowCamMove Then
' Select Case k
' Case Keys.W
' 'camera.Move(moveSpeed, moveSpeed, camMtx)
' MyCamera.UpdateCameraMatrixWithScrollWheel(moveSpeed, camMtx)
' savedCamPos = MyCamera.Position
' Case Keys.S
' 'camera.Move(-moveSpeed, -moveSpeed, camMtx)
' MyCamera.UpdateCameraMatrixWithScrollWheel(-moveSpeed, camMtx)
' savedCamPos = MyCamera.Position
' Case Keys.A
' 'camera.Move(-moveSpeed, 0, camMtx)
' MyCamera.UpdateCameraOffsetDirectly(-moveSpeed, 0, camMtx)
' Case Keys.D
' 'camera.Move(moveSpeed, 0, camMtx)
' MyCamera.UpdateCameraOffsetDirectly(moveSpeed, 0, camMtx)
' Case Keys.E
' 'camera.Move(0, -moveSpeed, camMtx)
' MyCamera.UpdateCameraOffsetDirectly(0, -moveSpeed, camMtx)
' Case Keys.Q
' 'camera.Move(0, moveSpeed, camMtx)
' MyCamera.UpdateCameraOffsetDirectly(0, moveSpeed, camMtx)
' End Select
' End If
'Next
If allowCamMove Then
Dim state As KeyboardState = Keyboard.GetState
If state(Key.W) Then
'camera.Move(moveSpeed, moveSpeed, camMtx)
MyCamera.UpdateCameraMatrixWithScrollWheel(moveSpeed, camMtx)
savedCamPos = MyCamera.Position
End If
If state(Key.S) Then
'camera.Move(-moveSpeed, -moveSpeed, camMtx)
MyCamera.UpdateCameraMatrixWithScrollWheel(-moveSpeed, camMtx)
savedCamPos = MyCamera.Position
End If
If state(Key.A) Then
'camera.Move(-moveSpeed, 0, camMtx)
MyCamera.UpdateCameraOffsetDirectly(-moveSpeed, 0, camMtx)
End If
If state(Key.D) Then
'camera.Move(moveSpeed, 0, camMtx)
MyCamera.UpdateCameraOffsetDirectly(moveSpeed, 0, camMtx)
End If
If state(Key.E) Then
'camera.Move(0, -moveSpeed, camMtx)
MyCamera.UpdateCameraOffsetDirectly(0, -moveSpeed, camMtx)
End If
If state(Key.Q) Then
'camera.Move(0, moveSpeed, camMtx)
MyCamera.UpdateCameraOffsetDirectly(0, moveSpeed, camMtx)
End If
End If
End Sub
Private Sub Camera_NeedSelectedObject(e As Camera.NeedSelectedObjectEventArgs) Handles MyCamera.NeedSelectedObject
e.Points = Nothing
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