Hi,
I'm working on a tile editor with SlimDX and VB.Net. I keep getting this weird error on the line in Form1.vb that says :
Bitmaps(b, a).FromBitmap(MyBitmap, New Point(0, 0), New Retangle(a * Width, b * Height, Width, Height))
when I click on add in the context menu in the tilesets list view. The error is : "An invalid parameter was passed to the returning function.". Here's my code:
Form1.vb:
Imports SlimDX Public Class Form1 Dim TileX As Integer = 0 Dim TileY As Integer = 0 Structure Layer Dim Name As String Sub New(Name As String) Me.Name = Name End Sub End Structure Structure Tileset Dim Name As String Dim Bitmaps As Array Sub New(Name As String, Bitmaps As Array) Me.Name = Name Me.Bitmaps = Bitmaps End Sub End Structure Public Layers As New List(Of Layer) Public Tilesets As New List(Of Tileset) Function ConvertGDIBitmapToDirect2DBitmap(MyBitmap As Bitmap, WindowRenderTarget As Direct2D.WindowRenderTarget) As Direct2D.Bitmap Dim MyBitmapData As Imaging.BitmapData = MyBitmap.LockBits(New Rectangle(0, 0, MyBitmap.Width, MyBitmap.Height), Imaging.ImageLockMode.ReadWrite, Imaging.PixelFormat.Format32bppPArgb) Dim MyDataStream As New DataStream(MyBitmapData.Scan0, MyBitmapData.Stride * MyBitmapData.Height, True, True) Dim MyBitmapProperties As New Direct2D.BitmapProperties() MyBitmapProperties.PixelFormat = New Direct2D.PixelFormat(DXGI.Format.R8G8B8A8_UNorm, Direct2D.AlphaMode.Premultiplied) Dim MyDirect2DBitmap As New Direct2D.Bitmap(WindowRenderTarget, New Size(MyBitmapData.Width, MyBitmapData.Height), MyDataStream, MyBitmapData.Stride, MyBitmapProperties) MyBitmap.UnlockBits(MyBitmapData) Return MyDirect2DBitmap End Function Function SplitDirect2DBitmap(Width As Integer, Height As Integer, MyBitmap As Direct2D.Bitmap, WindowRenderTarget As Direct2D.WindowRenderTarget) As Array Dim Bitmaps As Array = Array.CreateInstance(GetType(Direct2D.Bitmap), CInt(Math.Floor(MyBitmap.PixelSize.Height / Height)), CInt(Math.Floor(MyBitmap.PixelSize.Width / Width))) Dim MyBitmapProperties As New Direct2D.BitmapProperties MyBitmapProperties.PixelFormat = New Direct2D.PixelFormat(DXGI.Format.B8G8R8A8_UNorm, Direct2D.AlphaMode.Premultiplied) For a = 0 To Math.Floor(MyBitmap.PixelSize.Width / Width) For b = 0 To Math.Floor(MyBitmap.PixelSize.Height / Height) Bitmaps(b, a) = New Direct2D.Bitmap(WindowRenderTarget, New Size(Width, Height), MyBitmapProperties) Bitmaps(b, a).FromBitmap(MyBitmap, New Point(0, 0), New Rectangle(a * Width, b * Height, Width, Height)) Next Next Return Bitmaps End Function Sub DrawTransparent(Width As Integer, Height As Integer, WindowRenderTarget As Direct2D.WindowRenderTarget) Dim X As Integer = Math.Floor(WindowRenderTarget.PixelSize.Width / Width) Dim Y As Integer = Math.Floor(WindowRenderTarget.PixelSize.Height / Height) For a = 0 To X For b = 0 To Y If a Mod 2 = 0 Then If b Mod 2 = 0 Then WindowRenderTarget.FillRectangle(New Direct2D.SolidColorBrush(WindowRenderTarget, New Color4(1, 0.75, 0.75, 0.75)), New Rectangle(a * Width, b * Height, Width, Height)) Else WindowRenderTarget.FillRectangle(New Direct2D.SolidColorBrush(WindowRenderTarget, New Color4(1, 1, 1, 1)), New Rectangle(a * Width, b * Height, Width, Height)) End If Else If b Mod 2 = 0 Then WindowRenderTarget.FillRectangle(New Direct2D.SolidColorBrush(WindowRenderTarget, New Color4(1, 1, 1, 1)), New Rectangle(a * Width, b * Height, Width, Height)) Else WindowRenderTarget.FillRectangle(New Direct2D.SolidColorBrush(WindowRenderTarget, New Color4(1, 0.75, 0.75, 0.75)), New Rectangle(a * Width, b * Height, Width, Height)) End If End If Next Next End Sub Sub DrawGrid(X As Integer, Y As Integer, Width As Integer, Height As Integer, Color As Color4, WindowRenderTarget As Direct2D.WindowRenderTarget) For a = 0 To X WindowRenderTarget.DrawLine(New Direct2D.SolidColorBrush(WindowRenderTarget, Color), a * Width, 0, a * Width, Y * Height) Next For a = 0 To Y WindowRenderTarget.DrawLine(New Direct2D.SolidColorBrush(WindowRenderTarget, Color), 0, a * Height, X * Width, a * Height) Next End Sub Dim LayersFactory As Direct2D.Factory Dim LayersWindowRenderTargetProperties As Direct2D.WindowRenderTargetProperties Public LayersWindowRenderTarget As Direct2D.WindowRenderTarget Dim TilesetsFactory As Direct2D.Factory Dim TilesetsWindowRenderTargetProperties As Direct2D.WindowRenderTargetProperties Public TilesetsWindowRenderTarget As Direct2D.WindowRenderTarget Dim MainFactory As Direct2D.Factory Dim MainWindowRenderTargetProperties As Direct2D.WindowRenderTargetProperties Public MainWindowRenderTarget As Direct2D.WindowRenderTarget Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load LayersFactory = New Direct2D.Factory() LayersWindowRenderTargetProperties = New Direct2D.WindowRenderTargetProperties() LayersWindowRenderTargetProperties.Handle = SplitContainer2.Panel2.Handle LayersWindowRenderTargetProperties.PixelSize = SplitContainer2.Panel2.ClientSize LayersWindowRenderTargetProperties.PresentOptions = Direct2D.PresentOptions.None LayersWindowRenderTarget = New Direct2D.WindowRenderTarget(LayersFactory, LayersWindowRenderTargetProperties) TilesetsFactory = New Direct2D.Factory() TilesetsWindowRenderTargetProperties = New Direct2D.WindowRenderTargetProperties() TilesetsWindowRenderTargetProperties.Handle = SplitContainer3.Panel2.Handle TilesetsWindowRenderTargetProperties.PixelSize = SplitContainer3.Panel2.ClientSize TilesetsWindowRenderTargetProperties.PresentOptions = Direct2D.PresentOptions.None TilesetsWindowRenderTarget = New Direct2D.WindowRenderTarget(TilesetsFactory, TilesetsWindowRenderTargetProperties) MainFactory = New Direct2D.Factory() MainWindowRenderTargetProperties = New Direct2D.WindowRenderTargetProperties() MainWindowRenderTargetProperties.Handle = SplitContainer1.Panel2.Handle MainWindowRenderTargetProperties.PixelSize = SplitContainer1.Panel2.ClientSize MainWindowRenderTargetProperties.PresentOptions = Direct2D.PresentOptions.None MainWindowRenderTarget = New Direct2D.WindowRenderTarget(MainFactory, MainWindowRenderTargetProperties) LayersWindowRenderTarget.AntialiasMode = Direct2D.AntialiasMode.Aliased TilesetsWindowRenderTarget.AntialiasMode = Direct2D.AntialiasMode.Aliased MainWindowRenderTarget.AntialiasMode = Direct2D.AntialiasMode.Aliased End Sub Private Sub SplitContainer1_SplitterMoved(sender As Object, e As SplitterEventArgs) Handles SplitContainer1.SplitterMoved TabControl1.Width = SplitContainer1.Panel1.Width + 2 ListView1.Width = SplitContainer1.Panel1.Width - 12 ListView2.Width = SplitContainer1.Panel1.Width - 12 If SplitContainer1.Panel2.IsHandleCreated Then MainWindowRenderTarget.Resize(SplitContainer1.Panel2.ClientSize) End If If SplitContainer2.Panel2.IsHandleCreated Then LayersWindowRenderTarget.Resize(SplitContainer2.Panel2.ClientSize) End If If SplitContainer3.Panel2.IsHandleCreated Then TilesetsWindowRenderTarget.Resize(SplitContainer3.Panel2.ClientSize) End If End Sub Private Sub SplitContainer2_SplitterMoved(sender As Object, e As SplitterEventArgs) Handles SplitContainer2.SplitterMoved ListView1.Height = SplitContainer2.Panel1.Height If SplitContainer2.Panel2.IsHandleCreated Then LayersWindowRenderTarget.Resize(SplitContainer2.Panel2.ClientSize) End If End Sub Private Sub SplitContainer3_SplitterMoved(sender As Object, e As SplitterEventArgs) Handles SplitContainer3.SplitterMoved ListView2.Height = SplitContainer3.Panel1.Height If SplitContainer3.Panel2.IsHandleCreated Then TilesetsWindowRenderTarget.Resize(SplitContainer3.Panel2.ClientSize) End If End Sub Private Sub SplitContainer2_Panel2_Paint(sender As Object, e As PaintEventArgs) Handles SplitContainer2.Panel2.Paint LayersWindowRenderTarget.BeginDraw() DrawTransparent(16, 16, LayersWindowRenderTarget) If Not ListView1.SelectedIndices.Count = 0 Then End If LayersWindowRenderTarget.EndDraw() End Sub Private Sub SplitContainer3_Panel2_Paint(sender As Object, e As PaintEventArgs) Handles SplitContainer3.Panel2.Paint TilesetsWindowRenderTarget.BeginDraw() DrawTransparent(16, 16, TilesetsWindowRenderTarget) If Not ListView2.SelectedIndices.Count = 0 Then For a = 0 To Tilesets(ListView2.SelectedIndices(0)).Bitmaps.GetUpperBound(0) - 1 For b = 0 To Tilesets(ListView2.SelectedIndices(0)).Bitmaps.GetUpperBound(1) - 1 TilesetsWindowRenderTarget.DrawBitmap(Tilesets(ListView2.SelectedIndices(0)).Bitmaps(b, a), New Rectangle(a * 32, b * 32, 32, 32)) Next Next DrawGrid(Tilesets(ListView2.SelectedIndices(0)).Bitmaps.GetUpperBound(1), Tilesets(ListView2.SelectedIndices(0)).Bitmaps.GetUpperBound(0), 32, 32, New Color4(1, 0.5, 0.5, 0.5), TilesetsWindowRenderTarget) TilesetsWindowRenderTarget.DrawRectangle(New Direct2D.SolidColorBrush(TilesetsWindowRenderTarget, New Color4(1, 0.25, 0.25, 0.25)), New Rectangle(TileX * 32, TileY * 32, 32, 32)) End If TilesetsWindowRenderTarget.EndDraw() End Sub Private Sub SplitContainer1_Panel2_Paint(sender As Object, e As PaintEventArgs) Handles SplitContainer1.Panel2.Paint MainWindowRenderTarget.BeginDraw() DrawTransparent(16, 16, MainWindowRenderTarget) MainWindowRenderTarget.EndDraw() End Sub Private Sub ContextMenuStrip1_Opening(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles ContextMenuStrip1.Opening If ListView1.SelectedIndices.Count = 0 Then RemoveToolStripMenuItem.Enabled = False MoveUpToolStripMenuItem.Enabled = False MoveDownToolStripMenuItem.Enabled = False PropertiesToolStripMenuItem.Enabled = False Else RemoveToolStripMenuItem.Enabled = True If ListView1.SelectedIndices(0) = 0 Then MoveUpToolStripMenuItem.Enabled = False Else MoveUpToolStripMenuItem.Enabled = True End If If ListView1.SelectedIndices(0) = ListView1.Items.Count - 1 Then MoveDownToolStripMenuItem.Enabled = False Else MoveDownToolStripMenuItem.Enabled = True End If PropertiesToolStripMenuItem.Enabled = True End If End Sub Private Sub AddToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles AddToolStripMenuItem.Click Dim Name As String = "Layer " + CStr(Layers.Count + 1) ListView1.Items.Add(New ListViewItem(Name)) Layers.Add(New Layer(Name)) End Sub Private Sub RemoveToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles RemoveToolStripMenuItem.Click Dim Index As Integer = ListView1.SelectedIndices(0) ListView1.Items.RemoveAt(Index) Layers.RemoveAt(Index) End Sub Private Sub MoveUpToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles MoveUpToolStripMenuItem.Click End Sub Private Sub MoveDownToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles MoveDownToolStripMenuItem.Click End Sub Private Sub PropertiesToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles PropertiesToolStripMenuItem.Click LayerProperties.ShowDialog() End Sub Private Sub ContextMenuStrip2_Opening(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles ContextMenuStrip2.Opening If ListView2.SelectedIndices.Count = 0 Then RemoveToolStripMenuItem1.Enabled = False MoveUpToolStripMenuItem1.Enabled = False MoveDownToolStripMenuItem1.Enabled = False PropertiesToolStripMenuItem1.Enabled = False Else RemoveToolStripMenuItem1.Enabled = True If ListView2.SelectedIndices(0) = 0 Then MoveUpToolStripMenuItem1.Enabled = False Else MoveUpToolStripMenuItem1.Enabled = True End If If ListView2.SelectedIndices(0) = ListView2.Items.Count - 1 Then MoveDownToolStripMenuItem1.Enabled = False Else MoveDownToolStripMenuItem1.Enabled = True End If PropertiesToolStripMenuItem1.Enabled = True End If End Sub Private Sub AddToolStripMenuItem1_Click(sender As Object, e As EventArgs) Handles AddToolStripMenuItem1.Click Dim Name As String = "Tileset " + CStr(Tilesets.Count + 1) ListView2.Items.Add(New ListViewItem(Name)) Tilesets.Add(New Tileset(Name, SplitDirect2DBitmap(32, 32, ConvertGDIBitmapToDirect2DBitmap(New Bitmap("Tile.png"), TilesetsWindowRenderTarget), TilesetsWindowRenderTarget))) End Sub Private Sub RemoveToolStripMenuItem1_Click(sender As Object, e As EventArgs) Handles RemoveToolStripMenuItem1.Click Dim Index As Integer = ListView2.SelectedIndices(0) ListView2.Items.RemoveAt(Index) Tilesets.RemoveAt(Index) End Sub Private Sub MoveUpToolStripMenuItem1_Click(sender As Object, e As EventArgs) Handles MoveUpToolStripMenuItem1.Click End Sub Private Sub MoveDownToolStripMenuItem1_Click(sender As Object, e As EventArgs) Handles MoveDownToolStripMenuItem1.Click End Sub Private Sub PropertiesToolStripMenuItem1_Click(sender As Object, e As EventArgs) Handles PropertiesToolStripMenuItem1.Click TilesetProperties.ShowDialog() End Sub Private Sub ListView1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListView1.SelectedIndexChanged SplitContainer2.Panel2.Invalidate() End Sub Private Sub ListView2_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListView2.SelectedIndexChanged SplitContainer3.Panel2.Invalidate() End Sub Private Sub SplitContainer2_Panel2_Click(sender As Object, e As MouseEventArgs) Handles SplitContainer2.Panel2.Click If Not ListView1.SelectedIndices.Count = 0 Then End If End Sub Private Sub SplitContainer3_Panel2_Click(sender As Object, e As MouseEventArgs) Handles SplitContainer3.Panel2.Click If Not ListView2.SelectedIndices.Count = 0 Then 'TileX = Math.Min(Math.Floor(e.X / 32), Math.Floor(Tilesets(ListView2.SelectedIndices(0)).Bitmap.Size.Width / 32) - 1) 'TileY = Math.Min(Math.Floor(e.Y / 32), Math.Floor(Tilesets(ListView2.SelectedIndices(0)).Bitmap.Size.Height / 32) - 1) TileX = Math.Min(Math.Floor(e.X / 32), Tilesets(ListView2.SelectedIndices(0)).Bitmaps.GetUpperBound(1)) TileX = Math.Min(Math.Floor(e.Y / 32), Tilesets(ListView2.SelectedIndices(0)).Bitmaps.GetUpperBound(0)) SplitContainer3.Panel2.Invalidate() End If End Sub Private Sub SplitContainer1_Panel2_Click(sender As Object, e As MouseEventArgs) Handles SplitContainer1.Panel2.Click End Sub End Class
LayerProperties.vb:
Public Class LayerProperties Private Sub LayerProperties_Load(sender As Object, e As EventArgs) Handles MyBase.Load TextBox1.Text = Form1.Layers(Form1.ListView1.SelectedIndices(0)).Name End Sub Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Form1.Layers(Form1.ListView1.SelectedIndices(0)) = New Form1.Layer(TextBox1.Text) Form1.ListView1.Items(Form1.ListView1.SelectedIndices(0)) = New ListViewItem(TextBox1.Text) Me.Close() End Sub Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click Me.Close() End Sub End Class
TilesetProperties.vb:
Imports SlimDX Public Class TilesetProperties Private Sub TilesetProperties_Load(sender As Object, e As EventArgs) Handles MyBase.Load TextBox1.Text = Form1.Tilesets(Form1.ListView2.SelectedIndices(0)).Name End Sub Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Dim OldBitmap As Direct2D.Bitmap = Form1.ConvertGDIBitmapToDirect2DBitmap(New Bitmap(TextBox2.Text), Form1.TilesetsWindowRenderTarget) Dim NewBitmap As New Direct2D.Bitmap(Form1.TilesetsWindowRenderTarget, New Size(Math.Ceiling(OldBitmap.PixelSize.Width / 32) * 32, Math.Ceiling(OldBitmap.PixelSize.Height / 32) * 32)) NewBitmap.FromBitmap(OldBitmap, New Point(0, 0), New Rectangle(0, 0, OldBitmap.PixelSize.Width, OldBitmap.PixelSize.Height)) Form1.Tilesets(Form1.ListView2.SelectedIndices(0)) = New Form1.Tileset(TextBox1.Text, Form1.SplitDirect2DBitmap(32, 32, NewBitmap, Form1.TilesetsWindowRenderTarget)) Me.Close() End Sub Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click Me.Close() End Sub Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click OpenFileDialog1.ShowDialog() End Sub Private Sub OpenFileDialog1_FileOk(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles OpenFileDialog1.FileOk TextBox2.Text = OpenFileDialog1.FileName End Sub End Class
Thanks.