-1
\$\begingroup\$

I want to make a simple 3D engine using vb. It must be fast at creating frames obviously for a 3d game. So this code i have draws a frame at 4 fps

Dim SM = DateTime.Now.Millisecond
    Dim ETDFrame As New Bitmap(600, 600)
    Dim ETDGraphics As Graphics = Graphics.FromImage(ETDFrame)
    Dim DFrame As New PictureBox
    Dim x = 0
    Do Until x = 600
        Dim y = 0
        Do Until y = 600
            ETDFrame.SetPixel(x, y, Color.Black)
            y += 1
        Loop
        x += 1
    Loop
    DFrame.Image = ETDFrame
    DFrame.Size = New Size(600, 600)
    DFrame.Location = New Point(0, 0)
    DFrame.Visible = True
    Controls.Add(DFrame)
    Dim EM = DateTime.Now.Millisecond
    Dim FM = EM - SM
    If FM < 0 Then
        FM += 1000
    End If
    Dim fps As Integer = 1000 / FM
    MsgBox(fps)

This code draws a frame at 333 to 500 fps but it is a solid color.

Dim SM = DateTime.Now.Millisecond
    Dim ETDFrame As New Bitmap(600, 600)
    Dim ETDGraphics As Graphics = Graphics.FromImage(ETDFrame)
    Dim DFrame As New PictureBox
    ETDGraphics.FillRectangle(Brushes.Red, 0, 0, 600, 600)
    DFrame.Image = ETDFrame
    DFrame.Size = New Size(600, 600)
    DFrame.Location = New Point(0, 0)
    DFrame.Visible = True
    Controls.Add(DFrame)
    Dim EM = DateTime.Now.Millisecond
    Dim FM = EM - SM
    If FM < 0 Then
        FM += 1000
    End If
    Dim fps As Integer = 1000 / FM
    MsgBox(fps)

All i know is that something is setting all the pixels to black in this bitmap very fast, but doing it yourself is really slow i was wondering is there a different way to do it with just vb or if a need to download something like DirectX SDK?

\$\endgroup\$
4
  • \$\begingroup\$ Don't use VB - I'm completely serious. \$\endgroup\$
    – Alec Teal
    Commented Sep 15, 2015 at 1:54
  • 2
    \$\begingroup\$ I use vb.net and am programming a game using xna. I would recommend you take a look at monogame (www.monogame.net). It's pretty much xna, with the exception that xna is dead. Vb.net is perfectly fine since it does exactly the same thing underneath as c#, but you'll find a lot of reference material in c#, and barely any in vb.net. By the way, this community doesn't like 'how to get started' questions. The website is meant for specific questions \$\endgroup\$
    – Peethor
    Commented Sep 15, 2015 at 5:12
  • \$\begingroup\$ Is MonoGame capable of drawing frames quickly? \$\endgroup\$
    – NoahGav
    Commented Sep 15, 2015 at 14:35
  • \$\begingroup\$ Your problem is not VB, your problem is that you're implementing your (software) rendering by manually setting individual pixels. This is just about the slowest way to do it. You'll either want to look at more direct bitmap manipulation as in Ausa's answer, or using an API like MonoGame or XNA that leverage hardware accelerated rendering APIs. \$\endgroup\$
    – user1430
    Commented Dec 17, 2015 at 16:25

1 Answer 1

1
\$\begingroup\$

GDI+ is not the best way to go for this kind of thing. The issue with SetPixel is it locks and unlocks the image each loop.

Read up on using LockBits (There is a lot of info on the web about it).

Here is your code with a little adjustment for example.

        Dim SM = DateTime.Now.Millisecond
        Dim ETDFrame As New Bitmap(600, 600)

        Dim b As Imaging.BitmapData = ETDFrame.LockBits(New Rectangle(0, 0, ETDFrame.Width, ETDFrame.Height), Imaging.ImageLockMode.WriteOnly, Imaging.PixelFormat.Format24bppRgb)

        Dim ptr As IntPtr = b.Scan0

        Dim bytes As Integer = Math.Abs(b.Stride) * ETDFrame.Height
        Dim rgbValues(bytes - 1) As Byte

        Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes)
        For counter As Integer = 0 To rgbValues.Length - 1 Step 3
            rgbValues(counter) = 255     'Blue
            rgbValues(counter + 1) = 255 'Green
            rgbValues(counter + 2) = 255 'Red
        Next

        System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes)

        ETDFrame.UnlockBits(b)

        Dim DFrame As New PictureBox

        DFrame.Image = ETDFrame
        DFrame.Size = New Size(600, 600)
        DFrame.Location = New Point(0, 0)
        DFrame.Visible = True
        Controls.Add(DFrame)
        Dim EM = DateTime.Now.Millisecond
        Dim FM = EM - SM
        If FM < 0 Then
            FM += 1000
        End If
        Dim fps As Integer = 1000 / FM
        MsgBox(fps)

For more speed you could skip the marshal and do it unsafe.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .