Go Back  Xtreme Visual Basic Talk > Visual Basic .NET (2002/2003/2005/2008, including Express editions) > .NET Game Programming > Copying tiles from sheet


Reply
 
Thread Tools Display Modes
  #1  
Old 03-21-2012, 04:24 PM
VB_Alien VB_Alien is offline
Contributor
 
Join Date: Apr 2004
Posts: 775
Default Copying tiles from sheet


I downloaded VB express 2010 free version about a
week ago and i'm totally lost. It sure has changed alot
from the old VB6 program.

Anyway, i've been trying for a week now to get a clipped
tile from a sheet and draw it in either it's destination picturebox
or draw it to a picturebox that will be the same size and the
clipped tile and then draw it from there to it's destination.

Nothing seems to work for me. I even tried using Bitblt but
that didn't go very far, although i had better luck with that
then the built in graphics functions.

So, for now, i removed all code and decided to start from
scratch again. I've been all over this site to find something
that i need but nothing seems to fit what i need.

The only thing i got so far is this:

Dim myImage As Bitmap = New Bitmap("C:\Users\SomeClown\Desktop\BitblitTest\bin\basis.bmp", True

picSource.Image = myImage

As you know, all this does is load a bitmap file into memory and
the second line draws the bitmap to a picturebox.

From there, i'm lost. I've been on this for a week now and i
still haven't gotten anywhere.

I'm hoping that the Coding Gods will have mercy on me and
throw me a bone or two.
Reply With Quote
  #2  
Old 03-21-2012, 11:59 PM
VB_Alien VB_Alien is offline
Contributor
 
Join Date: Apr 2004
Posts: 775
Default

OK. I got some code working now that copies
one tile from a tile sheet and puts it in a 32 by
32 picturebox. Here is that code.

' Create a new bitmap to hold source tiles bitmap
Dim fr_bm As New Bitmap(picSource.Image)

' Create a new blank bitmap to hold
' only one 32 by 32 tile
Dim to_bm As New Bitmap(32, 32)

' Create the drawing object
Dim gr As Graphics = Graphics.FromImage(to_bm)

' Get source and destination rectangles.
Dim fr_rect As New Rectangle(S_Xpos, S_Ypos, 32, 32)
Dim to_rect As New Rectangle(0, 0, 32, 32)

' Draw from the source to the destination.
gr.DrawImage(fr_bm, to_rect, fr_rect, GraphicsUnit.Pixel)

' Display the results in picturebox
picSelected.Image = to_bm


Using the same code with different variables, i tried to
draw from the 32 by 32 picturebox(picSelected) to the
destination picturebox(picDest) and although the tile
copies in the right spot that i choose, the previous tiles
are removed, leaving me only with the currently selected
tile in the picturebox. Here is that code:

' Create a new bitmap to hold source tile bitmap
Dim fr_bm As New Bitmap(picSelected.Image)

' Create a new blank bitmap to hold the copied tiles
Dim to_bm As New Bitmap(192, 96)

' Create the drawing object
Dim gr As Graphics = Graphics.FromImage(to_bm)

' Get source and destination rectangles.
Dim fr_rect As New Rectangle(0, 0, 32, 32)
Dim to_rect As New Rectangle(D_Xpos, D_Ypos, 32, 32)

' Draw from the source to the destination.
gr.DrawImage(fr_bm, to_rect, fr_rect, GraphicsUnit.Pixel)

' Display the results in picturebox ' I know the trouble is here but
picDest.Image = to_bm ' i don't know what to do to fix it.


I realize that i must be doing something wrong, so i would
appreciate any help.
Reply With Quote
  #3  
Old 03-22-2012, 03:57 AM
passel's Avatar
passel passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 7,862
Default

I did some experiments with different methods of transferring images in .Net, starting with a sprite sheet.
Generally, found it quickest to not use a spritesheet, but break the sprite sheet up, either ahead of time or at run time.
The latest version of that code is found here.
The code does use bitblt as one of the examples methods, but since you can get good results without using bitblt, as the program demonstrates, it would be cleanest to not use bitblt in .Net.

If you're just getting into .Net, and are interested in graphics, a recent thread to look at would be this one in Tech Discussions.
One of the links is to this example which has built into it a "step" mode where you can step through the stages of the drawing process, but still manipulate the graphics output by dragging on the various areas with left or right mouse, to see the effect of the accumlated actions (graphic transforms and graphic commands) at that stage of the drawing process.

Also, AtmaWeapon had a post (among many) in response to someone wanting to do move multiple "bullets" at a time.
His code here I believe is a good example of defining a control class to use as your drawing surface. I've played with that one a little as I should be more Object Oriented in my approaches and take advantage of classes.
The one thing I found in looking at the class, is that by adding the ControlStyles.Opaque in addition to the other options he has, it draws 20 to 40% faster on my machine.
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.
Reply With Quote
  #4  
Old 03-22-2012, 03:47 PM
VB_Alien VB_Alien is offline
Contributor
 
Join Date: Apr 2004
Posts: 775
Default

I tried using a part of your code from your SpriteSheetAnimation
demo but had no success.

I took this from the form_load of your demo:

In my Declarations area:

'Image (backbuffer) we're drawing on
Dim gameDisplay As Image

'Bitmap that will contain all the sprites on a transparent background
Dim spriteSheet As Bitmap
Dim gameGraphic As Graphics

'Where in the sprite map we fetch our sprite
Dim srcRect As New Rectangle(0, 0, 32, 32)

'Where in the display we draw the sprite
Dim dstRect As New Rectangle(0, 0, 32, 32)

'------------------------------------------------------------------------------

'our backbuffer
gameDisplay = New Bitmap(picDest.Width, picDest.Height)

'our Graphics object to access the backbuffer
gameGraphic = Graphics.FromImage(gameDisplay)

'our bitmap holding our sprites
' In my program, the source tile changes
spriteSheet = picSelected.Image.Clone

'Modified to create the transparent background
spriteSheet.MakeTransparent(Color.Magenta)

and i took this from your DrawCars_drawimage sub:

gameGraphic.DrawImage(spriteSheet, srcRect, dstRect, GraphicsUnit.Pixel)
picDest.Refresh()

Now all of this is in one sub:

Private Sub Draw_Tile()

'Update X & Y coordinates from the source picturebox
'This is just in place right now, in case i need use
' For now, both X & Y will always be 0, 0, 32, 32
'of it later on.
' srcRect.X = 0
' srcRect.Y = 0

'Update X & Y coordinates to the destination picturebox
dstRect.X = D_Xpos
dstRect.Y = D_Ypos

'our backbuffer
gameDisplay = New Bitmap(picDest.Width, picDest.Height)

'our Graphics object to access the backbuffer
gameGraphic = Graphics.FromImage(gameDisplay)

'our bitmap holding our sprites
spriteSheet = picSelected.Image.Clone


'Modified to create the transparent background
spriteSheet.MakeTransparent(Color.Magenta)

gameGraphic.Clear(Color.LightGreen)

gameGraphic.DrawImage(spriteSheet, srcRect, dstRect, GraphicsUnit.Pixel)

picDest.Refresh()

End Sub

I have checked to make sure that all my coordinates are
updating and they are and i made sure that spriteSheet
is holding an image and it is but i still can't get anything
to draw on my picDest picturebox.

The only thing i can figure is that gameGraphic.DrawImage
is not drawing anything.

All i'm doing in my program is trying to make a map maker
where i copy a tile and place it in the map drawing area.

I already have code working that copies a tile from a source
tile sheet and puts it in a 32 by 32 picturebox. Now i can't
figure out how to get it out of that picturebox to the map
drawing area. My trouble has been that either i get nothing
at all or when i do get a tile copied into the map drawing
area, the previous tiles disappear.
Reply With Quote
  #5  
Old 03-23-2012, 11:20 AM
VB_Alien VB_Alien is offline
Contributor
 
Join Date: Apr 2004
Posts: 775
Default

OK. I might know what i'm doing wrong but i
need verification of it. I'll be using different
drawing code to explain my possible mistake.

Code:
        ' Create a new bitmap to hold source tiles bitmap
        Dim fr_bm As New Bitmap(picSource.Image)

        ' Create a new blank bitmap to hold
        ' only one 32 by 32 tile
        Dim to_bm As New Bitmap(32, 32)

        ' Create the drawing object
        Dim gr As Graphics = Graphics.FromImage(to_bm)

        ' Get source and destination rectangles.
        Dim fr_rect As New Rectangle(S_Xpos, S_Ypos, 32, 32)
        Dim to_rect As New Rectangle(0, 0, 32, 32)

        ' Draw from the source to the destination.
        gr.DrawImage(fr_bm, to_rect, fr_rect, GraphicsUnit.Pixel)

        ' Display the results in picturebox
        picSelected.Image = to_bm
In all my other code, i've been leaving out the very last line
of this code. " picSelected.Image = to_bm "

I found out that if i comment out, either of the last two lines
of code, nothing gets drawn.

Then i realized that the code provided, never specifies what DC
to draw the image on.

So, may i ask that when using the DrawImage function, does
this only draw images in memory and not the actual surface
of a picturebox?
Reply With Quote
  #6  
Old 03-23-2012, 03:33 PM
passel's Avatar
passel passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 7,862
Default

I'm getting ready to head home from work right now so can't investigate the issues.
Bottom line, we're drawing on some kind of image in memory as a backbuffer, then transferring that image to the screen, which should be in conjunction with a Paint event.
You should only paint to the screen in the control you're using's paint event.

If you go back to that thread, and look back at the first example I posted, it may be easier to follow as it doesn't have 1/2 dozen methods of doing the draw. {edit: but be sure to read the last section of this post first as it gives the skinny on the simple, basic, (and probably considered proper) way to periodically update a picturebox control. Understand and follow that and you may not need to look at my other post.}

I'm not sure, but the first post probably only has the sprite sheet and drawimage method, not texture brushes, etc.

In the case of the last code you posted, you are creating to bitmaps fr_bm and to_bm
The next to the last line transfers an area from your fr_bm to the to_bm.
You then assign the to_bm to your picturebox.Image object.
This causes the picturebox to issue a paint event.
Assuming you have the default conditions, the pictureboxes are double-buffered.
So, assigning a bitmap to the .image should cause the following,
A memory buffer is used or created and cleared to the background color.
If a background image is assigned to the picturebox, that image is drawn in the buffer.
It then draws the image you assigned to the buffer.
It then raises the Paint Event, passing a Graphics Object to you so you can draw directly on that buffer, if desired.
After the Paint Event exits, the final result is refeshed to the screen, and you see it.

So, if you want to do tiling, and updating the screen often, you don't want to assign an image to the picturebox, most likely.
You just want to update the double buffer of the picturebox, using the Graphics object passed to you in the Paint event.
You can add an additional buffer of your own (the to_bm) and do all your drawing there, and when ready to update the screen (picturebox), issue a .Invalidate, which will cause the Paint event to happen, and in the paint event use DrawImage to Draw your to_bm to that object.

Or you could just cause the Paint event, by issuing a .Invalidate on the picturebox, and in the Paint event, do all your drawing, tiling, etc..
Since the picturebox is double buffered, you won't see that drawing happening, and when you exit the Paint event, all your drawing will be refreshed to the screen by the control.

That is the relatively straight forward .Net way of doing a periodic update of a game on a picturebox, with the least amount of extra memory (other than what the picturebox is going to take), since it is already doublebuffered, you don't necessarily need to create your own.

Here is the simplest way it should be done.

Assume we set a timer to go off 32 times per second.
In the timer we would only do, using Picturebox1 for an example:

Picturebox1.Invalidate.

In the Paint Event of Picturebox1, we would do all the drawing for that frame (using the Graphics object passed to us).

That's it. That is all you need to have a periodic updating picturebox, regardless of the type of GDI+ based graphics your are going to do on it.
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.
Reply With Quote
  #7  
Old 03-23-2012, 10:06 PM
VB_Alien VB_Alien is offline
Contributor
 
Join Date: Apr 2004
Posts: 775
Default

I tried using Picturebox1.Invalidate in a timer and placed
the Draw_Tile sub in the paint event of picDest but all i got
was a big red boxed in "X" in the picturebox.

I was going to attach my little demo to see if you can figured
out what i'm doing wrong but i don't know how to. I have
permission to do it but there's no button to click on for sending
attachments.

Ok. I just needed to used the advance features when posting.

So, i you wouldn't mind, could you look at my code to see what
i'm doing wrong?

Everything i'm working from is in the Draw_Tile sub.

Thank-you

{edit: removed the attachment, as you still had the obj directory and bin directory with executable files in them}

Last edited by passel; 03-25-2012 at 01:33 PM.
Reply With Quote
  #8  
Old 03-25-2012, 01:47 PM
passel's Avatar
passel passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 7,862
Default

Ok, I removed your attachment because the "executable" type files, the .objs and exe's were not removed.
Normally I just remove the bin and obj directories before zipping, but in your case, you would delete the obj directory and then remove all the files under the bin directory except for your bmp file as your program depends on that file being where it is.

Here is a "working" version of your code. I trimmed out most of the unecessary stuff, so it is a bit smaller.
One issue, and perhaps you know this, but just wanted to get by the drawing issues first, is that normally in addition to creating the visual output you would be creating a "map" of what tiles are located where, in multiple layers.
For instance you have a number of "transparent" tile images on the bottom right, which I assume, would be drawn on top of some of the "background" tiles from the left side of the source tiles bitmap.
Right now my code "works", so you can select and place background tiles in the destination, and then put "transparent" tiles over top, but if you need to change the "transparent" tile and put another in that place, you will have two transparent tiles superimposed on each other.
You could "clear" the area first, by redrawing the "background" tile first, but since you don't have a structure tracking what tiles are being written in what positions in what layer, there is no way for the program to do that.
You would have to know what the background tile was, manually reselect and place it in that location, then select the new transparent tile you want and place it at the same location.
Anyway, rather than post the whole project, I'm just pasting the "working" code, so you can just comment out all your code if you want to compare, and paste this code in place, or replace it, or copy the project to a new location, and replace it, etc...

One thing to note, in .Net winforms, is that the control doesn't have a notion of autoredraw built in, so your code would have to redraw everything in the Paint event (using the Graphics object passed to you, which you didn't pass on or use in your DrawTile routine, which was one problem).
Since you don't have a structure to keep track of all the tiles and layers, there is no way to redraw everything in the paint event.
So, I went the route of loading a bitmap into the picturebox.
You then update this bitmap in your drawing routine, and then trigger the Paint event, which will redraw the screen using that image.
This gives your the (Autodraw) persistence that you need to draw once and the control will refresh the sceen from that whenever it needs to, and when you "tell" it to.
Code:
Public Class Form1

  Private srcRect As Rectangle = New Rectangle(0, 0, 32, 32)    'Use to select a tile from the source
  Private dstRect As Rectangle = New Rectangle(0,0,32,32)       'Use to place a tile on the destination
  Private _0_0_Rect As Rectangle = New Rectangle(0, 0, 32, 32)  'A 0,0 reference rectangle used to put and get from the 
  '                                                              picSelected tile image

  ' Holds the source tiles bitmap to be used to select tiles from
  Private src_Image As Bitmap = New Bitmap(Application.StartupPath & "\basis.bmp", True)

  'Bitmap that will contain all the sprites on a transparent background
  Private SelectedTile As Bitmap
  Private DestBmp As Bitmap   'Persistent place to hold our output map

  Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

    ' Loadsorce tiles into picturebox
    src_Image.MakeTransparent(Color.Magenta)  'Make the magneta areas of our source bitmap transparent
    picSource.Image = src_Image

    picSelected.Image = New Bitmap(picSelected.ClientSize.Width, picSelected.ClientSize.Height)

    'Have to bring shape controls to front
    'in order for them to display on picturebox
    picSource.SendToBack()
    Shape1.BringToFront()

    picDest.SendToBack()
    Shape2.BringToFront()

    DestBmp = New Bitmap(picDest.ClientSize.Width, picDest.ClientSize.Height)
    picDest.Image = DestBmp  'Create a "back buffer" to hold the output map, which is displayed when picDest is Painted
    '    Timer1.Enabled = True

  End Sub

  Private Sub picSource_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles picSource.MouseMove
    Dim intX As Integer
    Dim intY As Integer

    intX = Int(e.X / 32)
    intY = Int(e.Y / 32)

    srcRect.X = intX * 32
    srcRect.Y = intY * 32

    Shape1.Location = srcRect.Location
    picSource.Refresh()
  End Sub

  Private Sub picDest_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles picDest.MouseMove
    Dim intX As Integer
    Dim intY As Integer

    intX = Int(e.X / 32)
    intY = Int(e.Y / 32)

    dstRect.X = intX * 32
    dstRect.Y = intY * 32

    Shape2.Location = dstRect.Location
    Me.Text = dstRect.Location.ToString
    picDest.Refresh()
  End Sub

  Private Sub Shape1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Shape1.MouseDown
    Dim gr As Graphics = Graphics.FromImage(picSelected.Image)  'get the bitmap "backing" the picSelected
    gr.Clear(Color.Transparent)                                 'Clear it so we don't see previous image (since we have transparency)
    gr.DrawImage(picSource.Image, _0_0_Rect, srcRect, GraphicsUnit.Pixel) 'draw the tile from the source into the bitmap
    gr.Dispose()                                                'We don't need the graphics object any longer
    picSelected.Invalidate()                                    'have the picSelected refresh the screen image of itself
  End Sub

  Private Sub Shape2_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Shape2.MouseDown
    Dim gr As Graphics = Graphics.FromImage(picDest.Image)  'get the bitmap "backing" the picDest
    gr.DrawImage(picSelected.Image, dstRect, _0_0_Rect, GraphicsUnit.Pixel) 'draw the tile from the source into the bitmap
    gr.Dispose()                                            'We don't need the graphics object any longer
    picDest.Invalidate()                                    'have the picSelected refresh the screen image of itself
  End Sub

  Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick
    '   picDest.Invalidate()
  End Sub
End Class
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.

Last edited by passel; 03-25-2012 at 02:03 PM.
Reply With Quote
  #9  
Old 03-25-2012, 08:41 PM
surfR2911 surfR2911 is offline
Contributor
 
Join Date: Oct 2009
Posts: 719
Default

Quote:
I downloaded VB express 2010 free version about a
week ago and I'm totally lost. It sure has changed a lot
from the old VB6 program.
This is the understatement of the year.

Quote:
Originally Posted by passel
You could "clear" the area first, by redrawing the "background" tile first,
but since you don't have a structure tracking what tiles are being written in what positions in what layer,
there is no way for the program to do that.

You would have to know what the background tile was,
manually reselect and place it in that location,
then select the new transparent tile you want and place it at the same location.
I grabbed the VB_Alien project attachment before it got excised.
From the attached screenshot you can see the white box represents the target destination
(not the picbox that has the sprite-minus-bkgrnd-color transferred to to the left of the white box).

What passel said is true but doesn't really fully explain the "awkwardness" inherent in your approach
(as you delineated in your original post):
Quote:
Originally Posted by Vb_Alien
Anyway, I've been trying for a week now to get a clipped tile from a sheet
and draw it in either it's destination picturebox
or draw it to a picturebox that will be the same size
and the clipped tile and then draw it from there to it's destination.
I know you are more focused on coding issues than interface (UI) design but just to give you something to think about..

Under VB6, drag images where normally limited to icon size unless special techniques were used.
That limitation is not built into VB.Net.
You can make a multi-layer tile map by drop and dragging.
Drag images can even have fuzzy drop shadows in real time!

To make it relatively easy I would use a single "drag surface"
(e.graphics "space" - I don't know what dot net calls it maybe graphics "instance"?)

You can make it look like the tile map area is separated from the area that the tiles are dragged from using a grey (button color) "rect-as-stripe".

You can even set up a the tile object storage area as a fake-tabbed space
(tabs could be for "ground/dirt" tiles, grass tiles, snow tiles, water tiles, overlay objects like fences, etc),
where no more than 1/3 of the total form area is devoted to "drag from tiles storage".

The difficulty is the structure tracking.
Layer number, array of tiles used, walkable/not-walkable, maybe even sprite sheet sequencing if you use
animated water tiles -- all these would have to be recorded in some loadable/store-able way.

passel has already shown several ways that double linked lists can be used for tracking layered graphics
(mostly in VB6 but I'm sure there is a dot net way to use double linked lists as well).
I have a feeling array manipulation code will come in handy as well.
You might want to look into set up a class of two to automate handling of GC disposing in the finalize event
(but I'm just getting used to using VB.Net graphics so I don't know much about such class usage at this point).

I will keep an eye on things to see how this project develops..
Attached Images
File Type: jpg VB_Alien_TileMapping.JPG (168.7 KB, 8 views)

Last edited by surfR2911; 03-25-2012 at 09:02 PM.
Reply With Quote
  #10  
Old 03-25-2012, 10:59 PM
VB_Alien VB_Alien is offline
Contributor
 
Join Date: Apr 2004
Posts: 775
Default

Before coming here again, i had just finally got
tiles to draw from source to destination but i had
to use Bitblt to do it.

It took a while but i finally realized that by me
refreshing the picDest picturebox after drawing to
it, totally wiped out my drawings. The shape control,
that i use for visual tracking of where the tile is to be
placed, will draw boxes to the picturebox if i didn't
refresh the picturebox.

Yeah. I didn't have any kind of tile tracking in place.
I usually always start out with making sure the drawing
part works first before i add tracking to the code. In
this case, i'm glad i did it.

I'll give your code a try passel and i do appreciate the help.
I'm a complete noob at VB Express.

I'm not sure if i'm liking it as well as VB6. Things were so much
more simpler with that program.

---------------------------------------------------------------------------

Just to pick your brain a little, i was wondering if you were
aware of the "RedrawWindow" API?

I tried using it but i didn't work. I know it's me and not the
API but i was wondering if you ever tried using it before with
success.

Thank-you
Reply With Quote
  #11  
Old 03-25-2012, 11:22 PM
VB_Alien VB_Alien is offline
Contributor
 
Join Date: Apr 2004
Posts: 775
Default

It works great passel and with far less code.
Thank-you Thank-you Thank-you

Now i can port that code in a better made map
editor that i made and start laying out some
tiling routines.

I'd probably never use the built in GDI Plus for
gaming though. Bitblt is still the way to go in
gaming. This is according to your own tests,
speed wise.

For an editor though, GDI will do nicely.

Thank-you...
Reply With Quote
  #12  
Old 03-26-2012, 05:09 PM
hDC_0 hDC_0 is offline
Contributor

* Expert *
 
Join Date: Feb 2004
Posts: 537
Default Moving from VB6 to VB.Net

Quote:
Originally Posted by VB_Alien
I'm not sure if I'm liking it as well as VB6. Things were so much
more simpler with that program.
I agree, but how's that old movie line go - "I don't think we're in Kansas anymore.."

This quote says to me that you are still somewhat "API focused":
Quote:
Originally Posted by VB_Alien
Before coming here again, i had just finally got
tiles to draw from source to destination but i had
to use Bitblt to do it.

Just to pick your brain a little, i was wondering if you were
aware of the "RedrawWindow" API?

I tried using it but i didn't work. I know it's me and not the
API but i was wondering if you ever tried using it before with
success.
Here's an MSDN article you might be interested in reading:
Walkthrough: Calling Windows APIs (Visual Basic)..which says:
Quote:
Windows APIs represent a special category of interoperability.
Windows APIs do not use managed code, do not have built-in type libraries,
and use data types that are different than those used with Visual Studio.

Because of these differences, and because Windows APIs are not COM objects,
interoperability with Windows APIs and the .NET Framework is performed using platform invoke, or PInvoke.

Platform invoke is a service that enables managed code to call unmanaged functions implemented in DLLs.
You can use PInvoke in Visual Basic by using either the Declare statement or applying the DllImport attribute to an empty procedure.

Windows API calls were an important part of Visual Basic programming in the past,
but are seldom necessary with [Vb.Net].
Whenever possible, you should use managed code from the .NET Framework to perform tasks, instead of Windows API calls.
I may be wrong but this says to me:
1.) Using Windows APIs by using either the Declare statement or applying the DllImport attribute causes a PInvoke
2.) PInvoke crosses the line between managed and unmanaged code in .Net
3.) Using managed code over unmanaged is almost always to be preferred in VB.Net,
therefore if you can find a way to use system.drawing to accomplish something in VB.net,
it is almost always preferred over making an unnecessarily API call.

Now, specifically as regard using Bitblt versus TextureBrush in VB.net,
here's what passel (essentially) said (and forgive me for quoting somewhat out of context):
Quote:
So, Yay!!!, you don't have to resort to unmanaged GDI bitblt to get fast updates.
Using TextureBrush..will beat even bitblt in Windows Forms.
..from this post in this thread.

OnErr0r even said in post #6 of the same thread:
Quote:
I like the TextureBrush trick too.
That for me is almost the xvbt forum's version of the "Good Housekeeping Seal of Approval".

You really should at least try out using Texturebrush instead of the Bitblt API or DrawImage,
(I think DrawImage was what you were using in your attachment that was deleted).

Plus, hopefully, you will spend a lot of time studying that spritesheetanimation attachment that passel linked to above.

As regarding using power pack shape controls - why?
There are GDI+ drawing calls in VB.net that can pretty duplicate all of them.

Some links on drawing rectangles and other shapes --the VB.Net way.
vbHelper: Draw rectangles, ellipses, lines, arcs, pie slices, and text in VB.NET
vbHelper: Add a DrawRectangle method to the Graphics class that takes a RectangleF as a parameter in Visual Basic .NET

The general programming ability you gained as a VB6 programmer can be leveraged as you go into VB.net,
but you sort of have to learn to transition -- learn the "VB.Net way" and not use VB6 coding as a "crutch".
I don't consider myself an expert in VB.Net but I'm trying head down that long and winding road..

Last edited by hDC_0; 03-26-2012 at 05:34 PM.
Reply With Quote
  #13  
Old 03-26-2012, 08:45 PM
VB_Alien VB_Alien is offline
Contributor
 
Join Date: Apr 2004
Posts: 775
Default

I seen passels spinning cars demo and bitblt definitely was
running faster than drawimage, according the the fps.

OnError even said that unmanaged BitBlt is still being called
by BufferedGraphics.Render so apparently bitblt is wrapped
up inside VB Express.

Once i getting my map editor made and i make a small game
area to run some animations, i'll use bitblt in one game and
drawimage in another and see what the speed difference is.

VB Express is running off of the GDI Plus wrapper, so i would
agree with OnError that bitblt is definitely being called.
Reply With Quote
  #14  
Old 03-27-2012, 10:56 PM
VB_Alien VB_Alien is offline
Contributor
 
Join Date: Apr 2004
Posts: 775
Default

Trouble using UDT's in VB Express

Can UDT's still be used in express? I tried it and
every time i try to put information in the structure,
i get 2 warnings that pop up. Here they are:

Use the "new" keyword to create an object instance
Check to determine if the object is null before calling method

That second line is asking to make sure a line of structure code
is null before calling it and the whole structure is empty as far
as i know.

In VB6 in a boolean before making it true was automatically
set to false or an integer to 0. Is this still true with VB Express?

I had read that VB Express will not run the old VB6 UDT's and it
must be true because i haven't seen any code using it yet. Further
reading said that using classes in place of UDT's is the way to go
now. I know how to make the class but not sure how to call it in
at the form level. I'll give you a bit of code here and maybe someone
can tell me if this is how to call a class object.

Code:
Public Class TileData

    Public Structure SourceTiles
        Public Walkable As Boolean
        Public Transparent As Boolean
    End Structure

End Class
Call it at the form level:
Code:
Dim EditTiles(29,15) as TileData.SourceTiles
Can i use it in a multi-dimensional array like that?

That you
Reply With Quote
  #15  
Old 03-28-2012, 01:36 AM
passel's Avatar
passel passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 7,862
Default

Quote:
Originally Posted by VB_Alien View Post
I seen passels spinning cars demo and bitblt definitely was
running faster than drawimage, according the the fps.

OnError even said that unmanaged BitBlt is still being called
by BufferedGraphics.Render so apparently bitblt is wrapped
up inside VB Express.

Once i getting my map editor made and i make a small game
area to run some animations, i'll use bitblt in one game and
drawimage in another and see what the speed difference is.

VB Express is running off of the GDI Plus wrapper, so i would
agree with OnError that bitblt is definitely being called.
Unfortunately, Windows isn't very consistent across the various platfroms and versions of the operating systems.
And, there are a couple versions of the spinning car demo, the later one having the bitblt and texturebrush, in addition to draw image drawn from an array of bitmaps, rather than from a sprite sheet directly.
The spritesheet is divided up in the form load into a two dimensional array of bitmaps.

On the machine I was using, the drawimage was on par, perhaps a little slower than bitblt.
But what surfR2911 was refering to was not using drawimage, but a texturebrush, which was faster than using bitblt.

And you might want to know, if you run this same demo on a Windows 7 64-bit machine, then bitbit has been significantly slower on the few machines I've tried it on. Slower than drawimage by an easily noticeable amount. Texturebrush is still the clear winner in all cases I've tried.
For instance, I'll run it on this laptop (low end Win-7 64-bit) and for 400 cars I get:
GDI BitBlt 29-31
DrawImage 33-35
Brush array 48-49
New Brush 50
Tile Structure (brush) 50

If you're looking for a simple structure, I am using one in that example, shown in this post.
The drawimage in that version is still extremely slow.
I don't believe I posted an updated version that split the spritesheet into an array of bitmaps, and included the BufferedGraphics class, which sped all the methods up.
I described the modifications to the code in the thread that surfR2911 linked to above.
The other thread is in "archive" mode at this point, so I guess I can zip up the version I just ran on this laptop. I don't know if it is the latest, or not, but it does have the two changes I just mentioned, splitting the spritesheet up at form_load, and using BufferedGraphics to speed up the backbuffer to frontbuffer transfer (from 7-8ms, to 2-3 ms).
That will give a better comparison of the methods, and should be faster drawing then the version in the other thread.

p.s. While I'm at it, I had another project in that folder, which is an older version of something I played around with last year, but has been sitting idle since.
It was built on someone else's question and posted code.
I haven't looked at it in awhile so don't know how messy the code is, probably a hodge pod.
It doesn't do much.
It uses a seemless texture to provide a background so it looks like the cars are moving over it.
You press the up arrow to accelerate, and the down arrow to brake and reverse direction.
The left and right keys steer.
The combo box lets you pick the desired frame rate in milliseconds.
It defaults to 16 at startup, so should be running at about 62.5 hz.
I should have added a fps indicator of what you selected vs what you're getting. Perhaps I have that in a later version.
The program is using a second thread to try to invoke the car update routine at the interval you selected. In any case, the car is looking at the elapsed time, so moves further when the frame rate is slow, and shorter when the frame rate is high.
So if you pick a longer interval, say 50, then the update will be choppier, 20hz frame rate, but the distance covered should be the same, so the car should go the same distance per unit of time regardless of the frame rate.
On a fast computer (I7) I have at work, I think the program can run up to 500 hz (interval of 2). The smallest number supported is 1, 1000hz, but I don't have a machine that will do that.
Anyway, so the 503 program will move a pack of racing car images around on an "endless" background, and not much else. But if you set the interval to 10 (100hz), it should look pretty smooth.

Pretty much everything you normally do in VB is inside a class (the forms are clases), but if you want examples, probably search out posts by AtmaWeapon and your'e bound to find almost everything he does is implemented in classes, so should have plenty of examples to chose from.

A structure in .Net is much like a class, and can have procedures as part of the structure, as you'll see if you look at the link I gave above to the "tile" structure I used for one of the methods using texturebrushes I tried.
I won't go into the difference between classes and structures, as I should have been in bed hours ago.
There is plenty written with a little bit of searching.
Attached Files
File Type: zip SpriteSheetAnimation.zip (199.3 KB, 18 views)
File Type: zip 503_vb9_1.zip (96.2 KB, 12 views)
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.

Last edited by passel; 03-28-2012 at 01:47 AM.
Reply With Quote
  #16  
Old 03-28-2012, 11:58 AM
VB_Alien VB_Alien is offline
Contributor
 
Join Date: Apr 2004
Posts: 775
Default

Did you change any of the code in the Sprite sheet animation demo?
I had already downloaded this demo a week ago and the one you
just posted today and the latest version runs faster than the first one.

I took down some reading from the first version and the second one.

------------------------------------------------------------------------------------
*First version readings*

Running 25 car animations i get

DrawImage = 20-21 fps
New Brush = 64-65 fps
Brush Array = 64-65 fps
Structure Brush = 64-65 fps
Bitblt = 64-65 fps

Running 100 car animations, i get

DrawImade = 5-6 fps
New Brush = 63-64 fps
Brush Array = 63 to 65 fps
Structure Brush = 64-65 fps
Bitblt = 57-58 fps

Running 200 car animations, i get
DrawImade = 1-2 fps
New Brush = 27-28 fps
Brush Array = 27-28 fps
Structure Brush = 27-28 fps
Bitblt = 27 to 29 fps

File Size 5.22 KB (5,354 bytes)


*Second version Newer version?*

Running 25 car animations i get

DrawImage = 60 to 65 fps
New Brush = 63 to 65 fps
Brush Array = 64-65 fps
Structure Brush = 64-65 fps
Bitblt = 58 to 64 fps

Running 100 car animations, i get
DrawImade = 64-65 fps
New Brush = 64-65 fps
Brush Array = 63 to 65 fps
Structure Brush = 63 to 65 fps
Bitblt = 51 to 58 fps

Running 200 car animations, i get
DrawImade = 30 to 34 fps
New Brush = 41 to 50 fps
Brush Array = 38 to 49 fps
Structure Brush = 38 to 50 fps
Bitblt = 26 to 31 fps

