speed speed speed!

JamesTheGreat
01-28-2002, 10:22 PM
I need to speed up my frames and I have created the most efficient code I can but it is still too slow. Currently I use the Polygon API to draw the images to an invisible picturebox and then use bitblt API to update the actualy display picbox. Are there any settings on VB, on the source picturebox, destination picturebox or forms that I can change to speed up this process at all??

Thanks,
James

Banjo
01-29-2002, 05:31 AM
It would be helpful for you to post your code, then we can have a look and see if we can improve it anywhere.

JamesTheGreat
01-29-2002, 10:21 AM
Okay here is my code for building the terrain. I am looking for efficient methods not only in the code but in VB and picturebox settings as well!

now lets see if I get this code tag working properly this time

:)


Public Sub DrawMesh()
Dim time As Double
' timer just to see how long it takes to draw 1 frame
time = Timer
Dim x, y As Integer
Dim Tiles_X, Tiles_Y As Long
' sets Tiles_X and Y to be the maximum pixel width and height
' of the map. (SizeofPointarray is how many points in the map)
' TileSize is the size of each point.
Tiles_X = (SizeOfPointArray - 1) * TileSize
Tiles_Y = (SizeOfPointArray - 1) * TileSize
Dim X2, Y2 As Byte
Dim colour As Long
Dim XPos1, YPos1, Xpos2, YPos2, XPos3, YPos3, YPos4 As Integer
Dim ScaleLeft, ScaleTop As Integer
' gets the current viewable co-ordinants
ScaleLeft = frmDisplayBuffer.Display.ScaleLeft
ScaleTop = frmDisplayBuffer.Display.ScaleTop
Dim c As Long
' DRAWS MAP TILES
' starts from Tiles_X-0 so that drawing is done from the "back"
' to the "front" and therefore tiles inthe back cannot overright
' tiles in the front
For x = Tiles_X To 0 Step -TileSize
X2 = x / TileSize
For y = 0 To Tiles_Y Step TileSize
Y2 = y / TileSize
' calculates the coordinants of this polygon
XPos1 = 2 * x + 2 * y
YPos1 = (Tiles_Y + TileSize) - x + y - P(X2, Y2).Height
Xpos2 = XPos1 + TileSize * 2
YPos2 = y - x + Tiles_Y - P(X2 + 1, Y2).Height
' second X for next Y
XPos3 = Xpos2 + TileSize * 2
YPos3 = y + TileSize - x + Tiles_Y - P(X2 + 1, (y + TileSize) / TileSize).Height
YPos4 = y - x + Tiles_Y + TileSize * 2 - P(X2, Y2 + 1).Height
' sets the coordinants into an array
PolygonPoints(0).x = XPos1 - ScaleLeft
PolygonPoints(0).y = YPos1 - ScaleTop
PolygonPoints(1).x = Xpos2 - ScaleLeft
PolygonPoints(1).y = YPos2 - ScaleTop
PolygonPoints(2).x = XPos3 - ScaleLeft
PolygonPoints(2).y = YPos3 - ScaleTop
PolygonPoints(3).x = Xpos2 - ScaleLeft
PolygonPoints(3).y = YPos4 - ScaleTop
' alters the colour of the polygon to fit the current
' time of day (eg. it will darken it if it's nighttime)
colour = ChangeLight(P(X2, Y2).colour, Light)
' tell the displaybuffer to use this new colour
frmDisplayBuffer.Display.FillColor = colour
frmDisplayBuffer.Display.ForeColor = colour
' draws polygon
Polygon frmDisplayBuffer.Display.HDC, PolygonPoints(0), 4
'End If
Next y
Next x
' Draws images onto the map, eg. trees, houses
For x = Tiles_X To 0 Step -TileSize
For y = 0 To Tiles_Y Step TileSize
' if image exists at this location
If P(x / TileSize, y / TileSize).OBJ > 0 Then
XPos1 = 2 * x + 2 * y - ScaleLeft
YPos1 = (Tiles_Y + TileSize) - x + y - P(x / TileSize, y / TileSize).Height - ScaleTop
' draw the image
DrawObject frmDisplayBuffer.Display, XPos1, YPos1, ObjectList(P(x / TileSize, y / TileSize).OBJ)
End If
Next y
Next x
' the image is now created, so copy the image from the buffer
' into the actual viewscreen
BitBlt frmDisplay.Display1.HDC, 0, 0, frmDisplayBuffer.Display.ScaleWidth, frmDisplayBuffer.Display.ScaleHeight, frmDisplayBuffer.Display.HDC, 0, 0, SRCCOPY
time = Timer - time
' display time it took to make this frame
frmDisplay.TimetoDraw.Text = Str(time) & "s"
' display average time
AverageDrawTime = (AverageDrawTime + time) / 2
frmDisplay.AverageTime.Text = Str(AverageDrawTime) & "s"
' clear the buffer to get it ready for the next frame
frmDisplayBuffer.Display.Cls
End Sub

Thinker
01-29-2002, 01:12 PM
I really didn't look carefully at your code, but one thing jumped out
at me immediately. It is a very common error, but can cause some
serious slowdowns. It is the way you declare your variables. Ex.

Dim x, y As Integer
Dim Tiles_X, Tiles_Y As Long

What is happening here is x and Tiles_X default to Variant because
you didn't explicitly give them a type. Better is

Dim x As Integer, y As Integer
Dim Tiles_X As Long, Tiles_Y As Long

You did this all the way through as far as I can see.

JamesTheGreat
01-29-2002, 04:13 PM
Hmm thanks a lot Tinker, I have always been under the assumption that variable declarations are associative. Well I geuss you learn something new every day! :)

JamesTheGreat
01-29-2002, 04:46 PM
Well there's no doubt in my mind now that VB doesnt' assosiate the type through a dim statement since after moving my definitions to each have their own line I realized a 20%+-5% increase in speed!

Any other insights would be helpful as I am trying to double my frame rate.

Thanks,
James

Mathijsken
06-01-2003, 09:16 AM
Yeeha,
finally the answer, i've got about a hundred variables defined like that in my game, and is does slows down your speed,

thanks guys

unrealportal
06-01-2003, 11:38 AM
I see u use a Double to measure time. Never use Doubles except if you need to do deal with many decimals.
Use Single variables instead, they're much faster, use less memory etc though not as precise as doubles, but I think single will be far enought for you. Only use double if very high precision is needed.

Denaes
06-02-2003, 05:39 AM
when you say:

Time = Timer

Is that a Timer object? I've heard that not only are they not precise, but take up extra resources. I'm not sure how much, but I've heard that the API function call:


Public Declare Function GetTickCount _
Lib "kernel32" () As Long

to get precise times.

Of course you have to subtract the End time from the start time for any period you want to count... 1,000 units in a second. I don't know if this will speed things up, but I think it should.

AndreRyan
06-02-2003, 05:46 AM
Timer is a global VB function for getting the current seconds since Midnight

unrealportal
06-02-2003, 06:22 AM
When writing timecritical code, never use a Timer control (that one you place on a form)
That's got 2 reasons:
1)They measure the specified interval from when the call returns back to the timer. That means if you want to time 0.01sec, and your code loop runs with 0.1sec it will be slightly delayed and you won't know.
2)The timers don't pass a DeltaTime variable that say exactly how much time has gone since last fire. You'll never be able wait exactly 0.01sec, it would be more like 0.01102739sec or something like that. So when calculating velocities you'll need to multiply with that deltatime, not what you expect the deltatime to be.
If you can, use the DirectXObject.TickCount instead (returns in millisec), 'cause that one's much faster that the Timer() function.

Denaes
06-02-2003, 07:07 AM
There's a DirectX timer function? I only knew about the API.

Well if this guy's not using DirectX I suppose the API would be the best bet. I'm not sure how reliable the Timer function is, since I've only seen the GetTickCount API function used in tutorials.

Is the directx timer funtion any better/faster/less resources?

unrealportal
06-02-2003, 07:33 AM
Okay, I recently made a test(research) project in ordewr to learn DirectDraw. After understanding blitting, I made an array of surfaces, and a small code that could cload any graphics into it with simple changes. I used the Timer function to time a 1/x framespersec delay. I turned out that I couldn't get any mroe than 18, maybe 20 in fps. Even if I turned the interval down to 0.0001 and more. After lookin' at some dx sdk sample/tutorials I tried out the TickCount() function. First it turned out to be wrong, then I realised it used millisecs.
With the TickCount() function I were able to accurately control the fps at i]any[/i] rate. 20, 40, 80, 100 even 200 in fps were poss. just by using that function. If you're first using DX/DD/DS in your app, use the TickCount() function. You can of course use the api call. I think both is fast enough, but I think that DX might be a little faster...

If you want, I can post up that project here :)

OnErr0r
06-02-2003, 07:51 AM
If you don't have a specific reason to use the Integer or Byte data types, use Long instead. Also, use integer division whenever possible (backslash instead of forward). I didn't see any .Refresh in your code, so I assume you're using AutoRedraw = False. If you are using AutoRedraw = True and Refreshing elsewhere, change to False and use the Paint event to BitBlt the image.

unrealportal
06-02-2003, 09:57 AM
Isn't the Integer variable using 2 bytes while the Long uses 4 bytes?
Wouldn't then the Integer be much faster? :huh:

OnErr0r
06-02-2003, 10:03 AM
32 bit processors deal with 32 bits of information at a time. In most cases its faster to use 32bit data types (or 4 bytes, like a long has). This uses the full extended registers in the native code.

Integer would use half the amount of memory, if you were talking about an array, that might be worth considering. But with single variables, that's not much of a consideration, given that most computers come with 128+ megs these days.

unrealportal
06-02-2003, 10:21 AM
Yes, the integers take less ram, but I'd say that few VB programs are going to be that big....

EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum