Magic key to speed of B3D?

Blitz3D Forums/Blitz3D Programming/Magic key to speed of B3D?

Jimmy(Posted 2011) [#1]
I've posted about this before and Im still experiencing slowness in all kinds of graphics in B3D.

E.g. You cannot even make a simple game without getting 4fps instead of 60 (which is what I got 10 years ago). Using DRAWIMAGE instead of DRAWBLOCK did actually speed UP things up till about 15fps but thats still slow.

I've been told hardware gone totally 3D and that's the cause of all this. But as 3D fails miserable on this machine while ZSNESW emulator runs perfectly?

And so I got a copy of B3D free library Spritecontrol, am I on the right track?

/One too old chap

Last edited 2011


Yasha(Posted 2011) [#2]
One question: are you just trying to use DrawImage and 2D for your entire game, or are you using 2D commands over a 3D scene? When 2D and 3D are mixed, the graphics card has to switch modes frequently (or something like that, don't really know the details) which causes a much greater slowdown than simply using 2D or 3D by themselves. This also applies to commands such as Text (a single line of debug text in the corner is enough to seriously impact performance of a game by itself).

Even if your machine isn't very good (how bad?), as long as it has a graphics card at all, it should be able to draw the four-verts-two-tris needed for a quad. So you should be on the right track; at least give it a try, as it's highly unlikely to actually be worse than whatever you're getting currently, and it will be better if you plan to distribute the game to other people with more modern machines.


Jimmy(Posted 2011) [#3]
Its all old 2d commands, and no switching between 3d, tried experimenting with graphics3d and all those commands but no difference really worth mentioning.

Been trying the Spritecontrol demo which follows spritecontrol getting 5-8 fps.

My wish were to be able to develop for any kind of descent computers not only gamers super computer machines.

The same machine shows a whole new performance from other uses, both XP and Win7 does.
They seem to use the machine right, gets very smooth in browsers, in emulators. Its all very fast and fluidly.
Why cannot B3d do it?

Might it be a Directx thing? all drivers seem to be installed correctly, and also this is the same in XP and Win7, it doesn't matter, except in win7 the IDE is corrupt too, which is expected according to Blitz support.

The machine is an Intel 1.3Ghz with 800mhz memory.

I would like to add that what makes things slow in this particular code now is 350 16x16 sprites, if I were to have a single 800x600 instead, that works out great.. 60fps.
It seem to that many imagedraw is a nono ? It seem to be the *number* of DRAWIMAGE's thats makes things slow not the actual size of it alone.

But 350 16x16 sprites is not that asking much is it? 5fps?

Last edited 2011

Last edited 2011

Last edited 2011

Last edited 2011


Rroff(Posted 2011) [#4]
I'd look at the fastimage and fasttext libs for 2D rendering at any kinda speed.


Jimmy(Posted 2011) [#5]
Tried fastimage and fasttext, they did something but not much still under 30fps unluckily


jfk EO-11110(Posted 2011) [#6]
maybe it's a graphics card that has no true direcx7 support. these cards use an emulation based on dx10, that is slow and bugous. additionally, on dx10 as far as i know you can't have true dx7 installed anyway. then again, i hear from some ppl they haven't got any probs with b3d on dx10. try a 3d substitute, but avoid sprites. (quads instead)


mv333(Posted 2011) [#7]
But 350 16x16 sprites is not that asking much is it? 5fps?


Sounds strange. Are you able to post the code here, so we can try it out?


Yasha(Posted 2011) [#8]
maybe it's a graphics card that has no true direcx7 support. these cards use an emulation based on dx10, that is slow and bugous.


From the description above, DirectX being too advanced seems like the least of his worries - if anything, I'm wondering if the machine has a graphics card at all. (DX7 emulation isn't a problem because the only cards where it's necessary are many times faster than DX7 cards anyway.)

It seem to be the *number* of DRAWIMAGE's thats makes things slow not the actual size of it alone.


Yes, this is normal. The only difference the size of the image makes is the amount of memory to copy in the actual drawing operation, and even very old hardware can copy memory close to instantaneously, so size makes very little difference overall. If you can work out any way to reduce that number of images, e.g. rendering the scene in stages, staggering it somehow (what kind of scene are we talking about?), you'll probably help performance. On the other hand... 350 really isn't that many. Is there something else eating a large number of cycles in the same loop?


Jimmy(Posted 2011) [#9]
the intensly eating part is the simplest possible loop putting game tiles forming a puzzle world.
That's 2 nested for..next (X & Y) and contents is a single DRAWIMAGE or DRAWBLOCK. DRAWIMAGE
performing better so that's changed, but after that I cannot do so much more its out of my control
to do any better as I see it, and fyi 20x20 tiny tiles seem to be what B3D may handle the most without
bumping down from the 60fps/50fps threshold i wish to keep it above.

Last edited 2011


Jimmy(Posted 2011) [#10]
Did a simple test too check where the fault are, I did not get any smarter but here the test I made:

I get 67 millisec on the Million-pixel-test, and 22 millisec on the 900-16x16-tiles-test.
It would be interestting knowing what times other gets with this?

I'm not measuring 3D-2D aspects as that actually seem very slow on this machine for some reason.





also, this particular scroller demo below from the archives I think, crashes the machine giving bluescreen on XP at least.
Bluescreen is something I usually never experience but this code does it. Code is abit compressed and altered to not use external files only pic.


it complains about a "igxpdd32.dll", I've tried look it up without much luck understanding what it could be, as the driver is very fresh this seem very odd and out of place.

Here's the snippet that crashes the machine:

UPDATE! It seems to crash only when used with the default walls.png, any other pic seem to work fine.



Last edited 2011

Last edited 2011

Last edited 2011

Last edited 2011

Last edited 2011


Ross C(Posted 2011) [#11]
Can you the post the actual code your trying to run and having problems with in the first post? Also, how much memory does your computer have, and what kind of graphics card, and how much memory does that have?


Jimmy(Posted 2011) [#12]
Well its a complete game and the test above (900 16x16 tiles-test) has the snippet that eats all processing time, I tested this by by commenting that loop out the game runs just amazingly smooth.

The computer specification Intel Atom Z520 1.33Ghz, Intel SCH US15W 533Mhz bus. The GPU/VVPU is a GMA 500 rev 7 (SMA/UMA)
It has 2GB DDR2 SDRAM 667MHz actually and not 800Mhz as mentioned.

This is a well known weak system, at best a reasonable low end computer which is why I choose it to develop on. When things run on this one it would run on anything.

I also want to say I handles everything I want with much excellence no complain in raw processor power actually it's brilliant.
Except this one thing (which I get to later), but it deals with pretty much anything also in powermode. Chnaging mode does not drastically chagne the fps only batterytime, so that's why I keep it this way.

So it delivers everything I want except, putting many tiles on the screen. Neither 2d via 3D, or the "true 2d", whatever that would be as everyone tells me there is none, must be a simulation ending up in 3d in the actual API?

So two things are the only put down..
1) Pure power for putting huge amount of tiles up
2) and the power for doing realtime DSP on them while doing this (change them in whatever imaginable way, flipping, shifting a pixel, blurring etc) before actually puttting them up.

These are the only things I miss now is my conclusion.

The DSP part would be (If I understand things correctly) handled by something called "shaders" today?

Which would be the part of the graphics card that you could customize with your own code, while the rest of the card is locked up with more or less standardized accelerations.

My guess is that graphics vendors think of two things when they make their cards:

1) What would be nice to have for 3D acceleration for games
2) And what would be needed for Windows to happen, e.g. truetype fonts etc? (maybe this would also be "2D emulated things in 3D", maybe not? I don't know how Windows does this on any level nowadays, I would love to learn this if anyone knows)

When the graphic vendors do their job, these things would be valuable things to offer? And it would need some kind of standards, I have just not yet discovered these standards and APIS which hopefully reach for my needs.
I know OpenGL I know DirectX. But from all sources I've read I've yet to learn what they ACTUALLY DO, e.g. when things are emulated 2d or not, and even knowing what common 3D "accelaration" actually is?

Sorry if it seem to be a trivial question which you might flimpse away with your hand saying"its a weak system get a descent and better one!"

But these weak systems are surprisingly common, One part of me is horrified how they even are allowed to sell them as a product. As they make you wanna drag your hair out while using them.

Don't get me wrong, any new computer today, even the cheap cheapest ones, they're basically excellent machines. It such a pity they are rouined by whatever it is ruing MY xeperience and getting my these kind of problems. Batterytime and cheap bus architectures I guess makes this happen. Perhaps Intel and other "onboard" graphicschips that has enormous bad and well known bad reputations is the source, I don't know. I don't know but my guess now is buses, onboard graphics meaning draining the single bus with emense information.

Either way its sad there's now truly and practical low common standard for what works.

This is what makes Iphone for example such a great platform to develop for. You know what you get.


PS

I will certainly go back trying to figure what 3d graphics standards are all about, (APIs used , and whats actually accelerated on a lower level? it used to be line generation and memory copies).
if any of you would mind helping out that would be most helpful.

I rather get a helpful description in your own words rather then getting pointed to various links, I will certainly look for information myself, but its always nice to have
someone describe things for you. I'm by no means a beginner its only that 3D graphics startles me, and how its done now are very new, abstract and weird to me. From hardware to many kinds of APIs. It just feels very hard to grasp I admit.

Last edited 2011

Last edited 2011

Last edited 2011


Ross C(Posted 2011) [#13]
I'm assuming it's the one with the writepixelfast in it? I'm assuming you don't use that in your code, cause that will kill the speed. Locking and unlocking the buffer takes time too.

Away from that, usually most tile engines using 2d, use triple buffering, whereby you have an image that is the size of the viewable screen, plus has a border added, of a tile. So your image would be:

ImageHeight = Screen Resolution Height + (Tile Height * 2)
ImageWidth = Screen Resolution Width + (Tile Width * 2)

Then you fill your image with all the viewable tiles on screen, plus your border of tiles round the sides, on the part of the screen you can't see.

Now, say for instance you want to scroll up. You will move your image downwards to give that illusion. When you the image scrolls to it's very top edge, you:

Move the image up the distance of a tile height. Then, draw your image on top of itself, but instead of drawing at co-ords (0,0), you will draw your image at (0,Tile_Height). This will leave a row at the top of tiles that weren't overdrawn. Now draw the appropriate tiles in this space.

This process should be completed before the screen is refreshed. To the player, nothing will have moved at all, and the most you will need to draw (If you scroll diagonally, and scroll off both edges of the image), is 31 tiles, rather than 256 tiles. And this will only happen once every time the image is scrolled off it's edge. So, in reality, most frames the only thing you will need to draw (forgetting about animating tiles) is the main buffer image.

Do it this way and your tilemap will be super quick!


Jimmy(Posted 2011) [#14]
Thanks for your reply, yes but I'm using realtime replacement of tiles here so that is not a solution, each one of the tiles onscreen may sudden vary each frame.

The way you describe is one I've used in the passed though, both double and n buffering of 3. But here I need to actually blit all the tiles.

To not confuse this is the dreadful code below (DRAWIMAGE)

For h=0 To 29 : For w=0 To 29 : DrawImage tiles,(w Shl 4),(h Shl 4),map(w,h) : Next : Next


Ross C(Posted 2011) [#15]
Do you need to draw each tile every frame? If not, use the triple buffering method anyway. Don't draw what you don't need to. And are you using writepixelfast in your code?

Last edited 2011


Yasha(Posted 2011) [#16]
I'm using realtime replacement of tiles here so that is not a solution


Unless a large number (over 50%) of the tiles are changing each frame, it should work fine. To change a tile in the middle of the screen, just redraw that individual tile on the FakeBuffer image, and leave the others alone. You might have to take a couple of extra steps in working out the draw coordinates but that's about it.


Ross C(Posted 2011) [#17]
Also, try:

flip false

You may be wait for a vsync to come and just missing it, forcing the frame rate down. You'll need your own timing code though.


Ross C(Posted 2011) [#18]
UPDATED
Try this code. Press space bar to toggle triple buffering. Press the enter key to toggle writepixelfast. What kind of frame times are you getting?

Graphics 800,600
SetBuffer BackBuffer()

tile = CreateImage(40,40)
SetBuffer ImageBuffer(tile)
Color 0,0,0
Rect 0,0,40,40
Color 255,255,255
Rect 1,1,38,38

SetBuffer BackBuffer()


triple_buffer = 0

triple_image = CreateImage(800,600)

While Not KeyHit(1)

	Cls
	frame_time = MilliSecs() - temp_time
	temp_time = MilliSecs()

	If KeyHit(57) Then
		triple_buffer = 1 - triple_buffer
	End If
	If KeyHit(28) Then
		write_pixel = 1 - write_pixel
	End If

	If triple_buffer = 0 Then
		For xloop = 0 To 19
			For yloop = 0 To 14
				DrawImage tile,xloop*40,yloop*40
			Next
		Next
		If write_pixel = 1 Then
			LockBuffer BackBuffer()
			For xloop = 50 To 550
				For yloop = 50 To 550
					WritePixelFast xloop,yloop,0
				Next
			Next
			UnlockBuffer BackBuffer()
		End If

	Else
		SetBuffer ImageBuffer(triple_image)
			For xloop = 0 To 19
				For yloop = 0 To 14
					DrawImage tile,xloop*40,yloop*40
				Next
			Next

		If write_pixel = 1 Then
			LockBuffer ImageBuffer(triple_image)
			For xloop = 50 To 550
				For yloop = 50 To 550
					WritePixelFast xloop,yloop,0
				Next
			Next
			UnlockBuffer ImageBuffer(triple_image)
		End If
		SetBuffer BackBuffer()
		DrawImage triple_image,0,0
	End If


	
	
	Color 0,0,0
	Rect 0,0,500,20
	Color 255,255,255
	Text 0,0,"frame time - "+frame_time+" triple buffering = "+triple_buffer+" writepixelfast = "+write_pixel
	Flip

Wend
End


Last edited 2011


Jimmy(Posted 2011) [#19]
I see your points and I thought about it and did some tests.
The worst scenario that would stop this being a good idea for bad systems is doing the tileshift would become 2 huge blits within the same frame, simply too much.

Actually just above what manages (If using 1024x768 32bit or other resolutions didn't matter too much, roughly the same speed)

Did I miss how things should be buffered or was the idea this?


I want to skip for a while to the part about handling new tiles each frame
I got the time coming up with a brilliant masking system for selecting new tiles while thinking on everything else. That's usually how ideas arrive isn't it?

(Okay so I want to share this at least if anyone have the use for one:
In this scenario I would not use several frames, and I would do the actual blitting by putting numbers in those arrays, as usual and call the everyday rasterizing routine as above. After that I would negative all tilenumbers within the array that has been drawn. I would continue put in tiles as normal using positive numbers (0-255 for example). Negative would mean already blitted and it would know that and ignore. And keep making them negative after drawing them for new positive ones to arrive. If anyone could come up with a simpler way finding new tiles I would challenge them do this. I would love to hear a better suggestion.

In Blitz if your picky about speeds, but this is innerloops so you should be picky. ABS SGN and even X=-X is not that fast, even X=0-X is faster. Instead of using sign you could add 256 or something for everything already blitted, anything would go, right.)

If to go back to my own dilemma having two huge imageblits within the same frame did not work fast enough, sadly. Did I miss how you meant buffering? You blit to this screensized image with extra border with room for tiles all around. the actual scrolling is moving this single huge image onscreen. Until tileshifting is needed then you reblit this image in itself offseted as suited, give it new tiles onborder and wherever you need elsewhere in my case aswell.

I like the idea, and it emulates how hardware i'm used to and how they used to work .
Old computers had similiar problems even with hardware doing this, but then it was the problem moving 8192 bytes at once within the same frame making the same problem. My problem is exactly the same but moving 3145728 bytes /1024x768 32 bit). The old solve was to do it in chunks of 2 or 3. Im about tro try come up with a similiar scheme ontop of this. But they could change address for graphics and in a way that is a hardware acceleration when you think of it, suddenly changing buffer. Having several images several buffers splitting things up inside Blitz would make the same.

As you might notice I wish this to work as it is.

And I'm appreciating every little help I could get, just so you know.


Jimmy(Posted 2011) [#20]
I also want to reply there's no writepixelfast or locking/unlocking buffers in the game to slow it down.

@ Ross Thanks I tried your code and got 34 and 135 as results for it.


Yasha(Posted 2011) [#21]
In Blitz if your picky about speeds, but this is innerloops so you should be picky. ABS SGN and even X=-X is not that fast, even X=0-X is faster. Instead of using sign you could add 256 or something for everything already blitted, anything would go, right.)


I wanna stop you right there and say: this is inner loops, so Blitz3D is the wrong tool for the job. You can optimise muls and subs and whatever all you want, but Blitz3D uses a non-optimising (except for constant-folding) compiler, so the resulting code is very, very slow by the standards of high-performance programs (B3D doesn't even use registers for local variables, so any kind of math optimisation is pretty much meaningless). If you need this sort of thing, code in C and use GCC, which has a massively powerful optimiser that produces code up to 10 times faster than B3D, then link that stuff in as a DLL.

More importantly, muls and subs are definitely not your bottleneck; even unoptimised code like B3D's will be fast enough for your purposes. You've got to be using millions of operations per frame before any of this stuff even becomes measurable. Your bottleneck is going to be with graphics.

My problem is exactly the same but moving 3145728 bytes /1024x768 32 bit). The old solve was to do it in chunks of 2 or 3.


Are you trying to copy images by using WritePixelFast? EDIT: I see that you are not, OK.

Just use CopyRect: memory copy operations are fast enough to be considered effectively free on any modern (and this includes your spec) hardware. The fewer chunks the better: most of the time is taken up in the supporting operations, such as the surrounding loop, not the copy itself.

Last edited 2011


Jimmy(Posted 2011) [#22]
I use Blitz for prototyping only and have a good idea about speeds what too expect where. Perhaps it was a stupid general statement. As it uglifies your code following it.

Blitz gives me great speed n every respect but live DSP. (and blits) Which is the king of innerloops. I wouldn't not even try let Blitz do this.

I just want to try gett Blitz do one more thing and that's blit many tiles fast enough. Trying solving this would be an interesting journy and expereince to see if its possible on low end systems.

I'm not moving bytes by pixels, that was bad phrasing I reliased the minutie i wrote it. I do it by DRAWIMAGE alone sa of now. (tried using 3D libraries this week, tried bunch of things), not pixels though. Madness.

Last edited 2011

Last edited 2011


Ross C(Posted 2011) [#23]
Your results. Did you have triple buffering on? Did you have writepixelfast on? Did you try flip false?

Last edited 2011


Jimmy(Posted 2011) [#24]
@ Ross

These are the results

None 34
Triple 135
Writepixelfast 69
Writepixelfast & triple 168

FLIP FALSE on that test gave about -10 on all tests and wild flickering

Last edited 2011


Ross C(Posted 2011) [#25]
Ok, so you can draw 300 tiles, at 30 fps. Not great... I don't really think there is anywhere you can go with this, bar triple buffering the tiles and only updating the ones you need. But adding that extra drawimage, or drawing to an image buffer, seems to really kill the speed. You could try lowering the screen resolution, take debug off, lower the colour depth, run in full screen...

Did you give the blitzplus, or blitzmax demos a try?

Last edited 2011


Jimmy(Posted 2011) [#26]
Thanks for helping though. Much appriciated.

btw I did manage 350 at 50fps, but thats the true limit. Probably I should say 300 in practice as the CPU is actually waiting for each graphicsdrawingcommand so it does not only draws slow but also takes away that CPU time from you.. so 300tiles and som time doing actual other things I recognize would be enough for this.

I've tried Plus and Max, being not custom to the Max syntax very much I havn't gotten to do elaborated tests. But what I've seen it pretty much about the same.

Last edited 2011


Jimmy(Posted 2011) [#27]
So it turns out I really do need blit everything each and every frame.
That negative idea would have worked out great if only I didn't need and had a CLS initializing each frame erasing previous sprites and such.

One could course make things complex and cookiecut all sprites and blit back only what have change too. But I notice when things turns into a mush and this is it. Iv'e been on this path before, and I so would've loved a simpler one.

One old playconsole NeoGeo I think uses 384 16x512 sprites and nothing else no background no layers they get amazing tile layers out of this, at least 3 with 80 sprites or so left to play with as sprites. This works with this machine aswell using this technique.
But of course we're talking a miniscule 320x240 resolution now.

Is there a standard way stretching a 320x240 fullscreen nicely using 3d hardware to various resolutions, centring or stretching it fully?

Last night I tried only windows with graphics mode 3 (stretchable windows) But it does not look so great, very smooth but not very watchable in other ways. Stretching 320x240 to fullscreen in some nice way would suffice as a start.

I've done this on many systems before but never using 3D and never using Blitz.


Ross C(Posted 2011) [#28]
I think this will be software modified, regardless of what system you use, as most monitors can't display that resolution full screen. The only way I can think is to have a 512 x 256 texture, placed over the screen. You won't get a sharp grainy look though, unless you can turn off bi-linear filtering.

Have you tried a single surface quad solution? You'll need 4 vertices for each quad, so you can set up the UV co-ords properly. But, again, your machine doesn't look like it would handle loading a fairly large texture.

I can knock a test up, and see how your machine deals with it, if you want?


Jimmy(Posted 2011) [#29]
@Ross Quads have worked pretty well or so-so with other systems, almost doubled the graphics possible at least, not on this one though with the free 3d library Ive tried and neither some you pay for, they are simply too slow.

Trying the single surface quad idea sounds like an idea worth trying to me.

Other than that my only current solution im thiniking of is building on the fact using what's good on a bad system and that is 32x32 sprites seem to be as cheap as 16x16 ones, then you start to pay for size so i'm thinking about use that fact somehow.

Not by doing a border but halfway, stripes, as the for exampled the neogeo sprites and also as the border mentioned above too only cut it in four. I can see this working in a twowayscroller if Blitz does not have amazing punishment in drawing image in images, and as long as speed of the scroller is below tilesize.
But in a 4wayscroller i cannot think yet how stripes both horisontal and vertical at screen edges would work, not without overdrawing that would kill any cpu time in its way.

In a two way scroller I would begin with filling screen with vertical stripes of tiles first. This not only half the number sprites but effetively a 30x30 (900) would become 30 sprites. And while smoothscrolling these you also do something else. 30sprites are not that bad you have time left. And that is building your new 2 stripes. One each direction as you cannot predict lets say. This should work 2way. Imtrying to think out a 4way now. I'm not convinced also that Blitz isn't slow at blittining inside other buffers, Im just assume it will do this nicely now.

That quad sounds like a more tidy solution.

Last edited 2011


Ross C(Posted 2011) [#30]
Ok, i'm almost ready with this. Just having some issues lining up the texture onto the quads.


Ross C(Posted 2011) [#31]
Ok, (stupid floating point error!) I've got it. Run this and see what frame time you get with it. It changes 100 tiles per frame.
I'm on 17 millisecs with flip normal, and between 0 and 1 millisecs with flip false. Warning, messy code up ahead!
Textures are a pixel or so out, but it's a test
Also you can change the texture size to any multiple of 2. Try and keep the width and height the same size.
I have set up the camera, so each pixel on the screen matches the 3d units. Since it's 3d, the Y axis is inverted too.


Global screen_resolution_width = 800
Global screen_resolution_height = 600

Graphics3D screen_resolution_width,screen_resolution_height
SetBuffer BackBuffer()


Global camera = CreateCamera()
PositionEntity camera,screen_resolution_width*0.5,-screen_resolution_height*0.5,-screen_resolution_width*0.5
CameraRange camera,0.1,1000


s = CreateSphere()

EntityColor s,255,0,0
PositionEntity s,400,-300,0


Global texture_width# = 512
Global texture_height# = 512

Global num_tiles_wide = 12
Global num_tiles_high = 12

Global tile_width# = texture_width/num_tiles_wide
Global tile_height# = texture_height/num_tiles_high


;DebugLog("tile width = "+tile_width)

texture = CreateTexture(texture_width,texture_height)
SetBuffer TextureBuffer(texture)

For xloop = 0 To num_tiles_wide-1
	For yloop = 0 To num_tiles_wide-1
		Color Rand(0,255),Rand(0,255),Rand(0,255)
		Rect xloop*tile_width, yloop*tile_height,tile_width,tile_height
		;DebugLog("Rect("+(xloop*tile_width)+","+(yloop*tile_height)+","+tile_width+","+tile_height)
	Next
Next

SetBuffer BackBuffer()



Dim tilemap(num_tiles_wide,num_tiles_high,4)

tile_mesh = CreateMesh()
tile_surf = CreateSurface(tile_mesh)
create_mesh_tilemap(tile_mesh,tile_surf,num_tiles_wide,num_tiles_high,tile_width,tile_height)

EntityTexture tile_mesh,texture


While Not KeyHit(1)

	frame_time = MilliSecs() - temp_time
	temp_time = MilliSecs()


	For loop = 1 To 100
		change_tile(tile_surf,Rand(0,11),Rand(0,11),Rand(0,11),Rand(0,11))
	Next
	
	

	UpdateWorld
	RenderWorld
	Color 255,255,255
	Text 0,0,"frame time - "+frame_time
	Flip
	
Wend
End


Function create_mesh_tilemap(mesh,surf,num_x,num_y,width#,height#)

	Local index = -4

	For xloop = 0 To num_x-1
	
		For yloop = 0 To num_y-1
		
			index = index + 4
			tilemap(xloop,yloop,4) = index
			tilemap(xloop,yloop,0) = AddVertex(surf,xloop*width        ,-yloop*height         ,0, (1.0/num_x)*xloop            ,(1.0/num_y)*yloop            ) ; top left
			tilemap(xloop,yloop,1) = AddVertex(surf,xloop*width + width,-yloop*height         ,0, (1.0/num_x)*xloop+(1.0/num_x),(1.0/num_y)*yloop            ) ; lop right
			tilemap(xloop,yloop,2) = AddVertex(surf,xloop*width        ,-yloop*height - height,0, (1.0/num_x)*xloop            ,(1.0/num_y)*yloop+(1.0/num_y)) ; bottom left
			tilemap(xloop,yloop,3) = AddVertex(surf,xloop*width + width,-yloop*height - height,0, (1.0/num_x)*xloop+(1.0/num_x),(1.0/num_y)*yloop+(1.0/num_y)) ; bottom right
			
			;s = CreateSphere()
			;PositionEntity s,xloop*width        ,-yloop*height         ,0
			;s = CreateSphere()
			;PositionEntity s,xloop*width + width,-yloop*height         ,0
			;s = CreateSphere()
			;PositionEntity s,xloop*width        ,-yloop*height - height,0
			;s = CreateSphere()
			;PositionEntity s,xloop*width + width,-yloop*height - height,0
			
			;DebugLog("-----------------------------------")
			;DebugLog(" xloop("+xloop+") yloop("+yloop+")")
			;DebugLog("v0("+( xloop*width)       +","+( -yloop*height)        +",0)"+"("+((1.0/num_x)*xloop)+")")
			;DebugLog("v1("+((xloop*width)+width)+","+( -yloop*height)        +",0)"+"("+( ((1.0/num_x)*xloop)+1.0/num_x)+")")
			;DebugLog("v2("+( xloop*width)       +","+((-yloop*height)-height)+",0)")
			;DebugLog("v3("+((xloop*width)+width)+","+((-yloop*height)-height)+",0)")
			AddTriangle surf,tilemap(xloop,yloop,0),tilemap(xloop,yloop,1),tilemap(xloop,yloop,2)
			AddTriangle surf,tilemap(xloop,yloop,2),tilemap(xloop,yloop,1),tilemap(xloop,yloop,3)

		Next
		
	Next
	UpdateNormals mesh
	
End Function

;function to change the texture showing in tile (x,y) to texture tile (tx,ty)
Function change_tile(surf,x,y,tx,ty)

	VertexTexCoords (surf,tilemap(x,y,4)  ,(1.0/num_tiles_wide)*tx                     ,(1.0/num_tiles_high)*ty                     )
	VertexTexCoords (surf,tilemap(x,y,4)+1,(1.0/num_tiles_wide)*tx+(1.0/num_tiles_wide),(1.0/num_tiles_high)*ty                     )
	VertexTexCoords (surf,tilemap(x,y,4)+2,(1.0/num_tiles_wide)*tx                     ,(1.0/num_tiles_high)*ty+(1.0/num_tiles_high))
	VertexTexCoords (surf,tilemap(x,y,4)+3,(1.0/num_tiles_wide)*tx+(1.0/num_tiles_wide),(1.0/num_tiles_high)*ty+(1.0/num_tiles_high))
	
End Function


Last edited 2011

Last edited 2011

Last edited 2011

Last edited 2011


Jimmy(Posted 2011) [#32]
@Ross Thanks, I get 17 occasionally 38 with FLIP, and 18 with occasional 27 with FLIP FALSE. 20msec being exactly one whole frame in 50hz this does not look promising on this system. I dont get that difference you get at all.

Why do you think you aswell get 17 aswell with FLIP?


Ross C(Posted 2011) [#33]
My monitors vsync is set at 60hz ish, which flip true tells blitz to wait for a vsync before proceeding.

So your getting better results with the 3d quads then. You can even drop down your texture size to 256 x 256, and see if it helps. And move the camera in further. Fill rate might kill your pc, if the quads fill the entire screen, that's my worry. But on the plus side, changing 100 tiles per second isn't bad for that speed.

Unfortunelty, my PC has a quad core CPU, 2GB RAM, 512 MB of video RAM and a fairly mid range graphics card, so that isn't going to stress it...

Just out of curiosity, what does this tile map do? It seems to be very active.

Last edited 2011


Jimmy(Posted 2011) [#34]
With 3D quads, does the texturesize mean the same as tilesize? I'm not good with 3D but I will certanly start and get a feel for it, the squares overlap strangely but I guess that could be fixed later if it happens
to be the way to go?

The tilemap is just a simple puzzle arcade game, nothing fancy.

Here's a also some code for the technique of my idea earlier I came up with. Using the fact that bigger fewer blits are much cheaper than many smaller ones.

It seem to work with 11 or so columns. The problem on this system comes when increasing number of bars.
The result is surprisingly effeicent but have too many columns and strange things happens, instant blue screens, graphical weird effects that should not happen.
Put shortly windows and driver do not like it one bit.

I'm not putting in any new world yet, but it recycles columns. it prints a number on each columns so its visible what's going on.
But what does show up is always perfectly smooth, which could impress on a low system.

Too bad it goes blue or flickers with an copy of itself when doing above. This stops me at my tracks.

I would like to know if anyone else gets this weird behaviour.

Graphics 1024,600 : SetBuffer BackBuffer() : tiles=LoadAnimImage("tiles.bmp",32,32,0,64)
Dim map(512,512) : For y=0 To 511 : For x=0 To 511: map(x,y)=Rnd(23) : Next : Next

num=10 ; how many columns of tiles to use to fill screen here! 10 works here, but above that you could never know what happens.

bars=CreateImage(32,600,num+2) ; create num+2 sprites 32 x 512 (num*32 widescreen + 2 invisible edges)

scrollx=0 : scrolly=0
free=0

For n=0 To num
SetBuffer ImageBuffer(bars,free) : free=free+1 : If free>num Then free=0
For y=my To my+20 : DrawImage tiles,0,(y*32),map(mx,y) : 
Color 0,0,0:Text 0,0,Str$(n) : Text 0+1,0,Str$(n) :Text 0,0+1,Str$(n) : Text 0+1,0+1,Str$(n) : Next
mx=mx+1
Next
SetBuffer BackBuffer()

Repeat
Cls
scrollx=scrollx-1
scrollx=scrollx+1 : If scrollx => 32 Then scrollx=scrollx-32 : mx=mx+1 : free=free-1 : If free < 0 Then free=num
scrollx=scrollx-1 : If scrollx < 0 Then scrollx=scrollx+32 : mx=mx-1 : free=free+1 : If free > num Then free=0

temp=0 : n=free

Repeat
DrawImage bars,(temp*32)+scrollx-32,0,n
n=n+1 : If n>num Then n=0
temp=temp+1
Until temp=num

; When too much gone at left side Then 0 is free to recycle and should be renewed and put at rightmost of screen
; Draw mx,my vertical column into free sprite when needed

Flip
Until MouseDown(2)


Last edited 2011

Last edited 2011


Ross C(Posted 2011) [#35]
Texturesize does not exactly mean tile size. You set your tilesheet up, and tell the code how many tiles there will be horizontally, and how many tiles there will be vertically. The code will then construct the correct number of quads, and assign the UV's to them. The tiles overlapping, is an error in my UV mapping.

Only problem with smaller textures is, you will get pixel blurring. Best to decide on what size of tile you want, and keep that tiles sized at a multiple of 2. Say 32 pixels by 32 pixels. You would therefore fit 16 tiles horizontally and 16 tiles vertically, giving you 256 different tiles.

A problem I can see, is multiple layers of texture. You would need to create a quad layour for each layer. However, this does have it's advantages. You could have a shadow layer, and blend this done, give you nice alphaed shadows.

The code you posted above. Maybe your animated tiles are too large. Your loading in, essentially, a 2048 x 32 image. Iv'e seen instances of some machines not being happy about loading images larger than the desktop size, or above a certain size. My old computer refused to load 4096 wide images, so maybe that's causing a fair slowdown.


Jimmy(Posted 2011) [#36]
@Ross First I want to say thanks for making the test, is it hard to make an exact version? Okay so graphics memory is too limited, windows crashes, I never understood that limit until till now. Btw there was no slowdown mind you. Instead it gave an amazing and silky smooth performance. Sad it started crashing and behaving odd before even covering 1/3rd of screen so the practical use dropped dead.

Sorry but I am new to all this, so about textures, 8x8 would be too small then? Are there any simple examples on doing exact 2D using 3D? And so graphicscards actually blit using actually some kind of 3D coordinates? called UV coordinates? and doing 2D means converting then into 3Dcoordinates according to the current camera position?

But if there's no lines and dots. how does flash, pdf, truetype and such, how do they gain from all this 3D?

I never had any problems working on digital sizes such as 8x8 16x16 32x32 64x64, if this is all thats possible with 3D thats still okay. It would be great if someone wants to show a simplest example (I glanced at free 3D library a bit thats available here,too overwhelming just yet)


Yasha(Posted 2011) [#37]
Are there any simple examples on doing exact 2D using 3D? And so graphicscards actually blit using actually some kind of 3D coordinates? called UV coordinates? and doing 2D means converting then into 3Dcoordinates according to the current camera position?

But if there's no lines and dots. how does flash, pdf, truetype and such, how do they gain from all this 3D?


I smell a new convert in the making...

Take a look at these:
http://www.blitzbasic.com/Community/posts.php?topic=92270 (Version 2)
http://www.blitzbasic.com/Community/posts.php?topic=78304 (Version 1, simpler and smaller but less powerful)

I would have posted these before, but I'd assumed by your earlier comments that you'd actually been all over this sort of thing already.

You can find documentation here: http://www.blitzforum.de/help/?cat=8
It's in German, but Google Translate does an excellent job on it.

The API is a little odd in places (e.g. to create an image you specify the power of two, not the size itself), but the library (both versions) is really very good.


Ross C(Posted 2011) [#38]
Your using essentially a texture used to store every tile you need. Reason being, blitz performs better (up to certain limits), when you use less surfaces.

The code I did, creates 1 mesh, and builds quads within this mesh. Each quad is selecting a part of the texture by setting UV's. I have built a gif animation to explain a little better:

www.rcsolutions.webspace.virginmedia.com/3duvcoords.gif

Last edited 2011


Ross C(Posted 2011) [#39]
Took me so long to post that, i didn't see Yasha's comment. You'll def best using an existing solution. Building one yourself is a very time consuming task.


Jimmy(Posted 2011) [#40]
Yasha@ Yes my gray nut got quiet few holes on this subject as I've never been a fan of 3D, avoiding it like few and no time for new converters unluckily. But who knows, I might be learning 3D before I die. Dying hip.

@Ross That's a nice illustration, thanks!


Jimmy(Posted 2011) [#41]
As for anyone wondering about hardware acceleration on Flash, PDF's and TTF I want to mention my research here: they do it by using nVidia/ATI/Intel Shader model 2 and 3, and to be of practical use they need to have at least 128MB.

Other applications e.g. Photoshop have pickier standards such as Shader 3.0 and 256MB+.

They all use the GPU for their needs, I do not know if you should call this 2D or 3D. I would speculate that it's the shaders that makes all this possible, customizing GPU's code inside.

Just thought I'll share what I've learned.


Kenshin Yurihara(Posted 2011) [#42]
I will admit, my previous post was a little less truthful.
I get 60-120 FPS, with 528 16x16 pixels on the screen and them ALL
being checked for collision. Which is decent, I suppose.

Last edited 2011


Ross C(Posted 2011) [#43]
Wrong thread? :D


Kenshin Yurihara(Posted 2011) [#44]
No, was right thread. I had posted something before, at that same spot, that was talking about how the FPS should be fine, which they still should, but their a little less epic then I thought. I was talking about how, in my tile mapper, I have images, 16x16 on a 800x606 Screen, Check for collision with ALL of them at all times, translate them over to screen position by my "faked" camera(cause its 2D) and I still get 60-120 frames. I'm not sure thats even a accurate frame rate, because I threw in a simplistic particle system, emitting anywhere from 20-30 Particles every second and had like 10 or 20 of the emitters. So thats 200-300 or 400-600 Particles on screen every second. I still experience no drops lower then 60 FPS. My particles are also checked for collision at all times and translate over to the camera.

I went around the forums and found "Ignition" by Jeppe Nielsen and used his particle system, 5000 Particles on screen and moving, no lower then 60 FPS :D

Last edited 2011