File Size 7.15 KB (7,322 bytes)

The second version runs faster than the first one.
Yes, you proved your point. Bitblt is slower but i
think it depends on how you use it in code.

In the first set of readings, Bitblt almost held it own
through all the animations but in the second set of
readings bitblt was running a bit slower.

Thank-you
Reply With Quote
  #17  
Old 03-28-2012, 04:08 PM
VB_Alien VB_Alien is offline
Contributor
 
Join Date: Apr 2004
Posts: 775
Default

Well passel. It's been fun but i give up. VB express, in
my opinion is a piece of real garbage that ms just quickly
threw together to satisfy the vb6 crowd.

The most simplest of code, just does not want to run at all
in express. I can't even make my shape control move in the
right directions after i scroll the picture.

I work for 2 days to get a Structure to work and when i do, it
doesn't want to take or give data information.

Pictureboxes have no hDC, no Auto-redraw and won't act as
a container.

The stuff i am doing is very simple, yet express wants complicated
code to do simple things.

I just give up on it. I'll did around for something more suited to
my needs. Thank you passel for your help and advice.
Reply With Quote
  #18  
Old 03-28-2012, 08:21 PM
passel's Avatar
passel passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 7,862
Default

Quote:
Originally Posted by VB_Alien View Post
Did you change any of the code in the Sprite sheet animation demo?
I had already downloaded this demo a week ago and the one you
just posted today and the latest version runs faster than the first one.
...
The second version runs faster than the first one.
...

In the first set of readings, Bitblt almost held it own
through all the animations but in the second set of
readings bitblt was running a bit slower.
...
Bitblt was running relatively slower. The bitblt in the latest was faster than in the first.
I mentioned that while all the speeds improved, the percentage of improvement in bitblt speed was less than the percentage of improvement to the other drawing methods.
I mentioned that the primary difference for that speed up was the use of the BufferedGraphics Class.
After speeding up things as much as I could using the various drawing methods, the bottle neck was getting the memory buffer refreshed to the screen efficiently.
That process was taking 6-8ms, limiting the fps rate to a maximum of around 120 hz, if I did no drawing at all, just refreshing the display.
But once I used the BufferedGraphics Class, that memory buffer to screen refresh improved to 2-3ms to do the refresh, so that was 3-4 times faster than before.
Apparently using the BufferedGraphics Class also improved the drawing speed of the GDI+ methods (drawimage, fillRectangle, etc), but didn't improve the drawing speed of BitBlt, since the "drawing" was already as fast as it was going to go.
So, while the bitblt may have doubled in speed because the refresh was 3-4 times faster, the GDI+ methods may have quadrupled in speed because both the refresh and the drawing speeds improved.

The other "biggy" that I mentioned, was that using srcrect, dstrect with DrawImage is very slow. In the later test, I only used the srcrect,dstrect method at initialization to pull all the sprites from the spritesheet into an array of bitmaps, so each bitmap was the exact size of the sprite. and only the one sprite per bitmap.
This allowed just using the DrawImage method that wrote full source bitmap to a destionation point, so no possible stretching within the call itself, and it draws many times faster than srcrect to dstrect.

I have VB6 installed on my Win 7 64-bit machine, and I have a VB6 version of that spinning car demo, justing using bitblt, which was posted in that thread.
If I compile that, and run it outside the IDE on this machine, the speed is about the same as the bitblt version running under VB.Net.
If this was an XP 32-bit system (I don't have a Win 7 32-bit system to try it on), I believe the VB6 version will run much faster then VB.Net version in that environment.
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.

Last edited by passel; 03-28-2012 at 09:09 PM.
Reply With Quote
  #19  
Old 03-28-2012, 10:03 PM
VB_Alien VB_Alien is offline
Contributor
 
Join Date: Apr 2004
Posts: 775
Default

I'm using windows 7 - 64 bit to, but on a laptop. As i ran those demo's,
i could feel the back bottom of the laptop getting pretty hot. I'm going
to assume that demo would run faster on a desktop, since they tend
to run a little cooler than a laptop.

I'm curious as to what someone would get, running your demo in a
32 bit system. I'd say just half the speed that i got from it.....
Reply With Quote
  #20  
Old 03-29-2012, 06:22 AM
passel's Avatar
passel passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 7,862
Default

Since the data types and calls, and other things are 32-bit based, on a comparable processor, the 32-bit systems usually run this code faster.
When I compile on a 64-bit system and target 64-bit processor, I would expect it to be faster, but in the limited testing I've done, there is usally little improvement and in some cases, an executable targeting a 32-bit processor runs faster than the same code compiled a for 64-bit processor, so I suspect that there is some "thunking" going on, to convert parameters targeting 32-bit libraries running in 64-bit code.
Running code on a 64-bit operating system vs a 32-bit operating system will only make a significant speed difference if the code depends on the things that the 64-bit system makes available, i.e. huge amounts of memory, 64-bit (and above) data types, compiled against 64-bit versions of libraries, etc...
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
 
 
-->