Irrlicht Lime is a .NET wrapper for Irrlicht Engine

Announce new projects or updates of Irrlicht Engine related tools, games, and applications.
Also check the Wiki
peteym5
Posts: 21
Joined: Wed Sep 12, 2012 3:56 pm

Re: Irrlicht Lime is a .NET wrapper for Irrlicht Engine

Post by peteym5 »

Code: Select all

 
#Const EngineType_IrrlichtLime = 1
#Const EngineType_DarkGDK = 2
 
Imports IrrlichtLime
Imports IrrlichtLime.Core
Imports IrrlichtLime.GUI
Imports IrrlichtLime.IO
Imports IrrlichtLime.Video
Imports IrrlichtLime.Scene
Imports System
Imports System.IO
Imports System.Data.OleDb
Imports System.Math
Imports System.Collections.Generic
Imports System.Linq
Imports System.Text
Imports Microsoft.VisualBasic
 
Public Class Form1
 
    'IRRLICHT 3D ENGINE. ABLE TO USE OPEN GL, SOFTWARE, DIRECTX, PLUS CUSTOM SOFTWARE
    'IRRLICHTLINE - ALLOWS ENGINE TO INTERFACE WITH MICROSOFTs VISUAL STUDIO, VISUAL BASIC.NET (4.0), C#.
    'DARKIRRLICHT - ALLOWS ENGINE TO INTERFACE WITH THE GAME CREATORs DARK BASIC PROFESSIONAL.
 
    Public bbox As New AABBox()
    Public vertices As Vertex3D()
    Public materialx As Video.Material
    Public materiall As Material
    Public Shared terrain As TerrainSceneNode
    Public Shared skybox As SceneNode
    Public Shared skydome As SceneNode
    Public Shared camera As CameraSceneNode
    Public DriverCode As Integer
    Public driverType As DriverType = driverType.Direct3D9
    Public Driver As VideoDriver
    Public Light0 As SceneNode
    Public Shared envgui As GUIEnvironment
    Public Shared smgr As SceneManager
    Public Shared EndProgram As Boolean
    Public Shared device As IrrlichtDevice
    Public Shared listbox As GUIListBox
    Public Shared animc As SceneNodeAnimator
    Public Shared selector As TriangleSelector
    Public Shared winPosCounter As Integer = 0
    Public Shared showBox As Boolean
    Public Shared showDebug As Boolean
    Public Const GUI_ID_ButtonQuit As Integer = 101
    Public Const GUI_ID_ButtonWindowNew As Integer = 102
    Public Const GUI_ID_ButtonFileOpen As Integer = 103
    Public Const GUI_ID_ScrollbarTransparency As Integer = 104
    Public Shared WinCursor As Boolean
 
    'Trigonmetric Constants
    Public Const Pi As Double = System.Math.PI
    Public Const Degree_Convert As Double = 180 / System.Math.PI
 
    Public WallMesh(9) As Mesh
    Public WallNode(9) As SceneNode
 
    Private Sub Form1_KeyUp(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyUp
        If e.KeyCode = Keys.Escape Then EndProgram = True
    End Sub
 
    Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load
        EndProgram = False
        Me.Visible = True
        WinCursor = False
    End Sub
 
    Public Sub InitSample()
        device = IrrlichtDevice.CreateDevice(driverType, New Dimension2Di(1280, 1024), 32, True, False, False)
        device.SetWindowCaption("Irrlicht Project!")
 
        Dim driver As VideoDriver = device.VideoDriver
        Dim smgr As SceneManager = device.SceneManager
        Dim gui As GUIEnvironment = device.GUIEnvironment
 
        Do While device.Run()
            driver.BeginScene(True, True, New Color(100, 101, 140))
 
            smgr.DrawAll()
            gui.DrawAll()
 
            driver.EndScene()
        Loop
 
        device.Drop()
    End Sub
 
    Public Sub CombinedSample()
        Dim lastFPS As Integer = -1
        device = IrrlichtDevice.CreateDevice(driverType, New Dimension2Di(1024, 768))
        If (device Is Nothing) Then
            Return
        End If
        device.SetWindowCaption("Irrlicht Engine - User Interface Demo")
        device.SetWindowResizable(True)
        envgui = device.GUIEnvironment
        smgr = device.SceneManager
        Driver = device.VideoDriver
        device.FileSystem.AddFileArchive("media/map-20kdm2.pk3")
        Dim skin As GUISkin = envgui.Skin
        Dim font As GUIFont = envgui.GetFont("media/fonthaettenschweiler.bmp")
        Dim mesh1 As AnimatedMesh = smgr.GetMesh("media/sydney.md2")
        Dim node1 As AnimatedMeshSceneNode = smgr.AddAnimatedMeshSceneNode(mesh1)
        Dim node2 As SceneNode = smgr.AddCubeSceneNode()
        Dim node3 As SceneNode = smgr.AddSphereSceneNode()
        Dim node4 As SceneNode = Nothing
        Dim node5 As New CSampleSceneNode(smgr.RootNode, smgr, 667)
        Dim anim1 As SceneNodeAnimator = smgr.CreateFlyCircleAnimator(New Vector3Df(15, -16, 45), 15.0F, 0.002F)
        Dim anim2 As SceneNodeAnimator = smgr.CreateFlyStraightAnimator(New Vector3Df(200, -15, 10), New Vector3Df(-200, -15, 10), 6.5F, True)
        Dim anim3 As SceneNodeAnimator = smgr.CreateFlyStraightAnimator(New Vector3Df(-979999, 38400, -299999), New Vector3Df(979999, 38400, 299999), 120.0F, True)
        Dim anim4 As SceneNodeAnimator = smgr.CreateRotationAnimator(New Vector3Df(0.0025, 0.0031, 0.0049))
        Dim anim5 As SceneNodeAnimator = smgr.CreateRotationAnimator(New Vector3Df(0.8F, 0, 0.8F))
        Dim mesh6 As AnimatedMesh = smgr.GetMesh("20kdm2.bsp")
        Dim anms As AnimatedMeshSceneNode = smgr.AddAnimatedMeshSceneNode(smgr.GetMesh("media/ninja.b3d"))
        Dim scrollbar As GUIScrollBar = envgui.AddScrollBar(True, New Recti(150, 45, 350, 60), Nothing, GUI_ID_ScrollbarTransparency)
        Dim trq As GUIStaticText = envgui.AddStaticText("Logging ListBox:", New Recti(50, 110, 250, 130), True)
        Light0 = smgr.AddLightSceneNode(Nothing, New Vector3Df(0, 4096, 0), New Colorf(0.5, 1.0, 0.5, 1.0), 65535, 1)
        Light0.Visible = True
 
        'material.Wireframe = True
        camera = smgr.AddCameraSceneNodeFPS(Nothing, 100.0, 1.2)
        camera.Position = New Vector3Df(2700, 255 * 2, 2600)
        camera.Target = New Vector3Df(2397 * 2, 343 * 2, 2700 * 2)
        camera.FarValue = 999999.0F
        Make_Tunnel()
        Init_Meshes()
        If node1 IsNot Nothing Then
            node1.SetMaterialFlag(MaterialFlag.Lighting, False)
            node1.SetMD2Animation(AnimationTypeMD2.Stand)
            node1.SetMaterialTexture(0, Driver.GetTexture("media/sydney.bmp"))
        End If
        If node2 IsNot Nothing Then
            node2.Position = New Vector3Df(256, 20480, 2048)
            node2.SetMaterialTexture(0, Driver.GetTexture("media/borg.bmp"))
            node2.SetMaterialFlag(MaterialFlag.Lighting, False)
            node2.Scale = New Vector3Df(2048, 2048, 2048)
            If anim4 IsNot Nothing Then
                node2.AddAnimator(anim4)
                node2.AddAnimator(anim3)
                anim3.Drop()
                anim4.Drop()
            End If
 
        End If
 
        If node3 IsNot Nothing Then
            node3.SetMaterialTexture(0, Driver.GetTexture("media/t351sml.jpg"))
            node3.SetMaterialFlag(MaterialFlag.Lighting, False)
            node3.Position = New Vector3Df(20, 5, 10)
 
            If anim1 IsNot Nothing Then
                node3.AddAnimator(anim1)
                anim1.Drop()
            End If
        End If
        If mesh6 IsNot Nothing Then
            node4 = smgr.AddOctreeSceneNode(mesh6.GetMesh(0), Nothing, -1, 1024)
        End If
        If node4 IsNot Nothing Then
            node4.Position = New Vector3Df(-1300, -88, -1249)
        End If
 
        If anim5 IsNot Nothing Then
            node5.Position = New Vector3Df(-10, 12, 5)
            node5.AddAnimator(anim5)
            anim5.Drop()
            anim5 = Nothing
        End If
 
        Init_Terrain()
 
        If anms IsNot Nothing Then
            If anim2 IsNot Nothing Then
                anms.AddAnimator(anim2)
                anim2.Drop()
            End If
            anms.SetMaterialFlag(MaterialFlag.Lighting, False)
            anms.SetFrameLoop(0, 13)
            anms.AnimationSpeed = 15
            anms.Scale = New Vector3Df(5)
            anms.Rotation = New Vector3Df(0, -90, 0)
        End If
        'smgr.AddCameraSceneNodeFPS()
        If (Not (font) Is Nothing) Then
            skin.SetFont(font)
        End If
        envgui.Skin.SetFont(envgui.GetFont("media/fontlucida.png"))
        envgui.Skin.SetColor(New Color(255, 0, 192), GUIDefaultColor.ButtonText)
        envgui.Skin.SetColor(New Color(0, 32, 64), GUIDefaultColor.AppWorkspace)
        skin.SetFont(envgui.BuiltInFont, GUIDefaultFont.Tooltip)
 
        envgui.AddButton(New Recti(10, 240, 110, (240 + 32)), Nothing, GUI_ID_ButtonQuit, "Quit", "Exits Program")
        envgui.AddButton(New Recti(10, 280, 110, (280 + 32)), Nothing, GUI_ID_ButtonWindowNew, "New Window", "Launches a new Window")
        envgui.AddButton(New Recti(10, 320, 110, (320 + 32)), Nothing, GUI_ID_ButtonFileOpen, "File Open", "Opens a file")
        envgui.AddStaticText("Transparent Control:", New Recti(150, 20, 350, 40), True, True, Nothing, -1, True)
        envgui.AddEditBox("Editable Text", New Recti(750, 0, 950, 20))
 
        scrollbar.MaxValue = 255
        scrollbar.Position = CType(envgui.Skin.GetColor(GUIDefaultColor.WindowBackground).Alpha, Integer)
 
        listbox = envgui.AddListBox(New Recti(50, 140, 250, 210))
 
        AddHandler device.OnEvent, AddressOf Form1.device_OnEvent
        'envgui.AddImage(driver.GetTexture("../../media/irrlichtlogoalpha2.tga"), New Vector2Di(10, 10))
        'smgr.AddCameraSceneNode(Nothing, New Vector3Df(0, 30, -40), New Vector3Df(0, 5, 0))
 
        Dim fps As Integer = Driver.FPS
        While device.Run() And EndProgram = False
 
            If device.WindowActive Then
                Driver.BeginScene(True, True, New Color(200, 200, 200))
                smgr.DrawAll()
                envgui.DrawAll()
                Driver.EndScene()
                If lastFPS <> fps Then
                    envgui.AddStaticText([String].Format("Irrlicht Engine - User Interface Demo - Irrlicht Engine [{0}] fps: {1}", Driver.Name, fps), New Recti(20, 2, 600, 22), True, True, Nothing, -1, True)
                    lastFPS = fps
                End If
                'device.SetWindowCaption([String].Format("Terrain rendering example - Irrlicht Engine [{0}] fps: {1} Height: {2}", driver.Name, fps, terrain.GetHeight(camera.AbsolutePosition.X, camera.AbsolutePosition.Z)))
            End If
 
        End While
        device.Drop()
        End
    End Sub
 
 
    Shared KeyIsDown As New Dictionary(Of KeyCode, Boolean)
 
    Private Shared Function device_OnEvent(e As [Event]) As Boolean
 
        If e.Type = EventType.Key Then
            If KeyIsDown.ContainsKey(e.Key.Key) Then
                KeyIsDown(e.Key.Key) = e.Key.PressedDown
            Else
                KeyIsDown.Add(e.Key.Key, e.Key.PressedDown)
            End If
 
        End If
 
 
        If (e.Type = EventType.GUI) Then
            Dim id As Integer = e.GUI.Caller.ID
            Select Case (e.GUI.Type)
                Case GUIEventType.ScrollBarChanged
                    If (id = GUI_ID_ScrollbarTransparency) Then
                        Dim pos As Integer = CType(e.GUI.Caller, GUIScrollBar).Position
                        For Each which As GUIDefaultColor In [Enum].GetValues(GetType(GUIDefaultColor))
                            Dim color As Color = envgui.Skin.GetColor(which)
                            color.Alpha = pos
                            envgui.Skin.SetColor(color, which)
                        Next
                    End If
                Case GUIEventType.ButtonClicked
                    Select Case (id)
                        Case GUI_ID_ButtonQuit
                            device.Close()
                            Return True
                        Case GUI_ID_ButtonWindowNew
                            listbox.AddItem("Window created")
                            winPosCounter = (winPosCounter + 30)
                            If (winPosCounter > 200) Then
                                winPosCounter = 0
                            End If
                            Dim c As Integer = winPosCounter
                            Dim window As GUIWindow = envgui.AddWindow(New Recti((100 + c), (100 + c), (300 + c), (200 + c)), False, "Test window")
                            envgui.AddStaticText("Please close me", New Recti(35, 35, 140, 50), True, False, window)
                            Return True
                        Case GUI_ID_ButtonFileOpen
                            listbox.AddItem("File open")
                            ' There are some options for the file open dialog
                            ' We set the title, make it a modal window, and make sure
                            ' that the working directory is restored after the dialog
                            ' is finished.
                            envgui.AddFileOpenDialog("Please choose a file", True, Nothing, -1, True)
                            Return True
                        Case Else
                            Return False
                    End Select
                Case GUIEventType.FileDialogFileSelected
                    ' show the filename, selected in the file dialog
                    Dim d As GUIFileOpenDialog = CType(e.GUI.Caller, GUIFileOpenDialog)
                    listbox.AddItem(d.FileName)
                    Exit Select
            End Select
        End If
 
        If e.Type = EventType.Key AndAlso e.Key.PressedDown Then
            Select Case e.Key.Key
                Case KeyCode.Esc
                    EndProgram = True
                Case KeyCode.KeyW
                    ' switch wire frame mode
                    terrain.SetMaterialFlag(MaterialFlag.Wireframe, Not terrain.GetMaterial(0).Wireframe)
                    terrain.SetMaterialFlag(MaterialFlag.PointCloud, False)
                    Return True
 
                Case KeyCode.KeyP
                    ' switch point cloud mode
                    terrain.SetMaterialFlag(MaterialFlag.PointCloud, Not terrain.GetMaterial(0).PointCloud)
                    terrain.SetMaterialFlag(MaterialFlag.Wireframe, False)
                    Return True
 
                Case KeyCode.KeyC
                    ' toggle WinCursor
 
                    WinCursor = True ' Not WinCursor
                    If WinCursor = False Then
                        'selector = smgr.CreateTerrainTriangleSelector(terrain, 0)
                        animc = smgr.CreateCollisionResponseAnimator(selector, camera, New Vector3Df(60, 100, 60), New Vector3Df(0, 0, 0), New Vector3Df(0, 50, 0))
                        camera.AddAnimator(animc)
                        device.CursorControl.Visible = False
                    ElseIf WinCursor = True Then
                        camera.RemoveAnimator(animc)
                        camera.RemoveAnimators()
                        animc.Drop()
                        'selector.Drop()
                        device.CursorControl.Visible = True
 
 
                    End If
 
                    Return True
 
 
                Case KeyCode.KeyD
                    ' toggle detail map
                    terrain.SetMaterialType(If(terrain.GetMaterial(0).Type = MaterialType.Solid, MaterialType.DetailMap, MaterialType.Solid))
                    Return True
 
                Case KeyCode.KeyS
                    ' toggle skies
                    showBox = Not showBox
                    skybox.Visible = showBox
                    skydome.Visible = Not showBox
                    Return True
 
                Case KeyCode.KeyX
                    ' toggle debug information
                    showDebug = Not showDebug
                    terrain.DebugDataVisible = If(showDebug, DebugSceneType.BBoxAll, DebugSceneType.Off)
                    Return True
            End Select
        End If
 
        Return False
    End Function
 
    Private Shared Function IsKeyDown(keyCode As KeyCode) As Boolean
        Return If(KeyIsDown.ContainsKey(keyCode), KeyIsDown(keyCode), False)
    End Function
 
 
    Private Sub RadioButton1_CheckedChanged(sender As System.Object, e As System.EventArgs) Handles RadioButton1.CheckedChanged
        DriverCode = 1
        driverType = driverType.BurningsVideo
 
    End Sub
 
    Private Sub RadioButton2_CheckedChanged(sender As System.Object, e As System.EventArgs) Handles RadioButton2.CheckedChanged
        DriverCode = 2
        driverType = driverType.Direct3D8
    End Sub
 
    Private Sub RadioButton3_CheckedChanged(sender As System.Object, e As System.EventArgs) Handles RadioButton3.CheckedChanged
        DriverCode = 3
        driverType = driverType.Direct3D9
    End Sub
 
    Private Sub RadioButton4_CheckedChanged(sender As System.Object, e As System.EventArgs) Handles RadioButton4.CheckedChanged
        DriverCode = 4
        driverType = driverType.Null
    End Sub
 
    Private Sub RadioButton5_CheckedChanged(sender As System.Object, e As System.EventArgs) Handles RadioButton5.CheckedChanged
        DriverCode = 5
        driverType = driverType.OpenGL
    End Sub
 
    Private Sub RadioButton6_CheckedChanged(sender As System.Object, e As System.EventArgs) Handles RadioButton6.CheckedChanged
        DriverCode = 6
        driverType = driverType.Software
    End Sub
 
    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        Panel1.Visible = False
        CombinedSample()
    End Sub
 
    Public Sub Init_Terrain()
 
        skybox = smgr.AddSkyBoxSceneNode("media/irrlicht2_up.jpg", "media/irrlicht2_dn.jpg", "media/irrlicht2_lf.jpg", "media/irrlicht2_rt.jpg", "media/irrlicht2_ft.jpg", "media/irrlicht2_bk.jpg")
        skydome = smgr.AddSkyDomeSceneNode(Driver.GetTexture("media/skydome.jpg"), 16, 8, 0.95F, 2)
        terrain = smgr.AddTerrainSceneNode("media/heightmap2.bmp", Nothing, -1, New Vector3Df(), New Vector3Df(), New Vector3Df(40, 4.4F, 40), New Color(255, 255, 255), 5, TerrainPatchSize._17, 4)
        selector = smgr.CreateTerrainTriangleSelector(terrain, 0)
 
        Dim lastFPS As Integer = -1
        Dim TerrainEvent As New TerrainEventReceiver(device, terrain, skybox, skydome)
        terrain.Scale = New Vector3Df(64, 8, 64)
        terrain.Position = New Vector3Df(-8192, -48, -8192)
        Driver.SetTextureCreationFlag(TextureCreationFlag.Always32Bit, True)
 
        ' add irrlicht logo
        'envgui.AddImage(driver.GetTexture("media/irrlichtlogoalpha2.tga"), New Vector2Di(10))
        ' set gui font
 
 
        ' add some help text
        envgui.AddStaticText("Press 'W' to change wireframe mode" & vbLf & "Press 'C' to release Mouse" & vbLf & "Press 'D' to toggle detail map" & vbLf & "Press 'S' to toggle skybox/skydome" & vbLf & "Press 'P' to toggle Point Cloud" & vbLf & "Press 'X' to toggle Point Debug", New Recti(2, 512, 242, 640), True, True, Nothing, -1, True)
 
        ' add camera
 
 
        ' disable mouse cursor
 
        ' add terrain scene node
        ' heightmap
        ' parent node
        ' node id
        ' position
        ' rotation
        ' scale
        ' vertex color
        ' max LOD
        ' patch size
        ' smooth factor
        terrain.SetMaterialFlag(MaterialFlag.Lighting, False)
        terrain.SetMaterialTexture(0, Driver.GetTexture("media/terrain-texture.jpg"))
        terrain.SetMaterialTexture(1, Driver.GetTexture("media/detailmap3.jpg"))
        terrain.SetMaterialType(MaterialType.DetailMap)
        terrain.ScaleTexture(1, 20)
        ' create triangle selector for the terrain
        terrain.TriangleSelector = selector
        terrain.OverrideLODDistance(4, 16384)
        ' create collision response animator and attach it to the camera
        animc = smgr.CreateCollisionResponseAnimator(selector, camera, New Vector3Df(60, 100, 60), New Vector3Df(0, 0, 0), New Vector3Df(0, 50, 0))
        device.CursorControl.Visible = False
 
        ' create skybox and skydome
        Driver.SetTextureCreationFlag(TextureCreationFlag.CreateMipMaps, False)
        Driver.SetTextureCreationFlag(TextureCreationFlag.CreateMipMaps, True)
 
        ' create event receiver
 
        showBox = True
        showDebug = False
    End Sub
 
    Sub Init_Meshes()
        Dim buf0 As MeshBuffer = MeshBuffer.Create(VertexType.Standard, IndexType._16Bit)
        Dim buf1 As MeshBuffer = MeshBuffer.Create(VertexType.Standard, IndexType._16Bit)
        Dim buf2 As MeshBuffer = MeshBuffer.Create(VertexType.Standard, IndexType._16Bit)
        Dim buf3 As MeshBuffer = MeshBuffer.Create(VertexType.Standard, IndexType._16Bit)
        Dim buf4 As MeshBuffer = MeshBuffer.Create(VertexType.Standard, IndexType._16Bit)
        Dim vertices(7 * 2 - 1) As Vertex3D
        Dim indices(5 * 6 - 1) As UShort
        Dim indices4 As UShort() = New UShort() {0, 1, 2, 1, 3, 2} ',
        Dim i As Integer
        Dim j As Single
        Dim k As Integer
        Dim v As Integer
        Dim iColor As New Video.Color(40, 40, 255)
 
 
 
        k = 0
        i = 0
        v = 0
        For v = 0 To 6 Step 2
            If j < 384 Then
                indices(k + 0) = v + 0
                indices(k + 1) = v + 1
                indices(k + 2) = v + 2
                indices(k + 3) = v + 1
                indices(k + 4) = v + 3
                indices(k + 5) = v + 2
                k = k + 6
            End If
        Next
        v = 0
        i = 0
 
 
        materialx = New Video.Material
        materialx.SetTexture(0, Driver.GetTexture("media/wall02.jpg"))
        materialx.BackfaceCulling = False
        materialx.Type = MaterialType.Solid
        materialx.Shininess = 128
        materialx.Fog = False
        materialx.SetFlag(MaterialFlag.Lighting, False)
        materialx.SetFlag(MaterialFlag.NormalizeNormals, True)
        materialx.Lighting = False
        materialx.AmbientColor = New Color(0, 0, 0, 128)
        materialx.DiffuseColor = New Color(0, 0, 0, 128)
        materialx.EmissiveColor = New Color(0, 0, 0, 0)
        materialx.SpecularColor = New Color(64, 32, 0, 128)
 
        For j = 0 To 1536 Step 256
            vertices(v + 0) = New Vertex3D(100, 200, j, 50, 0, j, New Color(255, 255, 255, 128), 0, i)
            vertices(v + 1) = New Vertex3D(100, 0, j, 50, 0, j, New Color(255, 255, 255, 128), 1, i)
            v = v + 2
            i = i + 1
        Next j
        WallMesh(0) = IrrlichtLime.Scene.Mesh.Create
        WallMesh(0).AddMeshBuffer(buf0)
        buf0.Append(vertices, indices)
        buf0.SetMaterial(materialx)
        buf0.RecalculateBoundingBox()
        buf0.Drop()
        WallNode(0) = smgr.AddMeshSceneNode(WallMesh(0))
        WallNode(0).SetMaterial(0, materialx)
        WallNode(0).Position = New Vector3Df(-384, 768, 128)
        WallNode(0).SetMaterialFlag(MaterialFlag.ColorMaterial, True)
        'WallNode(0).SetMaterial(0, materialx)
        WallMesh(0).SetMaterialFlag(MaterialFlag.Lighting, False)
        WallMesh(0).SetMaterialFlag(MaterialFlag.ColorMaterial, True)
 
        i = 0
        v = 0
        For j = 0 To 1536 Step 256
            vertices(v + 1) = New Vertex3D(-100, 200, j, 0, 0, 0, New Color(255, 255, 255), 1, i)
            vertices(v + 0) = New Vertex3D(-100, 0, j, 0, 0, 0, New Color(255, 255, 255), 0, i)
            v = v + 2
            i = i + 1
        Next j
        WallMesh(1) = IrrlichtLime.Scene.Mesh.Create
        WallMesh(1).AddMeshBuffer(buf1)
        buf1.Append(vertices, indices)
        buf1.SetMaterial(materialx)
        buf1.RecalculateBoundingBox()
        buf1.Drop()
        WallNode(1) = smgr.AddMeshSceneNode(WallMesh(1))
        WallNode(1).SetMaterial(1, materialx)
        WallMesh(1).SetMaterialFlag(MaterialFlag.Lighting, False)
        WallNode(1).Position = New Vector3Df(-384, 768, 128)
        'WallNode(1).SetMaterial(0, materialx)
 
        i = 0
        v = 0
        For j = 0 To 1536 Step 256
            vertices(v + 0) = New Vertex3D(-100, 200, j, 0, 0, 0, New Color(255, 255, 255), 0, i)
            vertices(v + 1) = New Vertex3D(100, 200, j, 0, 0, 0, New Color(255, 255, 255), 1, i)
            v = v + 2
            i = i + 1
        Next j
        WallMesh(2) = IrrlichtLime.Scene.Mesh.Create
        WallMesh(2).AddMeshBuffer(buf2)
        buf2.Append(vertices, indices)
        buf2.RecalculateBoundingBox()
        buf2.Drop()
        WallNode(2) = smgr.AddMeshSceneNode(WallMesh(2))
        WallNode(2).Position = New Vector3Df(-384, 768, 128)
        'WallNode(2).SetMaterial(0, materialx)
        i = 0
        v = 0
        For j = 0 To 1536 Step 256
            vertices(v + 0) = New Vertex3D(100, 0, j, 0, 0, j, New Color(255, 255, 255), 0, i)
            vertices(v + 1) = New Vertex3D(-100, 0, j, 0, 0, j, New Color(255, 255, 255), 1, i)
            v = v + 2
            i = i + 1
        Next j
        WallMesh(3) = IrrlichtLime.Scene.Mesh.Create
        WallMesh(3).AddMeshBuffer(buf3)
        buf3.Append(vertices, indices)
        buf3.RecalculateBoundingBox()
        buf3.Drop()
        WallNode(3) = smgr.AddMeshSceneNode(WallMesh(3))
        WallNode(3).Position = New Vector3Df(-384, 768, 128)
        'WallNode(3).SetMaterial(0, materialx)
        vertices(0) = New Vertex3D(-100, 200, 0, 0, 0, 0, New Color(255, 255, 255), 0, 0)
        vertices(1) = New Vertex3D(-100, 0, 0, 0, 0, 0, New Color(255, 255, 255), 0, 1)
        vertices(2) = New Vertex3D(100, 200, 0, 0, 0, 0, New Color(255, 255, 255), 1, 0)
        vertices(3) = New Vertex3D(100, 0, 0, 0, 0, 0, New Color(255, 255, 255), 1, 1)
 
 
        WallMesh(4) = IrrlichtLime.Scene.Mesh.Create
        WallMesh(4).AddMeshBuffer(buf4)
        buf4.Append(vertices, indices4)
        buf4.RecalculateBoundingBox()
        buf4.Drop()
        WallNode(4) = smgr.AddMeshSceneNode(WallMesh(4))
        WallNode(4).Position = New Vector3Df(-384, 768, 128)
 
 
        'materialx.MaterialTypeParam = 1
        'materialx.MaterialTypeParam2 = 2
        'materialx.ColorMask = ColorPlane.All
 
        For i = 0 To 4
            WallNode(i).SetMaterialFlag(MaterialFlag.BackFaceCulling, False)
            WallNode(i).SetMaterialFlag(MaterialFlag.Lighting, False)
            WallNode(i).SetMaterialFlag(MaterialFlag.NormalizeNormals, False)
            WallNode(i).SetMaterialFlag(MaterialFlag.BlendOperation, True)
            WallNode(i).SetMaterialTexture(0, Driver.GetTexture("media/wall02.jpg"))
            WallNode(i).SetMaterialFlag(MaterialFlag.ColorMaterial, False)
            WallNode(i).SetMaterialType(MaterialType.Solid)
            smgr.MeshManipulator.SetVertexColors(WallMesh(i), New Color(255, 0, 0, 128))
            WallNode(i).SetMaterial(0, materialx)
            ' WallNode(i).SetMaterial(1, materialx)
            ' WallNode(i).SetMaterial(2, materialx)
            ' WallNode(i).SetMaterial(3, materialx)
            ' WallNode(i).SetMaterial(4, materialx)
 
        Next i
 
 
        'WallNode(4).SetMaterial(0, materialx)
 
    End Sub
 
 
 
End Class
 
Class CSampleSceneNode
    Inherits SceneNode
    Private bbox As New AABBox()
    Private vertices As Vertex3D()
    Private material As New Material()
 
    Public Sub New(parent As SceneNode, smgr As SceneManager, id As Integer)
        MyBase.New(parent, smgr, id)
        vertices = New Vertex3D(5) {}
        AddHandler Me.OnRegisterSceneNode, AddressOf CSampleSceneNode_OnRegisterSceneNode
        AddHandler Me.OnRegisterSceneNode, AddressOf CSampleSceneNode_OnRegisterSceneNode
        AddHandler Me.OnRender, AddressOf CSampleSceneNode_OnRender
        AddHandler Me.OnGetBoundingBox, AddressOf CSampleSceneNode_OnGetBoundingBox
        AddHandler Me.OnGetMaterialCount, AddressOf CSampleSceneNode_OnGetMaterialCount
        AddHandler Me.OnGetMaterial, AddressOf CSampleSceneNode_OnGetMaterial
 
        material.Wireframe = False
        material.Lighting = False
 
        ' Very Similar to Truevisions 6.5 .AddVertex() statement, but color is before texture coordinates. Identical to TV 6.3< version of the command.
 
        vertices(0) = New Vertex3D(3, 0, 3, 1, 1, 0, New Color(0, 0, 155), 1, 1)
        vertices(1) = New Vertex3D(3, 0, -3, 1, 0, 0, New Color(0, 155, 0), 1, 0)
        vertices(2) = New Vertex3D(-3, 0, -3, 0, 0, 1, New Color(0, 155, 155), 0, 0)
        vertices(3) = New Vertex3D(-3, 0, 3, 0, 0, 1, New Color(155, 0, 0), 0, 1)
        vertices(4) = New Vertex3D(0, 5, 0, 0, 1, 1, New Color(155, 0, 155), 0.5, 0.5)
        vertices(5) = New Vertex3D(0, -5, 0, 0, 1, 1, New Color(155, 155, 0), 0.5, 0.5)
 
        bbox.[Set](vertices(0).Position)
        For i As Integer = 1 To 5
            bbox.AddInternalPoint(vertices(i).Position)
        Next i
    End Sub
 
    Private Sub CSampleSceneNode_OnRegisterSceneNode()
        If Visible Then
            SceneManager.RegisterNodeForRendering(Me)
        End If
    End Sub
 
    Private Sub CSampleSceneNode_OnRender()
        Dim indices As UShort() = New UShort() {5, 3, 2, 5, 1, 0, 5, 2, 1, 5, 0, 3, 4, 2, 3, 4, 0, 1, 4, 1, 2, 4, 3, 0}
        Dim driver As VideoDriver = SceneManager.VideoDriver
        driver.SetMaterial(material)
        driver.SetTransform(TransformationState.World, AbsoluteTransformation)
        driver.DrawVertexPrimitiveList(vertices, indices)
    End Sub
 
    Private Function CSampleSceneNode_OnGetBoundingBox() As AABBox
        Return bbox
    End Function
 
    Private Function CSampleSceneNode_OnGetMaterialCount() As Integer
        Return 1
    End Function
 
    Private Function CSampleSceneNode_OnGetMaterial(index As Integer) As Material
        Return material
    End Function
End Class
 
Class TerrainEventReceiver
    Private terrain As SceneNode
    Private skybox As SceneNode
    Private skydome As SceneNode
 
    Public Sub New(device As IrrlichtDevice, terrain As SceneNode, skybox As SceneNode, skydome As SceneNode)
        Me.terrain = terrain
        Me.skybox = skybox
        Me.skydome = skydome
        skybox.Visible = True
        skydome.Visible = False
    End Sub
End Class
 
Here is the Source Code. I am trying to figure out how to attach files to me post because there is some image files I am using. You can always swap them out with your own images. If you manage to get it to work, the meshes I am targeting will be above that structure.

I am looking to port a Role Playing Game Builder over to a different 3D engine. Right now it is using Truevision3D, but the people seem to had abandoned their 3D middleware. I am considering either IRRLICHT LIME or Dark GDK at this point to drive the 3D graphics part of
Jonhson243
Posts: 9
Joined: Sun Aug 04, 2013 4:03 pm

Problem with WPF integration

Post by Jonhson243 »

Hi there,

Thank you very much for this wrapper!*

I'm trying to integrate Irrlicht lime in a WPF window but i'm having some troubles. I had troubles to register to this forum (I couldn't receive the confirmation email) therefore I lost several weeks of work and now I am very late with this project in my company. :(

I have two problems :

[*] The mouse is locked in the Irrlicht Control : even if I move it, it goes back by itself to the center of the control (even when I switch program using alt+tab), I have to quit my program to make this behaviour cease.
[*] The second and the biggest problem is that i cannot interact with the irrlicht component from my WPF window. I cannot move the camera neither with the mouse or with the keyboard. So basically I have a fixed image, and a mouse cursor that is locked... the only good new is that irrlicht loads correctly :lol:

Before integrating it to WPF, i created and tested my classes in a standalone Irrlicht Window and everything was just working fine. I 'm having troubles with my attempts to integrate it in a WPF Window. Concerning my code, it is largely based on the Lesson 08 sample I just adapted it to meet my needs : I changed the part of the initialisation to avoid charging the defaut scene but instead my static *.obj objects.

Here is the code concerning Irrlicht :

Code: Select all

/* Code du processus asynchrone */
void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
            
           /*Code to initialize irrlicht and the scene goes here
              driver, device and smgr are static members of the XXX object*/
 
            p = new IrrlichtCreationParameters();
            p.DriverType = DriverType.Direct3D9;
            p.WindowID = (IntPtr)e.Argument;
 
 
            XXX.device = IrrlichtDevice.CreateDevice(p);
 
            // if device cannot be created by any reason - we just leave this thread,
            // after all IsRedering will report false, so it is all OK.
            if (XXX.device == null)
            {
                p.DriverType = DriverType.Direct3D8;
                XXX.device = IrrlichtDevice.CreateDevice(p);
            }
 
            if (XXX.device == null)
            {
                p.DriverType = DriverType.OpenGL;
                XXX.device = IrrlichtDevice.CreateDevice(p);
            }
            if (XXX.device == null)
            {
                p.DriverType = DriverType.Software;
                XXX.device = IrrlichtDevice.CreateDevice(p);
            }
            if (XXX.device == null)
            {
                return;
            }
 
            XXX.driver = XXX.device.VideoDriver;
            XXX.smgr = device.SceneManager;
 
           //End of Irrlicht initialisation
 
          /* Code for creating the scene is not mentionned but goes here */
 
            while (XXX.device.Run())
            {
                XXX.driver.BeginScene(false);
                XXX.smgr.DrawAll();
                XXX.driver.EndScene();
            }
 
            if (worker.CancellationPending)
                XXX.device.Close();
 
            lock (backgroundCommand)
            {
                switch (backgroundCommand.Type)
                {
                    case Command.Kind.Resized:
                        XXX.driver.ResizeNotify(backgroundCommand.Value as Dimension2Di);
                        backgroundCommand.Clear();
                        break;
                }
            }
           XXX.device.Drop();
 
Here is what I get. The red parts represent parts of the window that are not the component.

Image

I haven't changed anything else from the example, the only thing here is that I use my personnal class from which XXX is an instance to load Irrlicht and the scene. Beside it I have just changed the the MainWindow XAML for layout purposes. here is the XAML :

Code: Select all

 
<Window x:Class="YYY_WPF.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" IsHitTestVisible="True" Height="350" Width="525" Loaded="Window_Loaded" WindowState="Maximized" WindowStyle="SingleBorderWindow" MouseMove="Window_MouseMove">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition Width="3*"/>
        </Grid.ColumnDefinitions>
        <WindowsFormsHost IsHitTestVisible="True" Grid.Column="2" Name="irrlichtHost"/>
    </Grid>
</Window>
 
 
By the way, my purpose is to make a very simple 3D catalog : I have some static 3D objects that I want to visualize in a part of my WPF Window. I will two buttons: one to rotate and one to translate the camera. And I will also have buttons to change the colors of some parts of the objects. So basically I want to interact with Irrlicht exclusively using buttons, interacting with the mouse would be a bonus if it's not too much hard to implement. I am a Irrlicht and more globally a 3D engines beginner. :)

I would be greatful if you could help me.

Thank you a lot !
greenya
Posts: 1012
Joined: Sun Jan 21, 2007 1:46 pm
Location: Ukraine
Contact:

Re: Irrlicht Lime is a .NET wrapper for Irrlicht Engine

Post by greenya »

Hello.
[*] The mouse is locked in the Irrlicht Control : even if I move it, it goes back by itself to the center of the control (even when I switch program using alt+tab), I have to quit my program to make this behaviour cease.
Its locked maybe because your scene has active FPS camera, if so, it will be locked and this behavior is not .NET related, native Irrlicht Engine behaves the same way. You need to catch event when your app loses focus and stop FPS camera from processing events.

Have you checked the examples witch are supplied with Lime?
Look into L04.ParticleEmitterViewer to see how you can have Irrlicht rendering control. The WPF and WinForms are not big difference, please check L08.WPFWindow. All the examples which uses Irrlicht as a control has behavior when Irrlicht only renders the scene (it has no FPS camera or any other user input). But you can get working user input by translating messages to Irrlicht directly, please read couple of posts from http://irrlicht.sourceforge.net/forum/v ... 29#p277729 for more details. Its tricky and may not work with all you need, but perhaps its enough for your case.
Jonhson243
Posts: 9
Joined: Sun Aug 04, 2013 4:03 pm

Re: Irrlicht Lime is a .NET wrapper for Irrlicht Engine

Post by Jonhson243 »

Thank you for your help Greenya!
Yes, I use the FPS camera indeed, I'll try to figure out how I can do without using it as soon as get back to home. Thank you very much.

Concerning the samples and the posts you suggested me : yes I have checked the samples and especially the two that you mentionned : the particlesEmitter and the lesson 08 with WPF Window. I was especially interested in Lesson04 but I'm not a great developper yet I didn't figured out how to translate it from the Winform logic to the WPF logic, therefore I used Sample L.08, I only changed the parts of the code that I mentionned.

I have great troubles to communicate with Irrlicht since it has to run in a different thread and I'm discovering these asynchronous programming concepts on the flow. But well, thanks to your help I'm able to move on, I'll begin by desactivating the FPS camera and then I'll try to send some mouse events. The mouse cursor problem didn't allow me to try it.

I'll let you know !
greenya
Posts: 1012
Joined: Sun Jan 21, 2007 1:46 pm
Location: Ukraine
Contact:

Re: Irrlicht Lime is a .NET wrapper for Irrlicht Engine

Post by greenya »

Jonhson243 wrote:I have great troubles to communicate with Irrlicht since it has to run in a different thread and I'm discovering these asynchronous programming concepts on the flow.
Example L04.ParticleEmitterViewer has all this "async" stuff you need. It has command queue class which is used to send commands to rendering thread. I suggest you to use same approach because it easily extendable and quite transparent in usage. The more simple way used in L02.WinFormsWindow, but its up to you what to use.

In L02.WinFormsWindow we use Backgroundworker's native stuff to communicate with the thread. We simply recreate rendering thread each time we need it. The only message we need to send to rendering thread is "shutdown" and we use call backgroundRendering.CancelAsync() and check it inside rendering thread with worker.CancellationPending. The rendering thread itself send some statistics using worker.ReportProgress(fps, drv.Name); The approach in this example is fine for cases when we only need any messages FROM the thread; in cases when we need any message INTO the thread, we use approach like in L04.ParticleEmitterViewer -- fully function message queue. Hope you caught the idea and the difference.
peteym5
Posts: 21
Joined: Wed Sep 12, 2012 3:56 pm

Re: Irrlicht Lime is a .NET wrapper for Irrlicht Engine

Post by peteym5 »

Not sure if you had any success converting my code back to C# or C++, and was able to play with the material functions. Seems like Setting the Object Material has no effect on the object I am trying to change color to.

The object I am trying to control is the long room floating above the terrain in the " Init_Meshes" sub routine. It seems as if WallNode(i).SetMaterial(0, materialx) has no effect on the walls, but smgr.MeshManipulator.SetVertexColors(WallMesh(i), New Color(255, 0, 0, 128)) does. What I need specifically is to control Shininess of objects. Lets say I want to make a shiny metallic sword. Maybe there is another way to do it. I figured out ways to make objects appear translucent.

You will have to rename some of your own image files to "wall01.jpg" "wall02.jpg" etc. This forum does not allow attachments.

When the next version of my project is ready I will find some web space for it.
Jonhson243
Posts: 9
Joined: Sun Aug 04, 2013 4:03 pm

Re: Irrlicht Lime is a .NET wrapper for Irrlicht Engine

Post by Jonhson243 »

Thank you, it was very helpful, now I understand those examples a lot more clearly. You also confirmed my first impression which was that a backgroundWorker can only receive data when it is first launched, although it can send data. Sample 4 definitely suits my needs, therefore I'm currently working with it and thanks to your explanations I am much more confident with its code. However I'm having a little problem.

On my WPF window, I placed a WindowsFormsHost control in order to have the control Handle property which is used for the creation of the Irrlicht Device in sample 4. Here is the code of my window :

Code: Select all

 
private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            Viewport viewport = new Viewport();
            viewport.Start(irrlichtHost.Handle);
        }
 
I haven't changed anything from the Viewport Class, and my problem is that I have no display from Irrlicht, I only get a blank window. The problem is that the ScreenSize property of the IrrlichtDevice is 0x0. I hard-coded 400x300 dimensions for the WindowsFormsHost for test purposes and I added :

Code: Select all

 
p.WindowSize = new Dimension2Di(200, 100);
 
To the IrrlichtCreationParameters variable, but right after the creation of the device, the screensize property is 0x0. Do you have any idea ? I really don't know what I can check...To summarize, since there is no Panel control in WPF to contain the Irrlicht Viewport, I had to use a WindowsFormsHost container instead so I get the Handle property which is no longer supported in new WPF controls. But I don't know why, IrrlichtLime doesn't seems to like it, what am I doing wrong ? :?
Jonhson243
Posts: 9
Joined: Sun Aug 04, 2013 4:03 pm

Re: Irrlicht Lime is a .NET wrapper for Irrlicht Engine

Post by Jonhson243 »

Well!

This was a misuse of the WindowsFormsControl control from my part! I didn't attached a child to the control, therefore the end was predictible. Here is what I have done to fix it :

I added this code to the ViewPoint.cs class (L04 ParticlesEmitter)

Code: Select all

 
using System.Windows.Forms;
 
And I made the Viewport class to be a partial class of UserControl so I can attach it as a child of a WindowsFormsControl :

Code: Select all

 
public partial class Viewport : UserControl
 
Then I finally put it in my MainWindow class

Code: Select all

 
private void Window_Loaded(object sender, RoutedEventArgs e)
{
       viewport = new Viewport();
       irrlichtHost.Child = viewport;
       viewport.Start(irrlichtHost.Handle);
}
 
I even did something very fooolish, I didn't defined the Viewport variable as a member of the MainWindow class but as a local variable of the Window_Loaded function... Sorry about that.

Now the things are a lot more better in Irrlicht, the screensize property of the driver is set to the dimensions of the IrrlichtHost and I even have an FPS count ! However there is no display on the screen, it is still blank :lol: . But I believe that this comes from a little mistake from my part, I'll tell you as soon as I fix it. I believe that it has nothing to do with IrrlichtLime by itself. Since the FPS is very high, and the node on which I try to load the mesh is empty, it seems that my scene is simply empty and that there is nothing to render. I rushed a little, and I didn't have the opportunity to make more rigorous tests, I'll let you know.
Jonhson243
Posts: 9
Joined: Sun Aug 04, 2013 4:03 pm

Re: Irrlicht Lime is a .NET wrapper for Irrlicht Engine

Post by Jonhson243 »

Okay, I've simply put back the scene from the example but I still can't have any display. :(
I have found that there is a certain known issue with the WIndowsFormControl so if the Window's AllowTransparency property is set to true, the WindowsFormsControl will be invisible as well as when the window uses styles. But it is not the case here, I have disabled all these properties. I can even see the control when I set a background color so this is not the problem.

I have checked all the visibility properties, both from the WindowsFormControl and from the Viewport object and all are set to visible. However, I can't see the display from Irrlicht. It's very frustating because everything is working fine, the nodes, the meshes and the animations are perfectly created, I even have a "normal" FPS which means that objects are being rendered, but I can't have anything displayed... I'm sure that the solution is simple, but it's very subtle and I can't find it. :(
greenya
Posts: 1012
Joined: Sun Jan 21, 2007 1:46 pm
Location: Ukraine
Contact:

Re: Irrlicht Lime is a .NET wrapper for Irrlicht Engine

Post by greenya »

Please show your code i will try to figure out what is wrong.
Jonhson243
Posts: 9
Joined: Sun Aug 04, 2013 4:03 pm

Re: Irrlicht Lime is a .NET wrapper for Irrlicht Engine

Post by Jonhson243 »

Thank you for your help greenya.

Here is the window's XAML :

Code: Select all

 
<Window x:Class="ProjectName_WPF.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" WindowStyle="None"  IsHitTestVisible="True" Height="350" Width="525" Loaded="Window_Loaded" WindowState="Maximized" MouseMove="Window_MouseMove" Background="#FFD86C6C" AllowsTransparency="False" >
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition Width="400"/>
        </Grid.ColumnDefinitions>
        <WindowsFormsHost  Grid.Column="1" Name="irrlichtHost" Background="#FF8D8D8D" />
    </Grid>
</Window>
 
Here is the window's code-behind :

Code: Select all

 
 public partial class MainWindow : Window
    {
        Viewport viewport;
 
        public MainWindow()
        {
            InitializeComponent(); 
        }
 
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            viewport = new Viewport();
            irrlichtHost.Child = viewport;
            viewport.Start(irrlichtHost.Handle);
            irrlichtHost.Visibility = Visibility.Visible; //useless
        }
 
        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            viewport.Stop();
        }
 
        private void buttonClose_Click(object sender, RoutedEventArgs e)
        {
            Close();
        }
 
        //Just for debugging purposes.
        private void Window_MouseMove(object sender, MouseEventArgs e)
        {
            this.Title = "FPS: " + viewport.fps.ToString() ;
        }
 
        
    }
 
And finally the viewport.cs class. I did the modifications that I mentionned in my previous post, and I've just remembered that I also deleted the code related to particules (L04. ParticlesEmitter). The rest is simply the original sample code.

Code: Select all

 
using System.Windows.Forms;
 
public partial class Viewport : UserControl
        {
            Thread irrThread;
            IrrlichtDevice irrDevice;
            Queue<Command> commandQueue;
            public int fps=0;
 
            public void Start(IntPtr windowHandle)
            {
                if (irrThread != null)
                    throw new InvalidOperationException("Previous viewport needs to be stopped!");
 
                commandQueue = new Queue<Command>();
 
                irrThread = new Thread(new ParameterizedThreadStart(irrThreadMain));
                irrThread.Name = "Irrlicht rendering";
 
                IrrlichtCreationParameters p = new IrrlichtCreationParameters();
                //p.AntiAliasing = 4;
                p.DriverType = DriverType.Direct3D9;    
                p.WindowID = windowHandle;
 
                irrThread.Start(p);
            }
 
            public void Stop()
            {
                EnqueueCommand(CommandType.Abort, null);
                irrThread.Join(200);
 
                if (irrThread.IsAlive)
                    irrThread.Abort();
 
                irrThread = null;
            }
 
            public void EnqueueCommand(CommandType type, object param)
            {
                Command c = new Command();
                c.Type = type;
                c.Param = param;
 
                // If this is Abort command -- we clean up all the queue (all old commands that still waiting
                // for processing) and add this Abort command, since it is a top priority command.
                if (c.Type == CommandType.Abort)
                {
                    lock (commandQueue)
                    {
                        commandQueue.Clear();
                        commandQueue.Enqueue(c);
                    }
                    return;
                }
 
                // We check for old same command and use it instead of adding new one -- for optimization.
                // This way we make not more than only one command of same type to be in the queue.
                lock (commandQueue)
                {
                    foreach (Command n in commandQueue)
                    {
                        if (n.Type == c.Type)
                        {
                            n.Param = c.Param;
                            return;
                        }
                    }
                }
 
                // We add new command to queue.
                lock (commandQueue)
                {
                    commandQueue.Enqueue(c);
                }
            }
 
            enum SceneNodeID
            {
                Camera,
                AxisX,
                AxisY,
                AxisZ,
                Plane,
                ParticleSystem
            }
 
 
            void irrThreadMain(object args)
            {
                irrDevice = IrrlichtDevice.CreateDevice(args as IrrlichtCreationParameters);
 
 
                // Camera
 
                CameraSceneNode camera = irrDevice.SceneManager.AddCameraSceneNode(null, new Vector3Df(0), new Vector3Df(0, 80, 0), (int)SceneNodeID.Camera);
                SceneNodeAnimator anim = irrDevice.SceneManager.CreateFlyCircleAnimator(new Vector3Df(0, 100, 0), 200.0f, 0.0002f);
                camera.AddAnimator(anim);
                anim.Drop();
 
                // Skydome
 
                irrDevice.SceneManager.AddSkyDomeSceneNode(irrDevice.VideoDriver.GetTexture("../../media/skydome.jpg"), 16, 8, 0.95f, 2.0f);
 
                // Plane
 
                var m = irrDevice.SceneManager.AddHillPlaneMesh("plane", new Dimension2Df(1000), new Dimension2Di(1), null, 0, new Dimension2Df(0), new Dimension2Df(8));
                var n = irrDevice.SceneManager.AddAnimatedMeshSceneNode(m, null, (int)SceneNodeID.Plane);
                n.SetMaterialFlag(MaterialFlag.Lighting, false);
                n.SetMaterialTexture(0, irrDevice.VideoDriver.GetTexture("../../media/rockwall.jpg"));
 
                // Axes
 
                m = irrDevice.SceneManager.AddArrowMesh("axisX");
                n = irrDevice.SceneManager.AddAnimatedMeshSceneNode(m, null, (int)SceneNodeID.AxisX, new Vector3Df(), new Vector3Df(0, 0, -90), new Vector3Df(50, 120, 50));
                n.GetMaterial(0).EmissiveColor = new Color(250, 250, 250);
                n.GetMaterial(1).EmissiveColor = new Color(250, 0, 0);
 
                m = irrDevice.SceneManager.AddArrowMesh("axisY");
                n = irrDevice.SceneManager.AddAnimatedMeshSceneNode(m, null, (int)SceneNodeID.AxisY, new Vector3Df(), new Vector3Df(0, 0, 0), new Vector3Df(50, 120, 50));
                n.GetMaterial(0).EmissiveColor = new Color(250, 250, 250);
                n.GetMaterial(1).EmissiveColor = new Color(0, 250, 0);
 
                m = irrDevice.SceneManager.AddArrowMesh("axisZ");
                n = irrDevice.SceneManager.AddAnimatedMeshSceneNode(m, null, (int)SceneNodeID.AxisZ, new Vector3Df(), new Vector3Df(90, 0, 0), new Vector3Df(50, 120, 50));
                n.GetMaterial(0).EmissiveColor = new Color(250, 250, 250);
                n.GetMaterial(1).EmissiveColor = new Color(0, 0, 250);
 
                // Rendering loop
 
                while (irrDevice.Run())
                {
                    if (irrDevice.VideoDriver.ScreenSize.Area != 0)
                    {
                        irrDevice.VideoDriver.BeginScene();
                        irrDevice.SceneManager.DrawAll();
                        irrDevice.VideoDriver.EndScene();
                        fps = irrDevice.VideoDriver.FPS;
                    }
                    else
                    {
                        Thread.Sleep(50);
                    }
 
                    irrThreadProcessCommandQueue();
                }
 
                irrDevice.Drop();
            }
 
 
 
            private void irrThreadProcessCommandQueue()
            {
                Command c;
 
                lock (commandQueue)
                {
                    if (commandQueue.Count == 0)
                        return;
 
                    c = commandQueue.Dequeue();
                }
 
                switch (c.Type)
                {
                    case CommandType.Abort:
                        {
                            irrDevice.Close();
                            break;
                        }
 
                    case CommandType.Axes:
                        {
                            break;
                        }
 
                    case CommandType.Plane:
                        {
                            var n = irrDevice.SceneManager.GetSceneNodeFromID((int)SceneNodeID.Plane);
                            n.Visible = (bool)c.Param;
                            break;
                        }
 
 
                    case CommandType.Resize:
                        {
                            int[] i = (int[])c.Param;
                            Dimension2Di d = new Dimension2Di(i[0], i[1]);
                            irrDevice.VideoDriver.ResizeNotify(d);
                            (irrDevice.SceneManager.GetSceneNodeFromID((int)SceneNodeID.Camera) as CameraSceneNode).AspectRatio =
                                i[2] == 1 ? (float)i[0] / i[1] : 1.333333f;
                            break;
                        }
 
                    case CommandType.Position:
                        {
                            float[] f = (float[])c.Param;
                            var p = irrDevice.SceneManager.GetSceneNodeFromID((int)SceneNodeID.ParticleSystem) as ParticleSystemSceneNode;
                            (p.Emitter as ParticleSphereEmitter).Center = new Vector3Df(f[0], f[1], f[2]);
                            break;
                        }
 
                    case CommandType.Radius:
                        {
                            float f = (float)c.Param;
                            var p = irrDevice.SceneManager.GetSceneNodeFromID((int)SceneNodeID.ParticleSystem) as ParticleSystemSceneNode;
                            (p.Emitter as ParticleSphereEmitter).Radius = f;
                            break;
                        }
 
                    case CommandType.CameraView:
                        {
                            float f = (float)c.Param;
                            var p = irrDevice.SceneManager.GetSceneNodeFromID((int)SceneNodeID.Camera) as CameraSceneNode;
                            p.Target = new Vector3Df(p.Target.X, f, p.Target.Z);
                            break;
                        }
 
                    case CommandType.Rate:
                        {
                            int v = (int)c.Param;
                            var p = irrDevice.SceneManager.GetSceneNodeFromID((int)SceneNodeID.ParticleSystem) as ParticleSystemSceneNode;
                            p.Emitter.MaxParticlesPerSecond = v;
                            p.Emitter.MinParticlesPerSecond = v / 2;
                            break;
                        }
 
                    case CommandType.Size:
                        {
                            int v = (int)c.Param;
                            var p = irrDevice.SceneManager.GetSceneNodeFromID((int)SceneNodeID.ParticleSystem) as ParticleSystemSceneNode;
                            p.Emitter.MaxStartSize = new Dimension2Df(v);
                            p.Emitter.MinStartSize = new Dimension2Df(v / 2);
                            break;
                        }
 
                    case CommandType.Direction:
                        {
                            float[] f = (float[])c.Param;
                            var p = irrDevice.SceneManager.GetSceneNodeFromID((int)SceneNodeID.ParticleSystem) as ParticleSystemSceneNode;
                            p.Emitter.Direction = new Vector3Df(f[0], f[1], f[2]);
                            break;
                        }
 
 
                    default:
                        throw new InvalidOperationException("Unexpected command type: " + c.Type.ToString());
                }
            }
        }
 
I hope you'll find what's wrong in it :)
greenya
Posts: 1012
Joined: Sun Jan 21, 2007 1:46 pm
Location: Ukraine
Contact:

Re: Irrlicht Lime is a .NET wrapper for Irrlicht Engine

Post by greenya »

Jonhson243,
While you combined WinFormsUserControl from L08.WPFWindow and ViewPort from L04.ParticleEmitterViewer, you made a mistake: you pass Handle of the WindowsFormsHost controls instead of UserControl (a native WindowsForms control). So to fix this you need to tweek a bit Viewport.Start(): it doesn't need Handle argument any more (since you made Viewport class to implement UserControl), you just change single line:

Code: Select all

p.WindowID = windowHandle;
to

Code: Select all

p.WindowID = Handle;
After this change you should see white background with colored arrows, but without textures. To make them visible the easiest and fastest way is to add next like just after IrrlichtDevice creation in rendering thread:

Code: Select all

irrDevice.FileSystem.AddFileArchive("../../../IrrlichtLime-1.4/media"); // the path to media folder relative to EXE file of your project
Also one more quick look, i would like to warn you about added by you

Code: Select all

public int fps = 0;
which you set in rendering thread and read it in your Window_MouseMove() handler. This is not thread safe. You need to add synchtonization object, you need to lock it each time you write it in rendering thread, and you need to lock it each time you read it from some get-property of Viewport class.
greenya
Posts: 1012
Joined: Sun Jan 21, 2007 1:46 pm
Location: Ukraine
Contact:

Re: Irrlicht Lime is a .NET wrapper for Irrlicht Engine

Post by greenya »

peteym5,

I feel like i need to clarify what is node, what is mesh, meshbuffer, what is material and what is vertex.
1. vertex a piece of information about rendering object; it has info about position vector, color, normal vector and more; it is a part of a meshbuffer;
2. meshbuffer is a rendering object which has arrays of vertices and indices, but the most important part is a material, meshbuffer has single material value which is used to draw all its vertices;
3. material is a piece of information about how vrtices are drawn; you can check what properties it has yourself; material has a lot of attributes but the most important is a Type, it defines what of those attributes will be used and how and what will be ignored; for example if material type is Solid, it will not use 2nd, 3rd and above textures even if you set them;
4. mesh is a set of meshbuffers; we need it because using only meshbuffer you cannot draw a room, which may has 10 materials, so it is 10 meshbuffers; keep in mind that even if all the settings in material the same but you need to use another texture, you need to use another material, that is why for example the "mesh" from 02.Quake3Map has 26 meshbuffers (and of cause 26 materials);
Looks like now we can draw whole rooms and other stuff, why do we need "node"?
SceneNode among all attributes it has, the most important stuff for our mesh it has is transformation matrix, this "thing" defines where the node is located in the space.

So now i will try to answer:
peteym5 wrote:It seems as if WallNode(i).SetMaterial(0, materialx) has no effect on the walls, but smgr.MeshManipulator.SetVertexColors(WallMesh(i), New Color(255, 0, 0, 128)) does.
There is big difference in those calls. The first one sets only 1st material of the node, so if it has 26 materials then other 25 will not be affected. Here is the screenshot where i call "node.SetMaterial(0, Material.IdentityRedWireframe);" in 02.Quake3Map:
Image
The second one does change every vertex' color to (255, 0, 0, 128). As you may got it is very slow to do it in runtime because it actually modifies the vertices data of your room (if you got them like 200k vertices and want to change them every frame, it may be quite slow).
Besides, if you use Solid material type, each color component defines how much of the color channel will be taken from the texture pixel. So for example if in some pixel of a texture has color (255, 127, 63) and you set vertex color to (63, 127, 255) the result will be rendered as (63,63,63). As you might get: 255 is a 100% of the color channel, 0 is 0%; so for example if the texture pixel is (0,0,255), with vertex color (255,0,0) it will be rendered as completely black.
peteym5
Posts: 21
Joined: Wed Sep 12, 2012 3:56 pm

Re: Irrlicht Lime is a .NET wrapper for Irrlicht Engine

Post by peteym5 »

This did provide some information, I can use "MaterialX" to set up textures and lighting, but not seem to be able to change the Red, Green, Blue, and Alpha of the diffuse, ambient, spectacular properties. As far as I know there is only one material per node. In my case, each wall is its own node. Unless its creating a primary material that I cannot alter the properties. I usually set up all the materials during the game initialization, or level initialization, and then set the materials to the 3D meshes used within the scene.
Jonhson243
Posts: 9
Joined: Sun Aug 04, 2013 4:03 pm

Re: Irrlicht Lime is a .NET wrapper for Irrlicht Engine

Post by Jonhson243 »

greenya wrote:Jonhson243,
While you combined WinFormsUserControl from L08.WPFWindow and ViewPort from L04.ParticleEmitterViewer, you made a mistake: you pass Handle of the WindowsFormsHost controls instead of UserControl (a native WindowsForms control). So to fix this you need to tweek a bit Viewport.Start(): it doesn't need Handle argument any more (since you made Viewport class to implement UserControl), you just change single line:

Code: Select all

p.WindowID = windowHandle;
to

Code: Select all

p.WindowID = Handle;
After this change you should see white background with colored arrows, but without textures. To make them visible the easiest and fastest way is to add next like just after IrrlichtDevice creation in rendering thread:

Code: Select all

irrDevice.FileSystem.AddFileArchive("../../../IrrlichtLime-1.4/media"); // the path to media folder relative to EXE file of your project
Also one more quick look, i would like to warn you about added by you

Code: Select all

public int fps = 0;
which you set in rendering thread and read it in your Window_MouseMove() handler. This is not thread safe. You need to add synchtonization object, you need to lock it each time you write it in rendering thread, and you need to lock it each time you read it from some get-property of Viewport class.
Image

Thank you very much greenya, you are awesome !! It's now working perfectly. Thank you for your explanation concerning the thread safe aspects. Now I understand why there are many lock{} in the code.

Okay I will be honest and at this point I am able to finish this project without needing any further help : since there is no any other complex problem and my project is quite simple I should find the rest of what I need in the documentation. However, since I only need 3 simple things to definitely be done with this project, I would like to ask you the questions, perhaps you already have the answer in mind and it will only take a few second for you but will save me several hours or even days... If one question is not this easy, please just let me know and I will do my job, you already helped me a lot and I'm very thankful for that.

Here are my 3 questions :
-Can you give me the one line statement to translate a camera ?
-The same but to rotate a camera
-And finally, I would just need to insert a background 2D image. So I just need the code to insert such background then I'll manage the rest myself. The idea is to position the 3D object on the background image.

My project consist in integrating buildings in an environment. Basically I load different meshes to be able to change the colors of the parts of the building distinctly. I move the building on the screen to let the user see it in more details and then to position it on the background picture so that he can imagine how it will look in the neighbourhood.

I'll post the code if I find it!
Have a nice day :D

Edit:
I was scared for nothing.

Code: Select all

CameraSceneNode cam = smgr.AddCameraSceneNode();
cam.Rotation = new Vector3Df(10, 20, 30);
cam.Position = new Vector3Df(cam.Position.X, cam.Position.Y, cam.Position.Z - 1);

Code: Select all

 driver->draw2DImage()
Post Reply